]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Bus/Isa/Ps2MouseAbsolutePointerDxe/Ps2MouseAbsolutePointer.c
Remove disabling keyboard/auxiliary interface in Driver Binding Protocol.Stop() of...
[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 - 2011, 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
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 //
449 // Cancel mouse data polling timer, close timer event
450 //
451 gBS->SetTimer (MouseAbsolutePointerDev->TimerEvent, TimerCancel, 0);
452 gBS->CloseEvent (MouseAbsolutePointerDev->TimerEvent);
453
454 //
455 // Since there will be no timer handler for mouse input any more,
456 // exhaust input data just in case there is still mouse data left
457 //
458 Status = EFI_SUCCESS;
459 while (!EFI_ERROR (Status)) {
460 Status = In8042Data (MouseAbsolutePointerDev->IsaIo, &Data);
461 }
462
463 gBS->CloseEvent (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput);
464 FreeUnicodeStringTable (MouseAbsolutePointerDev->ControllerNameTable);
465 FreePool (MouseAbsolutePointerDev);
466
467 gBS->CloseProtocol (
468 Controller,
469 &gEfiDevicePathProtocolGuid,
470 This->DriverBindingHandle,
471 Controller
472 );
473
474 gBS->CloseProtocol (
475 Controller,
476 &gEfiIsaIoProtocolGuid,
477 This->DriverBindingHandle,
478 Controller
479 );
480
481 return EFI_SUCCESS;
482 }
483
484 /**
485 Reset the Mouse and do BAT test for it, if ExtendedVerification isTRUE and there is a mouse device connectted to system.
486
487 @param This - Pointer of simple pointer Protocol.
488 @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip.
489
490
491 @retval EFI_SUCCESS - The command byte is written successfully.
492 @retval EFI_DEVICE_ERROR - Errors occurred during reseting keyboard.
493
494 **/
495 EFI_STATUS
496 EFIAPI
497 MouseAbsolutePointerReset (
498 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,
499 IN BOOLEAN ExtendedVerification
500 )
501 {
502 EFI_STATUS Status;
503 PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;
504 EFI_TPL OldTpl;
505 BOOLEAN KeyboardEnable;
506 UINT8 Data;
507
508 MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (This);
509
510 //
511 // Report reset progress code
512 //
513 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
514 EFI_PROGRESS_CODE,
515 EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET,
516 MouseAbsolutePointerDev->DevicePath
517 );
518
519 KeyboardEnable = FALSE;
520
521 //
522 // Raise TPL to avoid keyboard operation impact
523 //
524 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
525
526 ZeroMem (&MouseAbsolutePointerDev->State, sizeof (EFI_ABSOLUTE_POINTER_STATE));
527 MouseAbsolutePointerDev->StateChanged = FALSE;
528
529 //
530 // Exhaust input data
531 //
532 Status = EFI_SUCCESS;
533 while (!EFI_ERROR (Status)) {
534 Status = In8042Data (MouseAbsolutePointerDev->IsaIo, &Data);
535 }
536
537 CheckKbStatus (MouseAbsolutePointerDev->IsaIo, &KeyboardEnable);
538
539 KbcDisableKb (MouseAbsolutePointerDev->IsaIo);
540
541 MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);
542
543 //
544 // if there's data block on KBC data port, read it out
545 //
546 if ((Data & KBC_OUTB) == KBC_OUTB) {
547 MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Data);
548 }
549
550 Status = EFI_SUCCESS;
551 //
552 // The PS2 mouse driver reset behavior is always successfully return no matter wheater or not there is mouse connected to system.
553 // This behavior is needed by performance speed. The following mouse command only succeessfully finish when mouse device is
554 // connected to system, so if PS2 mouse device not connect to system or user not ask for, we skip the mouse configuration and enabling
555 //
556 if (ExtendedVerification && CheckMouseAbsolutePointerConnect (MouseAbsolutePointerDev)) {
557 //
558 // Send mouse reset command and set mouse default configure
559 //
560 Status = PS2MouseReset (MouseAbsolutePointerDev->IsaIo);
561 if (EFI_ERROR (Status)) {
562 Status = EFI_DEVICE_ERROR;
563 goto Exit;
564 }
565
566 Status = PS2MouseSetSampleRate (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->SampleRate);
567 if (EFI_ERROR (Status)) {
568 Status = EFI_DEVICE_ERROR;
569 goto Exit;
570 }
571
572 Status = PS2MouseSetResolution (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Resolution);
573 if (EFI_ERROR (Status)) {
574 Status = EFI_DEVICE_ERROR;
575 goto Exit;
576 }
577
578 Status = PS2MouseSetScaling (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Scaling);
579 if (EFI_ERROR (Status)) {
580 Status = EFI_DEVICE_ERROR;
581 goto Exit;
582 }
583
584 Status = PS2MouseEnable (MouseAbsolutePointerDev->IsaIo);
585 if (EFI_ERROR (Status)) {
586 Status = EFI_DEVICE_ERROR;
587 goto Exit;
588 }
589 }
590 Exit:
591 gBS->RestoreTPL (OldTpl);
592
593 if (KeyboardEnable) {
594 KbcEnableKb (MouseAbsolutePointerDev->IsaIo);
595 }
596
597 return Status;
598 }
599
600 /**
601 Check whether there is Ps/2 mouse device in system
602
603 @param MouseAbsolutePointerDev - Absolute Pointer Device Private Data Structure
604
605 @retval TRUE - Keyboard in System.
606 @retval FALSE - Keyboard not in System.
607
608 **/
609 BOOLEAN
610 CheckMouseAbsolutePointerConnect (
611 IN PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev
612 )
613
614 {
615 EFI_STATUS Status;
616
617 Status = PS2MouseEnable (MouseAbsolutePointerDev->IsaIo);
618 if (!EFI_ERROR (Status)) {
619 return TRUE;
620 }
621
622 return FALSE;
623 }
624
625 /**
626 Get and Clear mouse status.
627
628 @param This - Pointer of simple pointer Protocol.
629 @param State - Output buffer holding status.
630
631 @retval EFI_INVALID_PARAMETER Output buffer is invalid.
632 @retval EFI_NOT_READY Mouse is not changed status yet.
633 @retval EFI_SUCCESS Mouse status is changed and get successful.
634 **/
635 EFI_STATUS
636 EFIAPI
637 MouseAbsolutePointerGetState (
638 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,
639 IN OUT EFI_ABSOLUTE_POINTER_STATE *State
640 )
641 {
642 PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;
643 EFI_TPL OldTpl;
644
645 MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (This);
646
647 if (State == NULL) {
648 return EFI_INVALID_PARAMETER;
649 }
650
651 if (!MouseAbsolutePointerDev->StateChanged) {
652 return EFI_NOT_READY;
653 }
654
655 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
656 CopyMem (State, &(MouseAbsolutePointerDev->State), sizeof (EFI_ABSOLUTE_POINTER_STATE));
657
658 //
659 // clear mouse state
660 //
661 MouseAbsolutePointerDev->State.CurrentX = 0;
662 MouseAbsolutePointerDev->State.CurrentY = 0;
663 MouseAbsolutePointerDev->State.CurrentZ = 0;
664 MouseAbsolutePointerDev->State.ActiveButtons = 0x0;
665 MouseAbsolutePointerDev->StateChanged = FALSE;
666 gBS->RestoreTPL (OldTpl);
667
668 return EFI_SUCCESS;
669 }
670
671 /**
672
673 Event notification function for SIMPLE_POINTER.WaitForInput event.
674 Signal the event if there is input from mouse.
675
676 @param Event event object
677 @param Context event context
678
679 **/
680 VOID
681 EFIAPI
682 MouseAbsolutePointerWaitForInput (
683 IN EFI_EVENT Event,
684 IN VOID *Context
685 )
686 {
687 PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;
688
689 MouseAbsolutePointerDev = (PS2_MOUSE_ABSOLUTE_POINTER_DEV *) Context;
690
691 //
692 // Someone is waiting on the mouse event, if there's
693 // input from mouse, signal the event
694 //
695 if (MouseAbsolutePointerDev->StateChanged) {
696 gBS->SignalEvent (Event);
697 }
698
699 }
700
701 /**
702 Event notification function for TimerEvent event.
703 If mouse device is connected to system, try to get the mouse packet data.
704
705 @param Event - TimerEvent in PS2_MOUSE_DEV
706 @param Context - Pointer to PS2_MOUSE_DEV structure
707
708 **/
709 VOID
710 EFIAPI
711 PollMouseAbsolutePointer(
712 IN EFI_EVENT Event,
713 IN VOID *Context
714 )
715
716 {
717 PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;
718
719 MouseAbsolutePointerDev = (PS2_MOUSE_ABSOLUTE_POINTER_DEV *) Context;
720
721 //
722 // Polling mouse packet data
723 //
724 PS2MouseGetPacket (MouseAbsolutePointerDev);
725 }
726
727 /**
728 The user Entry Point for module Ps2MouseAbsolutePointer. The user code starts with this function.
729
730 @param[in] ImageHandle The firmware allocated handle for the EFI image.
731 @param[in] SystemTable A pointer to the EFI System Table.
732
733 @retval EFI_SUCCESS The entry point is executed successfully.
734 @retval other Some error occurs when executing this entry point.
735
736 **/
737 EFI_STATUS
738 EFIAPI
739 InitializePs2MouseAbsolutePointer(
740 IN EFI_HANDLE ImageHandle,
741 IN EFI_SYSTEM_TABLE *SystemTable
742 )
743 {
744 EFI_STATUS Status;
745
746 //
747 // Install driver model protocol(s).
748 //
749 Status = EfiLibInstallDriverBindingComponentName2 (
750 ImageHandle,
751 SystemTable,
752 &gPS2MouseAbsolutePointerDriver,
753 ImageHandle,
754 &gPs2MouseAbsolutePointerComponentName,
755 &gPs2MouseAbsolutePointerComponentName2
756 );
757 ASSERT_EFI_ERROR (Status);
758
759
760 return Status;
761 }
762