Merge 4.5-rc6 into usb-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 Mar 2016 00:13:54 +0000 (16:13 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 Mar 2016 00:13:54 +0000 (16:13 -0800)
We want the USB fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1  2 
MAINTAINERS
drivers/usb/core/hub.c

diff --combined MAINTAINERS
@@@ -920,17 -920,24 +920,24 @@@ M:      Emilio López <emilio@elopez.com.ar
  S:    Maintained
  F:    drivers/clk/sunxi/
  
- ARM/Amlogic MesonX SoC support
+ ARM/Amlogic Meson SoC support
  M:    Carlo Caione <carlo@caione.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+ L:    linux-meson@googlegroups.com
+ W:    http://linux-meson.com/
  S:    Maintained
- F:    drivers/media/rc/meson-ir.c
- N:    meson[x68]
+ F:    arch/arm/mach-meson/
+ F:    arch/arm/boot/dts/meson*
+ N:    meson
  
  ARM/Annapurna Labs ALPINE ARCHITECTURE
  M:    Tsahee Zidenberg <tsahee@annapurnalabs.com>
+ M:    Antoine Tenart <antoine.tenart@free-electrons.com>
  S:    Maintained
  F:    arch/arm/mach-alpine/
+ F:    arch/arm/boot/dts/alpine*
+ F:    arch/arm64/boot/dts/al/
+ F:    drivers/*/*alpine*
  
  ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT
  M:    Nicolas Ferre <nicolas.ferre@atmel.com>
@@@ -1442,8 -1449,8 +1449,8 @@@ S:      Maintaine
  ARM/RENESAS ARM64 ARCHITECTURE
  M:    Simon Horman <horms@verge.net.au>
  M:    Magnus Damm <magnus.damm@gmail.com>
- L:    linux-sh@vger.kernel.org
- Q:    http://patchwork.kernel.org/project/linux-sh/list/
+ L:    linux-renesas-soc@vger.kernel.org
+ Q:    http://patchwork.kernel.org/project/linux-renesas-soc/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next
  S:    Supported
  F:    arch/arm64/boot/dts/renesas/
@@@ -3444,7 -3451,6 +3451,6 @@@ F:      drivers/usb/dwc2
  DESIGNWARE USB3 DRD IP DRIVER
  M:    Felipe Balbi <balbi@kernel.org>
  L:    linux-usb@vger.kernel.org
- L:    linux-omap@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
  S:    Maintained
  F:    drivers/usb/dwc3/
@@@ -6128,7 -6134,7 +6134,7 @@@ F:      include/uapi/linux/sunrpc
  
  KERNEL SELFTEST FRAMEWORK
  M:    Shuah Khan <shuahkh@osg.samsung.com>
- L:    linux-api@vger.kernel.org
+ L:    linux-kselftest@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/shuah/linux-kselftest
  S:    Maintained
  F:    tools/testing/selftests
@@@ -7354,7 -7360,7 +7360,7 @@@ F:      drivers/tty/isicom.
  F:    include/linux/isicom.h
  
  MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
- M:    Felipe Balbi <balbi@kernel.org>
+ M:    Bin Liu <b-liu@ti.com>
  L:    linux-usb@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
  S:    Maintained
@@@ -7686,13 -7692,13 +7692,13 @@@ S:   Maintaine
  F:    arch/nios2/
  
  NOKIA N900 POWER SUPPLY DRIVERS
- M:    Pali Rohár <pali.rohar@gmail.com>
- S:    Maintained
+ R:    Pali Rohár <pali.rohar@gmail.com>
  F:    include/linux/power/bq2415x_charger.h
  F:    include/linux/power/bq27xxx_battery.h
  F:    include/linux/power/isp1704_charger.h
  F:    drivers/power/bq2415x_charger.c
  F:    drivers/power/bq27xxx_battery.c
+ F:    drivers/power/bq27xxx_battery_i2c.c
  F:    drivers/power/isp1704_charger.c
  F:    drivers/power/rx51_battery.c
  
@@@ -7923,11 -7929,9 +7929,9 @@@ F:     drivers/media/platform/omap3isp
  F:    drivers/staging/media/omap4iss/
  
  OMAP USB SUPPORT
- M:    Felipe Balbi <balbi@kernel.org>
  L:    linux-usb@vger.kernel.org
  L:    linux-omap@vger.kernel.org
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
- S:    Maintained
+ S:    Orphan
  F:    drivers/usb/*/*omap*
  F:    arch/arm/*omap*/usb*
  
@@@ -9558,6 -9562,12 +9562,12 @@@ M:    Andreas Noever <andreas.noever@gmail
  S:    Maintained
  F:    drivers/thunderbolt/
  
+ TI BQ27XXX POWER SUPPLY DRIVER
+ R:    Andrew F. Davis <afd@ti.com>
+ F:    include/linux/power/bq27xxx_battery.h
+ F:    drivers/power/bq27xxx_battery.c
+ F:    drivers/power/bq27xxx_battery_i2c.c
  TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
  M:    John Stultz <john.stultz@linaro.org>
  M:    Thomas Gleixner <tglx@linutronix.de>
@@@ -11246,7 -11256,7 +11256,7 @@@ F:   include/linux/mtd/ubi.
  F:    include/uapi/mtd/ubi-user.h
  
  USB ACM DRIVER
 -M:    Oliver Neukum <oliver@neukum.org>
 +M:    Oliver Neukum <oneukum@suse.com>
  L:    linux-usb@vger.kernel.org
  S:    Maintained
  F:    Documentation/usb/acm.txt
@@@ -12013,7 -12023,6 +12023,6 @@@ F:   arch/arm64/xen
  F:    arch/arm64/include/asm/xen/
  
  XEN NETWORK BACKEND DRIVER
- M:    Ian Campbell <ian.campbell@citrix.com>
  M:    Wei Liu <wei.liu2@citrix.com>
  L:    xen-devel@lists.xenproject.org (moderated for non-subscribers)
  L:    netdev@vger.kernel.org
diff --combined drivers/usb/core/hub.c
@@@ -49,7 -49,7 +49,7 @@@ static void hub_event(struct work_struc
  DEFINE_MUTEX(usb_port_peer_mutex);
  
  /* cycle leds on hubs that aren't blinking for attention */
 -static bool blinkenlights = 0;
 +static bool blinkenlights;
  module_param(blinkenlights, bool, S_IRUGO);
  MODULE_PARM_DESC(blinkenlights, "true to cycle leds on hubs");
  
@@@ -78,7 -78,7 +78,7 @@@ MODULE_PARM_DESC(initial_descriptor_tim
   * otherwise the new scheme is used.  If that fails and "use_both_schemes"
   * is set, then the driver will make another attempt, using the other scheme.
   */
 -static bool old_scheme_first = 0;
 +static bool old_scheme_first;
  module_param(old_scheme_first, bool, S_IRUGO | S_IWUSR);
  MODULE_PARM_DESC(old_scheme_first,
                 "start with the old device initialization scheme");
@@@ -298,7 -298,7 +298,7 @@@ static void usb_set_lpm_parameters(stru
        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);
@@@ -537,34 -537,29 +537,34 @@@ static int get_hub_status(struct usb_de
  
  /*
   * USB 2.0 spec Section 11.24.2.7
 + * USB 3.1 takes into use the wValue and wLength fields, spec Section 10.16.2.6
   */
  static int get_port_status(struct usb_device *hdev, int port1,
 -              struct usb_port_status *data)
 +                         void *data, u16 value, u16 length)
  {
        int i, status = -ETIMEDOUT;
  
        for (i = 0; i < USB_STS_RETRIES &&
                        (status == -ETIMEDOUT || status == -EPIPE); i++) {
                status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
 -                      USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port1,
 -                      data, sizeof(*data), USB_STS_TIMEOUT);
 +                      USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, value,
 +                      port1, data, length, USB_STS_TIMEOUT);
        }
        return status;
  }
  
 -static int hub_port_status(struct usb_hub *hub, int port1,
 -              u16 *status, u16 *change)
 +static int hub_ext_port_status(struct usb_hub *hub, int port1, int type,
 +                             u16 *status, u16 *change, u32 *ext_status)
  {
        int ret;
 +      int len = 4;
 +
 +      if (type != HUB_PORT_STATUS)
 +              len = 8;
  
        mutex_lock(&hub->status_mutex);
 -      ret = get_port_status(hub->hdev, port1, &hub->status->port);
 -      if (ret < 4) {
 +      ret = get_port_status(hub->hdev, port1, &hub->status->port, type, len);
 +      if (ret < len) {
                if (ret != -ENODEV)
                        dev_err(hub->intfdev,
                                "%s failed (err = %d)\n", __func__, ret);
        } else {
                *status = le16_to_cpu(hub->status->port.wPortStatus);
                *change = le16_to_cpu(hub->status->port.wPortChange);
 -
 +              if (type != HUB_PORT_STATUS && ext_status)
 +                      *ext_status = le32_to_cpu(
 +                              hub->status->port.dwExtPortStatus);
                ret = 0;
        }
        mutex_unlock(&hub->status_mutex);
        return ret;
  }
  
 +static int hub_port_status(struct usb_hub *hub, int port1,
 +              u16 *status, u16 *change)
 +{
 +      return hub_ext_port_status(hub, port1, HUB_PORT_STATUS,
 +                                 status, change, NULL);
 +}
 +
  static void kick_hub_wq(struct usb_hub *hub)
  {
        struct usb_interface *intf;
@@@ -2145,7 -2131,7 +2145,7 @@@ static void hub_disconnect_children(str
   * Something got disconnected. Get rid of it and all of its children.
   *
   * If *pdev is a normal device then the parent hub must already be locked.
 - * If *pdev is a root hub then the caller must hold the usb_bus_list_lock,
 + * If *pdev is a root hub then the caller must hold the usb_bus_idr_lock,
   * which protects the set of root hubs as well as the list of buses.
   *
   * Only hub drivers (including virtual root hub drivers for host
@@@ -2443,7 -2429,7 +2443,7 @@@ static void set_usb_port_removable(stru
   * enumerated.  The device descriptor is available, but not descriptors
   * for any device configuration.  The caller must have locked either
   * the parent hub (if udev is a normal device) or else the
 - * usb_bus_list_lock (if udev is a root hub).  The parent's pointer to
 + * usb_bus_idr_lock (if udev is a root hub).  The parent's pointer to
   * udev has already been installed, but udev is not yet visible through
   * sysfs or other filesystem code.
   *
@@@ -2626,32 -2612,6 +2626,32 @@@ out_authorized
        return result;
  }
  
 +/*
 + * Return 1 if port speed is SuperSpeedPlus, 0 otherwise
 + * check it from the link protocol field of the current speed ID attribute.
 + * current speed ID is got from ext port status request. Sublink speed attribute
 + * table is returned with the hub BOS SSP device capability descriptor
 + */
 +static int port_speed_is_ssp(struct usb_device *hdev, int speed_id)
 +{
 +      int ssa_count;
 +      u32 ss_attr;
 +      int i;
 +      struct usb_ssp_cap_descriptor *ssp_cap = hdev->bos->ssp_cap;
 +
 +      if (!ssp_cap)
 +              return 0;
 +
 +      ssa_count = le32_to_cpu(ssp_cap->bmAttributes) &
 +              USB_SSP_SUBLINK_SPEED_ATTRIBS;
 +
 +      for (i = 0; i <= ssa_count; i++) {
 +              ss_attr = le32_to_cpu(ssp_cap->bmSublinkSpeedAttr[i]);
 +              if (speed_id == (ss_attr & USB_SSP_SUBLINK_SPEED_SSID))
 +                      return !!(ss_attr & USB_SSP_SUBLINK_SPEED_LP);
 +      }
 +      return 0;
 +}
  
  /* Returns 1 if @hub is a WUSB root hub, 0 otherwise */
  static unsigned hub_is_wusb(struct usb_hub *hub)
        struct usb_hcd *hcd;
        if (hub->hdev->parent != NULL)  /* not a root hub? */
                return 0;
 -      hcd = container_of(hub->hdev->bus, struct usb_hcd, self);
 +      hcd = bus_to_hcd(hub->hdev->bus);
        return hcd->wireless;
  }
  
   */
  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);
@@@ -2716,7 -2676,6 +2716,7 @@@ static int hub_port_wait_reset(struct u
        int delay_time, ret;
        u16 portstatus;
        u16 portchange;
 +      u32 ext_portstatus = 0;
  
        for (delay_time = 0;
                        delay_time < HUB_RESET_TIMEOUT;
                msleep(delay);
  
                /* read and decode port status */
 -              ret = hub_port_status(hub, port1, &portstatus, &portchange);
 +              if (hub_is_superspeedplus(hub->hdev))
 +                      ret = hub_ext_port_status(hub, port1,
 +                                                HUB_EXT_PORT_STATUS,
 +                                                &portstatus, &portchange,
 +                                                &ext_portstatus);
 +              else
 +                      ret = hub_port_status(hub, port1, &portstatus,
 +                                            &portchange);
                if (ret < 0)
                        return ret;
  
  
        if (hub_is_wusb(hub))
                udev->speed = USB_SPEED_WIRELESS;
 +      else if (hub_is_superspeedplus(hub->hdev) &&
 +               port_speed_is_ssp(hub->hdev, ext_portstatus &
 +                                 USB_EXT_PORT_STAT_RX_SPEED_ID))
 +              udev->speed = USB_SPEED_SUPER_PLUS;
        else if (hub_is_superspeed(hub->hdev))
                udev->speed = USB_SPEED_SUPER;
        else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
@@@ -4041,7 -3989,7 +4041,7 @@@ int usb_disable_lpm(struct usb_device *
        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;
@@@ -4100,7 -4048,7 +4100,7 @@@ void usb_enable_lpm(struct usb_device *
        struct usb_port *port_dev;
  
        if (!udev || !udev->parent ||
 -                      udev->speed != USB_SPEED_SUPER ||
 +                      udev->speed < USB_SPEED_SUPER ||
                        !udev->lpm_capable ||
                        udev->state < USB_STATE_DEFAULT)
                return;
@@@ -4375,9 -4323,7 +4375,9 @@@ hub_port_init(struct usb_hub *hub, stru
  
        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;
        }
         * 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);
        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,
                                                r = -EPROTO;
                                        break;
                                }
 -                              if (r == 0)
 +                              /*
 +                               * Some devices time out if they are powered on
 +                               * when already connected. They need a second
 +                               * reset. But only on the first attempt,
 +                               * lest we get into a time out/reset loop
 +                               */
 +                              if (r == 0  || (r == -ETIMEDOUT && j == 0))
                                        break;
                        }
                        udev->descriptor.bMaxPacketSize0 =
                                                        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);
                        }
  
         * 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");
        }
  
        if (udev->descriptor.bMaxPacketSize0 == 0xff ||
 -                      udev->speed == USB_SPEED_SUPER)
 +                      udev->speed >= USB_SPEED_SUPER)
                i = 512;
        else
                i = udev->descriptor.bMaxPacketSize0;
@@@ -4811,7 -4749,7 +4811,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
@@@ -5463,6 -5401,7 +5463,7 @@@ static int usb_reset_and_verify_device(
        }
  
        bos = udev->bos;
+       udev->bos = NULL;
  
        for (i = 0; i < SET_CONFIG_TRIES; ++i) {
  
@@@ -5555,11 -5494,8 +5556,8 @@@ done
        usb_set_usb2_hardware_lpm(udev, 1);
        usb_unlocked_enable_lpm(udev);
        usb_enable_ltm(udev);
-       /* release the new BOS descriptor allocated  by hub_port_init() */
-       if (udev->bos != bos) {
-               usb_release_bos_descriptor(udev);
-               udev->bos = bos;
-       }
+       usb_release_bos_descriptor(udev);
+       udev->bos = bos;
        return 0;
  
  re_enumerate: