MdeModulePkg ConPlatform: Support IAD-style USB input devices.
Some multi-function input devices (e.g. combo keyboard and mouse) present as IAD-style devices (https://www.usb.org/defined-class-codes, https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-interface-association-descriptor). Historically, multi-function devices would report a DeviceClass of 0, indicating that interface matching should be done on the interface descriptor rather than the global device descriptor. IAD-style devices us DeviceClass of 0xEF, so they don't match MatchUsbClass() for keyboard (DeviceClass=3, SubClass=1, Proto=1). If they are treated as if they had a DeviceClass of zero, which is more traditional for legacy multi-function devices, then the interface descriptors are used instead and these types of devices will "just work" without needing to add a custom USB device path to ConIn. Signed-off-by: Aaron Pop <aaronpop@microsoft.com>
This commit is contained in:
parent
1b37b3659b
commit
472be4d139
|
@ -27,6 +27,15 @@ EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextOutDriverBinding = {
|
|||
NULL
|
||||
};
|
||||
|
||||
//
|
||||
// Values from Usb Inteface Association Descriptor Device
|
||||
// Class Code and Usage Model specification (iadclasscode_r10.pdf)
|
||||
// from Usb.org
|
||||
//
|
||||
#define USB_BASE_CLASS_MISCELLANEOUS 0xEF
|
||||
#define USB_MISCELLANEOUS_SUBCLASS_COMMON 0x02
|
||||
#define USB_MISCELLANEOUS_PROTOCOL_IAD 0x01
|
||||
|
||||
/**
|
||||
Entrypoint of this module.
|
||||
|
||||
|
@ -808,10 +817,16 @@ MatchUsbClass (
|
|||
DeviceClass = DevDesc.DeviceClass;
|
||||
DeviceSubClass = DevDesc.DeviceSubClass;
|
||||
DeviceProtocol = DevDesc.DeviceProtocol;
|
||||
if (DeviceClass == 0) {
|
||||
|
||||
if ((DeviceClass == 0) ||
|
||||
((DeviceClass == USB_BASE_CLASS_MISCELLANEOUS) &&
|
||||
(DeviceSubClass == USB_MISCELLANEOUS_SUBCLASS_COMMON) &&
|
||||
(DeviceProtocol == USB_MISCELLANEOUS_PROTOCOL_IAD)))
|
||||
{
|
||||
//
|
||||
// If Class in Device Descriptor is set to 0, use the Class, SubClass and
|
||||
// Protocol in Interface Descriptor instead.
|
||||
// If Class in Device Descriptor is set to 0 (Device), or
|
||||
// Class/SubClass/Protocol is 0xEF/0x02/0x01 (IAD), use the Class, SubClass
|
||||
// and Protocol in Interface Descriptor instead.
|
||||
//
|
||||
Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
|
Loading…
Reference in New Issue