diff options
| -rw-r--r-- | drivers/usb/host/ohci-mem.c | 7 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-q.c | 49 |
2 files changed, 23 insertions, 33 deletions
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index 2415f9c26554..11d4bac4a19c 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c @@ -176,13 +176,6 @@ td_alloc (struct ohci_hcd *hc, int mem_flags) pci_pool_free (hc->td_cache, td, dma); return NULL; } - // DEBUG ONLY want to see if these tds are really getting - // allocated. the last one in a page shouldn't be getting - // allocated during these tests! - if ((dma & 0x0fff) == 0x0fc0) { - dbg ("td = %p", td); - dump_stack (); - } } return td; } diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 0fac456f47d1..621841baef5f 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -736,42 +736,39 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) */ ed->hwINFO |= ED_SKIP; wmb (); - td->ed->hwHeadP &= ~ED_H; + ed->hwHeadP &= ~ED_H; + /* put any later tds from this urb onto the donelist, after 'td', + * order won't matter here: no errors, and nothing was transferred. + * also patch the ed so it looks as if those tds completed normally. + */ while (tmp != &ed->td_list) { struct td *next; + u32 info; next = list_entry (tmp, struct td, td_list); tmp = next->td_list.next; - /* move other tds from this urb to the donelist, after 'td'. - * order won't matter here: no errors, nothing transferred. - * - * NOTE: this "knows" short control reads won't need fixup: - * hc went from the (one) data TD to the status td. that'll - * change if multi-td control DATA segments are supported, - * and we want to send the status packet. + if (next->urb != urb) + break; + + /* NOTE: if multi-td control DATA segments get supported, + * this urb had one of them, this td wasn't the last td + * in that segment (TD_R clear), this ed halted because + * of a short read, _and_ URB_SHORT_NOT_OK is clear ... + * then we need to leave the control STATUS packet queued + * and clear ED_SKIP. */ - if (next->urb == urb) { - u32 info = next->hwINFO; - - info |= cpu_to_le32 (TD_DONE); - info &= ~cpu_to_le32 (TD_CC); - next->hwINFO = info; - next->next_dl_td = rev; - rev = next; - continue; - } + info = next->hwINFO; + info |= cpu_to_le32 (TD_DONE); + info &= ~cpu_to_le32 (TD_CC); + next->hwINFO = info; - /* restart ed with first td of this next urb */ - ed->hwHeadP = cpu_to_le32 (next->td_dma) | toggle; - tmp = 0; - break; - } + next->next_dl_td = rev; + rev = next; - /* no urbs queued? then ED is empty. */ - if (tmp) - ed->hwHeadP = cpu_to_le32 (ed->dummy->td_dma) | toggle; + ed->hwHeadP = next->hwNextTD | toggle; + } /* help for troubleshooting: */ dbg ("urb %p usb-%s-%s ep-%d-%s cc %d --> status %d", |
