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