[Linux-uvc-devel] Re: [PATCH] QC fusion almost working in kopete
Linux UVC driver and tools
Brought to you by:
pinchartl
|
From: Alexandre B. <di...@fr...> - 2006-02-02 21:44:23
|
On Thursday 02 February 2006 20:33, Nick Wiltshire wrote:
> uvcvideo: Failed to query UVC control 1 (unit 0) : -110.
>
> so I unloaded/reloaded the driver:
>
> usbcore: deregistering driver usbvideo
> uvcvideo: Found UVC 1.00 device <unnamed> (046d:08c1)
> uvcvideo: Failed to query UVC control 1 (unit 0) : -110.
> uvcvideo: Failed to initialize the device (-5).
> usbcore: registered new driver usbvideo
> USB Video Class driver (v0.1.0)
>
> any idea why this would happen?
I have the same problem when using my quickcam pro 5000 for some time.
Sending an usb reset to the camera solve the problem. I wrote a patch to reset
the camera on device close if an IO error occurred, and on device
initialization failure.
You may try this patch and see if it works for you.
Index: uvcvideo.c
===================================================================
--- uvcvideo.c (revision 16)
+++ uvcvideo.c (working copy)
@@ -317,6 +317,7 @@
enum uvc_device_state {
UVC_DEV_DISCONNECTED = 1,
+ UVC_DEV_IOERROR = 2,
};
struct uvc_device {
@@ -1317,6 +1318,29 @@
* UVC Controls
*/
+static int uvc_usb_reset(struct uvc_device *dev)
+{
+ int l, ret;
+
+ l = usb_lock_device_for_reset(dev->udev, dev->intf);
+
+ if (l >= 0) {
+ ret = usb_reset_device(dev->udev);
+ if (l)
+ usb_unlock_device(dev->udev);
+ }
+ else
+ ret = -EBUSY;
+
+ if (ret)
+ uvc_printk(KERN_DEBUG, "uvc_usb_reset: Unable to reset usb device"
+ "(%d).\n", ret);
+ else
+ dev->state &= ~UVC_DEV_IOERROR;
+
+ return ret;
+}
+
static int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
__u8 intfnum, __u8 cs, void *data, __u16 size)
{
@@ -1334,6 +1358,7 @@
if (ret != size) {
uvc_printk(KERN_ERR, "Failed to query UVC control %u "
"(unit %u) : %d.\n", cs, unit, ret);
+ dev->state |= UVC_DEV_IOERROR;
return -EIO;
}
@@ -1548,6 +1573,25 @@
* Video device
*/
+/*
+ * Reset and Re-Initialize video device
+ */
+static int uvc_video_reinit(struct uvc_video_device *video)
+{
+ int ret;
+
+ if ((ret = uvc_usb_reset(video->dev)) < 0)
+ return ret;
+
+ if ((ret = uvc_set_video_ctrl(video, &video->streaming->ctrl, 0)) < 0) {
+ uvc_printk(KERN_DEBUG, "uvc_video_reinit: Unable to commit format "
+ "(%d).\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
/*
* Initialize the UVC video device.
*
@@ -1942,6 +1986,10 @@
uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to free buffers.\n");
up(&video->queue.lock);
+ /* leave usb device in a clean state */
+ if (video->dev->state & UVC_DEV_IOERROR)
+ uvc_video_reinit(video);
+
atomic_inc(&video->count);
kref_put(&video->dev->kref, uvc_delete);
return 0;
@@ -2984,9 +3032,18 @@
* parameters.
*/
if ((ret = uvc_video_init(&dev->video)) < 0) {
- uvc_printk(KERN_ERR, "Failed to initialize the device "
- "(%d).\n", ret);
- return ret;
+
+ uvc_printk(KERN_ERR, "Failed to initialize the device, "
+ "(%d). trying to reset ...\n", ret);
+
+ if ((ret = uvc_usb_reset(dev)))
+ return ret;
+
+ if ((ret = uvc_video_init(&dev->video)) < 0) {
+ uvc_printk(KERN_ERR, "Failed to initialize the device "
+ "(%d).\n", ret);
+ return ret;
+ }
}
/* Register the device with V4L. */
--
Alexandre
|