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

Bug#782442: USB3 external HDD not recognized [regression]



Hi

Thanks for bringing this to my attention. 

On 10.05.2015 18:08, Alan Stern wrote:
> Sending to author of the offending commit and maintainer of the 
> xhci-hcd driver.
> 
> On Sat, 9 May 2015, Ralf Jung wrote:
> 
>> Hi,
>>
>> I did a bisect on these files only, and here's the result:
>>
>>> d6236f6d1d885aa19d1cd7317346fe795227a3cc is the first bad commit
>>> commit d6236f6d1d885aa19d1cd7317346fe795227a3cc
>>> Author: Wang, Yu <yu.y.wang@intel.com>
>>> Date:   Tue Jun 24 17:14:44 2014 +0300
>>>
>>>     xhci: Fix runtime suspended xhci from blocking system suspend.
>>
>> I confirmed that reverting this commit on top of v3.16 indeed fixes the
>> issue.

Ok, xhci is reset in resume in your case (indicated by the "root hub lost power or was reset" messages)
That patch adds an additional check that ensures there was some event before resuming the roothub.

Could you try out the following and see if it helps? If the event is lost/cleared during reset
then this change should work.

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 52acd1d..75db3ad 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -982,6 +982,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
        struct usb_hcd          *secondary_hcd;
        int                     retval = 0;
        bool                    comp_timer_running = false;
+       int                     resume_hubs = 0;
 
        /* Wait a bit if either of the roothubs need to settle from the
         * transition into bus suspend.
@@ -1017,6 +1018,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                temp = readl(&xhci->op_regs->status);
        }
 
+       resume_hubs = readl(&xhci->op_regs->status) & STS_EINT;
        /* If restore operation fails, re-initialize the HC during resume */
        if ((temp & STS_SRE) || hibernated) {
 
@@ -1097,7 +1099,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
        if (retval == 0) {
                /* Resume root hubs only when have pending events. */
                status = readl(&xhci->op_regs->status);
-               if (status & STS_EINT) {
+               if (status & STS_EINT || resume_hubs) {
                        usb_hcd_resume_root_hub(hcd);
                        usb_hcd_resume_root_hub(xhci->shared_hcd);
                }

-Mathias


Reply to: