To all,
I could use some advice tracking down a USB problem.
Summary:
>From sohci_unlink_urb(), I'm getting
"unlink URB timeout"
Background:
I'm trying to get my ibmcam to work with an OHCI controller (on
StrongARM 2.4.16-rmk1). The usbvideo driver submits two urb's with
transfer_flags == USB_ISO_ASAP. The urb status gets set to
USB_ST_URB_PENDING.
Many transfers later, the usbvideo driver decides it has enough data and
calls usb_unlink_urb() for each of the two urb's.
Since this is an ISOCHRONOUS pipe, sohci_return_urb() wants to
automatically resubmit the urb's on each OHCI_INTR_WDH interrupt. The
urb status is also automatically reset to USB_ST_URB_PENDING.
To break this cycle, sohci_unlink_urb() marks the urb for deletion, ie
urb_priv->state = URB_DEL;
and waits with a watchdog timeout.
In my case, when the waiting ends, an error is detected, with
urb->status == USB_ST_URB_PENDING. :-(
It appears that the bit of code which actually breaks the cycle of
resubmission is in dl_done_list(). Since dl_done_list() is called
from the interrupt handler, it can execute even tho the unlinking
thread is waiting. :-)
However, it seems that there is a path though the dl_done_list() code
that avoids the resubmission of the urb (good), but never the less
fails to clear the (urb->status == USB_ST_URB_PENDING) condition
(bad). Thus the error on wakeup.
Here's the bit of code in dl_done_list() I think may be in error:
if (++(urb_priv->td_cnt) == urb_priv->length) {
if ((ed->state & (ED_OPER | ED_UNLINK))
&& (urb_priv->state != URB_DEL)) {
urb->status = cc_to_error[cc];
sohci_return_urb (ohci, urb);
} else {
spin_lock_irqsave (&usb_ed_lock, flags);
dl_del_urb (urb);
spin_unlock_irqrestore (&usb_ed_lock, flags);
}
}
Note dl_del_urb() sets the urb status to something other than pending.
So when the first "if" fires, urb->status will be changed one way or
another (good). But if the td_cnt has not yet counted up to
urb_priv->length (32 in my case), urb->status remains
USB_ST_URB_PENDING (bad). My guess is that after urb_priv->state is
set to URB_DEL there must be a guarenteed way to get dl_del_urb() called.
However I can see it.
Hints would be appreciated.
Thanks,
-Tim
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel