On Wed, Dec 10, 2014 at 07:21:54AM +0100, Werner Zeh wrote:
Hi all.
I have made some tests with SeaBIOS and XHCI and found, that on my board (which is baytrail-based) a USB3.0 hub won't work. For those who are familar with SeaBIOS I have attached two logfiles from SeaBIOS. One of them is with the USB3.0 flash drive directly connected to one of the root ports of SoC (in which case the boot process starts from the flash drive) and the other is with the same flash drive but a USB3.0 hub in between (I have used a hub from Delock #62534, http://www.delock.de/produkte/F_247_extern_62534/merkmale.html). In the hub-case, I see the "No bootable device" screen and no boot will happen.
Maybe someone more experienced can see the cause from the logs.
?SeaBIOS (version rel-1.7.5-116-g56b252e-dirty-20141210_064921-deerlf0x73)
[...]
|1ad7d000| xhci_process_events: ring 0x1adcb200 [trb 0x1adcb200, evt 0x1adcb300, type 32, eidx 1, cc 1] |1ad7d000| device rev=0300 cls=09 sub=00 proto=03 size=512 |1ad7d000| xhci_realloc_pipe: usbdev 0x1ad82bc0, ring 0x1adba600, slotid 4, epid 1
[...]
|1ad7f000| xhci_process_events: ring 0x1adba600 [trb 0x1adba6c0, evt 0x1adba700, type 32, eidx 13, cc 6]
It looks like the hub is found, but responds with a "stall" error on the get_hub_desc() request. Looks like usb3 hubs use a different descriptor id. You could try the patch below - it's a lot of guess work though.
-Kevin
diff --git a/src/hw/usb-hub.c b/src/hw/usb-hub.c index c21cbfb..7688ef2 100644 --- a/src/hw/usb-hub.c +++ b/src/hw/usb-hub.c @@ -17,7 +17,10 @@ get_hub_desc(struct usb_pipe *pipe, struct usb_hub_descriptor *desc) struct usb_ctrlrequest req; req.bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE; req.bRequest = USB_REQ_GET_DESCRIPTOR; - req.wValue = USB_DT_HUB<<8; + if (pipe->speed == USB_SUPERSPEED) + req.wValue = USB_DT_HUB3<<8; + else + req.wValue = USB_DT_HUB<<8; req.wIndex = 0; req.wLength = sizeof(*desc); return usb_send_default_control(pipe, &req, desc); @@ -105,7 +108,9 @@ usb_hub_reset(struct usbhub_s *hub, u32 port) ret = get_port_status(hub, port, &sts); if (ret) goto fail; - if (!(sts.wPortStatus & USB_PORT_STAT_RESET)) + if (!(sts.wPortStatus & USB_PORT_STAT_RESET) + && (hub->usbdev->speed != USB_SUPERSPEED + || !(sts.wPortStatus & USB_PORT_STAT_LINK_MASK))) break; if (timer_check(end)) { warn_timeout(); @@ -119,6 +124,8 @@ usb_hub_reset(struct usbhub_s *hub, u32 port) // Device no longer present return -1;
+ if (hub->usbdev->speed == USB_SUPERSPEED) + return USB_SUPERSPEED; return ((sts.wPortStatus & USB_PORT_STAT_SPEED_MASK) >> USB_PORT_STAT_SPEED_SHIFT);
diff --git a/src/hw/usb-hub.h b/src/hw/usb-hub.h index 5b09947..f7436a5 100644 --- a/src/hw/usb-hub.h +++ b/src/hw/usb-hub.h @@ -11,6 +11,7 @@ int usb_hub_setup(struct usbdevice_s *usbdev); ****************************************************************/
#define USB_DT_HUB (USB_TYPE_CLASS | 0x09) +#define USB_DT_HUB3 (USB_TYPE_CLASS | 0x0a)
struct usb_hub_descriptor { u8 bDescLength; @@ -48,7 +49,8 @@ struct usb_port_status { #define USB_PORT_STAT_SUSPEND 0x0004 #define USB_PORT_STAT_OVERCURRENT 0x0008 #define USB_PORT_STAT_RESET 0x0010 -#define USB_PORT_STAT_L1 0x0020 +#define USB_PORT_STAT_LINK_SHIFT 5 +#define USB_PORT_STAT_LINK_MASK (0x7 << USB_PORT_STAT_LINK_SHIFT) #define USB_PORT_STAT_POWER 0x0100 #define USB_PORT_STAT_SPEED_SHIFT 9 #define USB_PORT_STAT_SPEED_MASK (0x3 << USB_PORT_STAT_SPEED_SHIFT)