From: Kevin O'Connor Date: Fri, 12 Dec 2014 19:16:43 +0000 (-0500) Subject: usb: Update USB hub code to support super speed hubs X-Git-Tag: rel-1.8.0~36 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=73fe49aef4a4328bf0edd4302f5f6dd99e61ba49;p=people%2Fandrewcoop%2Fseabios.git usb: Update USB hub code to support super speed hubs Super speed hubs (usb3 spec) have specific initialization requirements. Add the code necessary to detect and initialize these hubs. Signed-off-by: Kevin O'Connor --- 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,12 +17,27 @@ 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); } +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) { @@ -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 USB_SUPERSPEED; return ((sts.wPortStatus & USB_PORT_STAT_SPEED_MASK) >> USB_PORT_STAT_SPEED_SHIFT); @@ -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