[coreboot] SeaBIOS wit USB3.0 hub and USB3.0 devide behind the hub

Kevin O'Connor kevin at koconnor.net
Mon Dec 15 16:48:10 CET 2014


On Mon, Dec 15, 2014 at 09:06:51AM +0100, Werner Zeh wrote:
> Hi Kevin.
> 
> I have tried your fix but it doesn't help.
> You can find a (huge) log with loglevel 5 here: http://pastebin.com/21rrAhfA
> 

Thanks.  I obtained a USB3 hub and it works for me on both my c720 and
e350m1 with the updated patch below.

Please CC the seabios mailing list on replies.

-Kevin


>From 9b244e4a887adba2281d46c0fb366823111ba4bc Mon Sep 17 00:00:00 2001
From: Kevin O'Connor <kevin at koconnor.net>
Date: Fri, 12 Dec 2014 14:16:43 -0500
Subject: [PATCH] usb: Testing of USB3 hub support

Signed-off-by: Kevin O'Connor <kevin at 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.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)
 {
     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 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<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)
-- 
1.9.3




More information about the coreboot mailing list