MdeModulePkg/Usb/Keyboard: add SetIdle quirk handler

Some USB keyboards, like the Aspeed BMC HID keyboard,
require the SetIdle command to be issued before interrupt
transfers can be enabled. Add a quirk handler so any similar
devices can make use of same function by the addition of the
USB vendor/device IDs.

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
This commit is contained in:
Matt DeVillier
2019-12-17 22:57:51 -06:00
parent f1d5f1091d
commit b98c44e412
2 changed files with 60 additions and 1 deletions

View File

@@ -793,6 +793,29 @@ InitKeyboardLayout (
}
/**
Determine if SetIdle request is needed
@param DevDesc The EFI_USB_DEVICE_DESCRIPTOR instance.
@retval TRUE The USB device requires SetIdle to be called.
@retval FALSE The USB device does not require SetIdle to be called.
**/
BOOLEAN
UsbQuirkRequireSetIdle (
IN EFI_USB_DEVICE_DESCRIPTOR DevDesc
)
{
switch (DevDesc.IdVendor) {
case 0x0557:
return DevDesc.IdProduct == 0x2419;
default:
return FALSE;
}
}
/**
Initialize USB keyboard device and all private data structures.
@@ -807,7 +830,8 @@ InitUSBKeyboard (
IN OUT USB_KB_DEV *UsbKeyboardDevice
)
{
EFI_STATUS Status;
EFI_STATUS Status;
EFI_USB_DEVICE_DESCRIPTOR DevDesc;
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
EFI_PROGRESS_CODE,
@@ -819,6 +843,17 @@ InitUSBKeyboard (
InitQueue (&UsbKeyboardDevice->EfiKeyQueue, sizeof (EFI_KEY_DATA));
InitQueue (&UsbKeyboardDevice->EfiKeyQueueForNotify, sizeof (EFI_KEY_DATA));
//
// Get device descriptor so vendor/device IDs available
// for quirk handling
//
Status = UsbKeyboardDevice->UsbIo->UsbGetDeviceDescriptor (
UsbKeyboardDevice->UsbIo,
&DevDesc);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
//
// Set boot protocol for the USB Keyboard.
// This driver only supports boot protocol.
@@ -865,6 +900,16 @@ InitUSBKeyboard (
UsbKeyboardDevice->CurrentNsKey = NULL;
//
// Some keyboards don't send interrupt transfers until SetIdle is called
//
if (UsbQuirkRequireSetIdle(DevDesc)) {
UsbSetIdleRequest(UsbKeyboardDevice->UsbIo,
UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
0,
0);
}
//
// Sync the initial state of lights on keyboard.
//