Re: [RFC 01/15] USB 3.0 Hub Changes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2010/11/30 Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>:
> From: John Youn <John.Youn@xxxxxxxxxxxx>
>
> Update the USB core to deal with USB 3.0 hubs.  These hubs have a slightly
> different hub descriptor than USB 2.0 hubs, with a fixed (rather than
> variable length) size.  Change the USB core's hub descriptor to have a
> union for the last fields that differ.  Change the host controller drivers
> that access those last fields (DeviceRemovable and PortPowerCtrlMask) to
> use the union.
>
> Translate the new version of the hub port status field into the old
> version that khubd understands.  (Note: we need to fix it to translate the
> roothub's port status once we stop converting it to USB 2.0 hub status
> internally.)
>
> Add new code to handle link state change status.  Send out new control
> messages that are needed for USB 3.0 hubs, like Set Hub Depth.
>
> This patch is a modified version of the original patch submitted by John
> Youn.  John's original hub patch made the change to struct
> usb_hub_descriptor to make part of it into a union.  There's a few more
> drivers in the 2.6.37 tree that need their accesses updated for this
> change: the USB IP driver in staging, and the dummy HCD gadget driver.
>
> Signed-off-by: John Youn <johnyoun@xxxxxxxxxxxx>
> Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
> ---
>  drivers/staging/usbip/vhci_hcd.c |    4 +-
>  drivers/usb/core/hub.c           |   73 +++++++++++++++++++++++++++++++++----
>  drivers/usb/gadget/dummy_hcd.c   |    4 +-
>  drivers/usb/host/ehci-hub.c      |    4 +-
>  drivers/usb/host/imx21-hcd.c     |    4 +-
>  drivers/usb/host/isp116x-hcd.c   |    4 +-
>  drivers/usb/host/isp1362-hcd.c   |    4 +-
>  drivers/usb/host/isp1760-hcd.c   |    4 +-
>  drivers/usb/host/ohci-hub.c      |   10 +++---
>  drivers/usb/host/oxu210hp-hcd.c  |    4 +-
>  drivers/usb/host/r8a66597-hcd.c  |    4 +-
>  drivers/usb/host/sl811-hcd.c     |    4 +-
>  drivers/usb/host/u132-hcd.c      |   10 +++---
>  drivers/usb/host/xhci-hub.c      |    4 +-
>  drivers/usb/wusbcore/rh.c        |    4 +-
>  include/linux/usb/ch11.h         |   41 +++++++++++++++++++--

drivers/usb/musb/musb_virthub.c is missed.

>  16 files changed, 136 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
> index 832608d..7ec3e74 100644
> --- a/drivers/staging/usbip/vhci_hcd.c
> +++ b/drivers/staging/usbip/vhci_hcd.c
> @@ -257,8 +257,8 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc)
>        desc->wHubCharacteristics = (__force __u16)
>                (__constant_cpu_to_le16(0x0001));
>        desc->bNbrPorts = VHCI_NPORTS;
> -       desc->bitmap[0] = 0xff;
> -       desc->bitmap[1] = 0xff;
> +       desc->u.hs.bitmap[0] = 0xff;
> +       desc->u.hs.bitmap[1] = 0xff;

Maybe redefining bitmap as u.hs.bitmap is cleverer fix, isn't it?

>  }
>
>  static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index b98efae..d9e7973 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -82,6 +82,10 @@ struct usb_hub {
>        void                    **port_owners;
>  };
>
> +static inline int hub_is_superspeed(struct usb_device *hdev)
> +{
> +       return (hdev->descriptor.bDeviceProtocol == 3);
> +}
>
>  /* Protect struct usb_device->state and ->children members
>  * Note: Both are also protected by ->dev.sem, except that ->state can
> @@ -172,14 +176,23 @@ static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
>  }
>
>  /* USB 2.0 spec Section 11.24.4.5 */
> -static int get_hub_descriptor(struct usb_device *hdev, void *data, int size)
> +static int get_hub_descriptor(struct usb_device *hdev, void *data)
>  {
> -       int i, ret;
> +       int i, ret, size;
> +       unsigned dtype;
> +
> +       if (hub_is_superspeed(hdev)) {
> +               dtype = USB_DT_SS_HUB;
> +               size = USB_DT_SS_HUB_SIZE;
> +       } else {
> +               dtype = USB_DT_HUB;
> +               size = sizeof(struct usb_hub_descriptor);
> +       }
>
>        for (i = 0; i < 3; i++) {
>                ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
>                        USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
> -                       USB_DT_HUB << 8, 0, data, size,
> +                       dtype << 8, 0, data, size,
>                        USB_CTRL_GET_TIMEOUT);
>                if (ret >= (USB_DT_HUB_NONVAR_SIZE + 2))
>                        return ret;
> @@ -365,6 +378,19 @@ static int hub_port_status(struct usb_hub *hub, int port1,
>        } else {
>                *status = le16_to_cpu(hub->status->port.wPortStatus);
>                *change = le16_to_cpu(hub->status->port.wPortChange);
> +
> +               if ((hub->hdev->parent != NULL) &&
> +                               hub_is_superspeed(hub->hdev)) {
> +                       /* Translate the USB 3 port status */
> +                       u16 tmp = *status & USB_SS_PORT_STAT_MASK;
> +                       if (*status & USB_SS_PORT_STAT_POWER)
> +                               tmp |= USB_PORT_STAT_POWER;
> +                       if ((*status & USB_SS_PORT_STAT_SPEED) ==
> +                                       USB_PORT_STAT_SPEED_5GBPS)
> +                               tmp |= USB_PORT_STAT_SUPER_SPEED;
> +                       *status = tmp;
> +               }
> +
>                ret = 0;
>        }
>        mutex_unlock(&hub->status_mutex);
> @@ -607,7 +633,7 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
>        if (hdev->children[port1-1] && set_state)
>                usb_set_device_state(hdev->children[port1-1],
>                                USB_STATE_NOTATTACHED);
> -       if (!hub->error)
> +       if (!hub->error && !hub_is_superspeed(hub->hdev))
>                ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
>        if (ret)
>                dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
> @@ -774,6 +800,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
>                        clear_port_feature(hub->hdev, port1,
>                                        USB_PORT_FEAT_C_ENABLE);
>                }
> +               if (portchange & USB_PORT_STAT_C_LINK_STATE) {
> +                       need_debounce_delay = true;
> +                       clear_port_feature(hub->hdev, port1,
> +                                       USB_PORT_FEAT_C_PORT_LINK_STATE);
> +               }
>
>                /* We can forget about a "removed" device when there's a
>                 * physical disconnect or the connect status changes.
> @@ -943,12 +974,23 @@ static int hub_configure(struct usb_hub *hub,
>                goto fail;
>        }
>
> +       if (hub_is_superspeed(hdev) && (hdev->parent != NULL)) {
> +               ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
> +                               HUB_SET_DEPTH, USB_RT_HUB,
> +                               hdev->level - 1, 0, NULL, 0,
> +                               USB_CTRL_SET_TIMEOUT);
> +
> +               if (ret < 0) {
> +                       message = "can't set hub depth";
> +                       goto fail;
> +               }
> +       }
> +
>        /* Request the entire hub descriptor.
>         * hub->descriptor can handle USB_MAXCHILDREN ports,
>         * but the hub can/will return fewer bytes here.
>         */
> -       ret = get_hub_descriptor(hdev, hub->descriptor,
> -                       sizeof(*hub->descriptor));
> +       ret = get_hub_descriptor(hdev, hub->descriptor);
>        if (ret < 0) {
>                message = "can't read hub descriptor";
>                goto fail;
> @@ -970,12 +1012,14 @@ static int hub_configure(struct usb_hub *hub,
>
>        wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
>
> -       if (wHubCharacteristics & HUB_CHAR_COMPOUND) {
> +       /* FIXME for USB 3.0, skip for now */
> +       if ((wHubCharacteristics & HUB_CHAR_COMPOUND) &&
> +                       !(hub_is_superspeed(hdev))) {
>                int     i;
>                char    portstr [USB_MAXCHILDREN + 1];
>
>                for (i = 0; i < hdev->maxchild; i++)
> -                       portstr[i] = hub->descriptor->DeviceRemovable
> +                       portstr[i] = hub->descriptor->u.hs.DeviceRemovable
>                                    [((i + 1) / 8)] & (1 << ((i + 1) % 8))
>                                ? 'F' : 'R';
>                portstr[hdev->maxchild] = 0;
> @@ -2000,6 +2044,8 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
>                                udev->speed = USB_SPEED_HIGH;
>                        else if (portstatus & USB_PORT_STAT_LOW_SPEED)
>                                udev->speed = USB_SPEED_LOW;
> +                       else if (portstatus & USB_PORT_STAT_SUPER_SPEED)
> +                               udev->speed = USB_SPEED_SUPER;
>                        else
>                                udev->speed = USB_SPEED_FULL;
>                        return 0;
> @@ -3401,6 +3447,17 @@ static void hub_events(void)
>                                clear_port_feature(hdev, i,
>                                        USB_PORT_FEAT_C_RESET);
>                        }
> +                       if (portchange & USB_PORT_STAT_C_LINK_STATE) {
> +                               clear_port_feature(hub->hdev, i,
> +                                               USB_PORT_FEAT_C_PORT_LINK_STATE);
> +                       }
> +                       if (portchange & USB_PORT_STAT_C_CONFIG_ERROR) {
> +                               dev_warn(hub_dev,
> +                                       "config error on port %d\n",
> +                                       i);
> +                               clear_port_feature(hub->hdev, i,
> +                                               USB_PORT_FEAT_C_PORT_CONFIG_ERROR);
> +                       }
>
>                        if (connect_change)
>                                hub_port_connect_change(hub, i,
> diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
> index 13b9f47..aec9de5 100644
> --- a/drivers/usb/gadget/dummy_hcd.c
> +++ b/drivers/usb/gadget/dummy_hcd.c
> @@ -1593,8 +1593,8 @@ hub_descriptor (struct usb_hub_descriptor *desc)
>        desc->bDescLength = 9;
>        desc->wHubCharacteristics = cpu_to_le16(0x0001);
>        desc->bNbrPorts = 1;
> -       desc->bitmap [0] = 0xff;
> -       desc->bitmap [1] = 0xff;
> +       desc->u.hs.bitmap[0] = 0xff;
> +       desc->u.hs.bitmap[1] = 0xff;
>  }
>
>  static int dummy_hub_control (
> diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
> index 796ea0c..c8d82b3 100644
> --- a/drivers/usb/host/ehci-hub.c
> +++ b/drivers/usb/host/ehci-hub.c
> @@ -688,8 +688,8 @@ ehci_hub_descriptor (
>        desc->bDescLength = 7 + 2 * temp;
>
>        /* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
> -       memset (&desc->bitmap [0], 0, temp);
> -       memset (&desc->bitmap [temp], 0xff, temp);
> +       memset(&desc->u.hs.bitmap[0], 0, temp);
> +       memset(&desc->u.hs.bitmap[temp], 0xff, temp);
>
>        temp = 0x0008;                  /* per-port overcurrent reporting */
>        if (HCS_PPC (ehci->hcs_params))
> diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c
> index e49b75a..6e22530 100644
> --- a/drivers/usb/host/imx21-hcd.c
> +++ b/drivers/usb/host/imx21-hcd.c
> @@ -1471,8 +1471,8 @@ static int get_hub_descriptor(struct usb_hcd *hcd,
>                0x0010 |        /* No over current protection */
>                0);
>
> -       desc->bitmap[0] = 1 << 1;
> -       desc->bitmap[1] = ~0;
> +       desc->u.hs.bitmap[0] = 1 << 1;
> +       desc->u.hs.bitmap[1] = ~0;
>        return 0;
>  }
>
> diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
> index 0da7fc0..084e3c6 100644
> --- a/drivers/usb/host/isp116x-hcd.c
> +++ b/drivers/usb/host/isp116x-hcd.c
> @@ -952,8 +952,8 @@ static void isp116x_hub_descriptor(struct isp116x *isp116x,
>        desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f));
>        desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff);
>        /* two bitmaps:  ports removable, and legacy PortPwrCtrlMask */
> -       desc->bitmap[0] = 0;
> -       desc->bitmap[1] = ~0;
> +       desc->u.hs.bitmap[0] = 0;
> +       desc->u.hs.bitmap[1] = ~0;
>  }
>
>  /* Perform reset of a given port.
> diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
> index 8196fa1..c9b1434 100644
> --- a/drivers/usb/host/isp1362-hcd.c
> +++ b/drivers/usb/host/isp1362-hcd.c
> @@ -1557,8 +1557,8 @@ static void isp1362_hub_descriptor(struct isp1362_hcd *isp1362_hcd,
>        DBG(0, "%s: hubcharacteristics = %02x\n", __func__, cpu_to_le16((reg >> 8) & 0x1f));
>        desc->bPwrOn2PwrGood = (reg >> 24) & 0xff;
>        /* two bitmaps:  ports removable, and legacy PortPwrCtrlMask */
> -       desc->bitmap[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1;
> -       desc->bitmap[1] = ~0;
> +       desc->u.hs.bitmap[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1;
> +       desc->u.hs.bitmap[1] = ~0;
>
>        DBG(3, "%s: exit\n", __func__);
>  }
> diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
> index bdba8c5..c7c5370 100644
> --- a/drivers/usb/host/isp1760-hcd.c
> +++ b/drivers/usb/host/isp1760-hcd.c
> @@ -1845,8 +1845,8 @@ static void isp1760_hub_descriptor(struct isp1760_hcd *priv,
>        desc->bDescLength = 7 + 2 * temp;
>
>        /* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
> -       memset(&desc->bitmap[0], 0, temp);
> -       memset(&desc->bitmap[temp], 0xff, temp);
> +       memset(&desc->u.hs.bitmap[0], 0, temp);
> +       memset(&desc->u.hs.bitmap[temp], 0xff, temp);
>
>        /* per-port overcurrent reporting */
>        temp = 0x0008;
> diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
> index cddcda9..8a0924d 100644
> --- a/drivers/usb/host/ohci-hub.c
> +++ b/drivers/usb/host/ohci-hub.c
> @@ -582,13 +582,13 @@ ohci_hub_descriptor (
>
>        /* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
>        rh = roothub_b (ohci);
> -       memset(desc->bitmap, 0xff, sizeof(desc->bitmap));
> -       desc->bitmap [0] = rh & RH_B_DR;
> +       memset(desc->u.hs.bitmap, 0xff, sizeof(desc->u.hs.bitmap));
> +       desc->u.hs.bitmap[0] = rh & RH_B_DR;
>        if (ohci->num_ports > 7) {
> -               desc->bitmap [1] = (rh & RH_B_DR) >> 8;
> -               desc->bitmap [2] = 0xff;
> +               desc->u.hs.bitmap[1] = (rh & RH_B_DR) >> 8;
> +               desc->u.hs.bitmap[2] = 0xff;
>        } else
> -               desc->bitmap [1] = 0xff;
> +               desc->u.hs.bitmap[1] = 0xff;
>  }
>
>  /*-------------------------------------------------------------------------*/
> diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
> index 32149be..1104c4d 100644
> --- a/drivers/usb/host/oxu210hp-hcd.c
> +++ b/drivers/usb/host/oxu210hp-hcd.c
> @@ -452,8 +452,8 @@ static void ehci_hub_descriptor(struct oxu_hcd *oxu,
>        desc->bDescLength = 7 + 2 * temp;
>
>        /* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
> -       memset(&desc->bitmap[0], 0, temp);
> -       memset(&desc->bitmap[temp], 0xff, temp);
> +       memset(&desc->u.hs.bitmap[0], 0, temp);
> +       memset(&desc->u.hs.bitmap[temp], 0xff, temp);
>
>        temp = 0x0008;                  /* per-port overcurrent reporting */
>        if (HCS_PPC(oxu->hcs_params))
> diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
> index 3076b1c..102dc54 100644
> --- a/drivers/usb/host/r8a66597-hcd.c
> +++ b/drivers/usb/host/r8a66597-hcd.c
> @@ -2150,8 +2150,8 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597,
>        desc->bDescLength = 9;
>        desc->bPwrOn2PwrGood = 0;
>        desc->wHubCharacteristics = cpu_to_le16(0x0011);
> -       desc->bitmap[0] = ((1 << r8a66597->max_root_hub) - 1) << 1;
> -       desc->bitmap[1] = ~0;
> +       desc->u.hs.bitmap[0] = ((1 << r8a66597->max_root_hub) - 1) << 1;
> +       desc->u.hs.bitmap[1] = ~0;
>  }
>
>  static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
> diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
> index 990f06b..45317ea 100644
> --- a/drivers/usb/host/sl811-hcd.c
> +++ b/drivers/usb/host/sl811-hcd.c
> @@ -1111,8 +1111,8 @@ sl811h_hub_descriptor (
>        desc->wHubCharacteristics = cpu_to_le16(temp);
>
>        /* two bitmaps:  ports removable, and legacy PortPwrCtrlMask */
> -       desc->bitmap[0] = 0 << 1;
> -       desc->bitmap[1] = ~0;
> +       desc->u.hs.bitmap[0] = 0 << 1;
> +       desc->u.hs.bitmap[1] = ~0;
>  }
>
>  static void
> diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
> index fab7649..9a2b71f 100644
> --- a/drivers/usb/host/u132-hcd.c
> +++ b/drivers/usb/host/u132-hcd.c
> @@ -2604,13 +2604,13 @@ static int u132_roothub_descriptor(struct u132 *u132,
>        retval = u132_read_pcimem(u132, roothub.b, &rh_b);
>        if (retval)
>                return retval;
> -       memset(desc->bitmap, 0xff, sizeof(desc->bitmap));
> -       desc->bitmap[0] = rh_b & RH_B_DR;
> +       memset(desc->u.hs.bitmap, 0xff, sizeof(desc->u.hs.bitmap));
> +       desc->u.hs.bitmap[0] = rh_b & RH_B_DR;
>        if (u132->num_ports > 7) {
> -               desc->bitmap[1] = (rh_b & RH_B_DR) >> 8;
> -               desc->bitmap[2] = 0xff;
> +               desc->u.hs.bitmap[1] = (rh_b & RH_B_DR) >> 8;
> +               desc->u.hs.bitmap[2] = 0xff;
>        } else
> -               desc->bitmap[1] = 0xff;
> +               desc->u.hs.bitmap[1] = 0xff;
>        return 0;
>  }
>
> diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
> index fef5a1f..c242d18 100644
> --- a/drivers/usb/host/xhci-hub.c
> +++ b/drivers/usb/host/xhci-hub.c
> @@ -46,8 +46,8 @@ static void xhci_hub_descriptor(struct xhci_hcd *xhci,
>        desc->bDescLength = 7 + 2 * temp;
>
>        /* Why does core/hcd.h define bitmap?  It's just confusing. */
> -       memset(&desc->DeviceRemovable[0], 0, temp);
> -       memset(&desc->DeviceRemovable[temp], 0xff, temp);
> +       memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
> +       memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
>
>        /* Ugh, these should be #defines, FIXME */
>        /* Using table 11-13 in USB 2.0 spec. */
> diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c
> index a68ad7a..248017a 100644
> --- a/drivers/usb/wusbcore/rh.c
> +++ b/drivers/usb/wusbcore/rh.c
> @@ -184,8 +184,8 @@ static int wusbhc_rh_get_hub_descr(struct wusbhc *wusbhc, u16 wValue,
>        descr->bPwrOn2PwrGood = 0;
>        descr->bHubContrCurrent = 0;
>        /* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
> -       memset(&descr->bitmap[0], 0, temp);
> -       memset(&descr->bitmap[temp], 0xff, temp);
> +       memset(&descr->u.hs.bitmap[0], 0, temp);
> +       memset(&descr->u.hs.bitmap[temp], 0xff, temp);
>        return 0;
>  }
>
> diff --git a/include/linux/usb/ch11.h b/include/linux/usb/ch11.h
> index 10ec069..8618ee6 100644
> --- a/include/linux/usb/ch11.h
> +++ b/include/linux/usb/ch11.h
> @@ -26,6 +26,7 @@
>  #define HUB_RESET_TT           9
>  #define HUB_GET_TT_STATE       10
>  #define HUB_STOP_TT            11
> +#define HUB_SET_DEPTH          12
>
>  /*
>  * Hub class additional requests defined by USB 3.0 spec
> @@ -61,6 +62,12 @@
>  #define USB_PORT_FEAT_TEST              21
>  #define USB_PORT_FEAT_INDICATOR         22
>  #define USB_PORT_FEAT_C_PORT_L1         23
> +#define USB_PORT_FEAT_C_PORT_LINK_STATE        25
> +#define USB_PORT_FEAT_C_PORT_CONFIG_ERROR 26
> +#define USB_PORT_FEAT_PORT_REMOTE_WAKE_MASK 27
> +#define USB_PORT_FEAT_BH_PORT_RESET     28
> +#define USB_PORT_FEAT_C_BH_PORT_RESET   29
> +#define USB_PORT_FEAT_FORCE_LINKPM_ACCEPT 30
>
>  /*
>  * Port feature selectors added by USB 3.0 spec.
> @@ -110,8 +117,14 @@ struct usb_port_status {
>  */
>  #define USB_PORT_STAT_LINK_STATE       0x01e0
>  #define USB_SS_PORT_STAT_POWER         0x0200
> +#define USB_SS_PORT_STAT_SPEED         0x1c00
>  #define USB_PORT_STAT_SPEED_5GBPS      0x0000
>  /* Valid only if port is enabled */
> +/* Bits that are the same from USB 2.0 */
> +#define USB_SS_PORT_STAT_MASK (USB_PORT_STAT_CONNECTION |          \
> +                               USB_PORT_STAT_ENABLE |      \
> +                               USB_PORT_STAT_OVERCURRENT | \
> +                               USB_PORT_STAT_RESET)
>
>  /*
>  * Definitions for PORT_LINK_STATE values
> @@ -141,6 +154,13 @@ struct usb_port_status {
>  #define USB_PORT_STAT_C_OVERCURRENT    0x0008
>  #define USB_PORT_STAT_C_RESET          0x0010
>  #define USB_PORT_STAT_C_L1             0x0020
> +/*
> + * USB 3.0 wPortChange bit fields
> + * See USB 3.0 spec Table 10-11
> + */
> +#define USB_PORT_STAT_C_BH_RESET       0x0020
> +#define USB_PORT_STAT_C_LINK_STATE     0x0040
> +#define USB_PORT_STAT_C_CONFIG_ERROR   0x0080
>
>  /*
>  * wHubCharacteristics (masks)
> @@ -175,7 +195,9 @@ struct usb_hub_status {
>  */
>
>  #define USB_DT_HUB                     (USB_TYPE_CLASS | 0x09)
> +#define USB_DT_SS_HUB                  (USB_TYPE_CLASS | 0x0a)
>  #define USB_DT_HUB_NONVAR_SIZE         7
> +#define USB_DT_SS_HUB_SIZE              12
>
>  struct usb_hub_descriptor {
>        __u8  bDescLength;
> @@ -184,11 +206,22 @@ struct usb_hub_descriptor {
>        __le16 wHubCharacteristics;
>        __u8  bPwrOn2PwrGood;
>        __u8  bHubContrCurrent;
> -               /* add 1 bit for hub status change; round to bytes */
> -       __u8  DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
> -       __u8  PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
> -} __attribute__ ((packed));
>
> +       /* 2.0 and 3.0 hubs differ here */
> +       union {
> +               struct {
> +                       /* add 1 bit for hub status change; round to bytes */
> +                       __u8  DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
> +                       __u8  PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
> +               }  __attribute__ ((packed)) hs;
> +
> +               struct {
> +                       __u8 bHubHdrDecLat;
> +                       __u16 wHubDelay;
> +                       __u16 DeviceRemovable;
> +               }  __attribute__ ((packed)) ss;
> +       } u;
> +} __attribute__ ((packed));
>
>  /* port indicator status selectors, tables 11-7 and 11-25 */
>  #define HUB_LED_AUTO   0
> --
> 1.6.3.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Lei Ming
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux