On Thu, 24 Apr 2014, Matteo Fortini wrote: > After some time, we finally had another hangup on kernel 3.14. > > @Alan: Here's the info we got in the files you mentioned. At any rate, > we're keeping the board in the same state so that we can run/produce any > other needed info. > > http://pastebin.com/DZPAqjcd To find out exactly what's going wrong, I need more information. Below is a patch you can apply that will add more data to the "registers" file in the /sys/kernel/debug/usb/ohci/* directory. Run with the patched kernel, and the next time you get a similar hang, see what's in the "registers" file. In fact, since the contents change over time, make two copies of the file, a few seconds apart. Alan Stern Index: usb-3.14/drivers/usb/host/ohci-dbg.c =================================================================== --- usb-3.14.orig/drivers/usb/host/ohci-dbg.c +++ usb-3.14/drivers/usb/host/ohci-dbg.c @@ -108,6 +108,9 @@ ohci_dump_status (struct ohci_hcd *contr 0x03 & (temp >> 4), (temp & 0x0f), (temp & 0x0100) ? "with" : "NO", rh_state_string(controller)); + ohci_dbg_sw(controller, next, size, + "WDH count %u SF count %u\n", + controller->wdh_count, controller->sf_count); temp = ohci_readl (controller, ®s->control); ohci_dbg_sw (controller, next, size, @@ -354,6 +357,48 @@ ohci_dump_ed (const struct ohci_hcd *ohc } } +static void ohci_dump_ed_rm_list(struct ohci_hcd *ohci, + char **next, unsigned *size) +{ + unsigned temp; + struct ed *ed; + struct td *td, *td2; + unsigned tdptr, tdptr2; + unsigned tddma, tddma2; + unsigned info; + + temp = scnprintf(*next, *size, "ed_rm_list:\n"); + *size -= temp; + *next += temp; + + for (ed = ohci->ed_rm_list; ed; ed = ed->ed_next) { + info = hc32_to_cpu(ohci, ed->hwINFO); + tdptr = tdptr2 = 0; + tddma = tddma2 = 0; + if (!list_empty(&ed->td_list)) { + td = list_first_entry(&ed->td_list, struct td, td_list); + tdptr = hc32_to_cpu(ohci, ed->hwHeadP) & TD_MASK; + tddma = (unsigned) td->td_dma; + + if (list_is_last(&td->td_list, &ed->td_list)) + td2 = ed->dummy; + else + td2 = list_first_entry(&td->td_list, + struct td, td_list); + tdptr2 = hc32_to_cpu(ohci, td->hwNextTD) & TD_MASK; + tddma2 = (unsigned) td2->td_dma; + } + + temp = scnprintf(*next, *size, + " ED dev %d ep %x(%d) tick %04x td1 %x %x td2 %x %x\n", + info & 0x7f, (info >> 7) & 0xf, + (info >> 11) & 0x3, + ed->tick, tddma, tdptr, tddma2, tdptr2); + *size -= temp; + *next += temp; + } +} + /*-------------------------------------------------------------------------*/ static int debug_async_open(struct inode *, struct file *); @@ -652,6 +697,8 @@ static ssize_t fill_registers_buffer(str /* roothub */ ohci_dump_roothub (ohci, 1, &next, &size); + ohci_dump_ed_rm_list(ohci, &next, &size); + done: spin_unlock_irqrestore (&ohci->lock, flags); Index: usb-3.14/drivers/usb/host/ohci-hcd.c =================================================================== --- usb-3.14.orig/drivers/usb/host/ohci-hcd.c +++ usb-3.14/drivers/usb/host/ohci-hcd.c @@ -866,6 +866,7 @@ static irqreturn_t ohci_irq (struct usb_ if (ints & OHCI_INTR_WDH) { spin_lock (&ohci->lock); dl_done_list (ohci); + ++ohci->wdh_count; spin_unlock (&ohci->lock); } @@ -902,6 +903,8 @@ static irqreturn_t ohci_irq (struct usb_ spin_lock (&ohci->lock); if (ohci->ed_rm_list) finish_unlinks (ohci, ohci_frame_no(ohci)); + if (ints & OHCI_INTR_SF) + ++ohci->sf_count; if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list && !ohci->ed_to_check Index: usb-3.14/drivers/usb/host/ohci.h =================================================================== --- usb-3.14.orig/drivers/usb/host/ohci.h +++ usb-3.14/drivers/usb/host/ohci.h @@ -415,6 +415,8 @@ struct ohci_hcd { struct ed *ed_to_check; unsigned zf_delay; + unsigned sf_count, wdh_count; + struct dentry *debug_dir; struct dentry *debug_async; struct dentry *debug_periodic; -- 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