Can you see if this patch (against 2.5.44) helps get rid of those "bad entry" problems (and siblings)?
Basically it just simplifies some logic that was trying to be too clever about writing the "next TD" entry the hardware uses. - Dave
--- ./drivers/usb-dist/host/ohci-q.c Fri Oct 18 21:45:02 2002 +++ ./drivers/usb/host/ohci-q.c Thu Oct 24 21:32:22 2002 @@ -784,42 +784,38 @@ */ 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 was one of them, ed halted because of short read, + * and URB_SHORT_NOT_OK is clear ... then we need to leave + * the control STATUS packet queued and clear ED_SKIP. + * for single-td data segments, TD_R handles all that. */ - if (next->urb == urb) { - u32 info = next->hwINFO; + info = next->hwINFO; + info |= cpu_to_le32 (TD_DONE); + info &= ~cpu_to_le32 (TD_CC); + next->hwINFO = info; - info |= cpu_to_le32 (TD_DONE); - info &= ~cpu_to_le32 (TD_CC); - next->hwINFO = info; - next->next_dl_td = rev; - rev = next; - continue; - } - - /* 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", --- ./drivers/usb-dist/host/ohci-mem.c Fri Oct 18 21:45:02 2002 +++ ./drivers/usb/host/ohci-mem.c Thu Oct 24 20:39:15 2002 @@ -176,13 +176,6 @@ 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; }