]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.c
According to PI errata 0000654 and 000811, we need use 0xFFFE to instead of 0 for...
[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
abfbafd5 5Copyright (c) 2006 - 2011, 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
269 Status = MouseDev->SimplePointerProtocol.Reset (&MouseDev->SimplePointerProtocol, TRUE);\r
270 if (EFI_ERROR (Status)) {\r
271 //\r
272 // mouse not connected\r
273 //\r
274 Status = EFI_SUCCESS;\r
275 StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;\r
276 goto ErrorExit;\r
277 }\r
278 //\r
279 // Setup the WaitForKey event\r
280 //\r
281 Status = gBS->CreateEvent (\r
282 EVT_NOTIFY_WAIT,\r
283 TPL_NOTIFY,\r
284 MouseWaitForInput,\r
285 MouseDev,\r
286 &((MouseDev->SimplePointerProtocol).WaitForInput)\r
287 );\r
288 if (EFI_ERROR (Status)) {\r
289 Status = EFI_OUT_OF_RESOURCES;\r
290 goto ErrorExit;\r
291 }\r
292 //\r
293 // Setup a periodic timer, used to poll mouse state\r
294 //\r
295 Status = gBS->CreateEvent (\r
296 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
297 TPL_NOTIFY,\r
298 PollMouse,\r
299 MouseDev,\r
300 &MouseDev->TimerEvent\r
301 );\r
302 if (EFI_ERROR (Status)) {\r
303 Status = EFI_OUT_OF_RESOURCES;\r
304 goto ErrorExit;\r
305 }\r
306 //\r
307 // Start timer to poll mouse (100 samples per second)\r
308 //\r
309 Status = gBS->SetTimer (MouseDev->TimerEvent, TimerPeriodic, 100000);\r
310 if (EFI_ERROR (Status)) {\r
311 Status = EFI_OUT_OF_RESOURCES;\r
312 goto ErrorExit;\r
313 }\r
314\r
315 MouseDev->ControllerNameTable = NULL;\r
f3d08ccf 316 AddUnicodeString2 (\r
05fbd06d 317 "eng",\r
318 gPs2MouseComponentName.SupportedLanguages,\r
319 &MouseDev->ControllerNameTable,\r
f3d08ccf 320 L"PS/2 Mouse Device",\r
321 TRUE\r
05fbd06d 322 );\r
f3d08ccf 323 AddUnicodeString2 (\r
324 "en",\r
325 gPs2MouseComponentName2.SupportedLanguages,\r
326 &MouseDev->ControllerNameTable,\r
327 L"PS/2 Mouse Device",\r
328 FALSE\r
329 );\r
330\r
05fbd06d 331\r
332 //\r
333 // Install protocol interfaces for the mouse device.\r
334 //\r
335 Status = gBS->InstallMultipleProtocolInterfaces (\r
336 &Controller,\r
337 &gEfiSimplePointerProtocolGuid,\r
338 &MouseDev->SimplePointerProtocol,\r
339 NULL\r
340 );\r
341 if (EFI_ERROR (Status)) {\r
342 goto ErrorExit;\r
343 }\r
344\r
345 gBS->RestoreTPL (OldTpl);\r
346\r
347 return Status;\r
348\r
349ErrorExit:\r
350\r
007c18f5 351 if (Status != EFI_DEVICE_ERROR) {\r
352 KbcDisableAux (IsaIo);\r
353 }\r
05fbd06d 354\r
355 if (StatusCode != 0) {\r
356 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
357 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
358 StatusCode,\r
359 ParentDevicePath\r
360 );\r
361 }\r
362\r
363 if ((MouseDev != NULL) && (MouseDev->SimplePointerProtocol.WaitForInput != NULL)) {\r
364 gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput);\r
365 }\r
366\r
367 if ((MouseDev != NULL) && (MouseDev->TimerEvent != NULL)) {\r
368 gBS->CloseEvent (MouseDev->TimerEvent);\r
369 }\r
370\r
371 if ((MouseDev != NULL) && (MouseDev->ControllerNameTable != NULL)) {\r
372 FreeUnicodeStringTable (MouseDev->ControllerNameTable);\r
373 }\r
007c18f5 374 \r
375 if (Status != EFI_DEVICE_ERROR) {\r
376 //\r
377 // Since there will be no timer handler for mouse input any more,\r
378 // exhaust input data just in case there is still mouse data left\r
379 //\r
380 EmptyStatus = EFI_SUCCESS;\r
381 while (!EFI_ERROR (EmptyStatus)) {\r
382 EmptyStatus = In8042Data (IsaIo, &Data);\r
383 }\r
05fbd06d 384 }\r
385\r
386 if (MouseDev != NULL) {\r
24a2dd3d 387 FreePool (MouseDev);\r
05fbd06d 388 }\r
389\r
390 gBS->CloseProtocol (\r
391 Controller,\r
392 &gEfiDevicePathProtocolGuid,\r
393 This->DriverBindingHandle,\r
394 Controller\r
395 );\r
396\r
397 gBS->CloseProtocol (\r
398 Controller,\r
399 &gEfiIsaIoProtocolGuid,\r
400 This->DriverBindingHandle,\r
401 Controller\r
402 );\r
403\r
404 gBS->RestoreTPL (OldTpl);\r
405\r
406 return Status;\r
407}\r
408\r
ff1fcef8 409/**\r
410 Stop this driver on ControllerHandle. Support stoping any child handles\r
411 created by this driver.\r
412\r
413 @param This Protocol instance pointer.\r
414 @param ControllerHandle Handle of device to stop driver on\r
415 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
416 children is zero stop the entire bus driver.\r
417 @param ChildHandleBuffer List of Child Handles to Stop.\r
418\r
419 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
420 @retval other This driver was not removed from this device\r
421\r
422**/\r
05fbd06d 423EFI_STATUS\r
424EFIAPI\r
425PS2MouseDriverStop (\r
426 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
427 IN EFI_HANDLE Controller,\r
428 IN UINTN NumberOfChildren,\r
429 IN EFI_HANDLE *ChildHandleBuffer\r
430 )\r
05fbd06d 431{\r
432 EFI_STATUS Status;\r
433 EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol;\r
434 PS2_MOUSE_DEV *MouseDev;\r
435 UINT8 Data;\r
436\r
437 Status = gBS->OpenProtocol (\r
438 Controller,\r
439 &gEfiSimplePointerProtocolGuid,\r
440 (VOID **) &SimplePointerProtocol,\r
441 This->DriverBindingHandle,\r
442 Controller,\r
443 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
444 );\r
445 if (EFI_ERROR (Status)) {\r
446 return EFI_SUCCESS;\r
447 }\r
448\r
449 MouseDev = PS2_MOUSE_DEV_FROM_THIS (SimplePointerProtocol);\r
450\r
451 //\r
452 // Report that the keyboard is being disabled\r
453 //\r
454 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
455 EFI_PROGRESS_CODE,\r
456 EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE,\r
457 MouseDev->DevicePath\r
458 );\r
459\r
460 Status = gBS->UninstallProtocolInterface (\r
461 Controller,\r
462 &gEfiSimplePointerProtocolGuid,\r
463 &MouseDev->SimplePointerProtocol\r
464 );\r
465 if (EFI_ERROR (Status)) {\r
466 return Status;\r
467 }\r
05fbd06d 468\r
469 //\r
470 // Cancel mouse data polling timer, close timer event\r
471 //\r
472 gBS->SetTimer (MouseDev->TimerEvent, TimerCancel, 0);\r
473 gBS->CloseEvent (MouseDev->TimerEvent);\r
474\r
475 //\r
476 // Since there will be no timer handler for mouse input any more,\r
477 // exhaust input data just in case there is still mouse data left\r
478 //\r
479 Status = EFI_SUCCESS;\r
480 while (!EFI_ERROR (Status)) {\r
481 Status = In8042Data (MouseDev->IsaIo, &Data);\r
482 }\r
483\r
484 gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput);\r
485 FreeUnicodeStringTable (MouseDev->ControllerNameTable);\r
24a2dd3d 486 FreePool (MouseDev);\r
05fbd06d 487\r
488 gBS->CloseProtocol (\r
489 Controller,\r
490 &gEfiDevicePathProtocolGuid,\r
491 This->DriverBindingHandle,\r
492 Controller\r
493 );\r
494\r
495 gBS->CloseProtocol (\r
496 Controller,\r
497 &gEfiIsaIoProtocolGuid,\r
498 This->DriverBindingHandle,\r
499 Controller\r
500 );\r
501\r
502 return EFI_SUCCESS;\r
503}\r
504\r
bcd70414 505/**\r
05fbd06d 506 Reset the Mouse and do BAT test for it, if ExtendedVerification isTRUE and there is a mouse device connectted to system\r
507\r
ff1fcef8 508 @param This - Pointer of simple pointer Protocol.\r
509 @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip.\r
05fbd06d 510\r
05fbd06d 511\r
ff1fcef8 512 @retval EFI_SUCCESS - The command byte is written successfully.\r
513 @retval EFI_DEVICE_ERROR - Errors occurred during reseting keyboard.\r
05fbd06d 514\r
bcd70414 515**/\r
ff1fcef8 516EFI_STATUS\r
517EFIAPI\r
518MouseReset (\r
519 IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
520 IN BOOLEAN ExtendedVerification\r
521 )\r
05fbd06d 522{\r
523 EFI_STATUS Status;\r
524 PS2_MOUSE_DEV *MouseDev;\r
525 EFI_TPL OldTpl;\r
526 BOOLEAN KeyboardEnable;\r
527 UINT8 Data;\r
528\r
529 MouseDev = PS2_MOUSE_DEV_FROM_THIS (This);\r
530\r
531 //\r
532 // Report reset progress code\r
533 //\r
534 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
535 EFI_PROGRESS_CODE,\r
536 EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET,\r
537 MouseDev->DevicePath\r
538 );\r
539\r
540 KeyboardEnable = FALSE;\r
541\r
542 //\r
543 // Raise TPL to avoid keyboard operation impact\r
544 //\r
545 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
546\r
547 ZeroMem (&MouseDev->State, sizeof (EFI_SIMPLE_POINTER_STATE));\r
548 MouseDev->StateChanged = FALSE;\r
549\r
550 //\r
551 // Exhaust input data\r
552 //\r
553 Status = EFI_SUCCESS;\r
554 while (!EFI_ERROR (Status)) {\r
555 Status = In8042Data (MouseDev->IsaIo, &Data);\r
556 }\r
557\r
558 CheckKbStatus (MouseDev->IsaIo, &KeyboardEnable);\r
559\r
560 KbcDisableKb (MouseDev->IsaIo);\r
561\r
562 MouseDev->IsaIo->Io.Read (MouseDev->IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
563\r
564 //\r
565 // if there's data block on KBC data port, read it out\r
566 //\r
567 if ((Data & KBC_OUTB) == KBC_OUTB) {\r
568 MouseDev->IsaIo->Io.Read (MouseDev->IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Data);\r
569 }\r
570\r
571 Status = EFI_SUCCESS;\r
572 //\r
573 // The PS2 mouse driver reset behavior is always successfully return no matter wheater or not there is mouse connected to system.\r
574 // This behavior is needed by performance speed. The following mouse command only succeessfully finish when mouse device is\r
575 // 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
576 //\r
577 if (ExtendedVerification && CheckMouseConnect (MouseDev)) {\r
578 //\r
579 // Send mouse reset command and set mouse default configure\r
580 //\r
581 Status = PS2MouseReset (MouseDev->IsaIo);\r
582 if (EFI_ERROR (Status)) {\r
583 Status = EFI_DEVICE_ERROR;\r
584 goto Exit;\r
585 }\r
586\r
587 Status = PS2MouseSetSampleRate (MouseDev->IsaIo, MouseDev->SampleRate);\r
588 if (EFI_ERROR (Status)) {\r
589 Status = EFI_DEVICE_ERROR;\r
590 goto Exit;\r
591 }\r
592\r
593 Status = PS2MouseSetResolution (MouseDev->IsaIo, MouseDev->Resolution);\r
594 if (EFI_ERROR (Status)) {\r
595 Status = EFI_DEVICE_ERROR;\r
596 goto Exit;\r
597 }\r
598\r
599 Status = PS2MouseSetScaling (MouseDev->IsaIo, MouseDev->Scaling);\r
600 if (EFI_ERROR (Status)) {\r
601 Status = EFI_DEVICE_ERROR;\r
602 goto Exit;\r
603 }\r
604\r
605 Status = PS2MouseEnable (MouseDev->IsaIo);\r
606 if (EFI_ERROR (Status)) {\r
607 Status = EFI_DEVICE_ERROR;\r
608 goto Exit;\r
609 }\r
610 }\r
611Exit:\r
612 gBS->RestoreTPL (OldTpl);\r
613\r
614 if (KeyboardEnable) {\r
615 KbcEnableKb (MouseDev->IsaIo);\r
616 }\r
617\r
618 return Status;\r
619}\r
620\r
bcd70414 621/**\r
05fbd06d 622 Check whether there is Ps/2 mouse device in system\r
623\r
172870ef 624 @param MouseDev - Mouse Private Data Structure\r
05fbd06d 625\r
172870ef 626 @retval TRUE - Keyboard in System.\r
627 @retval FALSE - Keyboard not in System.\r
05fbd06d 628\r
bcd70414 629**/\r
ff1fcef8 630BOOLEAN\r
631CheckMouseConnect (\r
632 IN PS2_MOUSE_DEV *MouseDev\r
633 )\r
634\r
05fbd06d 635{\r
636 EFI_STATUS Status;\r
637\r
638 Status = PS2MouseEnable (MouseDev->IsaIo);\r
639 if (!EFI_ERROR (Status)) {\r
640 return TRUE;\r
641 }\r
642\r
643 return FALSE;\r
644}\r
645\r
ff1fcef8 646/**\r
647 Get and Clear mouse status.\r
648 \r
649 @param This - Pointer of simple pointer Protocol.\r
650 @param State - Output buffer holding status.\r
651\r
652 @retval EFI_INVALID_PARAMETER Output buffer is invalid.\r
653 @retval EFI_NOT_READY Mouse is not changed status yet.\r
654 @retval EFI_SUCCESS Mouse status is changed and get successful.\r
655**/\r
05fbd06d 656EFI_STATUS\r
657EFIAPI\r
658MouseGetState (\r
659 IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
660 IN OUT EFI_SIMPLE_POINTER_STATE *State\r
661 )\r
05fbd06d 662{\r
663 PS2_MOUSE_DEV *MouseDev;\r
664 EFI_TPL OldTpl;\r
665\r
666 MouseDev = PS2_MOUSE_DEV_FROM_THIS (This);\r
667\r
668 if (State == NULL) {\r
669 return EFI_INVALID_PARAMETER;\r
670 }\r
671\r
672 if (!MouseDev->StateChanged) {\r
673 return EFI_NOT_READY;\r
674 }\r
675\r
676 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
677 CopyMem (State, &(MouseDev->State), sizeof (EFI_SIMPLE_POINTER_STATE));\r
678\r
679 //\r
680 // clear mouse state\r
681 //\r
682 MouseDev->State.RelativeMovementX = 0;\r
683 MouseDev->State.RelativeMovementY = 0;\r
684 MouseDev->State.RelativeMovementZ = 0;\r
685 MouseDev->StateChanged = FALSE;\r
686 gBS->RestoreTPL (OldTpl);\r
687\r
688 return EFI_SUCCESS;\r
689}\r
690\r
bcd70414 691/**\r
05fbd06d 692\r
172870ef 693 Event notification function for SIMPLE_POINTER.WaitForInput event.\r
694 Signal the event if there is input from mouse.\r
05fbd06d 695\r
ff1fcef8 696 @param Event event object\r
697 @param Context event context\r
05fbd06d 698\r
bcd70414 699**/\r
ff1fcef8 700VOID\r
701EFIAPI\r
702MouseWaitForInput (\r
703 IN EFI_EVENT Event,\r
704 IN VOID *Context\r
705 )\r
05fbd06d 706{\r
707 PS2_MOUSE_DEV *MouseDev;\r
708\r
709 MouseDev = (PS2_MOUSE_DEV *) Context;\r
710\r
711 //\r
712 // Someone is waiting on the mouse event, if there's\r
713 // input from mouse, signal the event\r
714 //\r
715 if (MouseDev->StateChanged) {\r
716 gBS->SignalEvent (Event);\r
717 }\r
718\r
719}\r
720\r
ff1fcef8 721/**\r
18a73eb7 722 Event notification function for TimerEvent event.\r
723 If mouse device is connected to system, try to get the mouse packet data.\r
ff1fcef8 724\r
725 @param Event - TimerEvent in PS2_MOUSE_DEV\r
726 @param Context - Pointer to PS2_MOUSE_DEV structure\r
727\r
728**/\r
05fbd06d 729VOID\r
730EFIAPI\r
731PollMouse (\r
732 IN EFI_EVENT Event,\r
733 IN VOID *Context\r
734 )\r
05fbd06d 735\r
05fbd06d 736{\r
737 PS2_MOUSE_DEV *MouseDev;\r
738\r
739 MouseDev = (PS2_MOUSE_DEV *) Context;\r
740\r
741 //\r
742 // Polling mouse packet data\r
743 //\r
744 PS2MouseGetPacket (MouseDev);\r
745}\r
c21fc3e8 746\r
747/**\r
748 The user Entry Point for module Ps2Mouse. The user code starts with this function.\r
749\r
750 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
751 @param[in] SystemTable A pointer to the EFI System Table.\r
752 \r
753 @retval EFI_SUCCESS The entry point is executed successfully.\r
754 @retval other Some error occurs when executing this entry point.\r
755\r
756**/\r
757EFI_STATUS\r
758EFIAPI\r
759InitializePs2Mouse(\r
760 IN EFI_HANDLE ImageHandle,\r
761 IN EFI_SYSTEM_TABLE *SystemTable\r
762 )\r
763{\r
764 EFI_STATUS Status;\r
765\r
766 //\r
767 // Install driver model protocol(s).\r
768 //\r
f3d08ccf 769 Status = EfiLibInstallDriverBindingComponentName2 (\r
c21fc3e8 770 ImageHandle,\r
771 SystemTable,\r
772 &gPS2MouseDriver,\r
773 ImageHandle,\r
774 &gPs2MouseComponentName,\r
f3d08ccf 775 &gPs2MouseComponentName2\r
c21fc3e8 776 );\r
777 ASSERT_EFI_ERROR (Status);\r
778\r
779\r
780 return Status;\r
781}\r
ff1fcef8 782\r