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