This is a note to let you know that I've just added the patch titled

    xHCI: report USB2 port in resuming as suspend

to the 3.0-stable tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     xhci-report-usb2-port-in-resuming-as-suspend.patch
and it can be found in the queue-3.0 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <sta...@kernel.org> know about it.


>From 8a8ff2f9399b23b968901f585ccb5a70a537c5ae Mon Sep 17 00:00:00 2001
From: Andiry Xu <andiry...@amd.com>
Date: Wed, 3 Aug 2011 16:46:49 +0800
Subject: xHCI: report USB2 port in resuming as suspend

From: Andiry Xu <andiry...@amd.com>

commit 8a8ff2f9399b23b968901f585ccb5a70a537c5ae upstream.

When a USB2 port initiate a remote wakeup, software shall ensure that
resume is signaled for at least 20ms, and then write '0' to the PLS field.
According to this, xhci driver do the following things:

1. When receive a remote wakeup event in irq_handler, set the resume_done
   value as jiffies + 20ms, and modify rh_timer to poll root hub status at
   that time;
2. When receive a GetPortStatus request, if the jiffies is after the
   resume_done value, clear the resume signal and resume_done.

However, if usb_port_resume() is called before the rh_timer triggered, it
will indicate the port as Suspend Cleared and skip the clear resume signal
part. The device will fail the usb_get_status request in finish_port_resume(),
and usbcore will try a reset-resume instead. Device will work OK after
reset-resume, but resume_done value is not cleared in this case, and
xhci_bus_suspend() will fail because when it finds a non-zero resume_done
value, it will regard the port as resuming and return -EBUSY.

This causes issue on some platforms that the system fail to suspend
after remote wakeup from suspend by USB2 devices connected to xHCI port.

To fix this issue, report the port status as suspend if the resume is
signaling less that 20ms, and usb_port_resume() will wait 25ms and check
port status again, so xHCI driver can clear the resume signaling and
resume_done value.

This should be backported to kernels as old as 2.6.37.

Signed-off-by: Andiry Xu <andiry...@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sh...@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gre...@suse.de>

---
 drivers/usb/host/xhci-hub.c |   15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -463,11 +463,12 @@ int xhci_hub_control(struct usb_hcd *hcd
                                        && (temp & PORT_POWER))
                                status |= USB_PORT_STAT_SUSPEND;
                }
-               if ((temp & PORT_PLS_MASK) == XDEV_RESUME) {
+               if ((temp & PORT_PLS_MASK) == XDEV_RESUME &&
+                               !DEV_SUPERSPEED(temp)) {
                        if ((temp & PORT_RESET) || !(temp & PORT_PE))
                                goto error;
-                       if (!DEV_SUPERSPEED(temp) && time_after_eq(jiffies,
-                                               
bus_state->resume_done[wIndex])) {
+                       if (time_after_eq(jiffies,
+                                       bus_state->resume_done[wIndex])) {
                                xhci_dbg(xhci, "Resume USB2 port %d\n",
                                        wIndex + 1);
                                bus_state->resume_done[wIndex] = 0;
@@ -487,6 +488,14 @@ int xhci_hub_control(struct usb_hcd *hcd
                                xhci_ring_device(xhci, slot_id);
                                bus_state->port_c_suspend |= 1 << wIndex;
                                bus_state->suspended_ports &= ~(1 << wIndex);
+                       } else {
+                               /*
+                                * The resume has been signaling for less than
+                                * 20ms. Report the port status as SUSPEND,
+                                * let the usbcore check port status again
+                                * and clear resume signaling later.
+                                */
+                               status |= USB_PORT_STAT_SUSPEND;
                        }
                }
                if ((temp & PORT_PLS_MASK) == XDEV_U0


Patches currently in stable-queue which might be from andiry...@amd.com are

queue-3.0/xhci-fix-port-u3-status-check-condition.patch
queue-3.0/xhci-fix-memory-leak-during-failed-enqueue.patch
queue-3.0/xhci-remove-tds-from-td-lists-when-urbs-are-canceled.patch
queue-3.0/xhci-fix-failed-enqueue-in-the-middle-of-isoch-td.patch
queue-3.0/xhci-report-usb2-port-in-resuming-as-suspend.patch

_______________________________________________
stable mailing list
stable@linux.kernel.org
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to