]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.7-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 15 Jan 2013 13:01:04 +0000 (05:01 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 15 Jan 2013 13:01:04 +0000 (05:01 -0800)
added patches:
usb-add-device-quirk-for-microsoft-vx700-webcam.patch
usb-allow-usb-3.0-ports-to-be-disabled.patch
usb-handle-auto-transition-from-hot-to-warm-reset.patch
usb-handle-warm-reset-failure-on-empty-port.patch
usb-ignore-port-state-until-reset-completes.patch
usb-ignore-xhci-reset-device-status.patch
usb-increase-reset-timeout.patch

queue-3.7/series
queue-3.7/usb-add-device-quirk-for-microsoft-vx700-webcam.patch [new file with mode: 0644]
queue-3.7/usb-allow-usb-3.0-ports-to-be-disabled.patch [new file with mode: 0644]
queue-3.7/usb-handle-auto-transition-from-hot-to-warm-reset.patch [new file with mode: 0644]
queue-3.7/usb-handle-warm-reset-failure-on-empty-port.patch [new file with mode: 0644]
queue-3.7/usb-ignore-port-state-until-reset-completes.patch [new file with mode: 0644]
queue-3.7/usb-ignore-xhci-reset-device-status.patch [new file with mode: 0644]
queue-3.7/usb-increase-reset-timeout.patch [new file with mode: 0644]

index a47150b04d61eedbf89afa635817e93b92d4e141..479b430ca60e8f37117a7a0c37e2f18bc844129a 100644 (file)
@@ -167,3 +167,10 @@ drm-nouveau-fix-blank-lvds-screen-regression-on-pre-nv50-cards.patch
 drm-nouveau-add-locking-around-instobj-list-operations.patch
 drm-nouveau-clock-fix-support-for-more-than-2-monitors-on-nve0.patch
 drm-nvc0-fb-fix-crash-when-different-mutex-is-used-to-protect-same-list.patch
+usb-handle-auto-transition-from-hot-to-warm-reset.patch
+usb-add-device-quirk-for-microsoft-vx700-webcam.patch
+usb-ignore-xhci-reset-device-status.patch
+usb-allow-usb-3.0-ports-to-be-disabled.patch
+usb-increase-reset-timeout.patch
+usb-ignore-port-state-until-reset-completes.patch
+usb-handle-warm-reset-failure-on-empty-port.patch
diff --git a/queue-3.7/usb-add-device-quirk-for-microsoft-vx700-webcam.patch b/queue-3.7/usb-add-device-quirk-for-microsoft-vx700-webcam.patch
new file mode 100644 (file)
index 0000000..a2ca2f8
--- /dev/null
@@ -0,0 +1,31 @@
+From bc009eca8d539162f7271c2daf0ab5e9e3bb90a0 Mon Sep 17 00:00:00 2001
+From: Andreas Fleig <andreasfleig@gmail.com>
+Date: Wed, 5 Dec 2012 16:17:49 +0100
+Subject: USB: Add device quirk for Microsoft VX700 webcam
+
+From: Andreas Fleig <andreasfleig@gmail.com>
+
+commit bc009eca8d539162f7271c2daf0ab5e9e3bb90a0 upstream.
+
+Add device quirk for Microsoft Lifecam VX700 v2.0 webcams.
+Fixes squeaking noise of the microphone.
+
+Signed-off-by: Andreas Fleig <andreasfleig@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -43,6 +43,9 @@ static const struct usb_device_id usb_qu
+       /* Creative SB Audigy 2 NX */
+       { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
++      /* Microsoft LifeCam-VX700 v2.0 */
++      { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
++
+       /* Logitech Quickcam Fusion */
+       { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
diff --git a/queue-3.7/usb-allow-usb-3.0-ports-to-be-disabled.patch b/queue-3.7/usb-allow-usb-3.0-ports-to-be-disabled.patch
new file mode 100644 (file)
index 0000000..b6ee7d3
--- /dev/null
@@ -0,0 +1,170 @@
+From 41e7e056cdc662f704fa9262e5c6e213b4ab45dd Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Wed, 14 Nov 2012 16:42:32 -0800
+Subject: USB: Allow USB 3.0 ports to be disabled.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 41e7e056cdc662f704fa9262e5c6e213b4ab45dd upstream.
+
+If hot and warm reset fails, or a port remains in the Compliance Mode,
+the USB core needs to be able to disable a USB 3.0 port.  Unlike USB 2.0
+ports, once the port is placed into the Disabled link state, it will not
+report any new device connects.  To get device connect notifications, we
+need to put the link into the Disabled state, and then the RxDetect
+state.
+
+The xHCI driver needs to atomically clear all change bits on USB 3.0
+port disable, so that we get Port Status Change Events for future port
+changes.  We could technically do this in the USB core instead of in the
+xHCI roothub code, since the port state machine can't advance out of the
+disabled state until we set the link state to RxDetect.  However,
+external USB 3.0 hubs don't need this code.  They are level-triggered,
+not edge-triggered like xHCI, so they will continue to send interrupt
+events when any change bit is set.  Therefore it doesn't make sense to
+put this code in the USB core.
+
+This patch is part of a series to fix several reports of infinite loops
+on device enumeration failure.  This includes John, when he boots with
+a USB 3.0 device (Roseweil eusb3 enclosure) attached to his NEC 0.96
+host controller.  The fix requires warm reset support, so it does not
+make sense to backport this patch to stable kernels without warm reset
+support.
+
+This patch should be backported to kernels as old as 3.2, contain the
+commit ID 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine warm
+reset logic"
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-by: John Covici <covici@ccs.covici.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c      |   63 ++++++++++++++++++++++++++++++++++++++++++--
+ drivers/usb/host/xhci-hub.c |   31 ++++++++++++++++++++-
+ 2 files changed, 90 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -876,6 +876,60 @@ static int hub_hub_status(struct usb_hub
+       return ret;
+ }
++static int hub_set_port_link_state(struct usb_hub *hub, int port1,
++                      unsigned int link_status)
++{
++      return set_port_feature(hub->hdev,
++                      port1 | (link_status << 3),
++                      USB_PORT_FEAT_LINK_STATE);
++}
++
++/*
++ * If USB 3.0 ports are placed into the Disabled state, they will no longer
++ * detect any device connects or disconnects.  This is generally not what the
++ * USB core wants, since it expects a disabled port to produce a port status
++ * change event when a new device connects.
++ *
++ * Instead, set the link state to Disabled, wait for the link to settle into
++ * that state, clear any change bits, and then put the port into the RxDetect
++ * state.
++ */
++static int hub_usb3_port_disable(struct usb_hub *hub, int port1)
++{
++      int ret;
++      int total_time;
++      u16 portchange, portstatus;
++
++      if (!hub_is_superspeed(hub->hdev))
++              return -EINVAL;
++
++      ret = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_SS_DISABLED);
++      if (ret) {
++              dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
++                              port1, ret);
++              return ret;
++      }
++
++      /* Wait for the link to enter the disabled state. */
++      for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {
++              ret = hub_port_status(hub, port1, &portstatus, &portchange);
++              if (ret < 0)
++                      return ret;
++
++              if ((portstatus & USB_PORT_STAT_LINK_STATE) ==
++                              USB_SS_PORT_LS_SS_DISABLED)
++                      break;
++              if (total_time >= HUB_DEBOUNCE_TIMEOUT)
++                      break;
++              msleep(HUB_DEBOUNCE_STEP);
++      }
++      if (total_time >= HUB_DEBOUNCE_TIMEOUT)
++              dev_warn(hub->intfdev, "Could not disable port %d after %d ms\n",
++                              port1, total_time);
++
++      return hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_RX_DETECT);
++}
++
+ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
+ {
+       struct usb_device *hdev = hub->hdev;
+@@ -884,8 +938,13 @@ static int hub_port_disable(struct usb_h
+       if (hub->ports[port1 - 1]->child && set_state)
+               usb_set_device_state(hub->ports[port1 - 1]->child,
+                               USB_STATE_NOTATTACHED);
+-      if (!hub->error && !hub_is_superspeed(hub->hdev))
+-              ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
++      if (!hub->error) {
++              if (hub_is_superspeed(hub->hdev))
++                      ret = hub_usb3_port_disable(hub, port1);
++              else
++                      ret = clear_port_feature(hdev, port1,
++                                      USB_PORT_FEAT_ENABLE);
++      }
+       if (ret)
+               dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
+                               port1, ret);
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -761,12 +761,39 @@ int xhci_hub_control(struct usb_hcd *hcd
+                       break;
+               case USB_PORT_FEAT_LINK_STATE:
+                       temp = xhci_readl(xhci, port_array[wIndex]);
++
++                      /* Disable port */
++                      if (link_state == USB_SS_PORT_LS_SS_DISABLED) {
++                              xhci_dbg(xhci, "Disable port %d\n", wIndex);
++                              temp = xhci_port_state_to_neutral(temp);
++                              /*
++                               * Clear all change bits, so that we get a new
++                               * connection event.
++                               */
++                              temp |= PORT_CSC | PORT_PEC | PORT_WRC |
++                                      PORT_OCC | PORT_RC | PORT_PLC |
++                                      PORT_CEC;
++                              xhci_writel(xhci, temp | PORT_PE,
++                                      port_array[wIndex]);
++                              temp = xhci_readl(xhci, port_array[wIndex]);
++                              break;
++                      }
++
++                      /* Put link in RxDetect (enable port) */
++                      if (link_state == USB_SS_PORT_LS_RX_DETECT) {
++                              xhci_dbg(xhci, "Enable port %d\n", wIndex);
++                              xhci_set_link_state(xhci, port_array, wIndex,
++                                              link_state);
++                              temp = xhci_readl(xhci, port_array[wIndex]);
++                              break;
++                      }
++
+                       /* Software should not attempt to set
+-                       * port link state above '5' (Rx.Detect) and the port
++                       * port link state above '3' (U3) and the port
+                        * must be enabled.
+                        */
+                       if ((temp & PORT_PE) == 0 ||
+-                              (link_state > USB_SS_PORT_LS_RX_DETECT)) {
++                              (link_state > USB_SS_PORT_LS_U3)) {
+                               xhci_warn(xhci, "Cannot set link state.\n");
+                               goto error;
+                       }
diff --git a/queue-3.7/usb-handle-auto-transition-from-hot-to-warm-reset.patch b/queue-3.7/usb-handle-auto-transition-from-hot-to-warm-reset.patch
new file mode 100644 (file)
index 0000000..b5fc9f3
--- /dev/null
@@ -0,0 +1,50 @@
+From 1c7439c61fa6516419c32a9824976334ea969d47 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Wed, 14 Nov 2012 15:58:52 -0800
+Subject: USB: Handle auto-transition from hot to warm reset.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 1c7439c61fa6516419c32a9824976334ea969d47 upstream.
+
+USB 3.0 hubs and roothubs will automatically transition a failed hot
+reset to a warm (BH) reset.  In that case, the warm reset change bit
+will be set, and the link state change bit may also be set.  Change
+hub_port_finish_reset to unconditionally clear those change bits for USB
+3.0 hubs.  If these bits are not cleared, we may lose port change events
+from the roothub.
+
+This commit should be backported to kernels as old as 3.2, that contain
+the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine
+warm reset logic".
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2541,16 +2541,16 @@ static void hub_port_finish_reset(struct
+               clear_port_feature(hub->hdev,
+                               port1, USB_PORT_FEAT_C_RESET);
+               /* FIXME need disconnect() for NOTATTACHED device */
+-              if (warm) {
++              if (hub_is_superspeed(hub->hdev)) {
+                       clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_BH_PORT_RESET);
+                       clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_PORT_LINK_STATE);
+-              } else {
++              }
++              if (!warm)
+                       usb_set_device_state(udev, *status
+                                       ? USB_STATE_NOTATTACHED
+                                       : USB_STATE_DEFAULT);
+-              }
+               break;
+       }
+ }
diff --git a/queue-3.7/usb-handle-warm-reset-failure-on-empty-port.patch b/queue-3.7/usb-handle-warm-reset-failure-on-empty-port.patch
new file mode 100644 (file)
index 0000000..d9742e3
--- /dev/null
@@ -0,0 +1,76 @@
+From 65bdac5effd15d6af619b3b7218627ef4d84ed6a Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Wed, 14 Nov 2012 17:58:04 -0800
+Subject: USB: Handle warm reset failure on empty port.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 65bdac5effd15d6af619b3b7218627ef4d84ed6a upstream.
+
+An empty port can transition to either Inactive or Compliance Mode if a
+newly connected USB 3.0 device fails to link train.  In that case, we
+issue a warm reset.  Some devices, such as John's Roseweil eusb3
+enclosure, slip back into Compliance Mode after the warm reset.
+
+The current warm reset code does not check for device connect status on
+warm reset completion, and it incorrectly reports the warm reset
+succeeded.  This causes the USB core to attempt to send a Set Address
+control transfer to a port in Compliance Mode, which will always fail.
+
+Make hub_port_wait_reset check the current connect status and link state
+after the warm reset completes.  Return a failure status if the device
+is disconnected or the link state is Compliance Mode or SS.Inactive.
+
+Make hub_events disable the port if warm reset fails.  This will disable
+the port, and then bring it back into the RxDetect state.  Make the USB
+core ignore the connect change until the device reconnects.
+
+Note that this patch does NOT handle connected devices slipping into the
+Inactive state very well.  This is a concern, because devices can go
+into the Inactive state on U1/U2 exit failure.  However, the fix for
+that case is too large for stable, so it will be submitted in a separate
+patch.
+
+This patch should be backported to kernels as old as 3.2, contain the
+commit ID 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine warm
+reset logic"
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-by: John Covici <covici@ccs.covici.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |   12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2558,6 +2558,11 @@ static int hub_port_wait_reset(struct us
+                               return 0;
+                       }
+               } else {
++                      if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
++                                      hub_port_warm_reset_required(hub,
++                                              portstatus))
++                              return -ENOTCONN;
++
+                       return 0;
+               }
+@@ -4628,9 +4633,14 @@ static void hub_events(void)
+                        * SS.Inactive state.
+                        */
+                       if (hub_port_warm_reset_required(hub, portstatus)) {
++                              int status;
++
+                               dev_dbg(hub_dev, "warm reset port %d\n", i);
+-                              hub_port_reset(hub, i, NULL,
++                              status = hub_port_reset(hub, i, NULL,
+                                               HUB_BH_RESET_TIME, true);
++                              if (status < 0)
++                                      hub_port_disable(hub, i, 1);
++                              connect_change = 0;
+                       }
+                       if (connect_change)
diff --git a/queue-3.7/usb-ignore-port-state-until-reset-completes.patch b/queue-3.7/usb-ignore-port-state-until-reset-completes.patch
new file mode 100644 (file)
index 0000000..8733514
--- /dev/null
@@ -0,0 +1,84 @@
+From 4f43447e62b37ee19c82a13f72f35b1ca60a74d3 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Thu, 15 Nov 2012 14:58:04 -0800
+Subject: USB: Ignore port state until reset completes.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 4f43447e62b37ee19c82a13f72f35b1ca60a74d3 upstream.
+
+The port reset code bails out early if the current connect status is
+cleared (device disconnected).  If we're issuing a hot reset, it may
+also look at the link state before the reset is finished.
+
+Section 10.14.2.6 of the USB 3.0 spec says that when a port enters the
+Error state or Resetting state, the port connection bit retains the
+value from the previous state.  Therefore we can't trust it until the
+reset finishes.  Also, the xHCI spec section 4.19.1.2.5 says software
+shall ignore the link state while the port is resetting, as it can be in
+an unknown state.
+
+The port state during reset is also unknown for USB 2.0 hubs.  The hub
+sends a reset signal by driving the bus into an SE0 state.  This
+overwhelms the "connect" signal from the device, so the port can't tell
+whether anything is connected or not.
+
+Fix the port reset code to ignore the port link state and current
+connect bit until the reset finishes, and USB_PORT_STAT_RESET is
+cleared.
+
+Remove the check for USB_PORT_STAT_C_BH_RESET in the warm reset case,
+because it's redundant.  When the warm reset finishes, the port reset
+bit will be cleared at the same time USB_PORT_STAT_C_BH_RESET is set.
+Remove the now-redundant check for a cleared USB_PORT_STAT_RESET bit
+in the code to deal with the finished reset.
+
+This patch should be backported to all stable kernels.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2495,6 +2495,10 @@ static int hub_port_wait_reset(struct us
+               if (ret < 0)
+                       return ret;
++              /* The port state is unknown until the reset completes. */
++              if ((portstatus & USB_PORT_STAT_RESET))
++                      goto delay;
++
+               /*
+                * Some buggy devices require a warm reset to be issued even
+                * when the port appears not to be connected.
+@@ -2540,11 +2544,7 @@ static int hub_port_wait_reset(struct us
+                       if ((portchange & USB_PORT_STAT_C_CONNECTION))
+                               return -ENOTCONN;
+-                      /* if we`ve finished resetting, then break out of
+-                       * the loop
+-                       */
+-                      if (!(portstatus & USB_PORT_STAT_RESET) &&
+-                          (portstatus & USB_PORT_STAT_ENABLE)) {
++                      if ((portstatus & USB_PORT_STAT_ENABLE)) {
+                               if (hub_is_wusb(hub))
+                                       udev->speed = USB_SPEED_WIRELESS;
+                               else if (hub_is_superspeed(hub->hdev))
+@@ -2558,10 +2558,10 @@ static int hub_port_wait_reset(struct us
+                               return 0;
+                       }
+               } else {
+-                      if (portchange & USB_PORT_STAT_C_BH_RESET)
+-                              return 0;
++                      return 0;
+               }
++delay:
+               /* switch to the long delay after two short delay failures */
+               if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
+                       delay = HUB_LONG_RESET_TIME;
diff --git a/queue-3.7/usb-ignore-xhci-reset-device-status.patch b/queue-3.7/usb-ignore-xhci-reset-device-status.patch
new file mode 100644 (file)
index 0000000..008d941
--- /dev/null
@@ -0,0 +1,67 @@
+From 8b8132bc3d1cc3d4c0687e4d638a482fa920d98a Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Wed, 14 Nov 2012 16:10:49 -0800
+Subject: USB: Ignore xHCI Reset Device status.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 8b8132bc3d1cc3d4c0687e4d638a482fa920d98a upstream.
+
+When the USB core finishes reseting a USB device, the xHCI driver sends
+a Reset Device command to the host.  The xHC then updates its internal
+representation of the USB device to the 'Default' device state.  If the
+device was already in the Default state, the xHC will complete the
+command with an error status.
+
+If a device needs to be reset several times during enumeration, the
+second reset will always fail because of the xHCI Reset Device command.
+This can cause issues during enumeration.
+
+For example, usb_reset_and_verify_device calls into hub_port_init in a
+loop.  Say that on the first call into hub_port_init, the device is
+successfully reset, but doesn't respond to several set address control
+transfers.  Then the port will be disabled, but the udev will remain in
+tact.  usb_reset_and_verify_device will call into hub_port_init again.
+
+On the second call into hub_port_init, the device will be reset, and the
+xHCI driver will issue a Reset Device command.  This command will fail
+(because the device is already in the Default state), and
+usb_reset_and_verify_device will fail.  The port will be disabled, and
+the device won't be able to enumerate.
+
+Fix this by ignoring the return value of the HCD reset_device callback.
+
+This commit should be backported to kernels as old as 3.2, that contain
+the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine
+warm reset logic".
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |   13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2526,14 +2526,11 @@ static void hub_port_finish_reset(struct
+                       msleep(10 + 40);
+                       update_devnum(udev, 0);
+                       hcd = bus_to_hcd(udev->bus);
+-                      if (hcd->driver->reset_device) {
+-                              *status = hcd->driver->reset_device(hcd, udev);
+-                              if (*status < 0) {
+-                                      dev_err(&udev->dev, "Cannot reset "
+-                                                      "HCD device state\n");
+-                                      break;
+-                              }
+-                      }
++                      /* The xHC may think the device is already reset,
++                       * so ignore the status.
++                       */
++                      if (hcd->driver->reset_device)
++                              hcd->driver->reset_device(hcd, udev);
+               }
+               /* FALL THROUGH */
+       case -ENOTCONN:
diff --git a/queue-3.7/usb-increase-reset-timeout.patch b/queue-3.7/usb-increase-reset-timeout.patch
new file mode 100644 (file)
index 0000000..3881aa7
--- /dev/null
@@ -0,0 +1,37 @@
+From 77c7f072c87fa951e9a74805febf26466f31170c Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Wed, 14 Nov 2012 17:16:52 -0800
+Subject: USB: Increase reset timeout.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 77c7f072c87fa951e9a74805febf26466f31170c upstream.
+
+John's NEC 0.96 xHCI host controller needs a longer timeout for a warm
+reset to complete.  The logs show it takes 650ms to complete the warm
+reset, so extend the hub reset timeout to 800ms to be on the safe side.
+
+This commit should be backported to kernels as old as 3.2, that contain
+the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine
+warm reset logic".
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-by: John Covici <covici@ccs.covici.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2460,7 +2460,7 @@ static unsigned hub_is_wusb(struct usb_h
+ #define HUB_SHORT_RESET_TIME  10
+ #define HUB_BH_RESET_TIME     50
+ #define HUB_LONG_RESET_TIME   200
+-#define HUB_RESET_TIMEOUT     500
++#define HUB_RESET_TIMEOUT     800
+ static int hub_port_reset(struct usb_hub *hub, int port1,
+                       struct usb_device *udev, unsigned int delay, bool warm);