Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1551422
| From | Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 4.4 09/60] usb: hub: Fix auto-remount of safely removed or ejected USB-3 devices |
| Date | 2017-01-04 22:40 +0100 |
| Message-ID | <sW1rR-1SX-55@gated-at.bofh.it> (permalink) |
| References | <sW0Fr-1jk-5@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <mathias.nyman@linux.intel.com>
commit 37be66767e3cae4fd16e064d8bb7f9f72bf5c045 upstream.
USB-3 does not have any link state that will avoid negotiating a connection
with a plugged-in cable but will signal the host when the cable is
unplugged.
For USB-3 we used to first set the link to Disabled, then to RxDdetect to
be able to detect cable connects or disconnects. But in RxDetect the
connected device is detected again and eventually enabled.
Instead set the link into U3 and disable remote wakeups for the device.
This is what Windows does, and what Alan Stern suggested.
Cc: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/core/hub.c | 101 +++++++++++++++++--------------------------------
1 file changed, 36 insertions(+), 65 deletions(-)
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -101,6 +101,8 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rws
static void hub_release(struct kref *kref);
static int usb_reset_and_verify_device(struct usb_device *udev);
+static void hub_usb3_port_prepare_disable(struct usb_hub *hub,
+ struct usb_port *port_dev);
static inline char *portspeed(struct usb_hub *hub, int portstatus)
{
@@ -883,82 +885,28 @@ static int hub_set_port_link_state(struc
}
/*
- * 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.
+ * USB-3 does not have a similar link state as USB-2 that will avoid negotiating
+ * a connection with a plugged-in cable but will signal the host when the cable
+ * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices
*/
-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_port_status(hub, port1, &portstatus, &portchange);
- if (ret < 0)
- return ret;
-
- /*
- * USB controller Advanced Micro Devices, Inc. [AMD] FCH USB XHCI
- * Controller [1022:7814] will have spurious result making the following
- * usb 3.0 device hotplugging route to the 2.0 root hub and recognized
- * as high-speed device if we set the usb 3.0 port link state to
- * Disabled. Since it's already in USB_SS_PORT_LS_RX_DETECT state, we
- * check the state here to avoid the bug.
- */
- if ((portstatus & USB_PORT_STAT_LINK_STATE) ==
- USB_SS_PORT_LS_RX_DETECT) {
- dev_dbg(&hub->ports[port1 - 1]->dev,
- "Not disabling port; link state is RxDetect\n");
- return ret;
- }
-
- ret = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_SS_DISABLED);
- if (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->ports[port1 - 1]->dev,
- "Could not disable after %d ms\n", 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_port *port_dev = hub->ports[port1 - 1];
struct usb_device *hdev = hub->hdev;
int ret = 0;
- if (port_dev->child && set_state)
- usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
if (!hub->error) {
- if (hub_is_superspeed(hub->hdev))
- ret = hub_usb3_port_disable(hub, port1);
- else
+ if (hub_is_superspeed(hub->hdev)) {
+ hub_usb3_port_prepare_disable(hub, port_dev);
+ ret = hub_set_port_link_state(hub, port_dev->portnum,
+ USB_SS_PORT_LS_U3);
+ } else {
ret = usb_clear_port_feature(hdev, port1,
USB_PORT_FEAT_ENABLE);
+ }
}
+ if (port_dev->child && set_state)
+ usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
if (ret && ret != -ENODEV)
dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);
return ret;
@@ -4073,6 +4021,26 @@ void usb_unlocked_enable_lpm(struct usb_
}
EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm);
+/* usb3 devices use U3 for disabled, make sure remote wakeup is disabled */
+static void hub_usb3_port_prepare_disable(struct usb_hub *hub,
+ struct usb_port *port_dev)
+{
+ struct usb_device *udev = port_dev->child;
+ int ret;
+
+ if (udev && udev->port_is_suspended && udev->do_remote_wakeup) {
+ ret = hub_set_port_link_state(hub, port_dev->portnum,
+ USB_SS_PORT_LS_U0);
+ if (!ret) {
+ msleep(USB_RESUME_TIMEOUT);
+ ret = usb_disable_remote_wakeup(udev);
+ }
+ if (ret)
+ dev_warn(&udev->dev,
+ "Port disable: can't disable remote wake\n");
+ udev->do_remote_wakeup = 0;
+ }
+}
#else /* CONFIG_PM */
@@ -4080,6 +4048,9 @@ EXPORT_SYMBOL_GPL(usb_unlocked_enable_lp
#define hub_resume NULL
#define hub_reset_resume NULL
+static inline void hub_usb3_port_prepare_disable(struct usb_hub *hub,
+ struct usb_port *port_dev) { }
+
int usb_disable_lpm(struct usb_device *udev)
{
return 0;
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH 4.4 00/60] 4.4.40-stable review Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:30 +0100
[PATCH 4.4 47/60] dm flakey: return -EINVAL on interval bounds error in flakey_ctr() Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:30 +0100
[PATCH 4.4 07/60] USB: serial: kl5kusb105: fix open error path Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 34/60] ext4: use more strict checks for inodes_per_block on mount Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 33/60] ext4: fix stack memory corruption with 64k block size Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 36/60] ext4: add sanity checking to count_overhead() Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 30/60] ptrace: Capture the ptracers creds not PT_PTRACE_CAP Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 18/60] ALSA: hda - Gate the mic jack on HP Z1 Gen3 AiO Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 03/60] btrfs: store and load values of stripes_min/stripes_max in balance status item Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 21/60] Btrfs: fix memory leak in reading btree blocks Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 06/60] USB: serial: option: add dlink dwm-158 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 05/60] USB: serial: option: add support for Telit LE922A PIDs 0x1040, 0x1041 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 08/60] USB: cdc-acm: add device id for GW Instek AFG-125 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 32/60] ext4: fix mballoc breakage with 64k block size Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 04/60] Btrfs: fix qgroup rescan worker initialization Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 09/60] usb: hub: Fix auto-remount of safely removed or ejected USB-3 devices Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 35/60] ext4: fix in-superblock mount options processing Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:40 +0100
[PATCH 4.4 15/60] ALSA: hda/ca0132 - Add quirk for Alienware 15 R2 2016 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:50 +0100
[PATCH 4.4 13/60] ALSA: usb-audio: Add QuickCam Communicate Deluxe/S7500 to volume_control_quirks Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-04 22:50 +0100
Re: [PATCH 4.4 00/60] 4.4.40-stable review Shuah Khan <shuah.kh@samsung.com> - 2017-01-05 01:50 +0100
Re: [PATCH 4.4 00/60] 4.4.40-stable review Guenter Roeck <linux@roeck-us.net> - 2017-01-05 06:30 +0100
Re: [PATCH 4.4 00/60] 4.4.40-stable review Guillaume Nault <g.nault@alphalink.fr> - 2017-01-05 16:50 +0100
Re: [PATCH 4.4 00/60] 4.4.40-stable review Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-01-05 21:40 +0100
csiph-web