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