Hi Alan, On Wed, Jan 16, 2013 at 10:55:50AM -0500, Alan Stern wrote: [...] > I changed my mind -- it turns out that adding the fix is somewhat > easier than unlinking one QH at a time. > > So now we're ready for some serious testing. The patch below is based > on the 3.7 kernel, and it doesn't include any of the debugging stuff > you have been using. Remove all the old patches and apply this one > instead. It has two changes: the increase in the schedule polling time > and the fix for multiple unlinks. > > If this causes the problem to go away then I will submit it for > inclusion in the stable kernel series. I tried the patch below with kernel 3.7, I updated my local git copy to that version. I'm sorry to say it does not seem to fix the issue. Some explanation, I made three trials, with reboot inbetween, of course. The first one got the error -110 almost immediately, the second did not show any problem, even with some load of the CPU, the third did show the error, but after some time, specifically after I loaded the I/O sub system with a kernel recompilation. Note that, during the compilation (make -j5) the transfer rate of the USB HDDs went up and down, with about a decrease of 10% from the usual one (from 4100 KB/sec to 3700 KB/sec) as minimum. This I did not notice before, but maybe I just did not notice... I also tried to run twice the USB HDDs reading, in this case, while the problem did not show up, I could see that the transfer rate did not change, maybe the multiple queue operation did have some positive effects. Nevertheless, bottom line is that I got the problem two out of three times, so it seems to me the fix was not completely effective. I've some log, but there's a lot of garbage in it, I esitate to post here or on the bugzilla page, if you want I can dig something or I can retry in order to get a cleaner one. Hope this helps, bye, pg > Alan Stern > > > > Index: 3.7/drivers/usb/host/ehci-timer.c > =================================================================== > --- 3.7.orig/drivers/usb/host/ehci-timer.c > +++ 3.7/drivers/usb/host/ehci-timer.c > @@ -113,21 +113,22 @@ static void ehci_poll_ASS(struct ehci_hc > > if (want != actual) { > > - /* Poll again later, but give up after about 20 ms */ > - if (ehci->ASS_poll_count++ < 20) { > - ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); > - return; > - } > - ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n", > - want, actual); > + /* Poll again later */ > + ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); > + ++ehci->ASS_poll_count; > + return; > } > + > + if (ehci->ASS_poll_count > 20) > + ehci_dbg(ehci, "ASS poll count reached %d\n", > + ehci->ASS_poll_count); > ehci->ASS_poll_count = 0; > > /* The status is up-to-date; restart or stop the schedule as needed */ > if (want == 0) { /* Stopped */ > - if (ehci->async_count > 0) > + if (ehci->async_count > 0) { > ehci_set_command_bit(ehci, CMD_ASE); > - > + } > } else { /* Running */ > if (ehci->async_count == 0) { > > @@ -159,14 +160,14 @@ static void ehci_poll_PSS(struct ehci_hc > > if (want != actual) { > > - /* Poll again later, but give up after about 20 ms */ > - if (ehci->PSS_poll_count++ < 20) { > - ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); > - return; > - } > - ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n", > - want, actual); > + /* Poll again later */ > + ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); > + return; > } > + > + if (ehci->PSS_poll_count > 20) > + ehci_dbg(ehci, "PSS poll count reached %d\n", > + ehci->PSS_poll_count); > ehci->PSS_poll_count = 0; > > /* The status is up-to-date; restart or stop the schedule as needed */ > Index: 3.7/drivers/usb/host/ehci-q.c > =================================================================== > --- 3.7.orig/drivers/usb/host/ehci-q.c > +++ 3.7/drivers/usb/host/ehci-q.c > @@ -1174,6 +1174,18 @@ submit_async ( > static void single_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh) > { > struct ehci_qh *prev; > + __hc32 dma = QH_NEXT(ehci, qh->qh_dma); > + __hc32 dma_next = qh->hw->hw_next; > + > + /* No QH on the unlink lists should point to qh */ > + for (prev = ehci->async_unlink; prev; prev = prev->unlink_next) { > + if (prev->hw->hw_next == dma) > + prev->hw->hw_next = dma_next; > + } > + for (prev = ehci->async_iaa; prev; prev = prev->unlink_next) { > + if (prev->hw->hw_next == dma) > + prev->hw->hw_next = dma_next; > + } > > /* Add to the end of the list of QHs waiting for the next IAAD */ > qh->qh_state = QH_STATE_UNLINK; > @@ -1188,7 +1200,7 @@ static void single_unlink_async(struct e > while (prev->qh_next.qh != qh) > prev = prev->qh_next.qh; > > - prev->hw->hw_next = qh->hw->hw_next; > + prev->hw->hw_next = dma_next; > prev->qh_next = qh->qh_next; > if (ehci->qh_scan_next == qh) > ehci->qh_scan_next = qh->qh_next.qh; -- piergiorgio -- 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