MdeModulePkg/AtaAtapiPassThru: Revert patch to disable Bus Master
[mirror_edk2.git] / MdeModulePkg / Bus / Isa / Ps2MouseDxe / Ps2Mouse.c
CommitLineData
77833d0b
RN
1/** @file\r
2 PS/2 Mouse driver. Routines that interacts with callers,\r
3 conforming to EFI driver model.\r
4\r
5Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "Ps2Mouse.h"\r
17#include "CommPs2.h"\r
18\r
19///\r
20/// DriverBinding Protocol Instance\r
21///\r
22EFI_DRIVER_BINDING_PROTOCOL gPS2MouseDriver = {\r
23 PS2MouseDriverSupported,\r
24 PS2MouseDriverStart,\r
25 PS2MouseDriverStop,\r
26 0xa,\r
27 NULL,\r
28 NULL\r
29};\r
30\r
31/**\r
32 Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
33 than contains a IsaIo protocol can be supported.\r
34\r
35 @param This Protocol instance pointer.\r
36 @param ControllerHandle Handle of device to test\r
37 @param RemainingDevicePath Optional parameter use to pick a specific child\r
38 device to start.\r
39\r
40 @retval EFI_SUCCESS This driver supports this device\r
41 @retval EFI_ALREADY_STARTED This driver is already running on this device\r
42 @retval other This driver does not support this device\r
43\r
44**/\r
45EFI_STATUS\r
46EFIAPI\r
47PS2MouseDriverSupported (\r
48 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
49 IN EFI_HANDLE Controller,\r
50 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
51 )\r
52{\r
53 EFI_STATUS Status;\r
54 EFI_SIO_PROTOCOL *Sio;\r
55 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
56 ACPI_HID_DEVICE_PATH *Acpi;\r
57\r
58 //\r
59 // Check whether the controller is keyboard.\r
60 //\r
61 Status = gBS->OpenProtocol (\r
62 Controller,\r
63 &gEfiDevicePathProtocolGuid,\r
64 (VOID **) &DevicePath,\r
65 This->DriverBindingHandle,\r
66 Controller,\r
67 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
68 );\r
69 if (EFI_ERROR (Status)) {\r
70 return Status;\r
71 }\r
72\r
73 do {\r
74 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;\r
75 DevicePath = NextDevicePathNode (DevicePath);\r
76 } while (!IsDevicePathEnd (DevicePath));\r
77\r
78 if (DevicePathType (Acpi) != ACPI_DEVICE_PATH ||\r
79 (DevicePathSubType (Acpi) != ACPI_DP && DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)) {\r
80 return EFI_UNSUPPORTED;\r
81 }\r
82\r
83 switch (Acpi->HID) {\r
84 case EISA_PNP_ID (0xF03):\r
85 //\r
86 // Microsoft PS/2 style mouse\r
87 //\r
88 case EISA_PNP_ID (0xF13):\r
89 //\r
90 // PS/2 Port for PS/2-style Mice\r
91 //\r
92 break;\r
93\r
94 case EISA_PNP_ID (0x303):\r
95 //\r
96 // IBM Enhanced (101/102-key, PS/2 mouse support)\r
97 //\r
98 if (Acpi->UID == 1) {\r
99 break;\r
100 }\r
101\r
102 default:\r
103 return EFI_UNSUPPORTED;\r
104 break;\r
105 }\r
106\r
107 //\r
108 // Open the IO Abstraction(s) needed to perform the supported test\r
109 //\r
110 Status = gBS->OpenProtocol (\r
111 Controller,\r
112 &gEfiSioProtocolGuid,\r
113 (VOID **) &Sio,\r
114 This->DriverBindingHandle,\r
115 Controller,\r
116 EFI_OPEN_PROTOCOL_BY_DRIVER\r
117 );\r
118 if (EFI_ERROR (Status)) {\r
119 return Status;\r
120 }\r
121\r
122 //\r
123 // Close the I/O Abstraction(s) used to perform the supported test\r
124 //\r
125 gBS->CloseProtocol (\r
126 Controller,\r
127 &gEfiSioProtocolGuid,\r
128 This->DriverBindingHandle,\r
129 Controller\r
130 );\r
131\r
132 return Status;\r
133}\r
134\r
135/**\r
136 Start this driver on ControllerHandle by opening a Sio protocol, creating\r
137 PS2_MOUSE_DEV device and install gEfiSimplePointerProtocolGuid finally.\r
138\r
139 @param This Protocol instance pointer.\r
140 @param ControllerHandle Handle of device to bind driver to\r
141 @param RemainingDevicePath Optional parameter use to pick a specific child\r
142 device to start.\r
143\r
144 @retval EFI_SUCCESS This driver is added to ControllerHandle\r
145 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
146 @retval other This driver does not support this device\r
147\r
148**/\r
149EFI_STATUS\r
150EFIAPI\r
151PS2MouseDriverStart (\r
152 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
153 IN EFI_HANDLE Controller,\r
154 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
155 )\r
156{\r
157 EFI_STATUS Status;\r
158 EFI_STATUS EmptyStatus;\r
159 EFI_SIO_PROTOCOL *Sio;\r
160 PS2_MOUSE_DEV *MouseDev;\r
161 UINT8 Data;\r
162 EFI_TPL OldTpl;\r
163 EFI_STATUS_CODE_VALUE StatusCode;\r
164 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
165\r
166 StatusCode = 0;\r
167\r
168 //\r
169 // Open the device path protocol\r
170 //\r
171 Status = gBS->OpenProtocol (\r
172 Controller,\r
173 &gEfiDevicePathProtocolGuid,\r
174 (VOID **) &DevicePath,\r
175 This->DriverBindingHandle,\r
176 Controller,\r
177 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
178 );\r
179 if (EFI_ERROR (Status)) {\r
180 return Status;\r
181 }\r
182 //\r
183 // Report that the keyboard is being enabled\r
184 //\r
185 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
186 EFI_PROGRESS_CODE,\r
187 EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE,\r
188 DevicePath\r
189 );\r
190\r
191 //\r
192 // Get the ISA I/O Protocol on Controller's handle\r
193 //\r
194 Status = gBS->OpenProtocol (\r
195 Controller,\r
196 &gEfiSioProtocolGuid,\r
197 (VOID **) &Sio,\r
198 This->DriverBindingHandle,\r
199 Controller,\r
200 EFI_OPEN_PROTOCOL_BY_DRIVER\r
201 );\r
202 if (EFI_ERROR (Status)) {\r
203 return Status;\r
204 }\r
205 //\r
206 // Raise TPL to avoid keyboard operation impact\r
207 //\r
208 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
209\r
210 //\r
211 // Allocate private data\r
212 //\r
213 MouseDev = AllocateZeroPool (sizeof (PS2_MOUSE_DEV));\r
214 if (MouseDev == NULL) {\r
215 Status = EFI_OUT_OF_RESOURCES;\r
216 goto ErrorExit;\r
217 }\r
218 //\r
219 // Setup the device instance\r
220 //\r
221 MouseDev->Signature = PS2_MOUSE_DEV_SIGNATURE;\r
222 MouseDev->Handle = Controller;\r
223 MouseDev->SampleRate = SampleRate20;\r
224 MouseDev->Resolution = MouseResolution4;\r
225 MouseDev->Scaling = Scaling1;\r
226 MouseDev->DataPackageSize = 3;\r
227 MouseDev->DevicePath = DevicePath;\r
228\r
229 //\r
230 // Resolution = 4 counts/mm\r
231 //\r
232 MouseDev->Mode.ResolutionX = 4;\r
233 MouseDev->Mode.ResolutionY = 4;\r
234 MouseDev->Mode.LeftButton = TRUE;\r
235 MouseDev->Mode.RightButton = TRUE;\r
236\r
237 MouseDev->SimplePointerProtocol.Reset = MouseReset;\r
238 MouseDev->SimplePointerProtocol.GetState = MouseGetState;\r
239 MouseDev->SimplePointerProtocol.Mode = &(MouseDev->Mode);\r
240\r
241 //\r
242 // Initialize keyboard controller if necessary\r
243 //\r
244 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
245 EFI_PROGRESS_CODE,\r
246 EFI_PERIPHERAL_MOUSE | EFI_P_MOUSE_PC_SELF_TEST,\r
247 DevicePath\r
248 );\r
249\r
250 Data = IoRead8 (KBC_CMD_STS_PORT);\r
251 //\r
252 // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.\r
253 //\r
254 if ((Data & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) {\r
255 //\r
256 // If nobody decodes KBC I/O port, it will read back as 0xFF.\r
257 // Check the Time-Out and Parity bit to see if it has an active KBC in system\r
258 //\r
259 Status = EFI_DEVICE_ERROR;\r
260 StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;\r
261 goto ErrorExit;\r
262 }\r
263\r
264 if ((Data & KBC_SYSF) != KBC_SYSF) {\r
265 Status = KbcSelfTest ();\r
266 if (EFI_ERROR (Status)) {\r
267 StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR;\r
268 goto ErrorExit;\r
269 }\r
270 }\r
271\r
272 KbcEnableAux ();\r
273\r
274 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
275 EFI_PROGRESS_CODE,\r
276 EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT,\r
277 DevicePath\r
278 );\r
279\r
280 //\r
281 // Reset the mouse\r
282 //\r
283 Status = MouseDev->SimplePointerProtocol.Reset (\r
284 &MouseDev->SimplePointerProtocol,\r
285 FeaturePcdGet (PcdPs2MouseExtendedVerification)\r
286 );\r
287 if (EFI_ERROR (Status)) {\r
288 //\r
289 // mouse not connected\r
290 //\r
291 Status = EFI_SUCCESS;\r
292 StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;\r
293 goto ErrorExit;\r
294 }\r
295\r
296 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
297 EFI_PROGRESS_CODE,\r
298 EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED,\r
299 DevicePath\r
300 );\r
301\r
302 //\r
303 // Setup the WaitForKey event\r
304 //\r
305 Status = gBS->CreateEvent (\r
306 EVT_NOTIFY_WAIT,\r
307 TPL_NOTIFY,\r
308 MouseWaitForInput,\r
309 MouseDev,\r
310 &((MouseDev->SimplePointerProtocol).WaitForInput)\r
311 );\r
312 if (EFI_ERROR (Status)) {\r
313 Status = EFI_OUT_OF_RESOURCES;\r
314 goto ErrorExit;\r
315 }\r
316 //\r
317 // Setup a periodic timer, used to poll mouse state\r
318 //\r
319 Status = gBS->CreateEvent (\r
320 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
321 TPL_NOTIFY,\r
322 PollMouse,\r
323 MouseDev,\r
324 &MouseDev->TimerEvent\r
325 );\r
326 if (EFI_ERROR (Status)) {\r
327 Status = EFI_OUT_OF_RESOURCES;\r
328 goto ErrorExit;\r
329 }\r
330 //\r
331 // Start timer to poll mouse (100 samples per second)\r
332 //\r
333 Status = gBS->SetTimer (MouseDev->TimerEvent, TimerPeriodic, 100000);\r
334 if (EFI_ERROR (Status)) {\r
335 Status = EFI_OUT_OF_RESOURCES;\r
336 goto ErrorExit;\r
337 }\r
338\r
339 MouseDev->ControllerNameTable = NULL;\r
340 AddUnicodeString2 (\r
341 "eng",\r
342 gPs2MouseComponentName.SupportedLanguages,\r
343 &MouseDev->ControllerNameTable,\r
344 L"PS/2 Mouse Device",\r
345 TRUE\r
346 );\r
347 AddUnicodeString2 (\r
348 "en",\r
349 gPs2MouseComponentName2.SupportedLanguages,\r
350 &MouseDev->ControllerNameTable,\r
351 L"PS/2 Mouse Device",\r
352 FALSE\r
353 );\r
354\r
355\r
356 //\r
357 // Install protocol interfaces for the mouse device.\r
358 //\r
359 Status = gBS->InstallMultipleProtocolInterfaces (\r
360 &Controller,\r
361 &gEfiSimplePointerProtocolGuid,\r
362 &MouseDev->SimplePointerProtocol,\r
363 NULL\r
364 );\r
365 if (EFI_ERROR (Status)) {\r
366 goto ErrorExit;\r
367 }\r
368\r
369 gBS->RestoreTPL (OldTpl);\r
370\r
371 return Status;\r
372\r
373ErrorExit:\r
374\r
375 if (Status != EFI_DEVICE_ERROR) {\r
376 KbcDisableAux ();\r
377 }\r
378\r
379 if (StatusCode != 0) {\r
380 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
381 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
382 StatusCode,\r
383 DevicePath\r
384 );\r
385 }\r
386\r
387 if ((MouseDev != NULL) && (MouseDev->SimplePointerProtocol.WaitForInput != NULL)) {\r
388 gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput);\r
389 }\r
390\r
391 if ((MouseDev != NULL) && (MouseDev->TimerEvent != NULL)) {\r
392 gBS->CloseEvent (MouseDev->TimerEvent);\r
393 }\r
394\r
395 if ((MouseDev != NULL) && (MouseDev->ControllerNameTable != NULL)) {\r
396 FreeUnicodeStringTable (MouseDev->ControllerNameTable);\r
397 }\r
398\r
399 if (Status != EFI_DEVICE_ERROR) {\r
400 //\r
401 // Since there will be no timer handler for mouse input any more,\r
402 // exhaust input data just in case there is still mouse data left\r
403 //\r
404 EmptyStatus = EFI_SUCCESS;\r
405 while (!EFI_ERROR (EmptyStatus)) {\r
406 EmptyStatus = In8042Data (&Data);\r
407 }\r
408 }\r
409\r
410 if (MouseDev != NULL) {\r
411 FreePool (MouseDev);\r
412 }\r
413\r
414 gBS->CloseProtocol (\r
415 Controller,\r
416 &gEfiDevicePathProtocolGuid,\r
417 This->DriverBindingHandle,\r
418 Controller\r
419 );\r
420\r
421 gBS->CloseProtocol (\r
422 Controller,\r
423 &gEfiSioProtocolGuid,\r
424 This->DriverBindingHandle,\r
425 Controller\r
426 );\r
427\r
428 gBS->RestoreTPL (OldTpl);\r
429\r
430 return Status;\r
431}\r
432\r
433/**\r
ed356b9e 434 Stop this driver on ControllerHandle. Support stopping any child handles\r
77833d0b
RN
435 created by this driver.\r
436\r
437 @param This Protocol instance pointer.\r
438 @param ControllerHandle Handle of device to stop driver on\r
439 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
440 children is zero stop the entire bus driver.\r
441 @param ChildHandleBuffer List of Child Handles to Stop.\r
442\r
443 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
444 @retval other This driver was not removed from this device\r
445\r
446**/\r
447EFI_STATUS\r
448EFIAPI\r
449PS2MouseDriverStop (\r
450 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
451 IN EFI_HANDLE Controller,\r
452 IN UINTN NumberOfChildren,\r
453 IN EFI_HANDLE *ChildHandleBuffer\r
454 )\r
455{\r
456 EFI_STATUS Status;\r
457 EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol;\r
458 PS2_MOUSE_DEV *MouseDev;\r
459 UINT8 Data;\r
460\r
461 Status = gBS->OpenProtocol (\r
462 Controller,\r
463 &gEfiSimplePointerProtocolGuid,\r
464 (VOID **) &SimplePointerProtocol,\r
465 This->DriverBindingHandle,\r
466 Controller,\r
467 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
468 );\r
469 if (EFI_ERROR (Status)) {\r
470 return EFI_SUCCESS;\r
471 }\r
472\r
473 MouseDev = PS2_MOUSE_DEV_FROM_THIS (SimplePointerProtocol);\r
474\r
475 //\r
476 // Report that the keyboard is being disabled\r
477 //\r
478 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
479 EFI_PROGRESS_CODE,\r
480 EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE,\r
481 MouseDev->DevicePath\r
482 );\r
483\r
484 Status = gBS->UninstallProtocolInterface (\r
485 Controller,\r
486 &gEfiSimplePointerProtocolGuid,\r
487 &MouseDev->SimplePointerProtocol\r
488 );\r
489 if (EFI_ERROR (Status)) {\r
490 return Status;\r
491 }\r
492\r
493 //\r
494 // Cancel mouse data polling timer, close timer event\r
495 //\r
496 gBS->SetTimer (MouseDev->TimerEvent, TimerCancel, 0);\r
497 gBS->CloseEvent (MouseDev->TimerEvent);\r
498\r
499 //\r
500 // Since there will be no timer handler for mouse input any more,\r
501 // exhaust input data just in case there is still mouse data left\r
502 //\r
503 Status = EFI_SUCCESS;\r
504 while (!EFI_ERROR (Status)) {\r
505 Status = In8042Data (&Data);\r
506 }\r
507\r
508 gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput);\r
509 FreeUnicodeStringTable (MouseDev->ControllerNameTable);\r
510 FreePool (MouseDev);\r
511\r
512 gBS->CloseProtocol (\r
513 Controller,\r
514 &gEfiDevicePathProtocolGuid,\r
515 This->DriverBindingHandle,\r
516 Controller\r
517 );\r
518\r
519 gBS->CloseProtocol (\r
520 Controller,\r
521 &gEfiSioProtocolGuid,\r
522 This->DriverBindingHandle,\r
523 Controller\r
524 );\r
525\r
526 return EFI_SUCCESS;\r
527}\r
528\r
529/**\r
530 Reset the Mouse and do BAT test for it, if ExtendedVerification is TRUE and\r
ed356b9e 531 there is a mouse device connected to system.\r
77833d0b
RN
532\r
533 @param This - Pointer of simple pointer Protocol.\r
534 @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip.\r
535\r
536\r
537 @retval EFI_SUCCESS - The command byte is written successfully.\r
ed356b9e 538 @retval EFI_DEVICE_ERROR - Errors occurred during resetting keyboard.\r
77833d0b
RN
539\r
540**/\r
541EFI_STATUS\r
542EFIAPI\r
543MouseReset (\r
544 IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
545 IN BOOLEAN ExtendedVerification\r
546 )\r
547{\r
548 EFI_STATUS Status;\r
549 PS2_MOUSE_DEV *MouseDev;\r
550 EFI_TPL OldTpl;\r
551 BOOLEAN KeyboardEnable;\r
552 UINT8 Data;\r
553\r
554 MouseDev = PS2_MOUSE_DEV_FROM_THIS (This);\r
555\r
556 //\r
557 // Report reset progress code\r
558 //\r
559 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
560 EFI_PROGRESS_CODE,\r
561 EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET,\r
562 MouseDev->DevicePath\r
563 );\r
564\r
565 KeyboardEnable = FALSE;\r
566\r
567 //\r
568 // Raise TPL to avoid keyboard operation impact\r
569 //\r
570 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
571\r
572 ZeroMem (&MouseDev->State, sizeof (EFI_SIMPLE_POINTER_STATE));\r
573 MouseDev->StateChanged = FALSE;\r
574\r
575 //\r
576 // Exhaust input data\r
577 //\r
578 Status = EFI_SUCCESS;\r
579 while (!EFI_ERROR (Status)) {\r
580 Status = In8042Data (&Data);\r
581 }\r
582\r
583 CheckKbStatus (&KeyboardEnable);\r
584\r
585 KbcDisableKb ();\r
586\r
587 //\r
588 // if there's data block on KBC data port, read it out\r
589 //\r
590 if ((IoRead8 (KBC_CMD_STS_PORT) & KBC_OUTB) == KBC_OUTB) {\r
591 IoRead8 (KBC_DATA_PORT);\r
592 }\r
593\r
594 Status = EFI_SUCCESS;\r
595 //\r
596 // The PS2 mouse driver reset behavior is always successfully return no matter wheater or not there is mouse connected to system.\r
597 // This behavior is needed by performance speed. The following mouse command only succeessfully finish when mouse device is\r
598 // connected to system, so if PS2 mouse device not connect to system or user not ask for, we skip the mouse configuration and enabling\r
599 //\r
600 if (ExtendedVerification && CheckMouseConnect (MouseDev)) {\r
601 //\r
602 // Send mouse reset command and set mouse default configure\r
603 //\r
604 Status = PS2MouseReset ();\r
605 if (EFI_ERROR (Status)) {\r
606 Status = EFI_DEVICE_ERROR;\r
607 goto Exit;\r
608 }\r
609\r
610 Status = PS2MouseSetSampleRate (MouseDev->SampleRate);\r
611 if (EFI_ERROR (Status)) {\r
612 Status = EFI_DEVICE_ERROR;\r
613 goto Exit;\r
614 }\r
615\r
616 Status = PS2MouseSetResolution (MouseDev->Resolution);\r
617 if (EFI_ERROR (Status)) {\r
618 Status = EFI_DEVICE_ERROR;\r
619 goto Exit;\r
620 }\r
621\r
622 Status = PS2MouseSetScaling (MouseDev->Scaling);\r
623 if (EFI_ERROR (Status)) {\r
624 Status = EFI_DEVICE_ERROR;\r
625 goto Exit;\r
626 }\r
627\r
628 Status = PS2MouseEnable ();\r
629 if (EFI_ERROR (Status)) {\r
630 Status = EFI_DEVICE_ERROR;\r
631 goto Exit;\r
632 }\r
633 }\r
634Exit:\r
635 gBS->RestoreTPL (OldTpl);\r
636\r
637 if (KeyboardEnable) {\r
638 KbcEnableKb ();\r
639 }\r
640\r
641 return Status;\r
642}\r
643\r
644/**\r
645 Check whether there is Ps/2 mouse device in system\r
646\r
647 @param MouseDev - Mouse Private Data Structure\r
648\r
649 @retval TRUE - Keyboard in System.\r
650 @retval FALSE - Keyboard not in System.\r
651\r
652**/\r
653BOOLEAN\r
654CheckMouseConnect (\r
655 IN PS2_MOUSE_DEV *MouseDev\r
656 )\r
657\r
658{\r
659 EFI_STATUS Status;\r
660\r
661 Status = PS2MouseEnable ();\r
662 if (!EFI_ERROR (Status)) {\r
663 return TRUE;\r
664 }\r
665\r
666 return FALSE;\r
667}\r
668\r
669/**\r
670 Get and Clear mouse status.\r
671\r
672 @param This - Pointer of simple pointer Protocol.\r
673 @param State - Output buffer holding status.\r
674\r
675 @retval EFI_INVALID_PARAMETER Output buffer is invalid.\r
676 @retval EFI_NOT_READY Mouse is not changed status yet.\r
677 @retval EFI_SUCCESS Mouse status is changed and get successful.\r
678**/\r
679EFI_STATUS\r
680EFIAPI\r
681MouseGetState (\r
682 IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
683 IN OUT EFI_SIMPLE_POINTER_STATE *State\r
684 )\r
685{\r
686 PS2_MOUSE_DEV *MouseDev;\r
687 EFI_TPL OldTpl;\r
688\r
689 MouseDev = PS2_MOUSE_DEV_FROM_THIS (This);\r
690\r
691 if (State == NULL) {\r
692 return EFI_INVALID_PARAMETER;\r
693 }\r
694\r
695 if (!MouseDev->StateChanged) {\r
696 return EFI_NOT_READY;\r
697 }\r
698\r
699 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
700 CopyMem (State, &(MouseDev->State), sizeof (EFI_SIMPLE_POINTER_STATE));\r
701\r
702 //\r
703 // clear mouse state\r
704 //\r
705 MouseDev->State.RelativeMovementX = 0;\r
706 MouseDev->State.RelativeMovementY = 0;\r
707 MouseDev->State.RelativeMovementZ = 0;\r
708 MouseDev->StateChanged = FALSE;\r
709 gBS->RestoreTPL (OldTpl);\r
710\r
711 return EFI_SUCCESS;\r
712}\r
713\r
714/**\r
715\r
716 Event notification function for SIMPLE_POINTER.WaitForInput event.\r
717 Signal the event if there is input from mouse.\r
718\r
719 @param Event event object\r
720 @param Context event context\r
721\r
722**/\r
723VOID\r
724EFIAPI\r
725MouseWaitForInput (\r
726 IN EFI_EVENT Event,\r
727 IN VOID *Context\r
728 )\r
729{\r
730 PS2_MOUSE_DEV *MouseDev;\r
731\r
732 MouseDev = (PS2_MOUSE_DEV *) Context;\r
733\r
734 //\r
735 // Someone is waiting on the mouse event, if there's\r
736 // input from mouse, signal the event\r
737 //\r
738 if (MouseDev->StateChanged) {\r
739 gBS->SignalEvent (Event);\r
740 }\r
741\r
742}\r
743\r
744/**\r
745 Event notification function for TimerEvent event.\r
746 If mouse device is connected to system, try to get the mouse packet data.\r
747\r
748 @param Event - TimerEvent in PS2_MOUSE_DEV\r
749 @param Context - Pointer to PS2_MOUSE_DEV structure\r
750\r
751**/\r
752VOID\r
753EFIAPI\r
754PollMouse (\r
755 IN EFI_EVENT Event,\r
756 IN VOID *Context\r
757 )\r
758\r
759{\r
760 PS2_MOUSE_DEV *MouseDev;\r
761\r
762 MouseDev = (PS2_MOUSE_DEV *) Context;\r
763\r
764 //\r
765 // Polling mouse packet data\r
766 //\r
767 PS2MouseGetPacket (MouseDev);\r
768}\r
769\r
770/**\r
771 The user Entry Point for module Ps2Mouse. The user code starts with this function.\r
772\r
773 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
774 @param[in] SystemTable A pointer to the EFI System Table.\r
775\r
776 @retval EFI_SUCCESS The entry point is executed successfully.\r
777 @retval other Some error occurs when executing this entry point.\r
778\r
779**/\r
780EFI_STATUS\r
781EFIAPI\r
782InitializePs2Mouse(\r
783 IN EFI_HANDLE ImageHandle,\r
784 IN EFI_SYSTEM_TABLE *SystemTable\r
785 )\r
786{\r
787 EFI_STATUS Status;\r
788\r
789 //\r
790 // Install driver model protocol(s).\r
791 //\r
792 Status = EfiLibInstallDriverBindingComponentName2 (\r
793 ImageHandle,\r
794 SystemTable,\r
795 &gPS2MouseDriver,\r
796 ImageHandle,\r
797 &gPs2MouseComponentName,\r
798 &gPs2MouseComponentName2\r
799 );\r
800 ASSERT_EFI_ERROR (Status);\r
801\r
802\r
803 return Status;\r
804}\r
805\r