Dear Kevin,
thank you for the patch! I am adding Werner to CC.
Am Montag, den 15.12.2014, 21:47 -0500 schrieb Kevin O'Connor:
Super speed hubs (usb3 spec) have specific initialization requirements. Add the code necessary to detect and initialize these hubs.
Could you please add how you tested this? For example the board, the hub and what you booted from it for example.
Thanks,
Paul
Signed-off-by: Kevin O'Connor kevin@koconnor.net
src/hw/usb-hub.c | 36 ++++++++++++++++++++++++++++++++++-- src/hw/usb-hub.h | 6 +++++- 2 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/src/hw/usb-hub.c b/src/hw/usb-hub.c index c21cbfb..54e341b 100644 --- a/src/hw/usb-hub.c +++ b/src/hw/usb-hub.c @@ -17,13 +17,28 @@ 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.wIndex = 0; req.wLength = sizeof(*desc); return usb_send_default_control(pipe, &req, desc);req.wValue = USB_DT_HUB<<8;
}
static int +set_hub_depth(struct usb_pipe *pipe, u16 depth) +{
- struct usb_ctrlrequest req;
- req.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE;
- req.bRequest = HUB_REQ_SET_HUB_DEPTH;
- req.wValue = depth;
- req.wIndex = 0;
- req.wLength = 0;
- return usb_send_default_control(pipe, &req, NULL);
+}
+static int set_port_feature(struct usbhub_s *hub, int port, int feature) { struct usb_ctrlrequest req; @@ -105,7 +120,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 +136,8 @@ usb_hub_reset(struct usbhub_s *hub, u32 port) // Device no longer present return -1;
- if (hub->usbdev->speed == USB_SUPERSPEED)
return ((sts.wPortStatus & USB_PORT_STAT_SPEED_MASK) >> USB_PORT_STAT_SPEED_SHIFT);return USB_SUPERSPEED;
@@ -154,6 +173,19 @@ usb_hub_setup(struct usbdevice_s *usbdev) hub.portcount = desc.bNbrPorts; hub.op = &HubOp;
- if (usbdev->speed == USB_SUPERSPEED) {
int depth = 0;
struct usbdevice_s *parent = usbdev->hub->usbdev;
while (parent) {
depth++;
parent = parent->hub->usbdev;
}
ret = set_hub_depth(usbdev->defpipe, depth);
if (ret)
return ret;
- }
- // Turn on power to ports. int port; for (port=0; port<desc.bNbrPorts; port++) {
diff --git a/src/hw/usb-hub.h b/src/hw/usb-hub.h index 5b09947..880378c 100644 --- a/src/hw/usb-hub.h +++ b/src/hw/usb-hub.h @@ -11,6 +11,9 @@ int usb_hub_setup(struct usbdevice_s *usbdev); ****************************************************************/
#define USB_DT_HUB (USB_TYPE_CLASS | 0x09) +#define USB_DT_HUB3 (USB_TYPE_CLASS | 0x0a)
+#define HUB_REQ_SET_HUB_DEPTH 0x0C
struct usb_hub_descriptor { u8 bDescLength; @@ -48,7 +51,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)