USB: add missing delay during remote wakeup
[safe/jmp/linux-2.6] / drivers / usb / core / hub.c
index 6a5cb01..b9f5fcd 100644 (file)
@@ -45,7 +45,6 @@ struct usb_hub {
 
        /* buffer for urb ... with extra space in case of babble */
        char                    (*buffer)[8];
-       dma_addr_t              buffer_dma;     /* DMA address for buffer */
        union {
                struct usb_hub_status   hub;
                struct usb_port_status  port;
@@ -61,6 +60,8 @@ struct usb_hub {
                                                        status change */
        unsigned long           busy_bits[1];   /* ports being reset or
                                                        resumed */
+       unsigned long           removed_bits[1]; /* ports with a "removed"
+                                                       device present */
 #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
 #error event_bits[] is too short!
 #endif
@@ -70,6 +71,7 @@ struct usb_hub {
 
        unsigned                mA_per_port;    /* current for each child */
 
+       unsigned                init_done:1;
        unsigned                limited_power:1;
        unsigned                quiescing:1;
        unsigned                disconnected:1;
@@ -77,6 +79,8 @@ struct usb_hub {
        unsigned                has_indicators:1;
        u8                      indicator[USB_MAXCHILDREN];
        struct delayed_work     leds;
+       struct delayed_work     init_work;
+       void                    **port_owners;
 };
 
 
@@ -100,6 +104,17 @@ module_param (blinkenlights, bool, S_IRUGO);
 MODULE_PARM_DESC (blinkenlights, "true to cycle leds on hubs");
 
 /*
+ * Device SATA8000 FW1.0 from DATAST0R Technology Corp requires about
+ * 10 seconds to send reply for the initial 64-byte descriptor request.
+ */
+/* define initial 64-byte descriptor request timeout in milliseconds */
+static int initial_descriptor_timeout = USB_CTRL_GET_TIMEOUT;
+module_param(initial_descriptor_timeout, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(initial_descriptor_timeout,
+               "initial 64-byte descriptor request timeout in milliseconds "
+               "(default 5000 - 5.0 seconds)");
+
+/*
  * As of 2.6.10 we introduce a new USB device initialization scheme which
  * closely resembles the way Windows works.  Hopefully it will be compatible
  * with a wider range of devices than the old scheme.  However some previously
@@ -143,13 +158,17 @@ static inline char *portspeed(int portstatus)
                return "480 Mb/s";
        else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED))
                return "1.5 Mb/s";
+       else if (portstatus & (1 << USB_PORT_FEAT_SUPERSPEED))
+               return "5.0 Gb/s";
        else
                return "12 Mb/s";
 }
 
 /* Note that hdev or one of its children must be locked! */
-static inline struct usb_hub *hdev_to_hub(struct usb_device *hdev)
+static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
 {
+       if (!hdev || !hdev->actconfig)
+               return NULL;
        return usb_get_intfdata(hdev->actconfig->interface[0]);
 }
 
@@ -357,12 +376,13 @@ static void kick_khubd(struct usb_hub *hub)
 {
        unsigned long   flags;
 
-       /* Suppress autosuspend until khubd runs */
-       to_usb_interface(hub->intfdev)->pm_usage_cnt = 1;
-
        spin_lock_irqsave(&hub_event_lock, flags);
        if (!hub->disconnected && list_empty(&hub->event_list)) {
                list_add_tail(&hub->event_list, &hub_event_list);
+
+               /* Suppress autosuspend until khubd runs */
+               usb_autopm_get_interface_no_resume(
+                               to_usb_interface(hub->intfdev));
                wake_up(&khubd_wait);
        }
        spin_unlock_irqrestore(&hub_event_lock, flags);
@@ -370,8 +390,10 @@ static void kick_khubd(struct usb_hub *hub)
 
 void usb_kick_khubd(struct usb_device *hdev)
 {
-       /* FIXME: What if hdev isn't bound to the hub driver? */
-       kick_khubd(hdev_to_hub(hdev));
+       struct usb_hub *hub = hdev_to_hub(hdev);
+
+       if (hub)
+               kick_khubd(hub);
 }
 
 
@@ -380,7 +402,7 @@ static void hub_irq(struct urb *urb)
 {
        struct usb_hub *hub = urb->context;
        int status = urb->status;
-       int i;
+       unsigned i;
        unsigned long bits;
 
        switch (status) {
@@ -425,7 +447,7 @@ resubmit:
 static inline int
 hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
 {
-       return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
+       return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
                               HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo,
                               tt, NULL, 0, 1000);
 }
@@ -436,42 +458,47 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
  * talking to TTs must queue control transfers (not just bulk and iso), so
  * both can talk to the same hub concurrently.
  */
-static void hub_tt_kevent (struct work_struct *work)
+static void hub_tt_work(struct work_struct *work)
 {
        struct usb_hub          *hub =
-               container_of(work, struct usb_hub, tt.kevent);
+               container_of(work, struct usb_hub, tt.clear_work);
        unsigned long           flags;
        int                     limit = 100;
 
        spin_lock_irqsave (&hub->tt.lock, flags);
        while (--limit && !list_empty (&hub->tt.clear_list)) {
-               struct list_head        *temp;
+               struct list_head        *next;
                struct usb_tt_clear     *clear;
                struct usb_device       *hdev = hub->hdev;
+               const struct hc_driver  *drv;
                int                     status;
 
-               temp = hub->tt.clear_list.next;
-               clear = list_entry (temp, struct usb_tt_clear, clear_list);
+               next = hub->tt.clear_list.next;
+               clear = list_entry (next, struct usb_tt_clear, clear_list);
                list_del (&clear->clear_list);
 
                /* drop lock so HCD can concurrently report other TT errors */
                spin_unlock_irqrestore (&hub->tt.lock, flags);
                status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt);
-               spin_lock_irqsave (&hub->tt.lock, flags);
-
                if (status)
                        dev_err (&hdev->dev,
                                "clear tt %d (%04x) error %d\n",
                                clear->tt, clear->devinfo, status);
+
+               /* Tell the HCD, even if the operation failed */
+               drv = clear->hcd->driver;
+               if (drv->clear_tt_buffer_complete)
+                       (drv->clear_tt_buffer_complete)(clear->hcd, clear->ep);
+
                kfree(clear);
+               spin_lock_irqsave(&hub->tt.lock, flags);
        }
        spin_unlock_irqrestore (&hub->tt.lock, flags);
 }
 
 /**
- * usb_hub_tt_clear_buffer - clear control/bulk TT state in high speed hub
- * @udev: the device whose split transaction failed
- * @pipe: identifies the endpoint of the failed transaction
+ * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
+ * @urb: an URB associated with the failed or incomplete split transaction
  *
  * High speed HCDs use this to tell the hub driver that some split control or
  * bulk transaction failed in a way that requires clearing internal state of
@@ -481,8 +508,10 @@ static void hub_tt_kevent (struct work_struct *work)
  * It may not be possible for that hub to handle additional full (or low)
  * speed transactions until that state is fully cleared out.
  */
-void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
+int usb_hub_clear_tt_buffer(struct urb *urb)
 {
+       struct usb_device       *udev = urb->dev;
+       int                     pipe = urb->pipe;
        struct usb_tt           *tt = udev->tt;
        unsigned long           flags;
        struct usb_tt_clear     *clear;
@@ -494,7 +523,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
        if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) {
                dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
                /* FIXME recover somehow ... RESET_TT? */
-               return;
+               return -ENOMEM;
        }
 
        /* info that CLEAR_TT_BUFFER needs */
@@ -506,19 +535,28 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
                        : (USB_ENDPOINT_XFER_BULK << 11);
        if (usb_pipein (pipe))
                clear->devinfo |= 1 << 15;
-       
+
+       /* info for completion callback */
+       clear->hcd = bus_to_hcd(udev->bus);
+       clear->ep = urb->ep;
+
        /* tell keventd to clear state for this TT */
        spin_lock_irqsave (&tt->lock, flags);
        list_add_tail (&clear->clear_list, &tt->clear_list);
-       schedule_work (&tt->kevent);
+       schedule_work(&tt->clear_work);
        spin_unlock_irqrestore (&tt->lock, flags);
+       return 0;
 }
-EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer);
+EXPORT_SYMBOL_GPL(usb_hub_clear_tt_buffer);
 
-static void hub_power_on(struct usb_hub *hub)
+/* If do_delay is false, return the number of milliseconds the caller
+ * needs to delay.
+ */
+static unsigned hub_power_on(struct usb_hub *hub, bool do_delay)
 {
        int port1;
        unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
+       unsigned delay;
        u16 wHubCharacteristics =
                        le16_to_cpu(hub->descriptor->wHubCharacteristics);
 
@@ -537,7 +575,10 @@ static void hub_power_on(struct usb_hub *hub)
                set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER);
 
        /* Wait at least 100 msec for power to become stable */
-       msleep(max(pgood_delay, (unsigned) 100));
+       delay = max(pgood_delay, (unsigned) 100);
+       if (do_delay)
+               msleep(delay);
+       return delay;
 }
 
 static int hub_hub_status(struct usb_hub *hub,
@@ -598,22 +639,87 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
        kick_khubd(hub);
 }
 
+/**
+ * usb_remove_device - disable a device's port on its parent hub
+ * @udev: device to be disabled and removed
+ * Context: @udev locked, must be able to sleep.
+ *
+ * After @udev's port has been disabled, khubd is notified and it will
+ * see that the device has been disconnected.  When the device is
+ * physically unplugged and something is plugged in, the events will
+ * be received and processed normally.
+ */
+int usb_remove_device(struct usb_device *udev)
+{
+       struct usb_hub *hub;
+       struct usb_interface *intf;
+
+       if (!udev->parent)      /* Can't remove a root hub */
+               return -EINVAL;
+       hub = hdev_to_hub(udev->parent);
+       intf = to_usb_interface(hub->intfdev);
+
+       usb_autopm_get_interface(intf);
+       set_bit(udev->portnum, hub->removed_bits);
+       hub_port_logical_disconnect(hub, udev->portnum);
+       usb_autopm_put_interface(intf);
+       return 0;
+}
+
 enum hub_activation_type {
-       HUB_INIT, HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME
+       HUB_INIT, HUB_INIT2, HUB_INIT3,         /* INITs must come first */
+       HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME,
 };
 
+static void hub_init_func2(struct work_struct *ws);
+static void hub_init_func3(struct work_struct *ws);
+
 static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 {
        struct usb_device *hdev = hub->hdev;
        int port1;
        int status;
        bool need_debounce_delay = false;
+       unsigned delay;
+
+       /* Continue a partial initialization */
+       if (type == HUB_INIT2)
+               goto init2;
+       if (type == HUB_INIT3)
+               goto init3;
 
        /* After a resume, port power should still be on.
         * For any other type of activation, turn it on.
         */
-       if (type != HUB_RESUME)
-               hub_power_on(hub);
+       if (type != HUB_RESUME) {
+
+               /* Speed up system boot by using a delayed_work for the
+                * hub's initial power-up delays.  This is pretty awkward
+                * and the implementation looks like a home-brewed sort of
+                * setjmp/longjmp, but it saves at least 100 ms for each
+                * root hub (assuming usbcore is compiled into the kernel
+                * rather than as a module).  It adds up.
+                *
+                * This can't be done for HUB_RESUME or HUB_RESET_RESUME
+                * because for those activation types the ports have to be
+                * operational when we return.  In theory this could be done
+                * for HUB_POST_RESET, but it's easier not to.
+                */
+               if (type == HUB_INIT) {
+                       delay = hub_power_on(hub, false);
+                       PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func2);
+                       schedule_delayed_work(&hub->init_work,
+                                       msecs_to_jiffies(delay));
+
+                       /* Suppress autosuspend until init is done */
+                       usb_autopm_get_interface_no_resume(
+                                       to_usb_interface(hub->intfdev));
+                       return;         /* Continues at init2: below */
+               } else {
+                       hub_power_on(hub, true);
+               }
+       }
+ init2:
 
        /* Check each port and set hub->change_bits to let khubd know
         * which ports need attention.
@@ -655,6 +761,13 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
                                        USB_PORT_FEAT_C_ENABLE);
                }
 
+               /* We can forget about a "removed" device when there's a
+                * physical disconnect or the connect status changes.
+                */
+               if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
+                               (portchange & USB_PORT_STAT_C_CONNECTION))
+                       clear_bit(port1, hub->removed_bits);
+
                if (!udev || udev->state == USB_STATE_NOTATTACHED) {
                        /* Tell khubd to disconnect the device or
                         * check for a new connection
@@ -692,10 +805,22 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
         * If any port-status changes do occur during this delay, khubd
         * will see them later and handle them normally.
         */
-       if (need_debounce_delay)
-               msleep(HUB_DEBOUNCE_STABLE);
-
+       if (need_debounce_delay) {
+               delay = HUB_DEBOUNCE_STABLE;
+
+               /* Don't do a long sleep inside a workqueue routine */
+               if (type == HUB_INIT2) {
+                       PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3);
+                       schedule_delayed_work(&hub->init_work,
+                                       msecs_to_jiffies(delay));
+                       return;         /* Continues at init3: below */
+               } else {
+                       msleep(delay);
+               }
+       }
+ init3:
        hub->quiescing = 0;
+       hub->init_done = 1;
 
        status = usb_submit_urb(hub->urb, GFP_NOIO);
        if (status < 0)
@@ -705,6 +830,25 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 
        /* Scan all ports that need attention */
        kick_khubd(hub);
+
+       /* Allow autosuspend if it was suppressed */
+       if (type <= HUB_INIT3)
+               usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
+}
+
+/* Implement the continuations for the delays above */
+static void hub_init_func2(struct work_struct *ws)
+{
+       struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work);
+
+       hub_activate(hub, HUB_INIT2);
+}
+
+static void hub_init_func3(struct work_struct *ws)
+{
+       struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work);
+
+       hub_activate(hub, HUB_INIT3);
 }
 
 enum hub_quiescing_type {
@@ -716,6 +860,13 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
        struct usb_device *hdev = hub->hdev;
        int i;
 
+       cancel_delayed_work_sync(&hub->init_work);
+       if (!hub->init_done) {
+               hub->init_done = 1;
+               usb_autopm_put_interface_no_suspend(
+                               to_usb_interface(hub->intfdev));
+       }
+
        /* khubd and related activity won't re-trigger */
        hub->quiescing = 1;
 
@@ -732,7 +883,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
        if (hub->has_indicators)
                cancel_delayed_work_sync(&hub->leds);
        if (hub->tt.hub)
-               cancel_work_sync(&hub->tt.kevent);
+               cancel_work_sync(&hub->tt.clear_work);
 }
 
 /* caller has locked the hub device */
@@ -756,25 +907,23 @@ static int hub_post_reset(struct usb_interface *intf)
 static int hub_configure(struct usb_hub *hub,
        struct usb_endpoint_descriptor *endpoint)
 {
+       struct usb_hcd *hcd;
        struct usb_device *hdev = hub->hdev;
        struct device *hub_dev = hub->intfdev;
        u16 hubstatus, hubchange;
        u16 wHubCharacteristics;
        unsigned int pipe;
        int maxp, ret;
-       char *message;
+       char *message = "out of memory";
 
-       hub->buffer = usb_buffer_alloc(hdev, sizeof(*hub->buffer), GFP_KERNEL,
-                       &hub->buffer_dma);
+       hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL);
        if (!hub->buffer) {
-               message = "can't allocate hub irq buffer";
                ret = -ENOMEM;
                goto fail;
        }
 
        hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL);
        if (!hub->status) {
-               message = "can't kmalloc hub status buffer";
                ret = -ENOMEM;
                goto fail;
        }
@@ -782,7 +931,6 @@ static int hub_configure(struct usb_hub *hub,
 
        hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
        if (!hub->descriptor) {
-               message = "can't kmalloc hub descriptor";
                ret = -ENOMEM;
                goto fail;
        }
@@ -806,6 +954,12 @@ static int hub_configure(struct usb_hub *hub,
        dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild,
                (hdev->maxchild == 1) ? "" : "s");
 
+       hub->port_owners = kzalloc(hdev->maxchild * sizeof(void *), GFP_KERNEL);
+       if (!hub->port_owners) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
        wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
 
        if (wHubCharacteristics & HUB_CHAR_COMPOUND) {
@@ -849,7 +1003,7 @@ static int hub_configure(struct usb_hub *hub,
 
        spin_lock_init (&hub->tt.lock);
        INIT_LIST_HEAD (&hub->tt.clear_list);
-       INIT_WORK (&hub->tt.kevent, hub_tt_kevent);
+       INIT_WORK(&hub->tt.clear_work, hub_tt_work);
        switch (hdev->descriptor.bDeviceProtocol) {
                case 0:
                        break;
@@ -867,6 +1021,9 @@ static int hub_configure(struct usb_hub *hub,
                                        ret);
                        hub->tt.hub = hdev;
                        break;
+               case 3:
+                       /* USB 3.0 hubs don't have a TT */
+                       break;
                default:
                        dev_dbg(hub_dev, "Unrecognized hub protocol %d\n",
                                hdev->descriptor.bDeviceProtocol);
@@ -951,6 +1108,19 @@ static int hub_configure(struct usb_hub *hub,
                dev_dbg(hub_dev, "%umA bus power budget for each child\n",
                                hub->mA_per_port);
 
+       /* Update the HCD's internal representation of this hub before khubd
+        * starts getting port status changes for devices under the hub.
+        */
+       hcd = bus_to_hcd(hdev->bus);
+       if (hcd->driver->update_hub_device) {
+               ret = hcd->driver->update_hub_device(hcd, hdev,
+                               &hub->tt, GFP_KERNEL);
+               if (ret < 0) {
+                       message = "can't update HCD hub info";
+                       goto fail;
+               }
+       }
+
        ret = hub_hub_status(hub, &hubstatus, &hubchange);
        if (ret < 0) {
                message = "can't get hub status";
@@ -981,15 +1151,12 @@ static int hub_configure(struct usb_hub *hub,
 
        hub->urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!hub->urb) {
-               message = "couldn't allocate interrupt urb";
                ret = -ENOMEM;
                goto fail;
        }
 
        usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,
                hub, endpoint->bInterval);
-       hub->urb->transfer_dma = hub->buffer_dma;
-       hub->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
        /* maybe cycle the hub leds */
        if (hub->has_indicators && blinkenlights)
@@ -1021,7 +1188,10 @@ static void hub_disconnect(struct usb_interface *intf)
 
        /* Take the hub off the event list and don't let it be added again */
        spin_lock_irq(&hub_event_lock);
-       list_del_init(&hub->event_list);
+       if (!list_empty(&hub->event_list)) {
+               list_del_init(&hub->event_list);
+               usb_autopm_put_interface_no_suspend(intf);
+       }
        hub->disconnected = 1;
        spin_unlock_irq(&hub_event_lock);
 
@@ -1030,15 +1200,16 @@ static void hub_disconnect(struct usb_interface *intf)
        hub_quiesce(hub, HUB_DISCONNECT);
 
        usb_set_intfdata (intf, NULL);
+       hub->hdev->maxchild = 0;
 
        if (hub->hdev->speed == USB_SPEED_HIGH)
                highspeed_hubs--;
 
        usb_free_urb(hub->urb);
+       kfree(hub->port_owners);
        kfree(hub->descriptor);
        kfree(hub->status);
-       usb_buffer_free(hub->hdev, sizeof(*hub->buffer), hub->buffer,
-                       hub->buffer_dma);
+       kfree(hub->buffer);
 
        kref_put(&hub->kref, hub_release);
 }
@@ -1054,8 +1225,8 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
        hdev = interface_to_usbdev(intf);
 
        if (hdev->level == MAX_TOPO_LEVEL) {
-               dev_err(&intf->dev, "Unsupported bus topology: "
-                               "hub nested too deep\n");
+               dev_err(&intf->dev,
+                       "Unsupported bus topology: hub nested too deep\n");
                return -E2BIG;
        }
 
@@ -1099,6 +1270,7 @@ descriptor_error:
        hub->intfdev = &intf->dev;
        hub->hdev = hdev;
        INIT_DELAYED_WORK(&hub->leds, led_work);
+       INIT_DELAYED_WORK(&hub->init_work, NULL);
        usb_get_intf(intf);
 
        usb_set_intfdata (intf, hub);
@@ -1148,6 +1320,79 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
        }
 }
 
+/*
+ * Allow user programs to claim ports on a hub.  When a device is attached
+ * to one of these "claimed" ports, the program will "own" the device.
+ */
+static int find_port_owner(struct usb_device *hdev, unsigned port1,
+               void ***ppowner)
+{
+       if (hdev->state == USB_STATE_NOTATTACHED)
+               return -ENODEV;
+       if (port1 == 0 || port1 > hdev->maxchild)
+               return -EINVAL;
+
+       /* This assumes that devices not managed by the hub driver
+        * will always have maxchild equal to 0.
+        */
+       *ppowner = &(hdev_to_hub(hdev)->port_owners[port1 - 1]);
+       return 0;
+}
+
+/* In the following three functions, the caller must hold hdev's lock */
+int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, void *owner)
+{
+       int rc;
+       void **powner;
+
+       rc = find_port_owner(hdev, port1, &powner);
+       if (rc)
+               return rc;
+       if (*powner)
+               return -EBUSY;
+       *powner = owner;
+       return rc;
+}
+
+int usb_hub_release_port(struct usb_device *hdev, unsigned port1, void *owner)
+{
+       int rc;
+       void **powner;
+
+       rc = find_port_owner(hdev, port1, &powner);
+       if (rc)
+               return rc;
+       if (*powner != owner)
+               return -ENOENT;
+       *powner = NULL;
+       return rc;
+}
+
+void usb_hub_release_all_ports(struct usb_device *hdev, void *owner)
+{
+       int n;
+       void **powner;
+
+       n = find_port_owner(hdev, 1, &powner);
+       if (n == 0) {
+               for (; n < hdev->maxchild; (++n, ++powner)) {
+                       if (*powner == owner)
+                               *powner = NULL;
+               }
+       }
+}
+
+/* The caller must hold udev's lock */
+bool usb_device_is_owned(struct usb_device *udev)
+{
+       struct usb_hub *hub;
+
+       if (udev->state == USB_STATE_NOTATTACHED || !udev->parent)
+               return false;
+       hub = hdev_to_hub(udev->parent);
+       return !!hub->port_owners[udev->portnum - 1];
+}
+
 
 static void recursively_mark_NOTATTACHED(struct usb_device *udev)
 {
@@ -1220,6 +1465,7 @@ void usb_set_device_state(struct usb_device *udev,
                recursively_mark_NOTATTACHED(udev);
        spin_unlock_irqrestore(&device_state_lock, flags);
 }
+EXPORT_SYMBOL_GPL(usb_set_device_state);
 
 /*
  * WUSB devices are simple: they have no hubs behind, so the mapping
@@ -1237,6 +1483,11 @@ void usb_set_device_state(struct usb_device *udev,
  * 0 is reserved by USB for default address; (b) Linux's USB stack
  * uses always #1 for the root hub of the controller. So USB stack's
  * port #1, which is wusb virtual-port #0 has address #2.
+ *
+ * Devices connected under xHCI are not as simple.  The host controller
+ * supports virtualization, so the hardware assigns device addresses and
+ * the HCD must setup data structures before issuing a set address
+ * command to the hardware.
  */
 static void choose_address(struct usb_device *udev)
 {
@@ -1291,8 +1542,9 @@ static void usb_stop_pm(struct usb_device *udev)
                usb_autosuspend_device(udev->parent);
        usb_pm_unlock(udev);
 
-       /* Stop any autosuspend requests already submitted */
-       cancel_rearming_delayed_work(&udev->autosuspend);
+       /* Stop any autosuspend or autoresume requests already submitted */
+       cancel_delayed_work_sync(&udev->autosuspend);
+       cancel_work_sync(&udev->autoresume);
 }
 
 #else
@@ -1349,18 +1601,14 @@ void usb_disconnect(struct usb_device **pdev)
         */
        dev_dbg (&udev->dev, "unregistering device\n");
        usb_disable_device(udev, 0);
+       usb_hcd_synchronize_unlinks(udev);
 
+       usb_remove_ep_devs(&udev->ep0);
        usb_unlock_device(udev);
 
-       /* Remove the device-specific files from sysfs.  This must be
-        * done with udev unlocked, because some of the attribute
-        * routines try to acquire the device lock.
-        */
-       usb_remove_sysfs_dev_files(udev);
-
        /* Unregister the device.  The device driver is responsible
-        * for removing the device files from usbfs and sysfs and for
-        * de-configuring the device.
+        * for de-configuring the device and invoking the remove-device
+        * notifier chain (used by usbfs and possibly others).
         */
        device_del(&udev->dev);
 
@@ -1392,8 +1640,8 @@ static void announce_device(struct usb_device *udev)
        dev_info(&udev->dev, "New USB device found, idVendor=%04x, idProduct=%04x\n",
                le16_to_cpu(udev->descriptor.idVendor),
                le16_to_cpu(udev->descriptor.idProduct));
-       dev_info(&udev->dev, "New USB device strings: Mfr=%d, Product=%d, "
-               "SerialNumber=%d\n",
+       dev_info(&udev->dev,
+               "New USB device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
                udev->descriptor.iManufacturer,
                udev->descriptor.iProduct,
                udev->descriptor.iSerialNumber);
@@ -1410,12 +1658,12 @@ static inline void announce_device(struct usb_device *udev) { }
 #endif
 
 /**
- * usb_configure_device_otg - FIXME (usbcore-internal)
+ * usb_enumerate_device_otg - FIXME (usbcore-internal)
  * @udev: newly addressed device (in ADDRESS state)
  *
- * Do configuration for On-The-Go devices
+ * Finish enumeration for On-The-Go devices
  */
-static int usb_configure_device_otg(struct usb_device *udev)
+static int usb_enumerate_device_otg(struct usb_device *udev)
 {
        int err = 0;
 
@@ -1428,7 +1676,7 @@ static int usb_configure_device_otg(struct usb_device *udev)
        if (!udev->bus->is_b_host
                        && udev->config
                        && udev->parent == udev->bus->root_hub) {
-               struct usb_otg_descriptor       *desc = 0;
+               struct usb_otg_descriptor       *desc = NULL;
                struct usb_bus                  *bus = udev->bus;
 
                /* descriptor may appear anywhere in config */
@@ -1458,7 +1706,7 @@ static int usb_configure_device_otg(struct usb_device *udev)
                                         * customize to match your product.
                                         */
                                        dev_info(&udev->dev,
-                                               "can't set HNP mode; %d\n",
+                                               "can't set HNP mode: %d\n",
                                                err);
                                        bus->b_hnp_enable = 0;
                                }
@@ -1472,7 +1720,7 @@ static int usb_configure_device_otg(struct usb_device *udev)
                 * (Includes HNP test device.)
                 */
                if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
-                       err = usb_port_suspend(udev);
+                       err = usb_port_suspend(udev, PMSG_SUSPEND);
                        if (err < 0)
                                dev_dbg(&udev->dev, "HNP fail, %d\n", err);
                }
@@ -1486,7 +1734,7 @@ fail:
 
 
 /**
- * usb_configure_device - Detect and probe device intfs/otg (usbcore-internal)
+ * usb_enumerate_device - Read device configs/intfs/otg (usbcore-internal)
  * @udev: newly addressed device (in ADDRESS state)
  *
  * This is only called by usb_new_device() and usb_authorize_device()
@@ -1497,7 +1745,7 @@ fail:
  * the string descriptors, as they will be errored out by the device
  * until it has been authorized.
  */
-static int usb_configure_device(struct usb_device *udev)
+static int usb_enumerate_device(struct usb_device *udev)
 {
        int err;
 
@@ -1521,7 +1769,7 @@ static int usb_configure_device(struct usb_device *udev)
                                                      udev->descriptor.iManufacturer);
                udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
        }
-       err = usb_configure_device_otg(udev);
+       err = usb_enumerate_device_otg(udev);
 fail:
        return err;
 }
@@ -1531,8 +1779,8 @@ fail:
  * usb_new_device - perform initial device setup (usbcore-internal)
  * @udev: newly addressed device (in ADDRESS state)
  *
- * This is called with devices which have been enumerated, but not yet
- * configured.  The device descriptor is available, but not descriptors
+ * This is called with devices which have been detected but not fully
+ * 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
@@ -1551,21 +1799,27 @@ int usb_new_device(struct usb_device *udev)
 {
        int err;
 
-       usb_detect_quirks(udev);                /* Determine quirks */
-       err = usb_configure_device(udev);       /* detect & probe dev/intfs */
+       /* Increment the parent's count of unsuspended children */
+       if (udev->parent)
+               usb_autoresume_device(udev->parent);
+
+       usb_detect_quirks(udev);
+       err = usb_enumerate_device(udev);       /* Read descriptors */
        if (err < 0)
                goto fail;
+       dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",
+                       udev->devnum, udev->bus->busnum,
+                       (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
        /* export the usbdev device-node for libusb */
        udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,
                        (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
 
-       /* Increment the parent's count of unsuspended children */
-       if (udev->parent)
-               usb_autoresume_device(udev->parent);
+       /* Tell the world! */
+       announce_device(udev);
 
        /* Register the device.  The device driver is responsible
-        * for adding the device files to sysfs and for configuring
-        * the device.
+        * for configuring the device and invoking the add-device
+        * notifier chain (used by usbfs and possibly others).
         */
        err = device_add(&udev->dev);
        if (err) {
@@ -1573,15 +1827,12 @@ int usb_new_device(struct usb_device *udev)
                goto fail;
        }
 
-       /* put device-specific files into sysfs */
-       usb_create_sysfs_dev_files(udev);
-
-       /* Tell the world! */
-       announce_device(udev);
+       (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);
        return err;
 
 fail:
        usb_set_device_state(udev, USB_STATE_NOTATTACHED);
+       usb_stop_pm(udev);
        return err;
 }
 
@@ -1598,21 +1849,23 @@ fail:
  */
 int usb_deauthorize_device(struct usb_device *usb_dev)
 {
-       unsigned cnt;
        usb_lock_device(usb_dev);
        if (usb_dev->authorized == 0)
                goto out_unauthorized;
+
        usb_dev->authorized = 0;
        usb_set_configuration(usb_dev, -1);
+
+       kfree(usb_dev->product);
        usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
+       kfree(usb_dev->manufacturer);
        usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
+       kfree(usb_dev->serial);
        usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
-       kfree(usb_dev->config);
-       usb_dev->config = NULL;
-       for (cnt = 0; cnt < usb_dev->descriptor.bNumConfigurations; cnt++)
-               kfree(usb_dev->rawdescriptors[cnt]);
+
+       usb_destroy_configuration(usb_dev);
        usb_dev->descriptor.bNumConfigurations = 0;
-       kfree(usb_dev->rawdescriptors);
+
 out_unauthorized:
        usb_unlock_device(usb_dev);
        return 0;
@@ -1622,15 +1875,11 @@ out_unauthorized:
 int usb_authorize_device(struct usb_device *usb_dev)
 {
        int result = 0, c;
+
        usb_lock_device(usb_dev);
        if (usb_dev->authorized == 1)
                goto out_authorized;
-       kfree(usb_dev->product);
-       usb_dev->product = NULL;
-       kfree(usb_dev->manufacturer);
-       usb_dev->manufacturer = NULL;
-       kfree(usb_dev->serial);
-       usb_dev->serial = NULL;
+
        result = usb_autoresume_device(usb_dev);
        if (result < 0) {
                dev_err(&usb_dev->dev,
@@ -1643,10 +1892,18 @@ int usb_authorize_device(struct usb_device *usb_dev)
                        "authorization: %d\n", result);
                goto error_device_descriptor;
        }
+
+       kfree(usb_dev->product);
+       usb_dev->product = NULL;
+       kfree(usb_dev->manufacturer);
+       usb_dev->manufacturer = NULL;
+       kfree(usb_dev->serial);
+       usb_dev->serial = NULL;
+
        usb_dev->authorized = 1;
-       result = usb_configure_device(usb_dev);
+       result = usb_enumerate_device(usb_dev);
        if (result < 0)
-               goto error_configure;
+               goto error_enumerate;
        /* Choose and set the configuration.  This registers the interfaces
         * with the driver core and lets interface drivers bind to them.
         */
@@ -1661,8 +1918,10 @@ int usb_authorize_device(struct usb_device *usb_dev)
                }
        }
        dev_info(&usb_dev->dev, "authorized to connect\n");
-error_configure:
+
+error_enumerate:
 error_device_descriptor:
+       usb_autosuspend_device(usb_dev);
 error_autoresume:
 out_authorized:
        usb_unlock_device(usb_dev);     // complements locktree
@@ -1898,7 +2157,7 @@ static int check_port_resume_type(struct usb_device *udev,
  *
  * Returns 0 on success, else negative errno.
  */
-int usb_port_suspend(struct usb_device *udev)
+int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
 {
        struct usb_hub  *hub = hdev_to_hub(udev->parent);
        int             port1 = udev->portnum;
@@ -1918,9 +2177,13 @@ int usb_port_suspend(struct usb_device *udev)
                                USB_DEVICE_REMOTE_WAKEUP, 0,
                                NULL, 0,
                                USB_CTRL_SET_TIMEOUT);
-               if (status)
+               if (status) {
                        dev_dbg(&udev->dev, "won't remote wakeup, status %d\n",
                                        status);
+                       /* bail if autosuspend is requested */
+                       if (msg.event & PM_EVENT_AUTO)
+                               return status;
+               }
        }
 
        /* see 7.1.7.6 */
@@ -1929,7 +2192,8 @@ int usb_port_suspend(struct usb_device *udev)
                dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
                                port1, status);
                /* paranoia:  "should not happen" */
-               (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+               if (udev->do_remote_wakeup)
+                       (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE,
                                USB_DEVICE_REMOTE_WAKEUP, 0,
                                NULL, 0,
@@ -1937,7 +2201,7 @@ int usb_port_suspend(struct usb_device *udev)
        } else {
                /* device has up to 10 msec to fully suspend */
                dev_dbg(&udev->dev, "usb %ssuspend\n",
-                               udev->auto_pm ? "auto-" : "");
+                               (msg.event & PM_EVENT_AUTO ? "auto-" : ""));
                usb_set_device_state(udev, USB_STATE_SUSPENDED);
                msleep(10);
        }
@@ -1961,8 +2225,8 @@ static int finish_port_resume(struct usb_device *udev)
        u16     devstatus;
 
        /* caller owns the udev device lock */
-       dev_dbg(&udev->dev, "finish %sresume\n",
-                       udev->reset_resume ? "reset-" : "");
+       dev_dbg(&udev->dev, "%s\n",
+               udev->reset_resume ? "finish reset-resume" : "finish resume");
 
        /* usb ch9 identifies four variants of SUSPENDED, based on what
         * state the device resumes to.  Linux currently won't see the
@@ -2014,8 +2278,9 @@ static int finish_port_resume(struct usb_device *udev)
                                        NULL, 0,
                                        USB_CTRL_SET_TIMEOUT);
                        if (status)
-                               dev_dbg(&udev->dev, "disable remote "
-                                       "wakeup, status %d\n", status);
+                               dev_dbg(&udev->dev,
+                                       "disable remote wakeup, status %d\n",
+                                       status);
                }
                status = 0;
        }
@@ -2056,7 +2321,7 @@ static int finish_port_resume(struct usb_device *udev)
  *
  * Returns 0 on success, else negative errno.
  */
-int usb_port_resume(struct usb_device *udev)
+int usb_port_resume(struct usb_device *udev, pm_message_t msg)
 {
        struct usb_hub  *hub = hdev_to_hub(udev->parent);
        int             port1 = udev->portnum;
@@ -2081,7 +2346,7 @@ int usb_port_resume(struct usb_device *udev)
        } else {
                /* drive resume for at least 20 msec */
                dev_dbg(&udev->dev, "usb %sresume\n",
-                               udev->auto_pm ? "auto-" : "");
+                               (msg.event & PM_EVENT_AUTO ? "auto-" : ""));
                msleep(25);
 
                /* Virtual root hubs can trigger on GET_PORT_STATUS to
@@ -2122,7 +2387,7 @@ static int remote_wakeup(struct usb_device *udev)
        if (udev->state == USB_STATE_SUSPENDED) {
                dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-");
                usb_mark_last_busy(udev);
-               status = usb_external_resume_device(udev);
+               status = usb_external_resume_device(udev, PMSG_REMOTE_RESUME);
        }
        return status;
 }
@@ -2131,14 +2396,14 @@ static int remote_wakeup(struct usb_device *udev)
 
 /* When CONFIG_USB_SUSPEND isn't set, we never suspend or resume any ports. */
 
-int usb_port_suspend(struct usb_device *udev)
+int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
 {
        return 0;
 }
 
 /* However we may need to do a reset-resume */
 
-int usb_port_resume(struct usb_device *udev)
+int usb_port_resume(struct usb_device *udev, pm_message_t msg)
 {
        struct usb_hub  *hub = hdev_to_hub(udev->parent);
        int             port1 = udev->portnum;
@@ -2178,7 +2443,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
 
                udev = hdev->children [port1-1];
                if (udev && udev->can_submit) {
-                       if (!hdev->auto_pm)
+                       if (!(msg.event & PM_EVENT_AUTO))
                                dev_dbg(&intf->dev, "port %d nyet suspended\n",
                                                port1);
                        return -EBUSY;
@@ -2299,9 +2564,9 @@ static int hub_port_debounce(struct usb_hub *hub, int port1)
 
 void usb_ep0_reinit(struct usb_device *udev)
 {
-       usb_disable_endpoint(udev, 0 + USB_DIR_IN);
-       usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
-       usb_enable_endpoint(udev, &udev->ep0);
+       usb_disable_endpoint(udev, 0 + USB_DIR_IN, true);
+       usb_disable_endpoint(udev, 0 + USB_DIR_OUT, true);
+       usb_enable_endpoint(udev, &udev->ep0, true);
 }
 EXPORT_SYMBOL_GPL(usb_ep0_reinit);
 
@@ -2311,19 +2576,29 @@ EXPORT_SYMBOL_GPL(usb_ep0_reinit);
 static int hub_set_address(struct usb_device *udev, int devnum)
 {
        int retval;
+       struct usb_hcd *hcd = bus_to_hcd(udev->bus);
 
-       if (devnum <= 1)
+       /*
+        * The host controller will choose the device address,
+        * instead of the core having chosen it earlier
+        */
+       if (!hcd->driver->address_device && devnum <= 1)
                return -EINVAL;
        if (udev->state == USB_STATE_ADDRESS)
                return 0;
        if (udev->state != USB_STATE_DEFAULT)
                return -EINVAL;
-       retval = usb_control_msg(udev, usb_sndaddr0pipe(),
-               USB_REQ_SET_ADDRESS, 0, devnum, 0,
-               NULL, 0, USB_CTRL_SET_TIMEOUT);
+       if (hcd->driver->address_device) {
+               retval = hcd->driver->address_device(hcd, udev);
+       } else {
+               retval = usb_control_msg(udev, usb_sndaddr0pipe(),
+                               USB_REQ_SET_ADDRESS, 0, devnum, 0,
+                               NULL, 0, USB_CTRL_SET_TIMEOUT);
+               if (retval == 0)
+                       update_address(udev, devnum);
+       }
        if (retval == 0) {
                /* Device now using proper address. */
-               update_address(udev, devnum);
                usb_set_device_state(udev, USB_STATE_ADDRESS);
                usb_ep0_reinit(udev);
        }
@@ -2346,6 +2621,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
        static DEFINE_MUTEX(usb_address0_mutex);
 
        struct usb_device       *hdev = hub->hdev;
+       struct usb_hcd          *hcd = bus_to_hcd(hdev->bus);
        int                     i, j, retval;
        unsigned                delay = HUB_SHORT_RESET_TIME;
        enum usb_device_speed   oldspeed = udev->speed;
@@ -2368,11 +2644,24 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
 
        mutex_lock(&usb_address0_mutex);
 
-       /* Reset the device; full speed may morph to high speed */
-       retval = hub_port_reset(hub, port1, udev, delay);
-       if (retval < 0)         /* error or disconnect */
+       if ((hcd->driver->flags & HCD_USB3) && udev->config) {
+               /* FIXME this will need special handling by the xHCI driver. */
+               dev_dbg(&udev->dev,
+                               "xHCI reset of configured device "
+                               "not supported yet.\n");
+               retval = -EINVAL;
                goto fail;
-                               /* success, speed is known */
+       } else if (!udev->config && oldspeed == USB_SPEED_SUPER) {
+               /* Don't reset USB 3.0 devices during an initial setup */
+               usb_set_device_state(udev, USB_STATE_DEFAULT);
+       } else {
+               /* Reset the device; full speed may morph to high speed */
+               /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */
+               retval = hub_port_reset(hub, port1, udev, delay);
+               if (retval < 0)         /* error or disconnect */
+                       goto fail;
+               /* success, speed is known */
+       }
        retval = -ENODEV;
 
        if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) {
@@ -2387,21 +2676,22 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
         * reported as 0xff in the device descriptor). WUSB1.0[4.8.1].
         */
        switch (udev->speed) {
+       case USB_SPEED_SUPER:
        case USB_SPEED_VARIABLE:        /* fixed at 512 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(512);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
                break;
        case USB_SPEED_HIGH:            /* fixed at 64 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
                break;
        case USB_SPEED_FULL:            /* 8, 16, 32, or 64 */
                /* to determine the ep0 maxpacket size, try to read
                 * the device descriptor to get bMaxPacketSize0 and
                 * then correct our initial guess.
                 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
                break;
        case USB_SPEED_LOW:             /* fixed at 8 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
                break;
        default:
                goto fail;
@@ -2412,16 +2702,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
        case USB_SPEED_LOW:     speed = "low";  break;
        case USB_SPEED_FULL:    speed = "full"; break;
        case USB_SPEED_HIGH:    speed = "high"; break;
+       case USB_SPEED_SUPER:
+                               speed = "super";
+                               break;
        case USB_SPEED_VARIABLE:
                                speed = "variable";
                                type = "Wireless ";
                                break;
        default:                speed = "?";    break;
        }
-       dev_info (&udev->dev,
-                 "%s %s speed %sUSB device using %s and address %d\n",
-                 (udev->config) ? "reset" : "new", speed, type,
-                 udev->bus->controller->driver->name, devnum);
+       if (udev->speed != USB_SPEED_SUPER)
+               dev_info(&udev->dev,
+                               "%s %s speed %sUSB device using %s and address %d\n",
+                               (udev->config) ? "reset" : "new", speed, type,
+                               udev->bus->controller->driver->name, devnum);
 
        /* Set up TT records, if needed  */
        if (hdev->tt) {
@@ -2446,7 +2740,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
         * value.
         */
        for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
-               if (USE_NEW_SCHEME(retry_counter)) {
+               /*
+                * An xHCI controller cannot send any packets to a device until
+                * a set address command successfully completes.
+                */
+               if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) {
                        struct usb_device_descriptor *buf;
                        int r = 0;
 
@@ -2467,7 +2765,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                                        USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
                                        USB_DT_DEVICE << 8, 0,
                                        buf, GET_DESCRIPTOR_BUFSIZE,
-                                       USB_CTRL_GET_TIMEOUT);
+                                       initial_descriptor_timeout);
                                switch (buf->bMaxPacketSize0) {
                                case 8: case 16: case 32: case 64: case 255:
                                        if (buf->bDescriptorType ==
@@ -2498,9 +2796,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                                goto fail;
                        }
                        if (r) {
-                               dev_err(&udev->dev, "device descriptor "
-                                               "read/%s, error %d\n",
-                                               "64", r);
+                               dev_err(&udev->dev,
+                                       "device descriptor read/64, error %d\n",
+                                       r);
                                retval = -EMSGSIZE;
                                continue;
                        }
@@ -2512,7 +2810,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                 * unauthorized address in the Connect Ack sequence;
                 * authorization will assign the final address.
                 */
-               if (udev->wusb == 0) {
+               if (udev->wusb == 0) {
                        for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
                                retval = hub_set_address(udev, devnum);
                                if (retval >= 0)
@@ -2525,21 +2823,28 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                                        devnum, retval);
                                goto fail;
                        }
+                       if (udev->speed == USB_SPEED_SUPER) {
+                               devnum = udev->devnum;
+                               dev_info(&udev->dev,
+                                               "%s SuperSpeed USB device using %s and address %d\n",
+                                               (udev->config) ? "reset" : "new",
+                                               udev->bus->controller->driver->name, devnum);
+                       }
 
                        /* cope with hardware quirkiness:
                         *  - let SET_ADDRESS settle, some device hardware wants it
                         *  - read ep0 maxpacket even for high and low speed,
                         */
                        msleep(10);
-                       if (USE_NEW_SCHEME(retry_counter))
+                       if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3))
                                break;
                }
 
                retval = usb_get_device_descriptor(udev, 8);
                if (retval < 8) {
-                       dev_err(&udev->dev, "device descriptor "
-                                       "read/%s, error %d\n",
-                                       "8", retval);
+                       dev_err(&udev->dev,
+                                       "device descriptor read/8, error %d\n",
+                                       retval);
                        if (retval >= 0)
                                retval = -EMSGSIZE;
                } else {
@@ -2550,8 +2855,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
        if (retval)
                goto fail;
 
-       i = udev->descriptor.bMaxPacketSize0 == 0xff?   /* wusb device? */
-           512 : udev->descriptor.bMaxPacketSize0;
+       if (udev->descriptor.bMaxPacketSize0 == 0xff ||
+                       udev->speed == USB_SPEED_SUPER)
+               i = 512;
+       else
+               i = udev->descriptor.bMaxPacketSize0;
        if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {
                if (udev->speed != USB_SPEED_FULL ||
                                !(i == 8 || i == 16 || i == 32 || i == 64)) {
@@ -2566,8 +2874,8 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
   
        retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
        if (retval < (signed)sizeof(udev->descriptor)) {
-               dev_err(&udev->dev, "device descriptor read/%s, error %d\n",
-                       "all", retval);
+               dev_err(&udev->dev, "device descriptor read/all, error %d\n",
+                       retval);
                if (retval >= 0)
                        retval = -ENOMSG;
                goto fail;
@@ -2635,9 +2943,9 @@ hub_power_remaining (struct usb_hub *hub)
                else
                        delta = 8;
                if (delta > hub->mA_per_port)
-                       dev_warn(&udev->dev, "%dmA is over %umA budget "
-                                       "for port %d!\n",
-                                       delta, hub->mA_per_port, port1);
+                       dev_warn(&udev->dev,
+                                "%dmA is over %umA budget for port %d!\n",
+                                delta, hub->mA_per_port, port1);
                remaining -= delta;
        }
        if (remaining < 0) {
@@ -2683,50 +2991,25 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                                USB_PORT_STAT_C_ENABLE);
 #endif
 
-       /* Try to use the debounce delay for protection against
-        * port-enable changes caused, for example, by EMI.
-        */
-       if (portchange & (USB_PORT_STAT_C_CONNECTION |
-                               USB_PORT_STAT_C_ENABLE)) {
-               status = hub_port_debounce(hub, port1);
-               if (status < 0) {
-                       if (printk_ratelimit())
-                               dev_err (hub_dev, "connect-debounce failed, "
-                                               "port %d disabled\n", port1);
-                       portstatus &= ~USB_PORT_STAT_CONNECTION;
-               } else {
-                       portstatus = status;
-               }
-       }
-
        /* Try to resuscitate an existing device */
        udev = hdev->children[port1-1];
        if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
                        udev->state != USB_STATE_NOTATTACHED) {
-
                usb_lock_device(udev);
                if (portstatus & USB_PORT_STAT_ENABLE) {
                        status = 0;             /* Nothing to do */
-               } else if (!udev->persist_enabled) {
-                       status = -ENODEV;       /* Mustn't resuscitate */
 
 #ifdef CONFIG_USB_SUSPEND
-               } else if (udev->state == USB_STATE_SUSPENDED) {
+               } else if (udev->state == USB_STATE_SUSPENDED &&
+                               udev->persist_enabled) {
                        /* For a suspended device, treat this as a
                         * remote wakeup event.
                         */
-                       if (udev->do_remote_wakeup)
-                               status = remote_wakeup(udev);
-
-                       /* Otherwise leave it be; devices can't tell the
-                        * difference between suspended and disabled.
-                        */
-                       else
-                               status = 0;
+                       status = remote_wakeup(udev);
 #endif
 
                } else {
-                       status = usb_reset_device(udev);
+                       status = -ENODEV;       /* Don't resuscitate */
                }
                usb_unlock_device(udev);
 
@@ -2741,14 +3024,37 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                usb_disconnect(&hdev->children[port1-1]);
        clear_bit(port1, hub->change_bits);
 
-       /* Return now if debouncing failed or nothing is connected */
-       if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
+       /* We can forget about a "removed" device when there's a physical
+        * disconnect or the connect status changes.
+        */
+       if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
+                       (portchange & USB_PORT_STAT_C_CONNECTION))
+               clear_bit(port1, hub->removed_bits);
+
+       if (portchange & (USB_PORT_STAT_C_CONNECTION |
+                               USB_PORT_STAT_C_ENABLE)) {
+               status = hub_port_debounce(hub, port1);
+               if (status < 0) {
+                       if (printk_ratelimit())
+                               dev_err(hub_dev, "connect-debounce failed, "
+                                               "port %d disabled\n", port1);
+                       portstatus &= ~USB_PORT_STAT_CONNECTION;
+               } else {
+                       portstatus = status;
+               }
+       }
+
+       /* Return now if debouncing failed or nothing is connected or
+        * the device was "removed".
+        */
+       if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
+                       test_bit(port1, hub->removed_bits)) {
 
                /* maybe switch power back on (e.g. root hub was reset) */
                if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2
                                && !(portstatus & (1 << USB_PORT_FEAT_POWER)))
                        set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+
                if (portstatus & USB_PORT_STAT_ENABLE)
                        goto done;
                return;
@@ -2768,19 +3074,41 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                }
 
                usb_set_device_state(udev, USB_STATE_POWERED);
-               udev->speed = USB_SPEED_UNKNOWN;
                udev->bus_mA = hub->mA_per_port;
                udev->level = hdev->level + 1;
                udev->wusb = hub_is_wusb(hub);
 
-               /* set the address */
-               choose_address(udev);
-               if (udev->devnum <= 0) {
-                       status = -ENOTCONN;     /* Don't retry */
-                       goto loop;
+               /*
+                * USB 3.0 devices are reset automatically before the connect
+                * port status change appears, and the root hub port status
+                * shows the correct speed.  We also get port change
+                * notifications for USB 3.0 devices from the USB 3.0 portion of
+                * an external USB 3.0 hub, but this isn't handled correctly yet
+                * FIXME.
+                */
+
+               if (!(hcd->driver->flags & HCD_USB3))
+                       udev->speed = USB_SPEED_UNKNOWN;
+               else if ((hdev->parent == NULL) &&
+                               (portstatus & (1 << USB_PORT_FEAT_SUPERSPEED)))
+                       udev->speed = USB_SPEED_SUPER;
+               else
+                       udev->speed = USB_SPEED_UNKNOWN;
+
+               /*
+                * xHCI needs to issue an address device command later
+                * in the hub_port_init sequence for SS/HS/FS/LS devices.
+                */
+               if (!(hcd->driver->flags & HCD_USB3)) {
+                       /* set the address */
+                       choose_address(udev);
+                       if (udev->devnum <= 0) {
+                               status = -ENOTCONN;     /* Don't retry */
+                               goto loop;
+                       }
                }
 
-               /* reset and get descriptor */
+               /* reset (non-USB 3.0 devices) and get descriptor */
                status = hub_port_init(hub, udev, port1, i);
                if (status < 0)
                        goto loop;
@@ -2930,7 +3258,7 @@ static void hub_events(void)
                 * disconnected while waiting for the lock to succeed. */
                usb_lock_device(hdev);
                if (unlikely(hub->disconnected))
-                       goto loop;
+                       goto loop2;
 
                /* If the hub has died, clean up after it */
                if (hdev->state == USB_STATE_NOTATTACHED) {
@@ -3019,6 +3347,9 @@ static void hub_events(void)
                                        USB_PORT_FEAT_C_SUSPEND);
                                udev = hdev->children[i-1];
                                if (udev) {
+                                       /* TRSMRCY = 10 msec */
+                                       msleep(10);
+
                                        usb_lock_device(udev);
                                        ret = remote_wakeup(hdev->
                                                        children[i-1]);
@@ -3040,7 +3371,7 @@ static void hub_events(void)
                                        i);
                                clear_port_feature(hdev, i,
                                        USB_PORT_FEAT_C_OVER_CURRENT);
-                               hub_power_on(hub);
+                               hub_power_on(hub, true);
                        }
 
                        if (portchange & USB_PORT_STAT_C_RESET) {
@@ -3075,15 +3406,19 @@ static void hub_events(void)
                                dev_dbg (hub_dev, "overcurrent change\n");
                                msleep(500);    /* Cool down */
                                clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
-                               hub_power_on(hub);
+                               hub_power_on(hub, true);
                        }
                }
 
-loop_autopm:
-               /* Allow autosuspend if we're not going to run again */
-               if (list_empty(&hub->event_list))
-                       usb_autopm_enable(intf);
-loop:
+ loop_autopm:
+               /* Balance the usb_autopm_get_interface() above */
+               usb_autopm_put_interface_no_suspend(intf);
+ loop:
+               /* Balance the usb_autopm_get_interface_no_resume() in
+                * kick_khubd() and allow autosuspend.
+                */
+               usb_autopm_put_interface(intf);
+ loop2:
                usb_unlock_device(hdev);
                kref_put(&hub->kref, hub_release);
 
@@ -3275,6 +3610,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
 {
        struct usb_device               *parent_hdev = udev->parent;
        struct usb_hub                  *parent_hub;
+       struct usb_hcd                  *hcd = bus_to_hcd(udev->bus);
        struct usb_device_descriptor    descriptor = udev->descriptor;
        int                             i, ret = 0;
        int                             port1 = udev->portnum;
@@ -3314,10 +3650,20 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
                udev->descriptor = descriptor;  /* for disconnect() calls */
                goto re_enumerate;
        }
-  
+
+       /* Restore the device's previous configuration */
        if (!udev->actconfig)
                goto done;
 
+       mutex_lock(&hcd->bandwidth_mutex);
+       ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL);
+       if (ret < 0) {
+               dev_warn(&udev->dev,
+                               "Busted HC?  Not enough HCD resources for "
+                               "old configuration.\n");
+               mutex_unlock(&hcd->bandwidth_mutex);
+               goto re_enumerate;
+       }
        ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                        USB_REQ_SET_CONFIGURATION, 0,
                        udev->actconfig->desc.bConfigurationValue, 0,
@@ -3326,20 +3672,43 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
                dev_err(&udev->dev,
                        "can't restore configuration #%d (error=%d)\n",
                        udev->actconfig->desc.bConfigurationValue, ret);
+               mutex_unlock(&hcd->bandwidth_mutex);
                goto re_enumerate;
        }
+       mutex_unlock(&hcd->bandwidth_mutex);
        usb_set_device_state(udev, USB_STATE_CONFIGURED);
 
+       /* Put interfaces back into the same altsettings as before.
+        * Don't bother to send the Set-Interface request for interfaces
+        * that were already in altsetting 0; besides being unnecessary,
+        * many devices can't handle it.  Instead just reset the host-side
+        * endpoint state.
+        */
        for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
-               struct usb_interface *intf = udev->actconfig->interface[i];
+               struct usb_host_config *config = udev->actconfig;
+               struct usb_interface *intf = config->interface[i];
                struct usb_interface_descriptor *desc;
 
-               /* set_interface resets host side toggle even
-                * for altsetting zero.  the interface may have no driver.
-                */
                desc = &intf->cur_altsetting->desc;
-               ret = usb_set_interface(udev, desc->bInterfaceNumber,
-                       desc->bAlternateSetting);
+               if (desc->bAlternateSetting == 0) {
+                       usb_disable_interface(udev, intf, true);
+                       usb_enable_interface(udev, intf, true);
+                       ret = 0;
+               } else {
+                       /* We've just reset the device, so it will think alt
+                        * setting 0 is installed.  For usb_set_interface() to
+                        * work properly, we need to set the current alternate
+                        * interface setting to 0 (or the first alt setting, if
+                        * the device doesn't have alt setting 0).
+                        */
+                       intf->cur_altsetting =
+                               usb_find_alt_setting(config, i, 0);
+                       if (!intf->cur_altsetting)
+                               intf->cur_altsetting =
+                                       &config->intf_cache[i]->altsetting[0];
+                       ret = usb_set_interface(udev, desc->bInterfaceNumber,
+                                       desc->bAlternateSetting);
+               }
                if (ret < 0) {
                        dev_err(&udev->dev, "failed to restore interface %d "
                                "altsetting %d (error=%d)\n",
@@ -3429,7 +3798,7 @@ int usb_reset_device(struct usb_device *udev)
                                                USB_INTERFACE_BOUND)
                                        rebind = 1;
                        }
-                       if (rebind)
+                       if (ret == 0 && rebind)
                                usb_rebind_intf(cintf);
                }
        }
@@ -3438,3 +3807,46 @@ int usb_reset_device(struct usb_device *udev)
        return ret;
 }
 EXPORT_SYMBOL_GPL(usb_reset_device);
+
+
+/**
+ * usb_queue_reset_device - Reset a USB device from an atomic context
+ * @iface: USB interface belonging to the device to reset
+ *
+ * This function can be used to reset a USB device from an atomic
+ * context, where usb_reset_device() won't work (as it blocks).
+ *
+ * Doing a reset via this method is functionally equivalent to calling
+ * usb_reset_device(), except for the fact that it is delayed to a
+ * workqueue. This means that any drivers bound to other interfaces
+ * might be unbound, as well as users from usbfs in user space.
+ *
+ * Corner cases:
+ *
+ * - Scheduling two resets at the same time from two different drivers
+ *   attached to two different interfaces of the same device is
+ *   possible; depending on how the driver attached to each interface
+ *   handles ->pre_reset(), the second reset might happen or not.
+ *
+ * - If a driver is unbound and it had a pending reset, the reset will
+ *   be cancelled.
+ *
+ * - This function can be called during .probe() or .disconnect()
+ *   times. On return from .disconnect(), any pending resets will be
+ *   cancelled.
+ *
+ * There is no no need to lock/unlock the @reset_ws as schedule_work()
+ * does its own.
+ *
+ * NOTE: We don't do any reference count tracking because it is not
+ *     needed. The lifecycle of the work_struct is tied to the
+ *     usb_interface. Before destroying the interface we cancel the
+ *     work_struct, so the fact that work_struct is queued and or
+ *     running means the interface (and thus, the device) exist and
+ *     are referenced.
+ */
+void usb_queue_reset_device(struct usb_interface *iface)
+{
+       schedule_work(&iface->reset_ws);
+}
+EXPORT_SYMBOL_GPL(usb_queue_reset_device);