lkml.org 
[lkml]   [2016]   [Sep]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 036/113] usb: define USB_SPEED_SUPER_PLUS speed for SuperSpeedPlus USB3.1 devices
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Mathias Nyman <mathias.nyman@linux.intel.com>

    commit 8a1b2725a60d3267135c15e80984b4406054f650 upstream.

    Add a new USB_SPEED_SUPER_PLUS device speed, and make sure usb core can
    handle the new speed.
    In most cases the behaviour is the same as with USB_SPEED_SUPER SuperSpeed
    devices. In a few places we add a "Plus" string to inform the user of the
    new speed.

    Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/usb/common/common.c | 1 +
    drivers/usb/core/config.c | 3 ++-
    drivers/usb/core/devices.c | 10 ++++++----
    drivers/usb/core/hcd-pci.c | 2 +-
    drivers/usb/core/hcd.c | 6 +++---
    drivers/usb/core/hub.c | 26 +++++++++++++++-----------
    drivers/usb/core/urb.c | 3 ++-
    drivers/usb/core/usb.h | 2 +-
    include/uapi/linux/usb/ch9.h | 1 +
    9 files changed, 32 insertions(+), 22 deletions(-)

    --- a/drivers/usb/common/common.c
    +++ b/drivers/usb/common/common.c
    @@ -50,6 +50,7 @@ static const char *const speed_names[] =
    [USB_SPEED_HIGH] = "high-speed",
    [USB_SPEED_WIRELESS] = "wireless",
    [USB_SPEED_SUPER] = "super-speed",
    + [USB_SPEED_SUPER_PLUS] = "super-speed-plus",
    };

    const char *usb_speed_string(enum usb_device_speed speed)
    --- a/drivers/usb/core/config.c
    +++ b/drivers/usb/core/config.c
    @@ -191,6 +191,7 @@ static int usb_parse_endpoint(struct dev
    if (usb_endpoint_xfer_int(d)) {
    i = 1;
    switch (to_usb_device(ddev)->speed) {
    + case USB_SPEED_SUPER_PLUS:
    case USB_SPEED_SUPER:
    case USB_SPEED_HIGH:
    /* Many device manufacturers are using full-speed
    @@ -274,7 +275,7 @@ static int usb_parse_endpoint(struct dev
    }

    /* Parse a possible SuperSpeed endpoint companion descriptor */
    - if (to_usb_device(ddev)->speed == USB_SPEED_SUPER)
    + if (to_usb_device(ddev)->speed >= USB_SPEED_SUPER)
    usb_parse_ss_endpoint_companion(ddev, cfgno,
    inum, asnum, endpoint, buffer, size);

    --- a/drivers/usb/core/devices.c
    +++ b/drivers/usb/core/devices.c
    @@ -221,7 +221,7 @@ static char *usb_dump_endpoint_descripto
    break;
    case USB_ENDPOINT_XFER_INT:
    type = "Int.";
    - if (speed == USB_SPEED_HIGH || speed == USB_SPEED_SUPER)
    + if (speed == USB_SPEED_HIGH || speed >= USB_SPEED_SUPER)
    interval = 1 << (desc->bInterval - 1);
    else
    interval = desc->bInterval;
    @@ -230,7 +230,7 @@ static char *usb_dump_endpoint_descripto
    return start;
    }
    interval *= (speed == USB_SPEED_HIGH ||
    - speed == USB_SPEED_SUPER) ? 125 : 1000;
    + speed >= USB_SPEED_SUPER) ? 125 : 1000;
    if (interval % 1000)
    unit = 'u';
    else {
    @@ -322,7 +322,7 @@ static char *usb_dump_config_descriptor(

    if (start > end)
    return start;
    - if (speed == USB_SPEED_SUPER)
    + if (speed >= USB_SPEED_SUPER)
    mul = 8;
    else
    mul = 2;
    @@ -534,6 +534,8 @@ static ssize_t usb_device_dump(char __us
    speed = "480"; break;
    case USB_SPEED_SUPER:
    speed = "5000"; break;
    + case USB_SPEED_SUPER_PLUS:
    + speed = "10000"; break;
    default:
    speed = "??";
    }
    @@ -553,7 +555,7 @@ static ssize_t usb_device_dump(char __us

    /* super/high speed reserves 80%, full/low reserves 90% */
    if (usbdev->speed == USB_SPEED_HIGH ||
    - usbdev->speed == USB_SPEED_SUPER)
    + usbdev->speed >= USB_SPEED_SUPER)
    max = 800;
    else
    max = FRAME_TIME_MAX_USECS_ALLOC;
    --- a/drivers/usb/core/hcd-pci.c
    +++ b/drivers/usb/core/hcd-pci.c
    @@ -206,7 +206,7 @@ int usb_hcd_pci_probe(struct pci_dev *de
    * The xHCI driver has its own irq management
    * make sure irq setup is not touched for xhci in generic hcd code
    */
    - if ((driver->flags & HCD_MASK) != HCD_USB3) {
    + if ((driver->flags & HCD_MASK) < HCD_USB3) {
    if (!dev->irq) {
    dev_err(&dev->dev,
    "Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
    --- a/drivers/usb/core/hcd.c
    +++ b/drivers/usb/core/hcd.c
    @@ -1078,7 +1078,7 @@ static int register_root_hub(struct usb_
    retval = usb_get_bos_descriptor(usb_dev);
    if (!retval) {
    usb_dev->lpm_capable = usb_device_supports_lpm(usb_dev);
    - } else if (usb_dev->speed == USB_SPEED_SUPER) {
    + } else if (usb_dev->speed >= USB_SPEED_SUPER) {
    mutex_unlock(&usb_bus_list_lock);
    dev_dbg(parent_dev, "can't read %s bos descriptor %d\n",
    dev_name(&usb_dev->dev), retval);
    @@ -2112,7 +2112,7 @@ int usb_alloc_streams(struct usb_interfa
    hcd = bus_to_hcd(dev->bus);
    if (!hcd->driver->alloc_streams || !hcd->driver->free_streams)
    return -EINVAL;
    - if (dev->speed != USB_SPEED_SUPER)
    + if (dev->speed < USB_SPEED_SUPER)
    return -EINVAL;
    if (dev->state < USB_STATE_CONFIGURED)
    return -ENODEV;
    @@ -2160,7 +2160,7 @@ int usb_free_streams(struct usb_interfac

    dev = interface_to_usbdev(interface);
    hcd = bus_to_hcd(dev->bus);
    - if (dev->speed != USB_SPEED_SUPER)
    + if (dev->speed < USB_SPEED_SUPER)
    return -EINVAL;

    /* Double-free is not allowed */
    --- a/drivers/usb/core/hub.c
    +++ b/drivers/usb/core/hub.c
    @@ -298,7 +298,7 @@ static void usb_set_lpm_parameters(struc
    unsigned int hub_u1_del;
    unsigned int hub_u2_del;

    - if (!udev->lpm_capable || udev->speed != USB_SPEED_SUPER)
    + if (!udev->lpm_capable || udev->speed < USB_SPEED_SUPER)
    return;

    hub = usb_hub_to_struct_hub(udev->parent);
    @@ -2645,7 +2645,7 @@ static unsigned hub_is_wusb(struct usb_h
    */
    static bool use_new_scheme(struct usb_device *udev, int retry)
    {
    - if (udev->speed == USB_SPEED_SUPER)
    + if (udev->speed >= USB_SPEED_SUPER)
    return false;

    return USE_NEW_SCHEME(retry);
    @@ -3985,7 +3985,7 @@ int usb_disable_lpm(struct usb_device *u
    struct usb_hcd *hcd;

    if (!udev || !udev->parent ||
    - udev->speed != USB_SPEED_SUPER ||
    + udev->speed < USB_SPEED_SUPER ||
    !udev->lpm_capable ||
    udev->state < USB_STATE_DEFAULT)
    return 0;
    @@ -4042,7 +4042,7 @@ void usb_enable_lpm(struct usb_device *u
    struct usb_hcd *hcd;

    if (!udev || !udev->parent ||
    - udev->speed != USB_SPEED_SUPER ||
    + udev->speed < USB_SPEED_SUPER ||
    !udev->lpm_capable ||
    udev->state < USB_STATE_DEFAULT)
    return;
    @@ -4308,7 +4308,9 @@ hub_port_init(struct usb_hub *hub, struc

    retval = -ENODEV;

    - if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) {
    + /* Don't allow speed changes at reset, except usb 3.0 to faster */
    + if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed &&
    + !(oldspeed == USB_SPEED_SUPER && udev->speed > oldspeed)) {
    dev_dbg(&udev->dev, "device reset changed speed!\n");
    goto fail;
    }
    @@ -4320,6 +4322,7 @@ hub_port_init(struct usb_hub *hub, struc
    * reported as 0xff in the device descriptor). WUSB1.0[4.8.1].
    */
    switch (udev->speed) {
    + case USB_SPEED_SUPER_PLUS:
    case USB_SPEED_SUPER:
    case USB_SPEED_WIRELESS: /* fixed at 512 */
    udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
    @@ -4346,7 +4349,7 @@ hub_port_init(struct usb_hub *hub, struc
    else
    speed = usb_speed_string(udev->speed);

    - if (udev->speed != USB_SPEED_SUPER)
    + if (udev->speed < USB_SPEED_SUPER)
    dev_info(&udev->dev,
    "%s %s USB device number %d using %s\n",
    (udev->config) ? "reset" : "new", speed,
    @@ -4476,11 +4479,12 @@ hub_port_init(struct usb_hub *hub, struc
    devnum, retval);
    goto fail;
    }
    - if (udev->speed == USB_SPEED_SUPER) {
    + if (udev->speed >= USB_SPEED_SUPER) {
    devnum = udev->devnum;
    dev_info(&udev->dev,
    - "%s SuperSpeed USB device number %d using %s\n",
    + "%s SuperSpeed%s USB device number %d using %s\n",
    (udev->config) ? "reset" : "new",
    + (udev->speed == USB_SPEED_SUPER_PLUS) ? "Plus" : "",
    devnum, udev->bus->controller->driver->name);
    }

    @@ -4519,7 +4523,7 @@ hub_port_init(struct usb_hub *hub, struc
    * got from those devices show they aren't superspeed devices. Warm
    * reset the port attached by the devices can fix them.
    */
    - if ((udev->speed == USB_SPEED_SUPER) &&
    + if ((udev->speed >= USB_SPEED_SUPER) &&
    (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) {
    dev_err(&udev->dev, "got a wrong device descriptor, "
    "warm reset device\n");
    @@ -4530,7 +4534,7 @@ hub_port_init(struct usb_hub *hub, struc
    }

    if (udev->descriptor.bMaxPacketSize0 == 0xff ||
    - udev->speed == USB_SPEED_SUPER)
    + udev->speed >= USB_SPEED_SUPER)
    i = 512;
    else
    i = udev->descriptor.bMaxPacketSize0;
    @@ -4740,7 +4744,7 @@ static void hub_port_connect(struct usb_
    udev->level = hdev->level + 1;
    udev->wusb = hub_is_wusb(hub);

    - /* Only USB 3.0 devices are connected to SuperSpeed hubs. */
    + /* Devices connected to SuperSpeed hubs are USB 3.0 or later */
    if (hub_is_superspeed(hub->hdev))
    udev->speed = USB_SPEED_SUPER;
    else
    --- a/drivers/usb/core/urb.c
    +++ b/drivers/usb/core/urb.c
    @@ -401,7 +401,7 @@ int usb_submit_urb(struct urb *urb, gfp_
    /* SuperSpeed isoc endpoints have up to 16 bursts of up to
    * 3 packets each
    */
    - if (dev->speed == USB_SPEED_SUPER) {
    + if (dev->speed >= USB_SPEED_SUPER) {
    int burst = 1 + ep->ss_ep_comp.bMaxBurst;
    int mult = USB_SS_MULT(ep->ss_ep_comp.bmAttributes);
    max *= burst;
    @@ -499,6 +499,7 @@ int usb_submit_urb(struct urb *urb, gfp_
    }
    /* too big? */
    switch (dev->speed) {
    + case USB_SPEED_SUPER_PLUS:
    case USB_SPEED_SUPER: /* units are 125us */
    /* Handle up to 2^(16-1) microframes */
    if (urb->interval > (1 << 15))
    --- a/drivers/usb/core/usb.h
    +++ b/drivers/usb/core/usb.h
    @@ -45,7 +45,7 @@ static inline unsigned usb_get_max_power
    struct usb_host_config *c)
    {
    /* SuperSpeed power is in 8 mA units; others are in 2 mA units */
    - unsigned mul = (udev->speed == USB_SPEED_SUPER ? 8 : 2);
    + unsigned mul = (udev->speed >= USB_SPEED_SUPER ? 8 : 2);

    return c->desc.bMaxPower * mul;
    }
    --- a/include/uapi/linux/usb/ch9.h
    +++ b/include/uapi/linux/usb/ch9.h
    @@ -954,6 +954,7 @@ enum usb_device_speed {
    USB_SPEED_HIGH, /* usb 2.0 */
    USB_SPEED_WIRELESS, /* wireless (usb 2.5) */
    USB_SPEED_SUPER, /* usb 3.0 */
    + USB_SPEED_SUPER_PLUS, /* usb 3.1 */
    };



    \
     
     \ /
      Last update: 2016-09-17 09:58    [W:3.746 / U:0.564 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site