To all,

Thanks for the reply Dmitri

> The usbvideo module calls usb_unlink_urb() for each of the two urb's ONLY
> when it wants to stop the data pump, and that happens only when the device
> is being closed. It does NOT happen when "it has enough data" because

Yes, that is exactly what is happening - the app (streamer from xawtv)
calls close().  (I suppose it is really streamer that "has enough
data" so I mis-spoke.)  The close() leads to usbvideo_v4l_close() and
then on to usbvideo_StopDataPump().  The problems appear after
usb_unlink_urb() is called.  I believe the two calls to
usb_unlink_urb() from usbvideo.c are correct and expected.  I think
the difficultly is in usb-ohci.c, not usbvideo.c nor ibmcam.c.

> If you do the "cat test" (like in `cat < /dev/video0 > /dev/null`) then
> the device will be opened and should stay open until you cancel it. If you

Thanks for the suggestion.  However, `cat < /dev/video0 > /dev/null`
invokes (after a few seconds) usbvideo_StopDataPump() and on to
usb_unlink_urb() where I again get the "unlink URB timeout" error.
BTW, in both the "cat" and "streamer" cases the timeout error leads
immediately to a kernel panic.

I can still see no way for the code in usb-ohci.c to guarantee that
a urb marked for deletion (urb_priv->state = URB_DEL;) will always
get its status set to a value other than USB_ST_URB_PENDING.
The status USB_ST_URB_PENDING will always result in the timeout error
for any urb being "unlinked."

To reiterate from my first message:
(In usb-ohci.c)

Here's the bit of code in dl_done_list() I thought might 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);
                        }
                }
For fun I added
                  else {        
                        if (urb_priv->state == URB_DEL) {
                                spin_lock_irqsave (&usb_ed_lock, flags);
                                dl_del_urb (urb);
                                spin_unlock_irqrestore (&usb_ed_lock, flags);
                        }
                }

to cover the case where
(urb_priv->state == URB_DEL)                    is true but
(++(urb_priv->td_cnt) == urb_priv->length)      was false.

This prevented the timeout from occuring for the first urb to be unlinked,
but not the second. :-(

Any more thoughts would be appreciated.

-Tim

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to