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