/** Issue self test command via IsaIo interface. @return EFI_SUCCESS Success to do keyboard self testing. @return others Fail to do keyboard self testing. **/ EFI_STATUS KbcSelfTest ( VOID ) { EFI_STATUS Status; UINT8 Data; // // Keyboard controller self test // Status = Out8042Command (SELF_TEST); if (EFI_ERROR (Status)) { return Status; } // // Read return code // Status = In8042Data (&Data); if (EFI_ERROR (Status)) { return Status; } if (Data != 0x55) { return EFI_DEVICE_ERROR; } // // Set system flag // Status = Out8042Command (READ_CMD_BYTE); if (EFI_ERROR (Status)) { return Status; } Status = In8042Data (&Data); if (EFI_ERROR (Status)) { return Status; } Status = Out8042Command (WRITE_CMD_BYTE); if (EFI_ERROR (Status)) { return Status; } Data |= CMD_SYS_FLAG; Status = Out8042Data (Data); if (EFI_ERROR (Status)) { return Status; } return EFI_SUCCESS; }
/** Issue command to check keyboard status. @param KeyboardEnable return whether keyboard is enable. @return Status of command issuing. **/ EFI_STATUS CheckKbStatus ( OUT BOOLEAN *KeyboardEnable ) { EFI_STATUS Status; UINT8 Data; // // Send command to read KBC command byte // Status = Out8042Command (READ_CMD_BYTE); if (EFI_ERROR (Status)) { return Status; } Status = In8042Data (&Data); if (EFI_ERROR (Status)) { return Status; } // // Check keyboard enable or not // if ((Data & CMD_KB_STS) == CMD_KB_DIS) { *KeyboardEnable = FALSE; } else { *KeyboardEnable = TRUE; } return EFI_SUCCESS; }
/** Reset the Mouse and do BAT test for it, if ExtendedVerification isTRUE and there is a mouse device connectted to system. @param This - Pointer of simple pointer Protocol. @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip. @retval EFI_SUCCESS - The command byte is written successfully. @retval EFI_DEVICE_ERROR - Errors occurred during reseting keyboard. **/ EFI_STATUS EFIAPI MouseAbsolutePointerReset ( IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, IN BOOLEAN ExtendedVerification ) { EFI_STATUS Status; PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev; EFI_TPL OldTpl; BOOLEAN KeyboardEnable; UINT8 Data; MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (This); // // Report reset progress code // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET, MouseAbsolutePointerDev->DevicePath ); KeyboardEnable = FALSE; // // Raise TPL to avoid keyboard operation impact // OldTpl = gBS->RaiseTPL (TPL_NOTIFY); ZeroMem (&MouseAbsolutePointerDev->State, sizeof (EFI_ABSOLUTE_POINTER_STATE)); MouseAbsolutePointerDev->StateChanged = FALSE; // // Exhaust input data // Status = EFI_SUCCESS; while (!EFI_ERROR (Status)) { Status = In8042Data (MouseAbsolutePointerDev->IsaIo, &Data); } CheckKbStatus (MouseAbsolutePointerDev->IsaIo, &KeyboardEnable); KbcDisableKb (MouseAbsolutePointerDev->IsaIo); MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data); // // if there's data block on KBC data port, read it out // if ((Data & KBC_OUTB) == KBC_OUTB) { MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Data); } Status = EFI_SUCCESS; // // The PS2 mouse driver reset behavior is always successfully return no matter wheater or not there is mouse connected to system. // This behavior is needed by performance speed. The following mouse command only succeessfully finish when mouse device is // connected to system, so if PS2 mouse device not connect to system or user not ask for, we skip the mouse configuration and enabling // if (ExtendedVerification && CheckMouseAbsolutePointerConnect (MouseAbsolutePointerDev)) { // // Send mouse reset command and set mouse default configure // Status = PS2MouseReset (MouseAbsolutePointerDev->IsaIo); if (EFI_ERROR (Status)) { Status = EFI_DEVICE_ERROR; goto Exit; } Status = PS2MouseSetSampleRate (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->SampleRate); if (EFI_ERROR (Status)) { Status = EFI_DEVICE_ERROR; goto Exit; } Status = PS2MouseSetResolution (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Resolution); if (EFI_ERROR (Status)) { Status = EFI_DEVICE_ERROR; goto Exit; } Status = PS2MouseSetScaling (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Scaling); if (EFI_ERROR (Status)) { Status = EFI_DEVICE_ERROR; goto Exit; } Status = PS2MouseEnable (MouseAbsolutePointerDev->IsaIo); if (EFI_ERROR (Status)) { Status = EFI_DEVICE_ERROR; goto Exit; } } Exit: gBS->RestoreTPL (OldTpl); if (KeyboardEnable) { KbcEnableKb (MouseAbsolutePointerDev->IsaIo); } return Status; }
/** Stop this driver on ControllerHandle. Support stoping any child handles created by this driver. @param This Protocol instance pointer. @param ControllerHandle Handle of device to stop driver on @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of children is zero stop the entire bus driver. @param ChildHandleBuffer List of Child Handles to Stop. @retval EFI_SUCCESS This driver is removed ControllerHandle @retval other This driver was not removed from this device **/ EFI_STATUS EFIAPI PS2MouseAbsolutePointerDriverStop ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer ) { EFI_STATUS Status; EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointerProtocol; PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev; UINT8 Data; Status = gBS->OpenProtocol ( Controller, &gEfiAbsolutePointerProtocolGuid, (VOID **) &AbsolutePointerProtocol, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return EFI_SUCCESS; } MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (AbsolutePointerProtocol); // // Report that the keyboard is being disabled // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE, MouseAbsolutePointerDev->DevicePath ); Status = gBS->UninstallProtocolInterface ( Controller, &gEfiAbsolutePointerProtocolGuid, &MouseAbsolutePointerDev->AbsolutePointerProtocol ); if (EFI_ERROR (Status)) { return Status; } // // Cancel mouse data polling timer, close timer event // gBS->SetTimer (MouseAbsolutePointerDev->TimerEvent, TimerCancel, 0); gBS->CloseEvent (MouseAbsolutePointerDev->TimerEvent); // // Since there will be no timer handler for mouse input any more, // exhaust input data just in case there is still mouse data left // Status = EFI_SUCCESS; while (!EFI_ERROR (Status)) { Status = In8042Data (MouseAbsolutePointerDev->IsaIo, &Data); } gBS->CloseEvent (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput); FreeUnicodeStringTable (MouseAbsolutePointerDev->ControllerNameTable); FreePool (MouseAbsolutePointerDev); gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Controller ); gBS->CloseProtocol ( Controller, &gEfiIsaIoProtocolGuid, This->DriverBindingHandle, Controller ); return EFI_SUCCESS; }
/** Start this driver on ControllerHandle by opening a IsaIo protocol, creating PS2_MOUSE_ABSOLUTE_POINTER_DEV device and install gEfiAbsolutePointerProtocolGuid finally. @param This Protocol instance pointer. @param ControllerHandle Handle of device to bind driver to @param RemainingDevicePath Optional parameter use to pick a specific child device to start. @retval EFI_SUCCESS This driver is added to ControllerHandle @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle @retval other This driver does not support this device **/ EFI_STATUS EFIAPI PS2MouseAbsolutePointerDriverStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_STATUS EmptyStatus; EFI_ISA_IO_PROTOCOL *IsaIo; PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev; UINT8 Data; EFI_TPL OldTpl; EFI_STATUS_CODE_VALUE StatusCode; EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; StatusCode = 0; MouseAbsolutePointerDev = NULL; IsaIo = NULL; // // Open the device path protocol // Status = gBS->OpenProtocol ( Controller, &gEfiDevicePathProtocolGuid, (VOID **) &ParentDevicePath, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } // // Report that the keyboard is being enabled // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE, ParentDevicePath ); // // Get the ISA I/O Protocol on Controller's handle // Status = gBS->OpenProtocol ( Controller, &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Controller ); return EFI_INVALID_PARAMETER; } // // Raise TPL to avoid keyboard operation impact // OldTpl = gBS->RaiseTPL (TPL_NOTIFY); // // Allocate private data // MouseAbsolutePointerDev = AllocateZeroPool (sizeof (PS2_MOUSE_ABSOLUTE_POINTER_DEV)); if (MouseAbsolutePointerDev == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ErrorExit; } // // Setup the device instance // MouseAbsolutePointerDev->Signature = PS2_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE; MouseAbsolutePointerDev->Handle = Controller; MouseAbsolutePointerDev->SampleRate = SampleRate20; MouseAbsolutePointerDev->Resolution = MouseResolution4; MouseAbsolutePointerDev->Scaling = Scaling1; MouseAbsolutePointerDev->DataPackageSize = 3; MouseAbsolutePointerDev->IsaIo = IsaIo; MouseAbsolutePointerDev->DevicePath = ParentDevicePath; // // Resolution = 4 counts/mm // MouseAbsolutePointerDev->Mode.AbsoluteMaxX = 1024; MouseAbsolutePointerDev->Mode.AbsoluteMinX = 0; MouseAbsolutePointerDev->Mode.AbsoluteMaxY = 798; MouseAbsolutePointerDev->Mode.AbsoluteMinY = 0; MouseAbsolutePointerDev->Mode.AbsoluteMaxZ = 0; MouseAbsolutePointerDev->Mode.AbsoluteMinZ = 0; MouseAbsolutePointerDev->Mode.Attributes = 0x03; MouseAbsolutePointerDev->AbsolutePointerProtocol.Reset = MouseAbsolutePointerReset; MouseAbsolutePointerDev->AbsolutePointerProtocol.GetState = MouseAbsolutePointerGetState; MouseAbsolutePointerDev->AbsolutePointerProtocol.Mode = &(MouseAbsolutePointerDev->Mode); // // Initialize keyboard controller if necessary // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_MOUSE | EFI_P_MOUSE_PC_SELF_TEST, ParentDevicePath ); IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data); if ((Data & KBC_SYSF) != KBC_SYSF) { Status = KbcSelfTest (IsaIo); if (EFI_ERROR (Status)) { StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR; goto ErrorExit; } } KbcEnableAux (IsaIo); REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT, ParentDevicePath ); // // Reset the mouse // Status = MouseAbsolutePointerDev->AbsolutePointerProtocol.Reset ( &MouseAbsolutePointerDev->AbsolutePointerProtocol, FeaturePcdGet (PcdPs2MouseExtendedVerification) ); if (EFI_ERROR (Status)) { // // mouse not connected // Status = EFI_SUCCESS; StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED; goto ErrorExit; } REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED, ParentDevicePath ); // // Setup the WaitForKey event // Status = gBS->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY, MouseAbsolutePointerWaitForInput, MouseAbsolutePointerDev, &((MouseAbsolutePointerDev->AbsolutePointerProtocol).WaitForInput) ); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; goto ErrorExit; } // // Setup a periodic timer, used to poll mouse state // Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY, PollMouseAbsolutePointer, MouseAbsolutePointerDev, &MouseAbsolutePointerDev->TimerEvent ); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; goto ErrorExit; } // // Start timer to poll mouse (100 samples per second) // Status = gBS->SetTimer (MouseAbsolutePointerDev->TimerEvent, TimerPeriodic, 100000); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; goto ErrorExit; } MouseAbsolutePointerDev->ControllerNameTable = NULL; AddUnicodeString2 ( "eng", gPs2MouseAbsolutePointerComponentName.SupportedLanguages, &MouseAbsolutePointerDev->ControllerNameTable, L"Faked PS/2 Touchpad Device", TRUE ); AddUnicodeString2 ( "en", gPs2MouseAbsolutePointerComponentName2.SupportedLanguages, &MouseAbsolutePointerDev->ControllerNameTable, L"Faked PS/2 Touchpad Device", FALSE ); // // Install protocol interfaces for the mouse device. // Status = gBS->InstallMultipleProtocolInterfaces ( &Controller, &gEfiAbsolutePointerProtocolGuid, &MouseAbsolutePointerDev->AbsolutePointerProtocol, NULL ); if (EFI_ERROR (Status)) { goto ErrorExit; } gBS->RestoreTPL (OldTpl); return Status; ErrorExit: KbcDisableAux (IsaIo); if (StatusCode != 0) { REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_ERROR_CODE | EFI_ERROR_MINOR, StatusCode, ParentDevicePath ); } if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput != NULL)) { gBS->CloseEvent (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput); } if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->TimerEvent != NULL)) { gBS->CloseEvent (MouseAbsolutePointerDev->TimerEvent); } if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->ControllerNameTable != NULL)) { FreeUnicodeStringTable (MouseAbsolutePointerDev->ControllerNameTable); } // // Since there will be no timer handler for mouse input any more, // exhaust input data just in case there is still mouse data left // EmptyStatus = EFI_SUCCESS; while (!EFI_ERROR (EmptyStatus)) { EmptyStatus = In8042Data (IsaIo, &Data); } if (MouseAbsolutePointerDev != NULL) { FreePool (MouseAbsolutePointerDev); } gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Controller ); gBS->CloseProtocol ( Controller, &gEfiIsaIoProtocolGuid, This->DriverBindingHandle, Controller ); gBS->RestoreTPL (OldTpl); return Status; }
/** Start this driver on ControllerHandle by opening a Sio protocol, creating PS2_MOUSE_DEV device and install gEfiSimplePointerProtocolGuid finally. @param This Protocol instance pointer. @param ControllerHandle Handle of device to bind driver to @param RemainingDevicePath Optional parameter use to pick a specific child device to start. @retval EFI_SUCCESS This driver is added to ControllerHandle @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle @retval other This driver does not support this device **/ EFI_STATUS EFIAPI PS2MouseDriverStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_STATUS EmptyStatus; EFI_SIO_PROTOCOL *Sio; PS2_MOUSE_DEV *MouseDev; UINT8 Data; EFI_TPL OldTpl; EFI_STATUS_CODE_VALUE StatusCode; EFI_DEVICE_PATH_PROTOCOL *DevicePath; StatusCode = 0; // // Open the device path protocol // Status = gBS->OpenProtocol ( Controller, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return Status; } // // Report that the keyboard is being enabled // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE, DevicePath ); // // Get the ISA I/O Protocol on Controller's handle // Status = gBS->OpenProtocol ( Controller, &gEfiSioProtocolGuid, (VOID **) &Sio, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } // // Raise TPL to avoid keyboard operation impact // OldTpl = gBS->RaiseTPL (TPL_NOTIFY); // // Allocate private data // MouseDev = AllocateZeroPool (sizeof (PS2_MOUSE_DEV)); if (MouseDev == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ErrorExit; } // // Setup the device instance // MouseDev->Signature = PS2_MOUSE_DEV_SIGNATURE; MouseDev->Handle = Controller; MouseDev->SampleRate = SampleRate20; MouseDev->Resolution = MouseResolution4; MouseDev->Scaling = Scaling1; MouseDev->DataPackageSize = 3; MouseDev->DevicePath = DevicePath; // // Resolution = 4 counts/mm // MouseDev->Mode.ResolutionX = 4; MouseDev->Mode.ResolutionY = 4; MouseDev->Mode.LeftButton = TRUE; MouseDev->Mode.RightButton = TRUE; MouseDev->SimplePointerProtocol.Reset = MouseReset; MouseDev->SimplePointerProtocol.GetState = MouseGetState; MouseDev->SimplePointerProtocol.Mode = &(MouseDev->Mode); // // Initialize keyboard controller if necessary // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_MOUSE | EFI_P_MOUSE_PC_SELF_TEST, DevicePath ); Data = IoRead8 (KBC_CMD_STS_PORT); // // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS. // if ((Data & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) { // // If nobody decodes KBC I/O port, it will read back as 0xFF. // Check the Time-Out and Parity bit to see if it has an active KBC in system // Status = EFI_DEVICE_ERROR; StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED; goto ErrorExit; } if ((Data & KBC_SYSF) != KBC_SYSF) { Status = KbcSelfTest (); if (EFI_ERROR (Status)) { StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR; goto ErrorExit; } } KbcEnableAux (); REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT, DevicePath ); // // Reset the mouse // Status = MouseDev->SimplePointerProtocol.Reset ( &MouseDev->SimplePointerProtocol, FeaturePcdGet (PcdPs2MouseExtendedVerification) ); if (EFI_ERROR (Status)) { // // mouse not connected // Status = EFI_SUCCESS; StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED; goto ErrorExit; } REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED, DevicePath ); // // Setup the WaitForKey event // Status = gBS->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY, MouseWaitForInput, MouseDev, &((MouseDev->SimplePointerProtocol).WaitForInput) ); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; goto ErrorExit; } // // Setup a periodic timer, used to poll mouse state // Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY, PollMouse, MouseDev, &MouseDev->TimerEvent ); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; goto ErrorExit; } // // Start timer to poll mouse (100 samples per second) // Status = gBS->SetTimer (MouseDev->TimerEvent, TimerPeriodic, 100000); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; goto ErrorExit; } MouseDev->ControllerNameTable = NULL; AddUnicodeString2 ( "eng", gPs2MouseComponentName.SupportedLanguages, &MouseDev->ControllerNameTable, L"PS/2 Mouse Device", TRUE ); AddUnicodeString2 ( "en", gPs2MouseComponentName2.SupportedLanguages, &MouseDev->ControllerNameTable, L"PS/2 Mouse Device", FALSE ); // // Install protocol interfaces for the mouse device. // Status = gBS->InstallMultipleProtocolInterfaces ( &Controller, &gEfiSimplePointerProtocolGuid, &MouseDev->SimplePointerProtocol, NULL ); if (EFI_ERROR (Status)) { goto ErrorExit; } gBS->RestoreTPL (OldTpl); return Status; ErrorExit: if (Status != EFI_DEVICE_ERROR) { KbcDisableAux (); } if (StatusCode != 0) { REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_ERROR_CODE | EFI_ERROR_MINOR, StatusCode, DevicePath ); } if ((MouseDev != NULL) && (MouseDev->SimplePointerProtocol.WaitForInput != NULL)) { gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput); } if ((MouseDev != NULL) && (MouseDev->TimerEvent != NULL)) { gBS->CloseEvent (MouseDev->TimerEvent); } if ((MouseDev != NULL) && (MouseDev->ControllerNameTable != NULL)) { FreeUnicodeStringTable (MouseDev->ControllerNameTable); } if (Status != EFI_DEVICE_ERROR) { // // Since there will be no timer handler for mouse input any more, // exhaust input data just in case there is still mouse data left // EmptyStatus = EFI_SUCCESS; while (!EFI_ERROR (EmptyStatus)) { EmptyStatus = In8042Data (&Data); } } if (MouseDev != NULL) { FreePool (MouseDev); } gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Controller ); gBS->CloseProtocol ( Controller, &gEfiSioProtocolGuid, This->DriverBindingHandle, Controller ); gBS->RestoreTPL (OldTpl); return Status; }