1/** @file 2 A faked PS/2 Absolute Pointer driver. Routines that interacts with callers, 3 conforming to EFI driver model 4 5Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> 6This program and the accompanying materials 7are licensed and made available under the terms and conditions of the BSD License 8which accompanies this distribution. The full text of the license may be found at 9http://opensource.org/licenses/bsd-license.php 10 11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12WITHOUT 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// 22EFI_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**/ 45EFI_STATUS 46EFIAPI 47PS2MouseAbsolutePointerDriverSupported ( 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**/ 126EFI_STATUS 127EFIAPI 128PS2MouseAbsolutePointerDriverStart ( 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 349ErrorExit: 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 stoping 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**/ 418EFI_STATUS 419EFIAPI 420PS2MouseAbsolutePointerDriverStop ( 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 isTRUE and there is a mouse device connectted 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 reseting keyboard. 509 510**/ 511EFI_STATUS 512EFIAPI 513MouseAbsolutePointerReset ( 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 } 606Exit: 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**/ 625BOOLEAN 626CheckMouseAbsolutePointerConnect ( 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**/ 651EFI_STATUS 652EFIAPI 653MouseAbsolutePointerGetState ( 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**/ 696VOID 697EFIAPI 698MouseAbsolutePointerWaitForInput ( 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**/ 725VOID 726EFIAPI 727PollMouseAbsolutePointer( 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**/ 753EFI_STATUS 754EFIAPI 755InitializePs2MouseAbsolutePointer( 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