ReactOS  0.4.14-dev-50-g13bb5e2
pnp.c File Reference
#include "i8042prt.h"
#include <debug.h>
Include dependency graph for pnp.c:

Go to the source code of this file.

Functions

BOOLEAN i8042ChangeMode (IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
 
static NTSTATUS i8042BasicDetect (IN PPORT_DEVICE_EXTENSION DeviceExtension)
 
static VOID i8042DetectKeyboard (IN PPORT_DEVICE_EXTENSION DeviceExtension)
 
static VOID i8042DetectMouse (IN PPORT_DEVICE_EXTENSION DeviceExtension)
 
static NTSTATUS i8042ConnectKeyboardInterrupt (IN PI8042_KEYBOARD_EXTENSION DeviceExtension)
 
static NTSTATUS i8042ConnectMouseInterrupt (IN PI8042_MOUSE_EXTENSION DeviceExtension)
 
static NTSTATUS EnableInterrupts (IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
 
static NTSTATUS StartProcedure (IN PPORT_DEVICE_EXTENSION DeviceExtension)
 
static NTSTATUS i8042PnpStartDevice (IN PDEVICE_OBJECT DeviceObject, IN PCM_RESOURCE_LIST AllocatedResources, IN PCM_RESOURCE_LIST AllocatedResourcesTranslated)
 
static VOID i8042RemoveDevice (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI i8042Pnp (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 

Function Documentation

◆ EnableInterrupts()

static NTSTATUS EnableInterrupts ( IN PPORT_DEVICE_EXTENSION  DeviceExtension,
IN UCHAR  FlagsToDisable,
IN UCHAR  FlagsToEnable 
)
static

Definition at line 380 of file pnp.c.

384 {
385  i8042Flush(DeviceExtension);
386 
387  if (!i8042ChangeMode(DeviceExtension, FlagsToDisable, FlagsToEnable))
388  return STATUS_UNSUCCESSFUL;
389 
390  return STATUS_SUCCESS;
391 }
VOID i8042Flush(IN PPORT_DEVICE_EXTENSION DeviceExtension)
Definition: readwrite.c:21
BOOLEAN i8042ChangeMode(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
Definition: pnp.c:37
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
return STATUS_SUCCESS
Definition: btrfs.c:2966

Referenced by EHCI_InterruptDpc(), HalpInitializePICs(), and StartProcedure().

◆ i8042BasicDetect()

static NTSTATUS i8042BasicDetect ( IN PPORT_DEVICE_EXTENSION  DeviceExtension)
static

Definition at line 77 of file pnp.c.

79 {
81  ULONG ResendIterations;
82  UCHAR Value = 0;
83 
84  /* Don't enable keyboard and mouse interrupts, disable keyboard/mouse */
85  i8042Flush(DeviceExtension);
88 
89  i8042Flush(DeviceExtension);
90 
91  /* Issue a CTRL_SELF_TEST command to check if this is really an i8042 controller */
92  ResendIterations = DeviceExtension->Settings.ResendIterations + 1;
93  while (ResendIterations--)
94  {
95  if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST))
96  {
97  WARN_(I8042PRT, "Writing CTRL_SELF_TEST command failed\n");
98  return STATUS_IO_TIMEOUT;
99  }
100 
101  Status = i8042ReadDataWait(DeviceExtension, &Value);
102  if (!NT_SUCCESS(Status))
103  {
104  WARN_(I8042PRT, "Failed to read CTRL_SELF_TEST response, status 0x%08lx\n", Status);
105  return Status;
106  }
107 
108  if (Value == KBD_SELF_TEST_OK)
109  {
110  INFO_(I8042PRT, "CTRL_SELF_TEST completed successfully!\n");
111  break;
112  }
113  else if (Value == KBD_RESEND)
114  {
115  TRACE_(I8042PRT, "Resending...\n");
117  }
118  else
119  {
120  WARN_(I8042PRT, "Got 0x%02x instead of 0x55\n", Value);
121  return STATUS_IO_DEVICE_ERROR;
122  }
123  }
124 
125  return STATUS_SUCCESS;
126 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define CCB_MOUSE_INT_ENAB
Definition: i8042prt.h:260
#define CTRL_SELF_TEST
Definition: i8042prt.h:225
#define INFO_(ch,...)
Definition: debug.h:159
#define CCB_KBD_DISAB
Definition: i8042prt.h:262
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN PUCHAR addr, IN UCHAR data)
Definition: readwrite.c:199
VOID i8042Flush(IN PPORT_DEVICE_EXTENSION DeviceExtension)
Definition: readwrite.c:21
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
BOOLEAN i8042ChangeMode(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
Definition: pnp.c:37
#define KBD_SELF_TEST_OK
Definition: i8042prt.h:241
#define CCB_KBD_INT_ENAB
Definition: i8042prt.h:259
#define TRACE_(x)
Definition: compat.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
#define KBD_RESEND
Definition: i8042prt.h:244
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define CCB_MOUSE_DISAB
Definition: i8042prt.h:263
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Data)
Definition: readwrite.c:95
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define WARN_(ch,...)
Definition: debug.h:157
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:99

Referenced by StartProcedure().

◆ i8042ChangeMode()

BOOLEAN i8042ChangeMode ( IN PPORT_DEVICE_EXTENSION  DeviceExtension,
IN UCHAR  FlagsToDisable,
IN UCHAR  FlagsToEnable 
)

Definition at line 37 of file pnp.c.

41 {
42  UCHAR Value;
44 
45  if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, KBD_READ_MODE))
46  {
47  WARN_(I8042PRT, "Can't read i8042 mode\n");
48  return FALSE;
49  }
50 
51  Status = i8042ReadDataWait(DeviceExtension, &Value);
52  if (!NT_SUCCESS(Status))
53  {
54  WARN_(I8042PRT, "No response after read i8042 mode\n");
55  return FALSE;
56  }
57 
58  Value &= ~FlagsToDisable;
59  Value |= FlagsToEnable;
60 
61  if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, KBD_WRITE_MODE))
62  {
63  WARN_(I8042PRT, "Can't set i8042 mode\n");
64  return FALSE;
65  }
66 
67  if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value))
68  {
69  WARN_(I8042PRT, "Can't send i8042 mode\n");
70  return FALSE;
71  }
72 
73  return TRUE;
74 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN PUCHAR addr, IN UCHAR data)
Definition: readwrite.c:199
#define KBD_WRITE_MODE
Definition: i8042prt.h:222
#define KBD_READ_MODE
Definition: i8042prt.h:221
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
NTSTATUS i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Data)
Definition: readwrite.c:95
#define WARN_(ch,...)
Definition: debug.h:157

Referenced by EnableInterrupts(), i8042BasicDetect(), and i8042DetectKeyboard().

◆ i8042ConnectKeyboardInterrupt()

static NTSTATUS i8042ConnectKeyboardInterrupt ( IN PI8042_KEYBOARD_EXTENSION  DeviceExtension)
static

Definition at line 267 of file pnp.c.

269 {
270  PPORT_DEVICE_EXTENSION PortDeviceExtension;
271  KIRQL DirqlMax;
273 
274  TRACE_(I8042PRT, "i8042ConnectKeyboardInterrupt()\n");
275 
276  PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
277 
278  // Enable keyboard clock line
279  i8042Write(PortDeviceExtension, PortDeviceExtension->ControlPort, KBD_CLK_ENABLE);
280 
281  DirqlMax = MAX(
282  PortDeviceExtension->KeyboardInterrupt.Dirql,
283  PortDeviceExtension->MouseInterrupt.Dirql);
284 
285  INFO_(I8042PRT, "KeyboardInterrupt.Vector %lu\n",
286  PortDeviceExtension->KeyboardInterrupt.Vector);
287  INFO_(I8042PRT, "KeyboardInterrupt.Dirql %lu\n",
288  PortDeviceExtension->KeyboardInterrupt.Dirql);
289  INFO_(I8042PRT, "KeyboardInterrupt.DirqlMax %lu\n",
290  DirqlMax);
291  INFO_(I8042PRT, "KeyboardInterrupt.InterruptMode %s\n",
292  PortDeviceExtension->KeyboardInterrupt.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched");
293  INFO_(I8042PRT, "KeyboardInterrupt.ShareInterrupt %s\n",
294  PortDeviceExtension->KeyboardInterrupt.ShareInterrupt ? "yes" : "no");
295  INFO_(I8042PRT, "KeyboardInterrupt.Affinity 0x%lx\n",
296  PortDeviceExtension->KeyboardInterrupt.Affinity);
298  &PortDeviceExtension->KeyboardInterrupt.Object,
300  DeviceExtension, &PortDeviceExtension->SpinLock,
301  PortDeviceExtension->KeyboardInterrupt.Vector, PortDeviceExtension->KeyboardInterrupt.Dirql, DirqlMax,
302  PortDeviceExtension->KeyboardInterrupt.InterruptMode, PortDeviceExtension->KeyboardInterrupt.ShareInterrupt,
303  PortDeviceExtension->KeyboardInterrupt.Affinity, FALSE);
304  if (!NT_SUCCESS(Status))
305  {
306  WARN_(I8042PRT, "IoConnectInterrupt() failed with status 0x%08x\n", Status);
307  return Status;
308  }
309 
310  if (DirqlMax == PortDeviceExtension->KeyboardInterrupt.Dirql)
311  PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->KeyboardInterrupt.Object;
312  PortDeviceExtension->Flags |= KEYBOARD_INITIALIZED;
313  return STATUS_SUCCESS;
314 }
KSPIN_LOCK SpinLock
Definition: i8042prt.h:89
#define KEYBOARD_INITIALIZED
Definition: i8042prt.h:71
#define INFO_(ch,...)
Definition: debug.h:159
KAFFINITY Affinity
Definition: i8042prt.h:57
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42
PKINTERRUPT HighestDIRQLInterrupt
Definition: i8042prt.h:88
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN PUCHAR addr, IN UCHAR data)
Definition: readwrite.c:199
INTERRUPT_DATA KeyboardInterrupt
Definition: i8042prt.h:85
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:22
ULONG Vector
Definition: i8042prt.h:53
PKINTERRUPT Object
Definition: i8042prt.h:52
#define TRACE_(x)
Definition: compat.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN ShareInterrupt
Definition: i8042prt.h:56
#define KBD_CLK_ENABLE
Definition: i8042prt.h:227
INTERRUPT_DATA MouseInterrupt
Definition: i8042prt.h:87
Status
Definition: gdiplustypes.h:24
T MAX(T a, T b)
Definition: polytest.cpp:85
return STATUS_SUCCESS
Definition: btrfs.c:2966
KSERVICE_ROUTINE i8042KbdInterruptService
Definition: i8042prt.h:320
#define WARN_(ch,...)
Definition: debug.h:157
KINTERRUPT_MODE InterruptMode
Definition: i8042prt.h:55

Referenced by StartProcedure().

◆ i8042ConnectMouseInterrupt()

static NTSTATUS i8042ConnectMouseInterrupt ( IN PI8042_MOUSE_EXTENSION  DeviceExtension)
static

Definition at line 317 of file pnp.c.

319 {
320  PPORT_DEVICE_EXTENSION PortDeviceExtension;
321  KIRQL DirqlMax;
323 
324  TRACE_(I8042PRT, "i8042ConnectMouseInterrupt()\n");
325 
326  Status = i8042MouInitialize(DeviceExtension);
327  if (!NT_SUCCESS(Status))
328  return Status;
329 
330  PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
331  DirqlMax = MAX(
332  PortDeviceExtension->KeyboardInterrupt.Dirql,
333  PortDeviceExtension->MouseInterrupt.Dirql);
334 
335  INFO_(I8042PRT, "MouseInterrupt.Vector %lu\n",
336  PortDeviceExtension->MouseInterrupt.Vector);
337  INFO_(I8042PRT, "MouseInterrupt.Dirql %lu\n",
338  PortDeviceExtension->MouseInterrupt.Dirql);
339  INFO_(I8042PRT, "MouseInterrupt.DirqlMax %lu\n",
340  DirqlMax);
341  INFO_(I8042PRT, "MouseInterrupt.InterruptMode %s\n",
342  PortDeviceExtension->MouseInterrupt.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched");
343  INFO_(I8042PRT, "MouseInterrupt.ShareInterrupt %s\n",
344  PortDeviceExtension->MouseInterrupt.ShareInterrupt ? "yes" : "no");
345  INFO_(I8042PRT, "MouseInterrupt.Affinity 0x%lx\n",
346  PortDeviceExtension->MouseInterrupt.Affinity);
348  &PortDeviceExtension->MouseInterrupt.Object,
350  DeviceExtension, &PortDeviceExtension->SpinLock,
351  PortDeviceExtension->MouseInterrupt.Vector, PortDeviceExtension->MouseInterrupt.Dirql, DirqlMax,
352  PortDeviceExtension->MouseInterrupt.InterruptMode, PortDeviceExtension->MouseInterrupt.ShareInterrupt,
353  PortDeviceExtension->MouseInterrupt.Affinity, FALSE);
354  if (!NT_SUCCESS(Status))
355  {
356  WARN_(I8042PRT, "IoConnectInterrupt() failed with status 0x%08x\n", Status);
357  goto cleanup;
358  }
359 
360  if (DirqlMax == PortDeviceExtension->MouseInterrupt.Dirql)
361  PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->MouseInterrupt.Object;
362 
363  PortDeviceExtension->Flags |= MOUSE_INITIALIZED;
365 
366 cleanup:
367  if (!NT_SUCCESS(Status))
368  {
369  PortDeviceExtension->Flags &= ~MOUSE_INITIALIZED;
370  if (PortDeviceExtension->MouseInterrupt.Object)
371  {
372  IoDisconnectInterrupt(PortDeviceExtension->MouseInterrupt.Object);
373  PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->KeyboardInterrupt.Object;
374  }
375  }
376  return Status;
377 }
KSPIN_LOCK SpinLock
Definition: i8042prt.h:89
#define INFO_(ch,...)
Definition: debug.h:159
#define MOUSE_INITIALIZED
Definition: i8042prt.h:75
KAFFINITY Affinity
Definition: i8042prt.h:57
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42
PKINTERRUPT HighestDIRQLInterrupt
Definition: i8042prt.h:88
LONG NTSTATUS
Definition: precomp.h:26
INTERRUPT_DATA KeyboardInterrupt
Definition: i8042prt.h:85
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:22
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:140
ULONG Vector
Definition: i8042prt.h:53
PKINTERRUPT Object
Definition: i8042prt.h:52
#define TRACE_(x)
Definition: compat.h:66
NTSTATUS i8042MouInitialize(IN PI8042_MOUSE_EXTENSION DeviceExtension)
Definition: mouse.c:224
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN ShareInterrupt
Definition: i8042prt.h:56
INTERRUPT_DATA MouseInterrupt
Definition: i8042prt.h:87
Status
Definition: gdiplustypes.h:24
T MAX(T a, T b)
Definition: polytest.cpp:85
char * cleanup(char *str)
Definition: wpickclick.c:99
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define WARN_(ch,...)
Definition: debug.h:157
KINTERRUPT_MODE InterruptMode
Definition: i8042prt.h:55
KSERVICE_ROUTINE i8042MouInterruptService
Definition: i8042prt.h:369

Referenced by StartProcedure().

◆ i8042DetectKeyboard()

static VOID i8042DetectKeyboard ( IN PPORT_DEVICE_EXTENSION  DeviceExtension)
static

Definition at line 129 of file pnp.c.

131 {
133 
134  /* Set LEDs (that is not fatal if some error occurs) */
135  Status = i8042SynchWritePort(DeviceExtension, 0, KBD_CMD_SET_LEDS, TRUE);
136  if (NT_SUCCESS(Status))
137  {
138  Status = i8042SynchWritePort(DeviceExtension, 0, 0, TRUE);
139  if (!NT_SUCCESS(Status))
140  {
141  WARN_(I8042PRT, "Can't finish SET_LEDS (0x%08lx)\n", Status);
142  return;
143  }
144  }
145  else
146  {
147  WARN_(I8042PRT, "Warning: can't write SET_LEDS (0x%08lx)\n", Status);
148  }
149 
150  /* Turn on translation and SF (Some machines don't reboot if SF is not set, see ReactOS bug CORE-1713) */
151  if (!i8042ChangeMode(DeviceExtension, 0, CCB_TRANSLATE | CCB_SYSTEM_FLAG))
152  return;
153 
154  /*
155  * We used to send a KBD_LINE_TEST (0xAB) command, but on at least HP
156  * Pavilion notebooks the response to that command was incorrect.
157  * So now we just assume that a keyboard is attached.
158  */
159  DeviceExtension->Flags |= KEYBOARD_PRESENT;
160 
161  INFO_(I8042PRT, "Keyboard detected\n");
162 }
#define TRUE
Definition: types.h:120
#define INFO_(ch,...)
Definition: debug.h:159
LONG NTSTATUS
Definition: precomp.h:26
#define KEYBOARD_PRESENT
Definition: i8042prt.h:68
#define CCB_TRANSLATE
Definition: i8042prt.h:264
BOOLEAN i8042ChangeMode(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
Definition: pnp.c:37
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KBD_CMD_SET_LEDS
Definition: i8042prt.h:234
NTSTATUS NTAPI i8042SynchWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Port, IN UCHAR Value, IN BOOLEAN WaitForAck)
Definition: readwrite.c:144
Status
Definition: gdiplustypes.h:24
#define CCB_SYSTEM_FLAG
Definition: i8042prt.h:261
#define WARN_(ch,...)
Definition: debug.h:157

Referenced by StartProcedure().

◆ i8042DetectMouse()

static VOID i8042DetectMouse ( IN PPORT_DEVICE_EXTENSION  DeviceExtension)
static

Definition at line 165 of file pnp.c.

167 {
169  UCHAR Value;
170  UCHAR ExpectedReply[] = { MOUSE_ACK, 0xAA };
171  UCHAR ReplyByte;
172 
173  /* First do a mouse line test */
174  if (i8042Write(DeviceExtension, DeviceExtension->ControlPort, MOUSE_LINE_TEST))
175  {
176  Status = i8042ReadDataWait(DeviceExtension, &Value);
177 
178  if (!NT_SUCCESS(Status) || Value != 0)
179  {
180  WARN_(I8042PRT, "Mouse line test failed\n");
181  goto failure;
182  }
183  }
184 
185  /* Now reset the mouse */
186  i8042Flush(DeviceExtension);
187 
188  if(!i8042IsrWritePort(DeviceExtension, MOU_CMD_RESET, CTRL_WRITE_MOUSE))
189  {
190  WARN_(I8042PRT, "Failed to write reset command to mouse\n");
191  goto failure;
192  }
193 
194  /* The implementation of the "Mouse Reset" command differs much from chip to chip.
195 
196  By default, the first byte is an ACK, when the mouse is plugged in and working and NACK when it's not.
197  On success, the next bytes are 0xAA and 0x00.
198 
199  But on some systems (like ECS K7S5A Pro, SiS 735 chipset), we always get an ACK and 0xAA.
200  Only the last byte indicates, whether a mouse is plugged in.
201  It is either sent or not, so there is no byte, which indicates a failure here.
202 
203  After the Mouse Reset command was issued, it usually takes some time until we get a response.
204  So get the first two bytes in a loop. */
205  for (ReplyByte = 0;
206  ReplyByte < sizeof(ExpectedReply) / sizeof(ExpectedReply[0]);
207  ReplyByte++)
208  {
209  ULONG Counter = 500;
210 
211  do
212  {
213  Status = i8042ReadDataWait(DeviceExtension, &Value);
214 
215  if(!NT_SUCCESS(Status))
216  {
217  /* Wait some time before trying again */
219  }
220  } while (Status == STATUS_IO_TIMEOUT && Counter--);
221 
222  if (!NT_SUCCESS(Status))
223  {
224  WARN_(I8042PRT, "No ACK after mouse reset, status 0x%08lx\n", Status);
225  goto failure;
226  }
227  else if (Value != ExpectedReply[ReplyByte])
228  {
229  WARN_(I8042PRT, "Unexpected reply: 0x%02x (expected 0x%02x)\n", Value, ExpectedReply[ReplyByte]);
230  goto failure;
231  }
232  }
233 
234  /* Finally get the third byte, but only try it one time (see above).
235  Otherwise this takes around 45 seconds on a K7S5A Pro, when no mouse is plugged in. */
236  Status = i8042ReadDataWait(DeviceExtension, &Value);
237 
238  if(!NT_SUCCESS(Status))
239  {
240  WARN_(I8042PRT, "Last byte was not transmitted after mouse reset, status 0x%08lx\n", Status);
241  goto failure;
242  }
243  else if(Value != 0x00)
244  {
245  WARN_(I8042PRT, "Last byte after mouse reset was not 0x00, but 0x%02x\n", Value);
246  goto failure;
247  }
248 
249  DeviceExtension->Flags |= MOUSE_PRESENT;
250  INFO_(I8042PRT, "Mouse detected\n");
251  return;
252 
253 failure:
254  /* There is probably no mouse present. On some systems,
255  the probe locks the entire keyboard controller. Let's
256  try to get access to the keyboard again by sending a
257  reset */
258  i8042Flush(DeviceExtension);
259  i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST);
260  i8042ReadDataWait(DeviceExtension, &Value);
261  i8042Flush(DeviceExtension);
262 
263  INFO_(I8042PRT, "Mouse not detected\n");
264 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define CTRL_SELF_TEST
Definition: i8042prt.h:225
#define MOUSE_PRESENT
Definition: i8042prt.h:72
#define MOU_CMD_RESET
Definition: i8042prt.h:279
#define INFO_(ch,...)
Definition: debug.h:159
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN PUCHAR addr, IN UCHAR data)
Definition: readwrite.c:199
BOOLEAN i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Value, IN UCHAR SelectCmd OPTIONAL)
Definition: readwrite.c:40
VOID i8042Flush(IN PPORT_DEVICE_EXTENSION DeviceExtension)
Definition: readwrite.c:21
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned char UCHAR
Definition: xmlstorage.h:181
#define MOUSE_LINE_TEST
Definition: i8042prt.h:224
#define MOUSE_ACK
Definition: i8042prt.h:285
Status
Definition: gdiplustypes.h:24
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
static LARGE_INTEGER Counter
Definition: clock.c:43
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Data)
Definition: readwrite.c:95
#define WARN_(ch,...)
Definition: debug.h:157
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:99
#define CTRL_WRITE_MOUSE
Definition: i8042prt.h:228

Referenced by StartProcedure().

◆ i8042Pnp()

NTSTATUS NTAPI i8042Pnp ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 675 of file pnp.c.

678 {
679  PIO_STACK_LOCATION Stack;
684 
686  MinorFunction = Stack->MinorFunction;
688 
689  switch (MinorFunction)
690  {
691  case IRP_MN_START_DEVICE: /* 0x00 */
692  {
693  TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
694 
695  /* Call lower driver (if any) */
697  {
699  if (NT_SUCCESS(Status))
701  DeviceObject,
702  Stack->Parameters.StartDevice.AllocatedResources,
703  Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
704  }
705  else
707  break;
708  }
709  case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x07 */
710  {
711  switch (Stack->Parameters.QueryDeviceRelations.Type)
712  {
713  case BusRelations:
714  {
715  TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
717  }
718  case RemovalRelations:
719  {
720  TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
722  }
723  default:
724  ERR_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
725  Stack->Parameters.QueryDeviceRelations.Type);
727  }
728  break;
729  }
730  case IRP_MN_QUERY_CAPABILITIES: /* (optional) 0x09 */
731  {
732  TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
734  }
735  case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* (optional) 0x0d */
736  {
737  TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
739  }
740  case IRP_MN_QUERY_PNP_DEVICE_STATE: /* (optional) 0x14 */
741  {
742  TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
744  }
746  {
747  TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_REMOVE_DEVICE\n");
749  }
751  {
752  TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_CANCEL_REMOVE_DEVICE\n");
754  }
756  {
757  TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
760  return Status;
761  }
762  default:
763  {
764  ERR_(I8042PRT, "IRP_MJ_PNP / unknown minor function 0x%x\n", MinorFunction);
766  }
767  }
768 
769  Irp->IoStatus.Information = Information;
770  Irp->IoStatus.Status = Status;
772  return Status;
773 }
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_REMOVE_DEVICE
_In_ PIRP Irp
Definition: csq.h:116
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
DeviceType
Definition: mmdrv.h:41
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define ERR_(ch,...)
Definition: debug.h:156
LONG NTSTATUS
Definition: precomp.h:26
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1114
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define IRP_MN_QUERY_REMOVE_DEVICE
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IRP_MN_START_DEVICE
DRIVER_DISPATCH ForwardIrpAndWait
Definition: i8042prt.h:343
static VOID i8042RemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: pnp.c:655
static NTSTATUS i8042PnpStartDevice(IN PDEVICE_OBJECT DeviceObject, IN PCM_RESOURCE_LIST AllocatedResources, IN PCM_RESOURCE_LIST AllocatedResourcesTranslated)
Definition: pnp.c:500
_In_ UCHAR MinorFunction
Definition: pofuncs.h:42
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
enum _I8042_DEVICE_TYPE I8042_DEVICE_TYPE
#define IRP_MN_QUERY_DEVICE_RELATIONS
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define IRP_MN_QUERY_PNP_DEVICE_STATE
Iosb Information
Definition: create.c:4377
#define IRP_MN_QUERY_CAPABILITIES

Referenced by DriverEntry().

◆ i8042PnpStartDevice()

static NTSTATUS i8042PnpStartDevice ( IN PDEVICE_OBJECT  DeviceObject,
IN PCM_RESOURCE_LIST  AllocatedResources,
IN PCM_RESOURCE_LIST  AllocatedResourcesTranslated 
)
static

Definition at line 500 of file pnp.c.

504 {
505  PFDO_DEVICE_EXTENSION DeviceExtension;
506  PPORT_DEVICE_EXTENSION PortDeviceExtension;
507  PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor, ResourceDescriptorTranslated;
508  INTERRUPT_DATA InterruptData = { NULL };
509  BOOLEAN FoundDataPort = FALSE;
510  BOOLEAN FoundControlPort = FALSE;
511  BOOLEAN FoundIrq = FALSE;
512  ULONG i;
514 
515  TRACE_(I8042PRT, "i8042PnpStartDevice(%p)\n", DeviceObject);
517  PortDeviceExtension = DeviceExtension->PortDeviceExtension;
518 
519  ASSERT(DeviceExtension->PnpState == dsStopped);
520 
521  if (!AllocatedResources)
522  {
523  WARN_(I8042PRT, "No allocated resources sent to driver\n");
525  }
526  if (AllocatedResources->Count != 1)
527  {
528  WARN_(I8042PRT, "Wrong number of allocated resources sent to driver\n");
530  }
531  if (AllocatedResources->List[0].PartialResourceList.Version != 1
532  || AllocatedResources->List[0].PartialResourceList.Revision != 1
533  || AllocatedResourcesTranslated->List[0].PartialResourceList.Version != 1
534  || AllocatedResourcesTranslated->List[0].PartialResourceList.Revision != 1)
535  {
536  WARN_(I8042PRT, "Revision mismatch: %u.%u != 1.1 or %u.%u != 1.1\n",
537  AllocatedResources->List[0].PartialResourceList.Version,
538  AllocatedResources->List[0].PartialResourceList.Revision,
539  AllocatedResourcesTranslated->List[0].PartialResourceList.Version,
540  AllocatedResourcesTranslated->List[0].PartialResourceList.Revision);
542  }
543 
544  /* Get Irq and optionally control port and data port */
545  for (i = 0; i < AllocatedResources->List[0].PartialResourceList.Count; i++)
546  {
547  ResourceDescriptor = &AllocatedResources->List[0].PartialResourceList.PartialDescriptors[i];
548  ResourceDescriptorTranslated = &AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[i];
549  switch (ResourceDescriptor->Type)
550  {
551  case CmResourceTypePort:
552  {
553  if (ResourceDescriptor->u.Port.Length == 1)
554  {
555  /* We assume that the first resource will
556  * be the control port and the second one
557  * will be the data port...
558  */
559  if (!FoundDataPort)
560  {
561  PortDeviceExtension->DataPort = ULongToPtr(ResourceDescriptor->u.Port.Start.u.LowPart);
562  INFO_(I8042PRT, "Found data port: %p\n", PortDeviceExtension->DataPort);
563  FoundDataPort = TRUE;
564  }
565  else if (!FoundControlPort)
566  {
567  PortDeviceExtension->ControlPort = ULongToPtr(ResourceDescriptor->u.Port.Start.u.LowPart);
568  INFO_(I8042PRT, "Found control port: %p\n", PortDeviceExtension->ControlPort);
569  FoundControlPort = TRUE;
570  }
571  else
572  {
573  /* FIXME: implement PS/2 Active Multiplexing */
574  ERR_(I8042PRT, "Unhandled I/O ranges provided: 0x%lx\n", ResourceDescriptor->u.Port.Length);
575  }
576  }
577  else
578  WARN_(I8042PRT, "Invalid I/O range length: 0x%lx\n", ResourceDescriptor->u.Port.Length);
579  break;
580  }
582  {
583  if (FoundIrq)
585  InterruptData.Dirql = (KIRQL)ResourceDescriptorTranslated->u.Interrupt.Level;
586  InterruptData.Vector = ResourceDescriptorTranslated->u.Interrupt.Vector;
587  InterruptData.Affinity = ResourceDescriptorTranslated->u.Interrupt.Affinity;
588  if (ResourceDescriptorTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
589  InterruptData.InterruptMode = Latched;
590  else
591  InterruptData.InterruptMode = LevelSensitive;
592  InterruptData.ShareInterrupt = (ResourceDescriptorTranslated->ShareDisposition == CmResourceShareShared);
593  INFO_(I8042PRT, "Found irq resource: %lu\n", ResourceDescriptor->u.Interrupt.Level);
594  FoundIrq = TRUE;
595  break;
596  }
597  default:
598  WARN_(I8042PRT, "Unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type);
599  }
600  }
601 
602  if (!FoundIrq)
603  {
604  WARN_(I8042PRT, "Interrupt resource was not found in allocated resources list\n");
606  }
607  else if (DeviceExtension->Type == Keyboard && (!FoundDataPort || !FoundControlPort))
608  {
609  WARN_(I8042PRT, "Some required resources were not found in allocated resources list\n");
611  }
612  else if (DeviceExtension->Type == Mouse && (FoundDataPort || FoundControlPort))
613  {
614  WARN_(I8042PRT, "Too much resources were provided in allocated resources list\n");
616  }
617 
618  switch (DeviceExtension->Type)
619  {
620  case Keyboard:
621  {
623  &PortDeviceExtension->KeyboardInterrupt,
624  &InterruptData,
625  sizeof(INTERRUPT_DATA));
626  PortDeviceExtension->Flags |= KEYBOARD_STARTED;
627  Status = StartProcedure(PortDeviceExtension);
628  break;
629  }
630  case Mouse:
631  {
633  &PortDeviceExtension->MouseInterrupt,
634  &InterruptData,
635  sizeof(INTERRUPT_DATA));
636  PortDeviceExtension->Flags |= MOUSE_STARTED;
637  Status = StartProcedure(PortDeviceExtension);
638  break;
639  }
640  default:
641  {
642  WARN_(I8042PRT, "Unknown FDO type %u\n", DeviceExtension->Type);
643  ASSERT(!(PortDeviceExtension->Flags & KEYBOARD_CONNECTED) || !(PortDeviceExtension->Flags & MOUSE_CONNECTED));
645  }
646  }
647 
648  if (NT_SUCCESS(Status))
649  DeviceExtension->PnpState = dsStarted;
650 
651  return Status;
652 }
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:311
static NTSTATUS StartProcedure(IN PPORT_DEVICE_EXTENSION DeviceExtension)
Definition: pnp.c:394
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define ULongToPtr(ul)
Definition: basetsd.h:92
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define INFO_(ch,...)
Definition: debug.h:159
_Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PCM_RESOURCE_LIST * AllocatedResources
Definition: ndis.h:4640
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
KAFFINITY Affinity
Definition: i8042prt.h:57
#define ERR_(ch,...)
Definition: debug.h:156
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@371::@374 Interrupt
#define CmResourceTypePort
Definition: hwresource.cpp:123
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
INTERRUPT_DATA KeyboardInterrupt
Definition: i8042prt.h:85
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define MOUSE_STARTED
Definition: i8042prt.h:74
PPORT_DEVICE_EXTENSION PortDeviceExtension
Definition: i8042prt.h:134
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PCM_RESOURCE_LIST _Inout_opt_ PCM_RESOURCE_LIST * AllocatedResourcesTranslated
Definition: ndis.h:4640
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@371 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@371::@373 Port
ULONG Vector
Definition: i8042prt.h:53
#define TRACE_(x)
Definition: compat.h:66
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN ShareInterrupt
Definition: i8042prt.h:56
#define KEYBOARD_STARTED
Definition: i8042prt.h:70
I8042_DEVICE_TYPE Type
Definition: i8042prt.h:122
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define MOUSE_CONNECTED
Definition: i8042prt.h:73
INTERRUPT_DATA MouseInterrupt
Definition: i8042prt.h:87
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
DEVICE_STATE PnpState
Definition: i8042prt.h:132
#define KEYBOARD_CONNECTED
Definition: i8042prt.h:69
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: cmtypes.h:144
unsigned int ULONG
Definition: retypes.h:1
#define WARN_(ch,...)
Definition: debug.h:157
KINTERRUPT_MODE InterruptMode
Definition: i8042prt.h:55

Referenced by i8042Pnp().

◆ i8042RemoveDevice()

static VOID i8042RemoveDevice ( IN PDEVICE_OBJECT  DeviceObject)
static

Definition at line 655 of file pnp.c.

657 {
659  KIRQL OldIrql;
660  PFDO_DEVICE_EXTENSION DeviceExtension;
661 
664 
665  KeAcquireSpinLock(&DriverExtension->DeviceListLock, &OldIrql);
666  RemoveEntryList(&DeviceExtension->ListEntry);
667  KeReleaseSpinLock(&DriverExtension->DeviceListLock, OldIrql);
668 
669  IoDetachDevice(DeviceExtension->LowerDevice);
670 
672 }
LIST_ENTRY ListEntry
Definition: pci.h:82
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
struct _I8042_DRIVER_EXTENSION * PI8042_DRIVER_EXTENSION
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PDEVICE_OBJECT LowerDevice
Definition: i8042prt.h:130

Referenced by i8042Pnp().

◆ StartProcedure()

static NTSTATUS StartProcedure ( IN PPORT_DEVICE_EXTENSION  DeviceExtension)
static

Definition at line 394 of file pnp.c.

396 {
398  UCHAR FlagsToDisable = 0;
399  UCHAR FlagsToEnable = 0;
400  KIRQL Irql;
401 
402  if (DeviceExtension->DataPort == 0)
403  {
404  /* Unable to do something at the moment */
405  return STATUS_SUCCESS;
406  }
407 
408  if (!(DeviceExtension->Flags & (KEYBOARD_PRESENT | MOUSE_PRESENT)))
409  {
410  /* Try to detect them */
411  TRACE_(I8042PRT, "Check if the controller is really a i8042\n");
412  Status = i8042BasicDetect(DeviceExtension);
413  if (!NT_SUCCESS(Status))
414  {
415  WARN_(I8042PRT, "i8042BasicDetect() failed with status 0x%08lx\n", Status);
416  return STATUS_UNSUCCESSFUL;
417  }
418 
419  /* First detect the mouse and then the keyboard!
420  If we do it the other way round, some systems throw away settings like the keyboard translation, when detecting the mouse. */
421  TRACE_(I8042PRT, "Detecting mouse\n");
422  i8042DetectMouse(DeviceExtension);
423  TRACE_(I8042PRT, "Detecting keyboard\n");
424  i8042DetectKeyboard(DeviceExtension);
425 
426  INFO_(I8042PRT, "Keyboard present: %s\n", DeviceExtension->Flags & KEYBOARD_PRESENT ? "YES" : "NO");
427  INFO_(I8042PRT, "Mouse present : %s\n", DeviceExtension->Flags & MOUSE_PRESENT ? "YES" : "NO");
428 
429  TRACE_(I8042PRT, "Enabling i8042 interrupts\n");
430  if (DeviceExtension->Flags & KEYBOARD_PRESENT)
431  {
432  FlagsToDisable |= CCB_KBD_DISAB;
433  FlagsToEnable |= CCB_KBD_INT_ENAB;
434  }
435  if (DeviceExtension->Flags & MOUSE_PRESENT)
436  {
437  FlagsToDisable |= CCB_MOUSE_DISAB;
438  FlagsToEnable |= CCB_MOUSE_INT_ENAB;
439  }
440 
441  Status = EnableInterrupts(DeviceExtension, FlagsToDisable, FlagsToEnable);
442  if (!NT_SUCCESS(Status))
443  {
444  WARN_(I8042PRT, "EnableInterrupts failed: %lx\n", Status);
445  DeviceExtension->Flags &= ~(KEYBOARD_PRESENT | MOUSE_PRESENT);
446  return Status;
447  }
448  }
449 
450  /* Connect interrupts */
451  if (DeviceExtension->Flags & KEYBOARD_PRESENT &&
452  DeviceExtension->Flags & KEYBOARD_CONNECTED &&
453  DeviceExtension->Flags & KEYBOARD_STARTED &&
454  !(DeviceExtension->Flags & KEYBOARD_INITIALIZED))
455  {
456  /* Keyboard is ready to be initialized */
457  Status = i8042ConnectKeyboardInterrupt(DeviceExtension->KeyboardExtension);
458  if (NT_SUCCESS(Status))
459  {
460  DeviceExtension->Flags |= KEYBOARD_INITIALIZED;
461  }
462  else
463  {
464  WARN_(I8042PRT, "i8042ConnectKeyboardInterrupt failed: %lx\n", Status);
465  }
466  }
467 
468  if (DeviceExtension->Flags & MOUSE_PRESENT &&
469  DeviceExtension->Flags & MOUSE_CONNECTED &&
470  DeviceExtension->Flags & MOUSE_STARTED &&
471  !(DeviceExtension->Flags & MOUSE_INITIALIZED))
472  {
473  /* Mouse is ready to be initialized */
474  Status = i8042ConnectMouseInterrupt(DeviceExtension->MouseExtension);
475  if (NT_SUCCESS(Status))
476  {
477  DeviceExtension->Flags |= MOUSE_INITIALIZED;
478  }
479  else
480  {
481  WARN_(I8042PRT, "i8042ConnectMouseInterrupt failed: %lx\n", Status);
482  }
483 
484  /* Start the mouse */
485  Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt);
486  /* HACK: the mouse has already been reset in i8042DetectMouse. This second
487  reset prevents some touchpads/mice from working (Dell D531, D600).
488  See CORE-6901 */
489  if (!(i8042HwFlags & FL_INITHACK))
490  {
492  }
493  KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql);
494  }
495 
496  return Status;
497 }
#define CCB_MOUSE_INT_ENAB
Definition: i8042prt.h:260
#define MOUSE_PRESENT
Definition: i8042prt.h:72
static NTSTATUS EnableInterrupts(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
Definition: pnp.c:380
#define MOU_CMD_RESET
Definition: i8042prt.h:279
#define KEYBOARD_INITIALIZED
Definition: i8042prt.h:71
#define INFO_(ch,...)
Definition: debug.h:159
#define MOUSE_INITIALIZED
Definition: i8042prt.h:75
#define CCB_KBD_DISAB
Definition: i8042prt.h:262
LONG NTSTATUS
Definition: precomp.h:26
#define KEYBOARD_PRESENT
Definition: i8042prt.h:68
BOOLEAN i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Value, IN UCHAR SelectCmd OPTIONAL)
Definition: readwrite.c:40
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define MOUSE_STARTED
Definition: i8042prt.h:74
VOID NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql)
Definition: spinlock.c:165
#define CCB_KBD_INT_ENAB
Definition: i8042prt.h:259
#define TRACE_(x)
Definition: compat.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static NTSTATUS i8042ConnectKeyboardInterrupt(IN PI8042_KEYBOARD_EXTENSION DeviceExtension)
Definition: pnp.c:267
#define KEYBOARD_STARTED
Definition: i8042prt.h:70
KIRQL NTAPI KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
Definition: spinlock.c:148
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
#define MOUSE_CONNECTED
Definition: i8042prt.h:73
Status
Definition: gdiplustypes.h:24
ULONG i8042HwFlags
Definition: hwhacks.c:22
static NTSTATUS i8042ConnectMouseInterrupt(IN PI8042_MOUSE_EXTENSION DeviceExtension)
Definition: pnp.c:317
#define CCB_MOUSE_DISAB
Definition: i8042prt.h:263
#define KEYBOARD_CONNECTED
Definition: i8042prt.h:69
return STATUS_SUCCESS
Definition: btrfs.c:2966
static NTSTATUS i8042BasicDetect(IN PPORT_DEVICE_EXTENSION DeviceExtension)
Definition: pnp.c:77
#define WARN_(ch,...)
Definition: debug.h:157
#define CTRL_WRITE_MOUSE
Definition: i8042prt.h:228
static VOID i8042DetectMouse(IN PPORT_DEVICE_EXTENSION DeviceExtension)
Definition: pnp.c:165
static VOID i8042DetectKeyboard(IN PPORT_DEVICE_EXTENSION DeviceExtension)
Definition: pnp.c:129

Referenced by i8042PnpStartDevice().