Copy wininet to branch
[reactos.git] / reactos / drivers / input / psaux / controller.c
1 // All or parts of this file are from CHAOS (http://www.se.chaosdev.org/).
2 // CHAOS is also under the GNU General Public License.
3
4 #include <ddk/ntddk.h>
5
6 #include "controller.h"
7 #include "keyboard.h"
8 #include "mouse.h"
9
10 /* This reads the controller status port, and does the appropriate
11 action. It requires that we hold the keyboard controller spinlock. */
12
13 int controller_read_data(void);
14 unsigned handle_event(void)
15 {
16 unsigned status = controller_read_status();
17 unsigned int work;
18
19 for(work = 0; (work < 10000) && ((status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0); work++)
20 {
21 unsigned scancode;
22
23 scancode = controller_read_input();
24
25 #if 0
26 /* Ignore error bytes. */
27
28 if((status &(CONTROLLER_STATUS_GENERAL_TIMEOUT |
29 CONTROLLER_STATUS_PARITY_ERROR)) == 0)
30 #endif
31 {
32 if((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0)
33 {
34 // mouse_handle_event(scancode); we just use the mouse handler directly..
35 }
36 else
37 {
38 // keyboard_handle_event(scancode);
39 }
40 }
41
42 status = controller_read_status();
43
44 }
45
46 if(work == 10000)
47 {
48 DbgPrint("PSAUX: Keyboard controller jammed\n");
49 }
50
51 return status;
52 }
53
54 /* Wait for keyboard controller input buffer to drain.
55 Quote from PS/2 System Reference Manual:
56 "Address hex 0060 and address hex 0064 should be written only
57 when the input-buffer-full bit and output-buffer-full bit in the
58 Controller Status register are set 0." */
59
60 void controller_wait(void)
61 {
62 unsigned long timeout;
63 LARGE_INTEGER Millisecond_Timeout;
64
65 Millisecond_Timeout.QuadPart = -10000L;
66
67 for(timeout = 0; timeout < CONTROLLER_TIMEOUT; timeout++)
68 {
69 // "handle_keyboard_event()" will handle any incoming events
70 // while we wait -- keypresses or mouse movement
71
72 unsigned char status = handle_event();
73
74 if((status & CONTROLLER_STATUS_INPUT_BUFFER_FULL) == 0) return;
75
76 // Sleep for one millisecond
77 KeDelayExecutionThread (KernelMode, FALSE, &Millisecond_Timeout);
78 }
79
80 DbgPrint("PSAUX: Keyboard timed out\n");
81 }
82
83 /* Wait for input from the keyboard controller. */
84
85 int controller_wait_for_input(void)
86 {
87 int timeout;
88 LARGE_INTEGER Millisecond_Timeout;
89
90 Millisecond_Timeout.QuadPart = -10000L;
91
92 for(timeout = KEYBOARD_INIT_TIMEOUT; timeout > 0; timeout--)
93 {
94 int return_value = controller_read_data();
95
96 if(return_value >= 0) return return_value;
97
98 // Sleep for one millisecond
99 KeDelayExecutionThread (KernelMode, FALSE, &Millisecond_Timeout);
100 }
101
102 DbgPrint("PSAUX: Timed out on waiting for input from controller\n");
103 return -1;
104 }
105
106 /* Write a command word to the keyboard controller. */
107
108 void controller_write_command_word(unsigned data)
109 {
110 controller_wait();
111 controller_write_command(data);
112 }
113
114 /* Write an output word to the keyboard controller. */
115
116 void controller_write_output_word(unsigned data)
117 {
118 controller_wait();
119 controller_write_output(data);
120 }
121
122 /* Empty the keyboard input buffer. */
123
124 void keyboard_clear_input(void)
125 {
126 int max_read;
127
128 for(max_read = 0; max_read < 100; max_read++)
129 {
130 if(controller_read_data() == KEYBOARD_NO_DATA)
131 {
132 break;
133 }
134 }
135 }
136
137 /* Read data from the keyboard controller. */
138
139 int controller_read_data(void)
140 {
141 int return_value = KEYBOARD_NO_DATA;
142 unsigned status;
143
144 status = controller_read_status();
145 if(status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL)
146 {
147 unsigned data = controller_read_input();
148
149 return_value = data;
150 if(status &(CONTROLLER_STATUS_GENERAL_TIMEOUT |
151 CONTROLLER_STATUS_PARITY_ERROR))
152 {
153 return_value = KEYBOARD_BAD_DATA;
154 }
155 }
156 return return_value;
157 }