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