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