[RFC PATCH 0/4] port warm reset recovery

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Both the suspected quirky Synopsys xHC [1] and the
port-pm-runtime-resume path need to issue warm resets to reliably bring
ports back to an operational state.  Per Alan's observation this also
arranges for these warm resets to be queued asynchronously.  Per my
previous testing I found cases where khubd takes actions on ports that
are known to still be in recovery (unintended disconnects).  This set
mitigates those interactions by pushing resume operations into khubd
context by making khubd a workqueue.

Please focus review on patch 4.  usb_port_resume() running in khubd
context may turn out to not be necessary, but I need to test more.

The expected sequence of events for the hub_resume case is:

1/ hub_resume

2/ scan through all ports and queue (async) port warm resets if necessary

3/ kick_khubd

4/ hub_event() syncs all in-flight resets

5/ child device resume proceeds in parallel with hub_event as before
  (child device resume also syncs in-flight warm resets if it happens to
  occur before hub_event() runs)

The sequence of events in the pm-runtime case is:

1/ usb_port_runtime_resume queues an async warm reset, and requests a
   reset-resume of the child device if present

2/ child device resume syncs the in-flight reset and optionally does
   reset-resume

Note that this only implements the reset for the pm-runtime case.
xhci_port_resume() is where the xHC quirk can be placed to do the same
for the hub_resume() case.

Only lightly tested.  Looking for positive feedback before rebasing the
rest of the port power rework on top of this approach.

[1]: http://marc.info/?l=linux-usb&m=138683173421509&w=2

---

Dan Williams (4):
      usb: introduce hub->resume_bits and HCD_FLAG_RESET_RESUME
      usb: convert khubd to a workqueue
      usb: reset resume in khubd context
      usb: port pm recovery


 drivers/usb/core/driver.c    |   40 +++++++-
 drivers/usb/core/generic.c   |   23 ++++-
 drivers/usb/core/hub.c       |  211 +++++++++++++++++-------------------------
 drivers/usb/core/hub.h       |   25 +----
 drivers/usb/core/port.c      |   80 +++++++++++-----
 drivers/usb/core/usb.c       |    1 
 drivers/usb/core/usb.h       |    8 ++
 drivers/usb/host/xhci-pci.c  |    1 
 drivers/usb/host/xhci-plat.c |    1 
 drivers/usb/host/xhci.c      |    8 ++
 drivers/usb/host/xhci.h      |    2 
 include/linux/usb.h          |    6 +
 include/linux/usb/hcd.h      |    7 +
 13 files changed, 235 insertions(+), 178 deletions(-)

...not that I expect any review over the weekend, but wanted to get this
out before heading home.

--
Dan

One more note, the udev->reset_resume to hub->resume_bit conversion also
needs the below two patches, but I left them out of the series for now
to keep the patch
count lower.

commit e724d476af11c1066d425fa64d2fedcc0a4415b0
Author: Dan Williams <dan.j.williams@xxxxxxxxx>
Date:   Wed Dec 18 14:43:47 2013 -0800

    p54usb: set USB_QUIRK_RESET_RESUME
    
    ...rather than scheduling a single shot at probe.  Found by inspection
    not sure if this will cause regressions since only the first resume is
    guaranteed to trigger a reset.  I.e. this device may now see more
    resets.
    
    Cc: Christian Lamparter <chunkeey@xxxxxxxxxxxxxx>
    Cc: linux-wireless@xxxxxxxxxxxxxxx
    Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>

diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index e328d3058c41..f27674c46c1b 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -1035,10 +1035,8 @@ static int p54u_probe(struct usb_interface *intf,
 	priv->common.open = p54u_open;
 	priv->common.stop = p54u_stop;
 	if (recognized_pipes < P54U_PIPE_NUMBER) {
-#ifdef CONFIG_PM
 		/* ISL3887 needs a full reset on resume */
-		udev->reset_resume = 1;
-#endif /* CONFIG_PM */
+		udev->quirks |= USB_QUIRK_RESET_RESUME;
 		err = p54u_device_reset(dev);
 
 		priv->hw_type = P54U_3887;

commit 0dda95bd66c4a59d4c8dc247a998bbed658a26c4
Author: Dan Williams <dan.j.williams@xxxxxxxxx>
Date:   Wed Dec 18 14:32:22 2013 -0800

    ath9k_hif_usb: set USB_QUIRK_RESET_RESUME
    
    ...rather than scheduling a single shot at probe.  Found by inspection
    not sure if this will cause regressions since only the first resume is
    guaranteed to trigger a reset.  I.e. this device may now see more
    resets.
    
    Cc: Luis R. Rodriguez <mcgrof@xxxxxxxxxxxxxxxx>
    Cc: Jouni Malinen <jouni@xxxxxxxxxxxxxxxx>
    Cc: Vasanthakumar Thiagarajan <vthiagar@xxxxxxxxxxxxxxxx>
    Cc: Senthil Balasubramanian <senthilb@xxxxxxxxxxxxxxxx>
    Cc: linux-wireless@xxxxxxxxxxxxxxx
    Cc: ath9k-devel@xxxxxxxxxxxxxxx
    Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>

diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 6d5d716adc1b..44e5b3ee2938 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -1205,9 +1205,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
 	hif_dev->udev = udev;
 	hif_dev->interface = interface;
 	hif_dev->usb_device_id = id;
-#ifdef CONFIG_PM
-	udev->reset_resume = 1;
-#endif
+	udev->quirks |= USB_QUIRK_RESET_RESUME;
 	usb_set_intfdata(interface, hif_dev);
 
 	init_completion(&hif_dev->fw_done);
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux