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