Hi, I'm working on a device driver which uses interrupt mode transfers in both directions. The reception side is working happily, but I'm having some problems with the transmission side. My understanding is that the following pseudo-code is how I should attempt to use the USB system (main setup of endpoints etc omited for clarity). Tx interval is set to zero for one-shot mode (although it makes no difference if I set to the interval value from the endpoint).
driver_write() { ... if (tx_urb->status == -EINPROGRESS) { wait(tx_sem); /* hit by reception of -ECONNRESET in tx_completion */ } FILL_INT_URB(tx_urb, some data, tx_completion, etc.) usb_submit_urb(tgx_urb) ... } tx_completion(urb) { if (urb->status == -ECONNRESET) { wake_up(tx_sem); return; } if (more data to transmit) { FILL_INT_URB(tx_urb, more data, etc.); /* HCD will resubmit this */ } else { #ifdef EVIL_HACK_NO_94 urb->status = -EINPROGRESS; /* Bodge - see b) below */ #endif urb->transfer_flags |= USB_ASYNC_UNLINK; usb_unlink_urb(urb); } } My main question is whether this approach is correct? Whilst attempting to debug this on my system (Apple Titanium G4 PowerBook - uses OHCI controller usb-ohci.c) I have observed the following interesting 'features' of the OHCI driver: a) Unlike the documentation & usb-uhci.c, it only generates unlink completion events for asynchronous unlinks (-ECONNRESET) but not for synchronous unlinks (should be -ENOENT?). This appears to be a straight inconsistency between the implementations and is easily fixed. b) Calling usb_unlink_urb() from a completion routine does NOTHING because urb->status has been set to zero for the completion routine, and sohci_unlink_urb() returns immediately (with no error) if urb->status is not -EINPROGRESS. c) Having worked around b) by setting urb->status to -EINPROGRESS before calling usb_unlink_urb, I never receive a completion with status -ECONNRESET. After instrumenting usb-ohci.c I know that the unlink correctly marks the URB for unlinking and enables the start frame interrupt. The start frame interrupt does occur and does invoke the routine dl_del_list() for processing of the unlink, but it does not invoke dl_del_urb() on my (being) unlinked URB. Having dealt with the list, the start frame interrupt is disabled as no further worked is deemed necessary. At this point I am at the limit of my current knowledge....a few simple attempts at tweaking have generally resulted in a reboot being required :( The observed behaviour is that my first transmission works, then my second transmission waits forever for the URB to become unlinked. I am currently attempting to be able to try this on a UHCI based system for comparison, and reading the OHCI spec for enlightenment, but would be grateful for any suggestions (or patches for usb-ohci.c) to try. Regards Stu -- The Janitorium <http://www.janitorium.co.uk/> _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel