linux-uvc-devel  

Re: [Linux-uvc-devel] Logitech Orbit apply patch Howto

Stefan Monnier
Tue, 06 Mar 2007 12:45:31 -0800

> The patch appears to refer to a file called uvcvideo.c, but I cannot
> find such a file on my system.

The source code has been shuffled in the mean time, so it's indeed a bit
less straightforward.  I currently use the patch below.  Note that I have no
idea what I'm doing: I'm proficient in C but haven't spent any time trying
to understand the code of linux-uvc.

To apply the patch, just do 'patch <thisemail' in the source directory of
linux-uvc.

I make no guarantee about this patch at all.  It does seem to improve the
behavior of my Orbit MP camera, tho.


        Stefan


Index: uvc_video.c
===================================================================
--- uvc_video.c (revision 89)
+++ uvc_video.c (working copy)
@@ -27,6 +27,29 @@
  * UVC Controls
  */
 
+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;
+}
+
 int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
                        __u8 intfnum, __u8 cs, void *data, __u16 size)
 {
@@ -45,6 +68,7 @@
                uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u "
                        "(unit %u) : %d (exp. %u).\n", query, cs, unit, ret,
                        size);
+               dev->state |= UVC_DEV_IOERROR;
                return -EIO;
        }
 
@@ -656,6 +680,25 @@
  * Video device
  */
 
+/* 
+ * Reset and Re-Initialize video device
+ */
+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.
  *
Index: uvc_v4l2.c
===================================================================
--- uvc_v4l2.c  (revision 89)
+++ uvc_v4l2.c  (working copy)
@@ -435,6 +435,10 @@
                mutex_unlock(&video->queue.mutex);
        }
 
+       /* leave usb device in a clean state */
+       if (video->dev->state & UVC_DEV_IOERROR)
+               uvc_video_reinit(video);
+
        /* Release the file handle. */
        uvc_dismiss_privileges(handle);
        kfree(handle);
Index: uvc_driver.c
===================================================================
--- uvc_driver.c        (revision 89)
+++ uvc_driver.c        (working copy)
@@ -1159,9 +1159,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. */
Index: uvcvideo.h
===================================================================
--- uvcvideo.h  (revision 89)
+++ uvcvideo.h  (working copy)
@@ -515,6 +515,7 @@
 
 enum uvc_device_state {
        UVC_DEV_DISCONNECTED = 1,
+       UVC_DEV_IOERROR = 2,
 };
 
 struct uvc_device {
@@ -625,6 +626,8 @@
 extern struct file_operations uvc_fops;
 
 /* Video */
+extern int uvc_usb_reset(struct uvc_device *dev);
+extern int uvc_video_reinit(struct uvc_video_device *video);
 extern int uvc_video_init(struct uvc_video_device *video);
 extern int uvc_video_enable(struct uvc_video_device *video, int enable);
 extern int uvc_probe_video(struct uvc_video_device *video,

_______________________________________________
Linux-uvc-devel mailing list
Linux-uvc-devel@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel