From 472be4d139b26c50949cf30eeb47640810e5ef2c Mon Sep 17 00:00:00 2001 From: John Schock Date: Fri, 26 May 2023 16:50:41 -0700 Subject: 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 --- .../Universal/Console/ConPlatformDxe/ConPlatform.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'MdeModulePkg') diff --git a/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c b/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c index 700ea9d5c0..a7f0225f30 100644 --- a/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c +++ b/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c @@ -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)) { -- cgit