/** Reset the input device and optionally run diagnostics There are 2 types of reset for USB keyboard. For non-exhaustive reset, only keyboard buffer is cleared. For exhaustive reset, in addition to clearance of keyboard buffer, the hardware status is also re-initialized. @param This Protocol instance pointer. @param ExtendedVerification Driver may perform diagnostics on reset. @retval EFI_SUCCESS The device was reset. @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset. **/ EFI_STATUS EFIAPI USBKeyboardReset ( IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification ) { EFI_STATUS Status; USB_KB_DEV *UsbKeyboardDevice; UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This); REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET), UsbKeyboardDevice->DevicePath ); // // Non-exhaustive reset: // only reset private data structures. // if (!ExtendedVerification) { REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER), UsbKeyboardDevice->DevicePath ); // // Clear the key buffer of this USB keyboard // InitQueue (&UsbKeyboardDevice->UsbKeyQueue, sizeof (USB_KEY)); InitQueue (&UsbKeyboardDevice->EfiKeyQueue, sizeof (EFI_KEY_DATA)); InitQueue (&UsbKeyboardDevice->EfiKeyQueueForNotify, sizeof (EFI_KEY_DATA)); return EFI_SUCCESS; } // // Exhaustive reset // Status = InitUSBKeyboard (UsbKeyboardDevice); if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } return EFI_SUCCESS; }
/** Reads the next keystroke from the input device. @param This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance. @param Key A pointer to a buffer that is filled in with the keystroke information for the key that was pressed. @retval EFI_SUCCESS The keystroke information was returned. @retval EFI_NOT_READY There was no keystroke data availiable. @retval EFI_DEVICE_ERROR The keystroke information was not returned due to hardware errors. **/ EFI_STATUS EFIAPI USBKeyboardReadKeyStroke ( IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, OUT EFI_INPUT_KEY *Key ) { USB_KB_DEV *UsbKeyboardDevice; EFI_STATUS Status; EFI_KEY_DATA KeyData; UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This); // // Considering if the partial keystroke is enabled, there maybe a partial // keystroke in the queue, so here skip the partial keystroke and get the // next key from the queue // while (1) { Status = USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice, &KeyData); if (EFI_ERROR (Status)) { return Status; } // // SimpleTextIn Protocol doesn't support partial keystroke; // if (KeyData.Key.ScanCode == CHAR_NULL && KeyData.Key.UnicodeChar == SCAN_NULL) { continue; } // // Translate the CTRL-Alpha characters to their corresponding control value // (ctrl-a = 0x0001 through ctrl-Z = 0x001A) // if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) { if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') { KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'a' + 1); } else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') { KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'A' + 1); } } CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY)); return EFI_SUCCESS; } }
/** Stop the USB keyboard device handled by this driver. @param This The USB keyboard driver binding protocol. @param Controller The controller to release. @param NumberOfChildren The number of handles in ChildHandleBuffer. @param ChildHandleBuffer The array of child handle. @retval EFI_SUCCESS The device was stopped. @retval EFI_UNSUPPORTED Simple Text In Protocol or Simple Text In Ex Protocol is not installed on Controller. @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. @retval Others Fail to uninstall protocols attached on the device. **/ EFI_STATUS EFIAPI USBKeyboardDriverBindingStop ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer ) { EFI_STATUS Status; EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleInput; USB_KB_DEV *UsbKeyboardDevice; Status = gBS->OpenProtocol ( Controller, &gEfiSimpleTextInProtocolGuid, (VOID **) &SimpleInput, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } Status = gBS->OpenProtocol ( Controller, &gEfiSimpleTextInputExProtocolGuid, NULL, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (SimpleInput); // // The key data input from this device will be disabled. // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE), UsbKeyboardDevice->DevicePath ); // // Delete the Asynchronous Interrupt Transfer from this device // UsbKeyboardDevice->UsbIo->UsbAsyncInterruptTransfer ( UsbKeyboardDevice->UsbIo, UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress, FALSE, UsbKeyboardDevice->IntEndpointDescriptor.Interval, 0, NULL, NULL ); gBS->CloseProtocol ( Controller, &gEfiUsbIoProtocolGuid, This->DriverBindingHandle, Controller ); Status = gBS->UninstallMultipleProtocolInterfaces ( Controller, &gEfiSimpleTextInProtocolGuid, &UsbKeyboardDevice->SimpleInput, &gEfiSimpleTextInputExProtocolGuid, &UsbKeyboardDevice->SimpleInputEx, NULL ); // // Free all resources. // gBS->CloseEvent (UsbKeyboardDevice->TimerEvent); gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer); gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent); gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey); gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx); KbdFreeNotifyList (&UsbKeyboardDevice->NotifyList); ReleaseKeyboardLayoutResources (UsbKeyboardDevice); gBS->CloseEvent (UsbKeyboardDevice->KeyboardLayoutEvent); if (UsbKeyboardDevice->ControllerNameTable != NULL) { FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable); } DestroyQueue (&UsbKeyboardDevice->UsbKeyQueue); DestroyQueue (&UsbKeyboardDevice->EfiKeyQueue); FreePool (UsbKeyboardDevice); return Status; }
EFI_STATUS EFIAPI UsbKeyboardComponentNameGetControllerName ( #if (EFI_SPECIFICATION_VERSION >= 0x00020000) IN EFI_COMPONENT_NAME2_PROTOCOL *This, #else IN EFI_COMPONENT_NAME_PROTOCOL *This, #endif IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT CHAR16 **ControllerName ) /*++ Routine Description: Retrieves a Unicode string that is the user readable name of the controller that is being managed by an EFI Driver. Arguments: This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. ControllerHandle - The handle of a controller that the driver specified by This is managing. This handle specifies the controller whose name is to be returned. ChildHandle - The handle of the child controller to retrieve the name of. This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for a bus drivers that wish to retrieve the name of the bus controller. It will not be NULL for a bus driver that wishes to retrieve the name of a child controller. Language - A pointer to a three character ISO 639-2 language identifier. This is the language of the controller name that that the caller is requesting, and it must match one of the languages specified in SupportedLanguages. The number of languages supported by a driver is up to the driver writer. ControllerName - A pointer to the Unicode string to return. This Unicode string is the name of the controller specified by ControllerHandle and ChildHandle in the language specified by Language from the point of view of the driver specified by This. Returns: EFI_SUCCESS - The Unicode string for the user readable name in the language specified by Language for the driver specified by This was returned in DriverName. EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE. EFI_INVALID_PARAMETER - Language is NULL. EFI_INVALID_PARAMETER - ControllerName is NULL. EFI_UNSUPPORTED - The driver specified by This is not currently managing the controller specified by ControllerHandle and ChildHandle. EFI_UNSUPPORTED - The driver specified by This does not support the language specified by Language. --*/ { EFI_STATUS Status; USB_KB_DEV *UsbKbDev; EFI_SIMPLE_TEXT_IN_PROTOCOL *SimpleTxtIn; EFI_USB_IO_PROTOCOL *UsbIoProtocol; // // This is a device driver, so ChildHandle must be NULL. // if (ChildHandle != NULL) { return EFI_UNSUPPORTED; } // // Check Controller's handle // Status = gBS->OpenProtocol ( ControllerHandle, &gEfiUsbIoProtocolGuid, (VOID **) &UsbIoProtocol, gUsbKeyboardDriverBinding.DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (!EFI_ERROR (Status)) { gBS->CloseProtocol ( ControllerHandle, &gEfiUsbIoProtocolGuid, gUsbKeyboardDriverBinding.DriverBindingHandle, ControllerHandle ); return EFI_UNSUPPORTED; } if (Status != EFI_ALREADY_STARTED) { return EFI_UNSUPPORTED; } // // Get the device context // Status = gBS->OpenProtocol ( ControllerHandle, &gEfiSimpleTextInProtocolGuid, (VOID **) &SimpleTxtIn, gUsbKeyboardDriverBinding.DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return Status; } UsbKbDev = USB_KB_DEV_FROM_THIS (SimpleTxtIn); return EfiLibLookupUnicodeString ( Language, gUsbKeyboardComponentName.SupportedLanguages, UsbKbDev->ControllerNameTable, ControllerName ); }