On Mon, Mar 25, 2002, Martin Diehl <[EMAIL PROTECTED]> wrote: > On Thu, 21 Mar 2002, Johannes Erdfelt wrote: > > > > uhci.c: 3440: host controller process error. something bad happened > > > > This is what I was looking for. > > I'm getting exactly the same message with 2.5.7 when using irda-usb with > uhci (but not with usb-uhci). And the host locks solid, not even reacting > to any SysRq - but that's apparently not uhci's fault. > > What IMHO is an uhci problem however, is the special handling for > USB_ZERO_PACKET: Looks like some typo, because I don't believe it's a good > idea to send TD with bogus MaxLen field to the device ;-)
Doh! You're right, my fault. This is almost certainly the cause of the HCPE. > Furthermore, the decision when to add a zero-packet didn't cover all > details. > > The patch below vs. 2.5.7 fixes (hope so) these issues. At least it makes > the HCPE dissappear. irda-usb still isn't all that happy with it (in > contrast to my private driver using USB_ZERO_PACKET as well) - but that's > something to go on with Jean. There's a slight bug in your fixed code. len will always be 0 at the end of the previous loop, so your check will always incorrectly add the last zero packet. Does this patch work correctly? I've appended a corrected patch. Thanks very much for troubleshooting this. JE --- linux-2.4.19-pre3.orig/drivers/usb/uhci.c Sun Mar 24 17:26:20 2002 +++ linux-2.4.19-pre3/drivers/usb/uhci.c Sun Mar 24 17:24:31 2002 @@ -1259,20 +1259,29 @@ data); data += pktsze; - len -= pktsze; + len -= maxsze; usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)); } while (len > 0); + /* + * USB_ZERO_PACKET means adding a 0-length packet, if + * direction is OUT and the transfer_length was an + * exact multiple of maxsze, hence + * (len = transfer_length - N * maxsze) == 0 + * however, if transfer_length == 0, the zero packet + * was already prepared above. + */ if (usb_pipeout(urb->pipe) && (urb->transfer_flags & USB_ZERO_PACKET) && - urb->transfer_buffer_length) { + !len && urb->transfer_buffer_length) { td = uhci_alloc_td(uhci, urb->dev); if (!td) return -ENOMEM; uhci_add_td_to_urb(urb, td); - uhci_fill_td(td, status, destination | UHCI_NULL_DATA_SIZE | + uhci_fill_td(td, status, destination | + (UHCI_NULL_DATA_SIZE << 21) | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE), data); _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel