xref: /reactos/drivers/input/i8042prt/i8042prt.h (revision 1734f297)
1 #ifndef _I8042PRT_PCH_
2 #define _I8042PRT_PCH_
3 
4 #include <ntifs.h>
5 #include <kbdmou.h>
6 #include <ntdd8042.h>
7 
8 /*-----------------------------------------------------
9  * Structures
10  * --------------------------------------------------*/
11 
12 #define I8042PRT_TAG '2408'
13 
14 typedef enum
15 {
16 	dsStopped,
17 	dsStarted,
18 	dsPaused,
19 	dsRemoved,
20 	dsSurpriseRemoved
21 } DEVICE_STATE;
22 
23 typedef struct _I8042_SETTINGS
24 {
25 	/* Registry settings */
26 	ULONG KeyboardDataQueueSize;           /* done */
27 	UNICODE_STRING KeyboardDeviceBaseName;
28 	ULONG MouseDataQueueSize;              /* done */
29 	ULONG MouseResolution;
30 	ULONG MouseSynchIn100ns;
31 	ULONG NumberOfButtons;
32 	UNICODE_STRING PointerDeviceBaseName;
33 	ULONG PollStatusIterations;            /* done */
34 	ULONG OverrideKeyboardType;
35 	ULONG OverrideKeyboardSubtype;
36 	ULONG PollingIterations;               /* done */
37 	ULONG PollingIterationsMaximum;
38 	ULONG ResendIterations;                /* done */
39 	ULONG SampleRate;
40 	ULONG CrashOnCtrlScroll;               /* done */
41 } I8042_SETTINGS, *PI8042_SETTINGS;
42 
43 typedef enum _MOUSE_TIMEOUT_STATE
44 {
45 	NoChange,
46 	TimeoutStart,
47 	TimeoutCancel
48 } MOUSE_TIMEOUT_STATE, *PMOUSE_TIMEOUT_STATE;
49 
50 typedef struct _INTERRUPT_DATA
51 {
52 	PKINTERRUPT Object;
53 	ULONG Vector;
54 	KIRQL Dirql;
55 	KINTERRUPT_MODE InterruptMode;
56 	BOOLEAN ShareInterrupt;
57 	KAFFINITY Affinity;
58 } INTERRUPT_DATA, *PINTERRUPT_DATA;
59 
60 #define WHEEL_DELTA 120
61 
62 struct _I8042_KEYBOARD_EXTENSION;
63 typedef struct _I8042_KEYBOARD_EXTENSION *PI8042_KEYBOARD_EXTENSION;
64 struct _I8042_MOUSE_EXTENSION;
65 typedef struct _I8042_MOUSE_EXTENSION *PI8042_MOUSE_EXTENSION;
66 
67 /* PORT_DEVICE_EXTENSION.Flags */
68 #define KEYBOARD_PRESENT     0x01 /* A keyboard is attached */
69 #define KEYBOARD_CONNECTED   0x02 /* Keyboard received IOCTL_INTERNAL_KEYBOARD_CONNECT */
70 #define KEYBOARD_STARTED     0x04 /* Keyboard FDO received IRP_MN_START_DEVICE */
71 #define KEYBOARD_INITIALIZED 0x08 /* Keyboard interrupt is connected */
72 #define MOUSE_PRESENT        0x10 /* A mouse is attached */
73 #define MOUSE_CONNECTED      0x20 /* Mouse received IOCTL_INTERNAL_MOUSE_CONNECT */
74 #define MOUSE_STARTED        0x40 /* Mouse FDO received IRP_MN_START_DEVICE */
75 #define MOUSE_INITIALIZED    0x80 /* Mouse interrupt is connected */
76 
77 typedef struct _PORT_DEVICE_EXTENSION
78 {
79 	PUCHAR DataPort;    /* Usually 0x60 */
80 	PUCHAR ControlPort; /* Usually 0x64 */
81 	I8042_SETTINGS Settings;
82 	ULONG Flags;
83 
84 	PI8042_KEYBOARD_EXTENSION KeyboardExtension;
85 	INTERRUPT_DATA KeyboardInterrupt;
86 	PI8042_MOUSE_EXTENSION MouseExtension;
87 	INTERRUPT_DATA MouseInterrupt;
88 	PKINTERRUPT HighestDIRQLInterrupt;
89 	KSPIN_LOCK SpinLock;
90 	KIRQL HighestDirql;
91 
92 	OUTPUT_PACKET Packet;
93 	ULONG PacketResends;
94 	BOOLEAN PacketComplete;
95 	NTSTATUS PacketResult;
96 	UCHAR PacketBuffer[16];
97 	UCHAR PacketPort;
98 
99 	PIRP CurrentIrp;
100 	PDEVICE_OBJECT CurrentIrpDevice;
101 } PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION;
102 
103 typedef struct _I8042_DRIVER_EXTENSION
104 {
105 	UNICODE_STRING RegistryPath;
106 
107 	PORT_DEVICE_EXTENSION Port;
108 	LIST_ENTRY DeviceListHead;
109 	KSPIN_LOCK DeviceListLock;
110 } I8042_DRIVER_EXTENSION, *PI8042_DRIVER_EXTENSION;
111 
112 typedef enum _I8042_DEVICE_TYPE
113 {
114 	Unknown,
115 	Keyboard,
116 	Mouse,
117 	PhysicalDeviceObject
118 } I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE;
119 
120 typedef struct _FDO_DEVICE_EXTENSION
121 {
122 	I8042_DEVICE_TYPE Type;
123 	// Linkage in I8042_DRIVER_EXTENSION.DeviceListHead
124 	LIST_ENTRY ListEntry;
125 	// Associated device object (FDO)
126 	PDEVICE_OBJECT Fdo;
127 	// Associated device object (PDO)
128 	PDEVICE_OBJECT Pdo;
129 	// Lower device object
130 	PDEVICE_OBJECT LowerDevice;
131 	// Current state of the driver
132 	DEVICE_STATE PnpState;
133 
134 	PPORT_DEVICE_EXTENSION PortDeviceExtension;
135 } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
136 
137 typedef struct _I8042_KEYBOARD_EXTENSION
138 {
139 	FDO_DEVICE_EXTENSION Common;
140 	CONNECT_DATA KeyboardData;
141 	INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; /* FIXME: IsrWritePort ignored */
142 	KDPC DpcKeyboard;
143 
144 	KEYBOARD_ATTRIBUTES KeyboardAttributes;
145 
146 	KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators;
147 
148 	KEYBOARD_SCAN_STATE KeyboardScanState;
149 	BOOLEAN KeyComplete;
150 	PKEYBOARD_INPUT_DATA KeyboardBuffer;
151 	ULONG KeysInBuffer;
152 
153 	/* Power keys items */
154 	ULONG ReportedCaps;
155 	ULONG NewCaps;
156 	ULONG LastPowerKey;
157 	UNICODE_STRING PowerInterfaceName;
158 	PIO_WORKITEM PowerWorkItem;
159 	PIRP PowerIrp;
160 
161 	/* Debug items */
162 	ULONG ComboPosition;
163 	PIO_WORKITEM DebugWorkItem;
164 	BOOLEAN TabPressed;
165 } I8042_KEYBOARD_EXTENSION;
166 
167 typedef enum _I8042_MOUSE_TYPE
168 {
169 	GenericPS2,
170 	Intellimouse,
171 	IntellimouseExplorer,
172 	Ps2pp
173 } I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE;
174 
175 typedef struct _I8042_MOUSE_EXTENSION
176 {
177 	FDO_DEVICE_EXTENSION Common;
178 	CONNECT_DATA MouseData;
179 	INTERNAL_I8042_HOOK_MOUSE MouseHook;
180 	KDPC DpcMouse;
181 
182 	MOUSE_ATTRIBUTES MouseAttributes;
183 
184 	MOUSE_STATE MouseState;
185 	BOOLEAN MouseComplete;
186 	MOUSE_RESET_SUBSTATE MouseResetState;
187 	PMOUSE_INPUT_DATA MouseBuffer;
188 	ULONG MouseInBuffer;
189 	USHORT MouseButtonState;
190 	ULARGE_INTEGER MousePacketStartTime;
191 
192 	KTIMER TimerMouseTimeout;
193 	KDPC DpcMouseTimeout;
194 	MOUSE_TIMEOUT_STATE MouseTimeoutState;
195 	BOOLEAN MouseTimeoutActive;
196 
197 	UCHAR MouseLogiBuffer[3];
198 	I8042_MOUSE_TYPE MouseType;
199 } I8042_MOUSE_EXTENSION;
200 
201 typedef struct _I8042_HOOK_WORKITEM
202 {
203 	PIO_WORKITEM WorkItem;
204 	PIRP Irp;
205 } I8042_HOOK_WORKITEM, *PI8042_HOOK_WORKITEM;
206 
207 /*-----------------------------------------------------
208  * Some defines
209  * --------------------------------------------------*/
210 
211 #define MAX(a, b) ((a) >= (b) ? (a) : (b))
212 
213 #define KEYBOARD_POWER_CODE 0x5E
214 #define KEYBOARD_SLEEP_CODE 0x5F
215 #define KEYBOARD_WAKE_CODE  0x63
216 
217 /*-----------------------------------------------------
218  * Controller commands
219  * --------------------------------------------------*/
220 
221 #define KBD_READ_MODE      0x20
222 #define KBD_WRITE_MODE     0x60
223 #define MOUSE_ENAB         0xA8
224 #define MOUSE_LINE_TEST    0xA9
225 #define CTRL_SELF_TEST     0xAA
226 #define KBD_CLK_DISABLE    0xAD
227 #define KBD_CLK_ENABLE     0xAE
228 #define CTRL_WRITE_MOUSE   0xD4
229 
230 /*-----------------------------------------------------
231  * Keyboard commands
232  * --------------------------------------------------*/
233 
234 #define KBD_CMD_SET_LEDS   0xED
235 #define KBD_CMD_GET_ID     0xF2
236 
237 /*-----------------------------------------------------
238  * Keyboard responses
239  * --------------------------------------------------*/
240 
241 #define KBD_SELF_TEST_OK   0x55
242 #define KBD_ACK            0xFA
243 #define KBD_NACK           0xFC
244 #define KBD_RESEND         0xFE
245 
246 /*-----------------------------------------------------
247  * Controller status register bits
248  * --------------------------------------------------*/
249 
250 #define KBD_OBF            0x01
251 #define KBD_IBF            0x02
252 #define MOU_OBF            0x20
253 #define KBD_PERR           0x80
254 
255 /*-----------------------------------------------------
256  * Controller command byte bits
257  * --------------------------------------------------*/
258 
259 #define CCB_KBD_INT_ENAB   0x01
260 #define CCB_MOUSE_INT_ENAB 0x02
261 #define CCB_SYSTEM_FLAG    0x04
262 #define CCB_KBD_DISAB      0x10
263 #define CCB_MOUSE_DISAB    0x20
264 #define CCB_TRANSLATE      0x40
265 
266 /*-----------------------------------------------------
267  * LED bits
268  * --------------------------------------------------*/
269 
270 #define KBD_LED_SCROLL     0x01
271 #define KBD_LED_NUM        0x02
272 #define KBD_LED_CAPS       0x04
273 
274 /*-----------------------------------------------------
275  * Mouse commands
276  * --------------------------------------------------*/
277 
278 #define MOU_ENAB           0xF4
279 #define MOU_CMD_RESET      0xFF
280 
281 /*-----------------------------------------------------
282  * Mouse responses
283  * --------------------------------------------------*/
284 
285 #define MOUSE_ACK          0xFA
286 #define MOUSE_ERROR        0xFC
287 #define MOUSE_NACK         0xFE
288 
289 /*-----------------------------------------------------
290  * Prototypes
291  * --------------------------------------------------*/
292 
293 /* createclose.c */
294 
295 IO_WORKITEM_ROUTINE i8042SendHookWorkItem;
296 
297 _Dispatch_type_(IRP_MJ_CREATE)
298 DRIVER_DISPATCH i8042Create;
299 
300 _Dispatch_type_(IRP_MJ_CLEANUP)
301 DRIVER_DISPATCH i8042Cleanup;
302 
303 _Dispatch_type_(IRP_MJ_CLOSE)
304 DRIVER_DISPATCH i8042Close;
305 
306 /* keyboard.c */
307 
308 NTSTATUS NTAPI
309 i8042SynchWritePortKbd(
310 	IN PVOID Context,
311 	IN UCHAR Value,
312 	IN BOOLEAN WaitForAck);
313 
314 DRIVER_STARTIO i8042KbdStartIo;
315 
316 DRIVER_DISPATCH i8042KbdDeviceControl;
317 
318 DRIVER_DISPATCH i8042KbdInternalDeviceControl;
319 
320 KSERVICE_ROUTINE i8042KbdInterruptService;
321 
322 /* i8042prt.c */
323 
324 DRIVER_ADD_DEVICE i8042AddDevice;
325 
326 BOOLEAN
327 i8042PacketIsr(
328 	IN PPORT_DEVICE_EXTENSION DeviceExtension,
329 	IN UCHAR Output);
330 
331 NTSTATUS
332 i8042StartPacket(
333 	IN PPORT_DEVICE_EXTENSION DeviceExtension,
334 	IN PFDO_DEVICE_EXTENSION FdoDeviceExtension,
335 	IN PUCHAR Bytes,
336 	IN ULONG ByteCount,
337 	IN PIRP Irp);
338 
339 /* misc.c */
340 
341 DRIVER_DISPATCH ForwardIrpAndForget;
342 
343 NTSTATUS
344 DuplicateUnicodeString(
345 	IN ULONG Flags,
346 	IN PCUNICODE_STRING SourceString,
347 	OUT PUNICODE_STRING DestinationString);
348 
349 /* mouse.c */
350 
351 VOID
352 i8042MouHandle(
353 	IN PI8042_MOUSE_EXTENSION DeviceExtension,
354 	IN UCHAR Output);
355 
356 VOID
357 i8042MouHandleButtons(
358 	IN PI8042_MOUSE_EXTENSION DeviceExtension,
359 	IN USHORT Mask);
360 
361 NTSTATUS
362 i8042MouInitialize(
363 	IN PI8042_MOUSE_EXTENSION DeviceExtension);
364 
365 DRIVER_DISPATCH i8042MouInternalDeviceControl;
366 
367 KSERVICE_ROUTINE i8042MouInterruptService;
368 
369 /* pnp.c */
370 
371 BOOLEAN
372 i8042ChangeMode(
373 	IN PPORT_DEVICE_EXTENSION DeviceExtension,
374 	IN UCHAR FlagsToDisable,
375 	IN UCHAR FlagsToEnable);
376 
377 _Dispatch_type_(IRP_MJ_PNP)
378 DRIVER_DISPATCH i8042Pnp;
379 
380 /* ps2pp.c */
381 VOID
382 i8042MouHandlePs2pp(
383 	IN PI8042_MOUSE_EXTENSION DeviceExtension,
384 	IN UCHAR Input);
385 
386 /* readwrite.c */
387 
388 VOID
389 i8042Flush(
390 	IN PPORT_DEVICE_EXTENSION DeviceExtension);
391 
392 BOOLEAN
393 i8042IsrWritePort(
394 	IN PPORT_DEVICE_EXTENSION DeviceExtension,
395 	IN UCHAR Value,
396 	IN UCHAR SelectCmd OPTIONAL);
397 
398 NTSTATUS
399 i8042ReadData(
400 	IN PPORT_DEVICE_EXTENSION DeviceExtension,
401 	IN UCHAR StatusFlags,
402 	OUT PUCHAR Data);
403 #define i8042ReadKeyboardData(DeviceExtension, Data) \
404 	i8042ReadData(DeviceExtension, KBD_OBF, Data)
405 #define i8042ReadMouseData(DeviceExtension, Data) \
406 	i8042ReadData(DeviceExtension, MOU_OBF, Data)
407 
408 NTSTATUS
409 i8042ReadDataWait(
410 	IN PPORT_DEVICE_EXTENSION DeviceExtension,
411 	OUT PUCHAR Data);
412 
413 NTSTATUS
414 i8042ReadStatus(
415 	IN PPORT_DEVICE_EXTENSION DeviceExtension,
416 	OUT PUCHAR Status);
417 
418 NTSTATUS NTAPI
419 i8042SynchReadPort(
420 	IN PVOID Context,
421 	OUT PUCHAR Value,
422 	IN BOOLEAN WaitForAck);
423 
424 NTSTATUS NTAPI
425 i8042SynchWritePort(
426 	IN PPORT_DEVICE_EXTENSION DeviceExtension,
427 	IN UCHAR Port,
428 	IN UCHAR Value,
429 	IN BOOLEAN WaitForAck);
430 
431 BOOLEAN
432 i8042Write(
433 	IN PPORT_DEVICE_EXTENSION DeviceExtension,
434 	IN PUCHAR addr,
435 	IN UCHAR data);
436 
437 /* registry.c */
438 
439 NTSTATUS
440 ReadRegistryEntries(
441 	IN PUNICODE_STRING RegistryPath,
442 	OUT PI8042_SETTINGS Settings);
443 
444 /* hwhacks.c */
445 
446 VOID
447 NTAPI
448 i8042InitializeHwHacks(
449     VOID);
450 
451 enum _FLAGS
452 {
453     FL_NOLOOP = 0x01,
454     FL_INITHACK = 0x02,
455 };
456 
457 extern ULONG i8042HwFlags;
458 
459 #endif /* _I8042PRT_PCH_ */
460