[SeaBIOS] [PATCH] usb: Update USB hub code to support super speed hubs

Paul Menzel paulepanter at users.sourceforge.net
Tue Dec 16 23:06:29 CET 2014


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 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)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: This is a digitally signed message part
URL: <http://www.seabios.org/pipermail/seabios/attachments/20141216/78415ce8/attachment.asc>


More information about the SeaBIOS mailing list