Message ID | 20241113235433.20244-1-quic_eserrao@quicinc.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v2] Revert "usb: gadget: composite: fix OS descriptors w_value logic" | expand |
>>>>> "Elson" == Elson Roy Serrao <quic_eserrao@quicinc.com> writes: > From: Michal Vrastil <michal.vrastil@hidglobal.com> > This reverts commit ec6ce7075ef879b91a8710829016005dc8170f17. > Fix installation of WinUSB driver using OS descriptors. Without the > fix the drivers are not installed correctly and the property > 'DeviceInterfaceGUID' is missing on host side. > The original change was based on the assumption that the interface > number is in the high byte of wValue but it is in the low byte, > instead. Unfortunately, the fix is based on MS documentation which is > also wrong. > The actual USB request for OS descriptors (using USB analyzer) looks > like: > Offset 0 1 2 3 4 5 6 7 > 0x000 C1 A1 02 00 05 00 0A 00 > C1: bmRequestType (device to host, vendor, interface) > A1: nas magic number > 0002: wValue (2: nas interface) > 0005: wIndex (5: get extended property i.e. nas interface GUID) > 008E: wLength (142) > The fix was tested on Windows 10 and Windows 11. > Cc: stable@vger.kernel.org > Fixes: ec6ce7075ef8 ("usb: gadget: composite: fix OS descriptors w_value logic") > Signed-off-by: Michal Vrastil <michal.vrastil@hidglobal.com> > Signed-off-by: Elson Roy Serrao <quic_eserrao@quicinc.com> Acked-by: Peter korsgaard <peter@korsgaard.com>
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 0e151b54aae8..9225c21d1184 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2111,8 +2111,20 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) memset(buf, 0, w_length); buf[5] = 0x01; switch (ctrl->bRequestType & USB_RECIP_MASK) { + /* + * The Microsoft CompatID OS Descriptor Spec(w_index = 0x4) and + * Extended Prop OS Desc Spec(w_index = 0x5) state that the + * HighByte of wValue is the InterfaceNumber and the LowByte is + * the PageNumber. This high/low byte ordering is incorrectly + * documented in the Spec. USB analyzer output on the below + * request packets show the high/low byte inverted i.e LowByte + * is the InterfaceNumber and the HighByte is the PageNumber. + * Since we dont support >64KB CompatID/ExtendedProp descriptors, + * PageNumber is set to 0. Hence verify that the HighByte is 0 + * for below two cases. + */ case USB_RECIP_DEVICE: - if (w_index != 0x4 || (w_value & 0xff)) + if (w_index != 0x4 || (w_value >> 8)) break; buf[6] = w_index; /* Number of ext compat interfaces */ @@ -2128,9 +2140,9 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) } break; case USB_RECIP_INTERFACE: - if (w_index != 0x5 || (w_value & 0xff)) + if (w_index != 0x5 || (w_value >> 8)) break; - interface = w_value >> 8; + interface = w_value & 0xFF; if (interface >= MAX_CONFIG_INTERFACES || !os_desc_cfg->interface[interface]) break;