Takashi Iwai 314ae0
From e76b3bf7654c3c94554c24ba15a3d105f4006c80 Mon Sep 17 00:00:00 2001
Takashi Iwai 314ae0
From: Kai-Heng Feng <kai.heng.feng@canonical.com>
Takashi Iwai 314ae0
Date: Wed, 6 Nov 2019 14:27:10 +0800
Takashi Iwai 314ae0
Subject: [PATCH] usb: Allow USB device to be warm reset in suspended state
Takashi Iwai 314ae0
Git-commit: e76b3bf7654c3c94554c24ba15a3d105f4006c80
Takashi Iwai 314ae0
Patch-mainline: v5.5-rc1
Takashi Iwai 314ae0
References: bsc#1051510
Takashi Iwai 314ae0
Takashi Iwai 314ae0
On Dell WD15 dock, sometimes USB ethernet cannot be detected after plugging
Takashi Iwai 314ae0
cable to the ethernet port, the hub and roothub get runtime resumed and
Takashi Iwai 314ae0
runtime suspended immediately:
Takashi Iwai 314ae0
...
Takashi Iwai 314ae0
[  433.315169] xhci_hcd 0000:3a:00.0: hcd_pci_runtime_resume: 0
Takashi Iwai 314ae0
[  433.315204] usb usb4: usb auto-resume
Takashi Iwai 314ae0
[  433.315226] hub 4-0:1.0: hub_resume
Takashi Iwai 314ae0
[  433.315239] xhci_hcd 0000:3a:00.0: Get port status 4-1 read: 0x10202e2, return 0x10343
Takashi Iwai 314ae0
[  433.315264] usb usb4-port1: status 0343 change 0001
Takashi Iwai 314ae0
[  433.315279] xhci_hcd 0000:3a:00.0: clear port1 connect change, portsc: 0x10002e2
Takashi Iwai 314ae0
[  433.315293] xhci_hcd 0000:3a:00.0: Get port status 4-2 read: 0x2a0, return 0x2a0
Takashi Iwai 314ae0
[  433.317012] xhci_hcd 0000:3a:00.0: xhci_hub_status_data: stopping port polling.
Takashi Iwai 314ae0
[  433.422282] xhci_hcd 0000:3a:00.0: Get port status 4-1 read: 0x10002e2, return 0x343
Takashi Iwai 314ae0
[  433.422307] usb usb4-port1: do warm reset
Takashi Iwai 314ae0
[  433.422311] usb 4-1: device reset not allowed in state 8
Takashi Iwai 314ae0
[  433.422339] hub 4-0:1.0: state 7 ports 2 chg 0002 evt 0000
Takashi Iwai 314ae0
[  433.422346] xhci_hcd 0000:3a:00.0: Get port status 4-1 read: 0x10002e2, return 0x343
Takashi Iwai 314ae0
[  433.422356] usb usb4-port1: do warm reset
Takashi Iwai 314ae0
[  433.422358] usb 4-1: device reset not allowed in state 8
Takashi Iwai 314ae0
[  433.422428] xhci_hcd 0000:3a:00.0: set port remote wake mask, actual port 0 status  = 0xf0002e2
Takashi Iwai 314ae0
[  433.422455] xhci_hcd 0000:3a:00.0: set port remote wake mask, actual port 1 status  = 0xe0002a0
Takashi Iwai 314ae0
[  433.422465] hub 4-0:1.0: hub_suspend
Takashi Iwai 314ae0
[  433.422475] usb usb4: bus auto-suspend, wakeup 1
Takashi Iwai 314ae0
[  433.426161] xhci_hcd 0000:3a:00.0: xhci_hub_status_data: stopping port polling.
Takashi Iwai 314ae0
[  433.466209] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting
Takashi Iwai 314ae0
[  433.510204] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting
Takashi Iwai 314ae0
[  433.554051] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting
Takashi Iwai 314ae0
[  433.598235] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting
Takashi Iwai 314ae0
[  433.642154] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting
Takashi Iwai 314ae0
[  433.686204] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting
Takashi Iwai 314ae0
[  433.730205] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting
Takashi Iwai 314ae0
[  433.774203] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting
Takashi Iwai 314ae0
[  433.818207] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting
Takashi Iwai 314ae0
[  433.862040] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting
Takashi Iwai 314ae0
[  433.862053] xhci_hcd 0000:3a:00.0: xhci_hub_status_data: stopping port polling.
Takashi Iwai 314ae0
[  433.862077] xhci_hcd 0000:3a:00.0: xhci_suspend: stopping port polling.
Takashi Iwai 314ae0
[  433.862096] xhci_hcd 0000:3a:00.0: // Setting command ring address to 0x8578fc001
Takashi Iwai 314ae0
[  433.862312] xhci_hcd 0000:3a:00.0: hcd_pci_runtime_suspend: 0
Takashi Iwai 314ae0
[  433.862445] xhci_hcd 0000:3a:00.0: PME# enabled
Takashi Iwai 314ae0
[  433.902376] xhci_hcd 0000:3a:00.0: restoring config space at offset 0xc (was 0x0, writing 0x20)
Takashi Iwai 314ae0
[  433.902395] xhci_hcd 0000:3a:00.0: restoring config space at offset 0x4 (was 0x100000, writing 0x100403)
Takashi Iwai 314ae0
[  433.902490] xhci_hcd 0000:3a:00.0: PME# disabled
Takashi Iwai 314ae0
[  433.902504] xhci_hcd 0000:3a:00.0: enabling bus mastering
Takashi Iwai 314ae0
[  433.902547] xhci_hcd 0000:3a:00.0: // Setting command ring address to 0x8578fc001
Takashi Iwai 314ae0
[  433.902649] pcieport 0000:00:1b.0: PME: Spurious native interrupt!
Takashi Iwai 314ae0
[  433.902839] xhci_hcd 0000:3a:00.0: Port change event, 4-1, id 3, portsc: 0xb0202e2
Takashi Iwai 314ae0
[  433.902842] xhci_hcd 0000:3a:00.0: resume root hub
Takashi Iwai 314ae0
[  433.902845] xhci_hcd 0000:3a:00.0: handle_port_status: starting port polling.
Takashi Iwai 314ae0
[  433.902877] xhci_hcd 0000:3a:00.0: xhci_resume: starting port polling.
Takashi Iwai 314ae0
[  433.902889] xhci_hcd 0000:3a:00.0: xhci_hub_status_data: stopping port polling.
Takashi Iwai 314ae0
[  433.902891] xhci_hcd 0000:3a:00.0: hcd_pci_runtime_resume: 0
Takashi Iwai 314ae0
[  433.902919] usb usb4: usb wakeup-resume
Takashi Iwai 314ae0
[  433.902942] usb usb4: usb auto-resume
Takashi Iwai 314ae0
[  433.902966] hub 4-0:1.0: hub_resume
Takashi Iwai 314ae0
...
Takashi Iwai 314ae0
Takashi Iwai 314ae0
As Mathias pointed out, the hub enters Cold Attach Status state and
Takashi Iwai 314ae0
requires a warm reset. However usb_reset_device() bails out early when
Takashi Iwai 314ae0
the device is in suspended state, as its callers port_event() and
Takashi Iwai 314ae0
hub_event() don't always resume the device.
Takashi Iwai 314ae0
Takashi Iwai 314ae0
Since there's nothing wrong to reset a suspended device, allow
Takashi Iwai 314ae0
usb_reset_device() to do so to solve the issue.
Takashi Iwai 314ae0
Takashi Iwai 314ae0
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Takashi Iwai 314ae0
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Takashi Iwai 314ae0
Cc: stable <stable@vger.kernel.org>
Takashi Iwai 314ae0
Link: https://lore.kernel.org/r/20191106062710.29880-1-kai.heng.feng@canonical.com
Takashi Iwai 314ae0
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Takashi Iwai 314ae0
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 314ae0
Takashi Iwai 314ae0
---
Takashi Iwai 314ae0
 drivers/usb/core/hub.c | 5 ++---
Takashi Iwai 314ae0
 1 file changed, 2 insertions(+), 3 deletions(-)
Takashi Iwai 314ae0
Takashi Iwai 314ae0
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
Takashi Iwai 314ae0
index fdcfa85b5b12..1709895387b9 100644
Takashi Iwai 314ae0
--- a/drivers/usb/core/hub.c
Takashi Iwai 314ae0
+++ b/drivers/usb/core/hub.c
Takashi Iwai 314ae0
@@ -5840,7 +5840,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
Takashi Iwai 314ae0
 
Takashi Iwai 314ae0
 /**
Takashi Iwai 314ae0
  * usb_reset_device - warn interface drivers and perform a USB port reset
Takashi Iwai 314ae0
- * @udev: device to reset (not in SUSPENDED or NOTATTACHED state)
Takashi Iwai 314ae0
+ * @udev: device to reset (not in NOTATTACHED state)
Takashi Iwai 314ae0
  *
Takashi Iwai 314ae0
  * Warns all drivers bound to registered interfaces (using their pre_reset
Takashi Iwai 314ae0
  * method), performs the port reset, and then lets the drivers know that
Takashi Iwai 314ae0
@@ -5868,8 +5868,7 @@ int usb_reset_device(struct usb_device *udev)
Takashi Iwai 314ae0
 	struct usb_host_config *config = udev->actconfig;
Takashi Iwai 314ae0
 	struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
Takashi Iwai 314ae0
 
Takashi Iwai 314ae0
-	if (udev->state == USB_STATE_NOTATTACHED ||
Takashi Iwai 314ae0
-			udev->state == USB_STATE_SUSPENDED) {
Takashi Iwai 314ae0
+	if (udev->state == USB_STATE_NOTATTACHED) {
Takashi Iwai 314ae0
 		dev_dbg(&udev->dev, "device reset not allowed in state %d\n",
Takashi Iwai 314ae0
 				udev->state);
Takashi Iwai 314ae0
 		return -EINVAL;
Takashi Iwai 314ae0
-- 
Takashi Iwai 314ae0
2.16.4
Takashi Iwai 314ae0