]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/Ps2MouseAbsolutePointerDxe/Ps2MouseAbsolutePointer.c
Use PCD to customize if ps2 mouse and mouse pointer device do full reset.
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / Ps2MouseAbsolutePointerDxe / Ps2MouseAbsolutePointer.c
CommitLineData
18a73eb7 1/** @file\r
2 A faked PS/2 Absolute Pointer driver. Routines that interacts with callers,\r
afd0fe22 3 conforming to EFI driver model\r
4 \r
abfbafd5 5Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
180a5a35 6This program and the accompanying materials\r
afd0fe22 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 "Ps2MouseAbsolutePointer.h"\r
17#include "CommPs2.h"\r
18\r
19//\r
20// DriverBinding Protocol Instance\r
21//\r
22EFI_DRIVER_BINDING_PROTOCOL gPS2MouseAbsolutePointerDriver = {\r
23 PS2MouseAbsolutePointerDriverSupported,\r
24 PS2MouseAbsolutePointerDriverStart,\r
25 PS2MouseAbsolutePointerDriverStop,\r
26 0x1,\r
27 NULL,\r
28 NULL\r
29};\r
30\r
bcd70414 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
afd0fe22 45EFI_STATUS\r
46EFIAPI\r
47PS2MouseAbsolutePointerDriverSupported (\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
afd0fe22 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 Mouse 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
bcd70414 111/**\r
cab302fd 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
bcd70414 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
afd0fe22 126EFI_STATUS\r
127EFIAPI\r
128PS2MouseAbsolutePointerDriverStart (\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
afd0fe22 133{\r
134 EFI_STATUS Status;\r
135 EFI_STATUS EmptyStatus;\r
136 EFI_ISA_IO_PROTOCOL *IsaIo;\r
137 PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;\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 MouseAbsolutePointerDev = 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 MouseAbsolutePointerDev = AllocateZeroPool (sizeof (PS2_MOUSE_ABSOLUTE_POINTER_DEV));\r
199 if (MouseAbsolutePointerDev == 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 MouseAbsolutePointerDev->Signature = PS2_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE;\r
207 MouseAbsolutePointerDev->Handle = Controller;\r
3ae99102 208 MouseAbsolutePointerDev->SampleRate = SampleRate20;\r
209 MouseAbsolutePointerDev->Resolution = MouseResolution4;\r
210 MouseAbsolutePointerDev->Scaling = Scaling1;\r
afd0fe22 211 MouseAbsolutePointerDev->DataPackageSize = 3;\r
212 MouseAbsolutePointerDev->IsaIo = IsaIo;\r
213 MouseAbsolutePointerDev->DevicePath = ParentDevicePath;\r
214\r
215 //\r
216 // Resolution = 4 counts/mm\r
217 //\r
218 MouseAbsolutePointerDev->Mode.AbsoluteMaxX = 1024;\r
219 MouseAbsolutePointerDev->Mode.AbsoluteMinX = 0;\r
220 MouseAbsolutePointerDev->Mode.AbsoluteMaxY = 798;\r
221 MouseAbsolutePointerDev->Mode.AbsoluteMinY = 0;\r
222 MouseAbsolutePointerDev->Mode.AbsoluteMaxZ = 0;\r
223 MouseAbsolutePointerDev->Mode.AbsoluteMinZ = 0;\r
224 MouseAbsolutePointerDev->Mode.Attributes = 0x03;\r
225\r
226 MouseAbsolutePointerDev->AbsolutePointerProtocol.Reset = MouseAbsolutePointerReset;\r
227 MouseAbsolutePointerDev->AbsolutePointerProtocol.GetState = MouseAbsolutePointerGetState;\r
228 MouseAbsolutePointerDev->AbsolutePointerProtocol.Mode = &(MouseAbsolutePointerDev->Mode);\r
229\r
230 //\r
231 // Initialize keyboard controller if necessary\r
232 //\r
4bb5fd67 233 REPORT_STATUS_CODE_WITH_DEVICE_PATH ( \r
234 EFI_PROGRESS_CODE,\r
235 EFI_PERIPHERAL_MOUSE | EFI_P_MOUSE_PC_SELF_TEST,\r
236 ParentDevicePath\r
237 );\r
238\r
afd0fe22 239 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
240 if ((Data & KBC_SYSF) != KBC_SYSF) {\r
241 Status = KbcSelfTest (IsaIo);\r
242 if (EFI_ERROR (Status)) {\r
243 StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR;\r
244 goto ErrorExit;\r
245 }\r
246 }\r
247\r
248 KbcEnableAux (IsaIo);\r
249\r
250 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
251 EFI_PROGRESS_CODE,\r
252 EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT,\r
253 ParentDevicePath\r
254 );\r
255\r
256 //\r
257 // Reset the mouse\r
258 //\r
ace74c67 259 Status = MouseAbsolutePointerDev->AbsolutePointerProtocol.Reset (\r
260 &MouseAbsolutePointerDev->AbsolutePointerProtocol,\r
261 FeaturePcdGet (PcdPs2MouseExtendedVerification)\r
262 );\r
afd0fe22 263 if (EFI_ERROR (Status)) {\r
264 //\r
265 // mouse not connected\r
266 //\r
267 Status = EFI_SUCCESS;\r
268 StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;\r
269 goto ErrorExit;\r
270 }\r
271 //\r
272 // Setup the WaitForKey event\r
273 //\r
274 Status = gBS->CreateEvent (\r
275 EVT_NOTIFY_WAIT,\r
276 TPL_NOTIFY,\r
277 MouseAbsolutePointerWaitForInput,\r
278 MouseAbsolutePointerDev,\r
279 &((MouseAbsolutePointerDev->AbsolutePointerProtocol).WaitForInput)\r
280 );\r
281 if (EFI_ERROR (Status)) {\r
282 Status = EFI_OUT_OF_RESOURCES;\r
283 goto ErrorExit;\r
284 }\r
285 //\r
286 // Setup a periodic timer, used to poll mouse state\r
287 //\r
288 Status = gBS->CreateEvent (\r
289 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
290 TPL_NOTIFY,\r
291 PollMouseAbsolutePointer,\r
292 MouseAbsolutePointerDev,\r
293 &MouseAbsolutePointerDev->TimerEvent\r
294 );\r
295 if (EFI_ERROR (Status)) {\r
296 Status = EFI_OUT_OF_RESOURCES;\r
297 goto ErrorExit;\r
298 }\r
299 //\r
300 // Start timer to poll mouse (100 samples per second)\r
301 //\r
302 Status = gBS->SetTimer (MouseAbsolutePointerDev->TimerEvent, TimerPeriodic, 100000);\r
303 if (EFI_ERROR (Status)) {\r
304 Status = EFI_OUT_OF_RESOURCES;\r
305 goto ErrorExit;\r
306 }\r
307\r
308 MouseAbsolutePointerDev->ControllerNameTable = NULL;\r
309 AddUnicodeString2 (\r
310 "eng",\r
311 gPs2MouseAbsolutePointerComponentName.SupportedLanguages,\r
312 &MouseAbsolutePointerDev->ControllerNameTable,\r
313 L"Faked PS/2 Touchpad Device",\r
314 TRUE\r
315 );\r
316 AddUnicodeString2 (\r
317 "en",\r
318 gPs2MouseAbsolutePointerComponentName2.SupportedLanguages,\r
319 &MouseAbsolutePointerDev->ControllerNameTable,\r
320 L"Faked PS/2 Touchpad Device",\r
321 FALSE\r
322 );\r
323\r
324\r
325 //\r
326 // Install protocol interfaces for the mouse device.\r
327 //\r
328 Status = gBS->InstallMultipleProtocolInterfaces (\r
329 &Controller,\r
330 &gEfiAbsolutePointerProtocolGuid,\r
331 &MouseAbsolutePointerDev->AbsolutePointerProtocol,\r
332 NULL\r
333 );\r
334 if (EFI_ERROR (Status)) {\r
335 goto ErrorExit;\r
336 }\r
337\r
338 gBS->RestoreTPL (OldTpl);\r
339\r
340 return Status;\r
341\r
342ErrorExit:\r
343\r
344 KbcDisableAux (IsaIo);\r
345\r
346 if (StatusCode != 0) {\r
347 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
348 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
349 StatusCode,\r
350 ParentDevicePath\r
351 );\r
352 }\r
353\r
354 if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput != NULL)) {\r
355 gBS->CloseEvent (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput);\r
356 }\r
357\r
358 if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->TimerEvent != NULL)) {\r
359 gBS->CloseEvent (MouseAbsolutePointerDev->TimerEvent);\r
360 }\r
361\r
362 if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->ControllerNameTable != NULL)) {\r
363 FreeUnicodeStringTable (MouseAbsolutePointerDev->ControllerNameTable);\r
364 }\r
365 //\r
366 // Since there will be no timer handler for mouse input any more,\r
367 // exhaust input data just in case there is still mouse data left\r
368 //\r
369 EmptyStatus = EFI_SUCCESS;\r
370 while (!EFI_ERROR (EmptyStatus)) {\r
371 EmptyStatus = In8042Data (IsaIo, &Data);\r
372 }\r
373\r
374 if (MouseAbsolutePointerDev != NULL) {\r
cab302fd 375 FreePool (MouseAbsolutePointerDev);\r
afd0fe22 376 }\r
377\r
378 gBS->CloseProtocol (\r
379 Controller,\r
380 &gEfiDevicePathProtocolGuid,\r
381 This->DriverBindingHandle,\r
382 Controller\r
383 );\r
384\r
385 gBS->CloseProtocol (\r
386 Controller,\r
387 &gEfiIsaIoProtocolGuid,\r
388 This->DriverBindingHandle,\r
389 Controller\r
390 );\r
391\r
392 gBS->RestoreTPL (OldTpl);\r
393\r
394 return Status;\r
395}\r
396\r
bcd70414 397/**\r
398 Stop this driver on ControllerHandle. Support stoping any child handles\r
399 created by this driver.\r
400\r
401 @param This Protocol instance pointer.\r
402 @param ControllerHandle Handle of device to stop driver on\r
403 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
404 children is zero stop the entire bus driver.\r
405 @param ChildHandleBuffer List of Child Handles to Stop.\r
406\r
407 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
408 @retval other This driver was not removed from this device\r
409\r
410**/\r
afd0fe22 411EFI_STATUS\r
412EFIAPI\r
413PS2MouseAbsolutePointerDriverStop (\r
414 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
415 IN EFI_HANDLE Controller,\r
416 IN UINTN NumberOfChildren,\r
417 IN EFI_HANDLE *ChildHandleBuffer\r
418 )\r
afd0fe22 419{\r
420 EFI_STATUS Status;\r
421 EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointerProtocol;\r
422 PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;\r
423 UINT8 Data;\r
424\r
425 Status = gBS->OpenProtocol (\r
426 Controller,\r
427 &gEfiAbsolutePointerProtocolGuid,\r
428 (VOID **) &AbsolutePointerProtocol,\r
429 This->DriverBindingHandle,\r
430 Controller,\r
431 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
432 );\r
433 if (EFI_ERROR (Status)) {\r
434 return EFI_SUCCESS;\r
435 }\r
436\r
437 MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (AbsolutePointerProtocol);\r
438\r
439 //\r
440 // Report that the keyboard is being disabled\r
441 //\r
442 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
443 EFI_PROGRESS_CODE,\r
444 EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE,\r
445 MouseAbsolutePointerDev->DevicePath\r
446 );\r
447\r
448 Status = gBS->UninstallProtocolInterface (\r
449 Controller,\r
450 &gEfiAbsolutePointerProtocolGuid,\r
451 &MouseAbsolutePointerDev->AbsolutePointerProtocol\r
452 );\r
453 if (EFI_ERROR (Status)) {\r
454 return Status;\r
455 }\r
afd0fe22 456\r
457 //\r
458 // Cancel mouse data polling timer, close timer event\r
459 //\r
460 gBS->SetTimer (MouseAbsolutePointerDev->TimerEvent, TimerCancel, 0);\r
461 gBS->CloseEvent (MouseAbsolutePointerDev->TimerEvent);\r
462\r
463 //\r
464 // Since there will be no timer handler for mouse input any more,\r
465 // exhaust input data just in case there is still mouse data left\r
466 //\r
467 Status = EFI_SUCCESS;\r
468 while (!EFI_ERROR (Status)) {\r
469 Status = In8042Data (MouseAbsolutePointerDev->IsaIo, &Data);\r
470 }\r
471\r
472 gBS->CloseEvent (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput);\r
473 FreeUnicodeStringTable (MouseAbsolutePointerDev->ControllerNameTable);\r
cab302fd 474 FreePool (MouseAbsolutePointerDev);\r
afd0fe22 475\r
476 gBS->CloseProtocol (\r
477 Controller,\r
478 &gEfiDevicePathProtocolGuid,\r
479 This->DriverBindingHandle,\r
480 Controller\r
481 );\r
482\r
483 gBS->CloseProtocol (\r
484 Controller,\r
485 &gEfiIsaIoProtocolGuid,\r
486 This->DriverBindingHandle,\r
487 Controller\r
488 );\r
489\r
490 return EFI_SUCCESS;\r
491}\r
492\r
bcd70414 493/**\r
18a73eb7 494 Reset the Mouse and do BAT test for it, if ExtendedVerification isTRUE and there is a mouse device connectted to system.\r
bcd70414 495\r
496 @param This - Pointer of simple pointer Protocol.\r
497 @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip.\r
498\r
499\r
500 @retval EFI_SUCCESS - The command byte is written successfully.\r
501 @retval EFI_DEVICE_ERROR - Errors occurred during reseting keyboard.\r
502\r
503**/\r
afd0fe22 504EFI_STATUS\r
505EFIAPI\r
506MouseAbsolutePointerReset (\r
507 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
508 IN BOOLEAN ExtendedVerification\r
509 )\r
afd0fe22 510{\r
511 EFI_STATUS Status;\r
512 PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;\r
513 EFI_TPL OldTpl;\r
514 BOOLEAN KeyboardEnable;\r
515 UINT8 Data;\r
516\r
517 MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (This);\r
518\r
519 //\r
520 // Report reset progress code\r
521 //\r
522 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
523 EFI_PROGRESS_CODE,\r
524 EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET,\r
525 MouseAbsolutePointerDev->DevicePath\r
526 );\r
527\r
528 KeyboardEnable = FALSE;\r
529\r
530 //\r
531 // Raise TPL to avoid keyboard operation impact\r
532 //\r
533 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
534\r
535 ZeroMem (&MouseAbsolutePointerDev->State, sizeof (EFI_ABSOLUTE_POINTER_STATE));\r
536 MouseAbsolutePointerDev->StateChanged = FALSE;\r
537\r
538 //\r
539 // Exhaust input data\r
540 //\r
541 Status = EFI_SUCCESS;\r
542 while (!EFI_ERROR (Status)) {\r
543 Status = In8042Data (MouseAbsolutePointerDev->IsaIo, &Data);\r
544 }\r
545\r
546 CheckKbStatus (MouseAbsolutePointerDev->IsaIo, &KeyboardEnable);\r
547\r
548 KbcDisableKb (MouseAbsolutePointerDev->IsaIo);\r
549\r
550 MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
551\r
552 //\r
553 // if there's data block on KBC data port, read it out\r
554 //\r
555 if ((Data & KBC_OUTB) == KBC_OUTB) {\r
556 MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Data);\r
557 }\r
558\r
559 Status = EFI_SUCCESS;\r
560 //\r
561 // The PS2 mouse driver reset behavior is always successfully return no matter wheater or not there is mouse connected to system.\r
562 // This behavior is needed by performance speed. The following mouse command only succeessfully finish when mouse device is\r
563 // 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
564 //\r
565 if (ExtendedVerification && CheckMouseAbsolutePointerConnect (MouseAbsolutePointerDev)) {\r
566 //\r
567 // Send mouse reset command and set mouse default configure\r
568 //\r
569 Status = PS2MouseReset (MouseAbsolutePointerDev->IsaIo);\r
570 if (EFI_ERROR (Status)) {\r
571 Status = EFI_DEVICE_ERROR;\r
572 goto Exit;\r
573 }\r
574\r
575 Status = PS2MouseSetSampleRate (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->SampleRate);\r
576 if (EFI_ERROR (Status)) {\r
577 Status = EFI_DEVICE_ERROR;\r
578 goto Exit;\r
579 }\r
580\r
581 Status = PS2MouseSetResolution (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Resolution);\r
582 if (EFI_ERROR (Status)) {\r
583 Status = EFI_DEVICE_ERROR;\r
584 goto Exit;\r
585 }\r
586\r
587 Status = PS2MouseSetScaling (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Scaling);\r
588 if (EFI_ERROR (Status)) {\r
589 Status = EFI_DEVICE_ERROR;\r
590 goto Exit;\r
591 }\r
592\r
593 Status = PS2MouseEnable (MouseAbsolutePointerDev->IsaIo);\r
594 if (EFI_ERROR (Status)) {\r
595 Status = EFI_DEVICE_ERROR;\r
596 goto Exit;\r
597 }\r
598 }\r
599Exit:\r
600 gBS->RestoreTPL (OldTpl);\r
601\r
602 if (KeyboardEnable) {\r
603 KbcEnableKb (MouseAbsolutePointerDev->IsaIo);\r
604 }\r
605\r
606 return Status;\r
607}\r
608\r
bcd70414 609/**\r
afd0fe22 610 Check whether there is Ps/2 mouse device in system\r
611\r
18a73eb7 612 @param MouseAbsolutePointerDev - Absolute Pointer Device Private Data Structure\r
afd0fe22 613\r
bcd70414 614 @retval TRUE - Keyboard in System.\r
615 @retval FALSE - Keyboard not in System.\r
afd0fe22 616\r
bcd70414 617**/\r
618BOOLEAN\r
619CheckMouseAbsolutePointerConnect (\r
620 IN PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev\r
621 )\r
afd0fe22 622\r
afd0fe22 623{\r
624 EFI_STATUS Status;\r
625\r
626 Status = PS2MouseEnable (MouseAbsolutePointerDev->IsaIo);\r
627 if (!EFI_ERROR (Status)) {\r
628 return TRUE;\r
629 }\r
630\r
631 return FALSE;\r
632}\r
633\r
bcd70414 634/**\r
635 Get and Clear mouse status.\r
636 \r
637 @param This - Pointer of simple pointer Protocol.\r
638 @param State - Output buffer holding status.\r
639\r
640 @retval EFI_INVALID_PARAMETER Output buffer is invalid.\r
641 @retval EFI_NOT_READY Mouse is not changed status yet.\r
642 @retval EFI_SUCCESS Mouse status is changed and get successful.\r
643**/\r
afd0fe22 644EFI_STATUS\r
645EFIAPI\r
646MouseAbsolutePointerGetState (\r
647 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
648 IN OUT EFI_ABSOLUTE_POINTER_STATE *State\r
649 )\r
afd0fe22 650{\r
651 PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;\r
652 EFI_TPL OldTpl;\r
653\r
654 MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (This);\r
655\r
656 if (State == NULL) {\r
657 return EFI_INVALID_PARAMETER;\r
658 }\r
659\r
660 if (!MouseAbsolutePointerDev->StateChanged) {\r
661 return EFI_NOT_READY;\r
662 }\r
663\r
664 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
665 CopyMem (State, &(MouseAbsolutePointerDev->State), sizeof (EFI_ABSOLUTE_POINTER_STATE));\r
666\r
667 //\r
668 // clear mouse state\r
669 //\r
670 MouseAbsolutePointerDev->State.CurrentX = 0;\r
671 MouseAbsolutePointerDev->State.CurrentY = 0;\r
672 MouseAbsolutePointerDev->State.CurrentZ = 0;\r
673 MouseAbsolutePointerDev->State.ActiveButtons = 0x0;\r
674 MouseAbsolutePointerDev->StateChanged = FALSE;\r
675 gBS->RestoreTPL (OldTpl);\r
676\r
677 return EFI_SUCCESS;\r
678}\r
679\r
bcd70414 680/**\r
afd0fe22 681\r
18a73eb7 682 Event notification function for SIMPLE_POINTER.WaitForInput event.\r
683 Signal the event if there is input from mouse.\r
afd0fe22 684\r
bcd70414 685 @param Event event object\r
686 @param Context event context\r
afd0fe22 687\r
bcd70414 688**/\r
bcd70414 689VOID\r
690EFIAPI\r
691MouseAbsolutePointerWaitForInput (\r
692 IN EFI_EVENT Event,\r
693 IN VOID *Context\r
694 )\r
afd0fe22 695{\r
696 PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;\r
697\r
698 MouseAbsolutePointerDev = (PS2_MOUSE_ABSOLUTE_POINTER_DEV *) Context;\r
699\r
700 //\r
701 // Someone is waiting on the mouse event, if there's\r
702 // input from mouse, signal the event\r
703 //\r
704 if (MouseAbsolutePointerDev->StateChanged) {\r
705 gBS->SignalEvent (Event);\r
706 }\r
707\r
708}\r
709\r
bcd70414 710/**\r
18a73eb7 711 Event notification function for TimerEvent event.\r
712 If mouse device is connected to system, try to get the mouse packet data.\r
bcd70414 713\r
714 @param Event - TimerEvent in PS2_MOUSE_DEV\r
715 @param Context - Pointer to PS2_MOUSE_DEV structure\r
716\r
717**/\r
afd0fe22 718VOID\r
719EFIAPI\r
720PollMouseAbsolutePointer(\r
721 IN EFI_EVENT Event,\r
722 IN VOID *Context\r
723 )\r
afd0fe22 724\r
afd0fe22 725{\r
726 PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;\r
727\r
728 MouseAbsolutePointerDev = (PS2_MOUSE_ABSOLUTE_POINTER_DEV *) Context;\r
729\r
730 //\r
731 // Polling mouse packet data\r
732 //\r
733 PS2MouseGetPacket (MouseAbsolutePointerDev);\r
734}\r
735\r
736/**\r
737 The user Entry Point for module Ps2MouseAbsolutePointer. The user code starts with this function.\r
738\r
739 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
740 @param[in] SystemTable A pointer to the EFI System Table.\r
741 \r
742 @retval EFI_SUCCESS The entry point is executed successfully.\r
743 @retval other Some error occurs when executing this entry point.\r
744\r
745**/\r
746EFI_STATUS\r
747EFIAPI\r
748InitializePs2MouseAbsolutePointer(\r
749 IN EFI_HANDLE ImageHandle,\r
750 IN EFI_SYSTEM_TABLE *SystemTable\r
751 )\r
752{\r
753 EFI_STATUS Status;\r
754\r
755 //\r
756 // Install driver model protocol(s).\r
757 //\r
758 Status = EfiLibInstallDriverBindingComponentName2 (\r
759 ImageHandle,\r
760 SystemTable,\r
761 &gPS2MouseAbsolutePointerDriver,\r
762 ImageHandle,\r
763 &gPs2MouseAbsolutePointerComponentName,\r
764 &gPs2MouseAbsolutePointerComponentName2\r
765 );\r
766 ASSERT_EFI_ERROR (Status);\r
767\r
768\r
769 return Status;\r
770}\r
bcd70414 771\r