A USB 3 device uses an exponential encoding of the max packet size for the default end point.
Signed-off-by: Kevin O'Connor kevin@koconnor.net ---
With this patch, my superspeed flash drive is now detected on my Haswell based xhci controller. (Interestingly, the same flash drive worked on my other computer without this patch, even though the max packet length is definitely not correct without this patch.)
This is also at:
https://github.com/KevinOConnor/seabios/tree/xhci-testing
--- src/hw/usb.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/hw/usb.c b/src/hw/usb.c index 8ffddf8..ff20b6c 100644 --- a/src/hw/usb.c +++ b/src/hw/usb.c @@ -319,13 +319,16 @@ configure_usb_device(struct usbdevice_s *usbdev) int ret = get_device_info8(usbdev->defpipe, &dinfo); if (ret) return 0; - dprintf(3, "device rev=%04x cls=%02x sub=%02x proto=%02x size=%02x\n" + u16 maxpacket = dinfo.bMaxPacketSize0; + if (dinfo.bcdUSB >= 0x0300) + maxpacket = 1 << dinfo.bMaxPacketSize0; + dprintf(3, "device rev=%04x cls=%02x sub=%02x proto=%02x size=%d\n" , dinfo.bcdUSB, dinfo.bDeviceClass, dinfo.bDeviceSubClass - , dinfo.bDeviceProtocol, dinfo.bMaxPacketSize0); - if (dinfo.bMaxPacketSize0 < 8 || dinfo.bMaxPacketSize0 > 64) + , dinfo.bDeviceProtocol, maxpacket); + if (maxpacket < 8) return 0; struct usb_endpoint_descriptor epdesc = { - .wMaxPacketSize = dinfo.bMaxPacketSize0, + .wMaxPacketSize = maxpacket, .bmAttributes = USB_ENDPOINT_XFER_CONTROL, }; usbdev->defpipe = usb_update_pipe(usbdev, usbdev->defpipe, &epdesc);