All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Slaby <jslaby@suse.cz>
To: stable@vger.kernel.org
Cc: Mathias Nyman <mathias.nyman@linux.intel.com>,
	Alan Stern <stern@rowland.harvard.edu>,
	Jiri Slaby <jslaby@suse.cz>
Subject: [patch added to 3.12-stable] usb: hub: Fix auto-remount of safely removed or ejected USB-3 devices
Date: Fri, 13 Jan 2017 08:41:32 +0100	[thread overview]
Message-ID: <20170113074159.26811-6-jslaby@suse.cz> (raw)
In-Reply-To: <20170113074159.26811-1-jslaby@suse.cz>

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

This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.

===============

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: Jiri Slaby <jslaby@suse.cz>
---
 drivers/usb/core/hub.c | 102 +++++++++++++++++--------------------------------
 1 file changed, 36 insertions(+), 66 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5e788077675b..2b11c552a909 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -115,6 +115,8 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
 
 static int usb_reset_and_verify_device(struct usb_device *udev);
 static void hub_release(struct kref *kref);
+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)
 {
@@ -878,82 +880,27 @@ static int hub_set_port_link_state(struct usb_hub *hub, int port1,
 }
 
 /*
- * 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->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;
 	int ret = 0;
 
-	if (hub->ports[port1 - 1]->child && set_state)
-		usb_set_device_state(hub->ports[port1 - 1]->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, hub->ports[port1 - 1]);
+			ret = hub_set_port_link_state(hub, hub->ports[port1 - 1]->portnum,
+						      USB_SS_PORT_LS_U3);
+		} else {
 			ret = usb_clear_port_feature(hdev, port1,
 					USB_PORT_FEAT_ENABLE);
+		}
 	}
+	if (hub->ports[port1 - 1]->child && set_state)
+		usb_set_device_state(hub->ports[port1 - 1]->child, USB_STATE_NOTATTACHED);
 	if (ret && ret != -ENODEV)
 		dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
 				port1, ret);
@@ -3885,6 +3832,26 @@ void usb_unlocked_enable_lpm(struct usb_device *udev)
 }
 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 */
 
@@ -3892,6 +3859,9 @@ EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm);
 #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;
-- 
2.11.0


  parent reply	other threads:[~2017-01-13  7:43 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-13  7:41 [patch added to 3.12-stable] Btrfs: fix tree search logic when replaying directory entry deletes Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] USB: serial: option: add support for Telit LE922A PIDs 0x1040, 0x1041 Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] USB: serial: option: add dlink dwm-158 Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] USB: serial: kl5kusb105: fix open error path Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] USB: cdc-acm: add device id for GW Instek AFG-125 Jiri Slaby
2017-01-13  7:41 ` Jiri Slaby [this message]
2017-01-13  7:41 ` [patch added to 3.12-stable] usb: gadget: composite: correctly initialize ep->maxpacket Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] USB: UHCI: report non-PME wakeup signalling for Intel hardware Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] ALSA: usb-audio: Add QuickCam Communicate Deluxe/S7500 to volume_control_quirks Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] ALSA: hiface: Fix M2Tech hiFace driver sampling rate change Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] ALSA: hda - Gate the mic jack on HP Z1 Gen3 AiO Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] Btrfs: fix memory leak in reading btree blocks Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] block_dev: don't test bdev->bd_contains when it is not stable Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] crypto: caam - fix AEAD givenc descriptors Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] ext4: fix mballoc breakage with 64k block size Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] ext4: fix stack memory corruption " Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] ext4: use more strict checks for inodes_per_block on mount Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] ext4: fix in-superblock mount options processing Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] ext4: add sanity checking to count_overhead() Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] ext4: reject inodes with negative size Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] ext4: return -ENOMEM instead of success Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] f2fs: set ->owner for debugfs status file's file_operations Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] mm/vmscan.c: set correct defer count for shrinker Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] fs: exec: apply CLOEXEC before changing dumpable task flags Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] usb: gadget: composite: always set ep->mult to a sensible value Jiri Slaby
2017-01-13  9:20   ` Felipe Balbi
2017-01-13  9:35     ` Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] dm crypt: mark key as invalid until properly loaded Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] dm space map metadata: fix 'struct sm_metadata' leak on failed create Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] CIFS: Fix a possible memory corruption during reconnect Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] CIFS: Fix missing nls unload in smb2_reconnect() Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] CIFS: Fix a possible memory corruption in push locks Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] xen/gntdev: Use VM_MIXEDMAP instead of VM_IO to avoid NUMA balancing Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] arm/xen: Use alloc_percpu rather than __alloc_percpu Jiri Slaby
2017-01-13  7:41 ` [patch added to 3.12-stable] xfs: set AGI buffer type in xlog_recover_clear_agi_bucket Jiri Slaby

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170113074159.26811-6-jslaby@suse.cz \
    --to=jslaby@suse.cz \
    --cc=mathias.nyman@linux.intel.com \
    --cc=stable@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.