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