> 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).
I think that "one shot interrupts" are a UHCI-ism. Unlink the urb in the completion handler, if you need it to complete only one of its transfers. > driver_write() > { > ... > if (tx_urb->status == -EINPROGRESS) > { > wait(tx_sem); /* hit by reception of -ECONNRESET in tx_completion */ It's not a good idea to access fields of URBs after they've been submitted, until the completion handler fires. Try reworking this semaphore so it acts as a mutex ... always grab it before writing, and release on an unlink completion. And then make all other completions start your unlink, unless there's still data to transmit. > } > 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 */ HCD still owns the urb, you shouldn't be modifying it in this handler. Copy the new data into the existing buffer, up to the transfer length you already specified. > } > else > { > #ifdef EVIL_HACK_NO_94 > urb->status = -EINPROGRESS; /* Bodge - see b) below */ Yes, this is annoying but necessary in this case. There's no real record that the URB is in the "owned by HCD but inside a completion handler" state. Should get fixed in the 2.5 tree; and a fix might get backported. > #endif > urb->transfer_flags |= USB_ASYNC_UNLINK; > usb_unlink_urb(urb); > } > } > > My main question is whether this approach is correct? Modulo some issues I mentioned above, I think so ... though I won't claim I could verify such a thing at this time. (No test hardware to verify it with :) > 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. Right, that shouldn't happen. I see code that should return -ENOENT, but you're saying it doesn't kick in for you. > 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. See above. Use that workaround for now. > 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. Hmm, that shouldn't be happening. > 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. Can you use the 2.5.2 tree with your driver? If so, I'd be interested to know whether the "ohci-hcd" driver (which I'll post soon as a patch) has the same failure modes for you. - Dave _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel