Hi,

In Ubuntu 9.10, support for Video Out devices (bulk-only) has been added. We 
noticed that when such a device is disconnected from a non-root hub, the queued 
urbs are returned with usb->status == -EPROTO. The video completion callback 
cancels the queue, and does not re-submit the urb.

Because the hub driver needs some time to process the disconnect properly, 
there is a brief interval in time where queued urbs for the disconnected device 
do not result in -ESHUTDOWN, as expected, but with other error codes (such as 
EPROTO).

We have found that (in case of status == -EPROTO) resubmitting the urb and not 
canceling the queue results in the correct behaviour. Eventually one of the 
urbs indeed comes back with status == -ESHUTDOWN and the device is properly 
administrated as disconnected. Subsequent QBUF attempts then also result in 
correct user-space experience.

We propose the following simple patch:

In uvc_video.c:

static void uvc_video_complete(struct urb *urb)
{
        struct uvc_video_device *video = urb->context;
        struct uvc_video_queue *queue = &video->queue;
        struct uvc_buffer *buf = NULL;
        unsigned long flags;
        int ret;

        switch (urb->status) {
        case 0:
                break;

        default:
                uvc_printk(KERN_WARNING, "Non-zero status (%d) in video "
                        "completion handler.\n", urb->status);
+               break;

        case -ENOENT:           /* usb_kill_urb() called. */
                if (video->frozen)
                        return;

        case -ECONNRESET:       /* usb_unlink_urb() called. */
        case -ESHUTDOWN:        /* The endpoint is being disabled. */
                uvc_queue_cancel(queue, urb->status == -ESHUTDOWN);
                return;
        }

        spin_lock_irqsave(&queue->irqlock, flags);
        if (!list_empty(&queue->irqqueue))
                buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
                                       queue);
        spin_unlock_irqrestore(&queue->irqlock, flags);

        video->decode(urb, video, buf);

        if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
                uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n",
                        ret);
        }
}

We welcome your comments.

Thanks,

Robert Lukassen




This e-mail message contains information which is confidential and may be 
privileged. It is intended for use by the addressee only. If you are not the 
intended addressee, we request that you notify the sender immediately and 
delete or destroy this e-mail message and any attachment(s), without copying, 
saving, forwarding, disclosing or using its contents in any other way. TomTom 
N.V., TomTom International BV or any other company belonging to the TomTom 
group of companies will not be liable for damage relating to the communication 
by e-mail of data, documents or any other information.
_______________________________________________
Linux-uvc-devel mailing list
Linux-uvc-devel@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to