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 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 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 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 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 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 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 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 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 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