Thank you for this patch, I am sure it will fix my problems with the webcam
locking up. One question though, how is this patch used? I tried copying the
text into a file (called reset-patch) and then running the command
patch < reset-patch
this results in the following output:

patch < reset-patch
patching file uvc_driver.c
Hunk #1 succeeded at 147 with fuzz 2.
Hunk #2 FAILED at 1244.
1 out of 2 hunks FAILED -- saving rejects to file uvc_driver.c.rej
patching file uvc_v4l2.c
Hunk #1 FAILED at 434.
1 out of 1 hunk FAILED -- saving rejects to file uvc_v4l2.c.rej
patching file uvc_video.c
Hunk #1 FAILED at 45.
1 out of 1 hunk FAILED -- saving rejects to file uvc_video.c.rej
patching file uvcvideo.h
Hunk #1 FAILED at 511.
Hunk #2 succeeded at 665 with fuzz 2.
1 out of 2 hunks FAILED -- saving rejects to file uvcvideo.h.rej

Note also that I do not have any folders called new or old when downloading
the split branch, when getting the last revision with this command:

svn checkout svn://svn.berlios.de/linux-uvc/linux-uvc/branches/split

The files I get are:
split/uvc_ctrl.c
split/uvc_queue.c
split/uvc_video.c
split/uvc_v4l2.c
split/uvc_compat.h
split/uvc_driver.c
split/uvcvideo.h
split/Makefile

Again, thank you for your work :)

Regards,
Vidar

On 11/4/06, Evgeny <[EMAIL PROTECTED]> wrote:
I'd like to present so-called "reset patch" for revision 64 of split-branch.
Enjoy

diff -u old/uvc_driver.c new/uvc_driver.c
--- old/uvc_driver.c    2006-11-04 22:14:32.000000000 +0300
+++ new/uvc_driver.c    2006-11-04 02:17:08.000000000 +0300
@@ -147,6 +147,52 @@
        return 0;
}

+
+/*
+ * 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;
+}
+
+
+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;
+}
+
+
+
/* Simplify a fraction using a simple continued fraction decomposition. The
  * idea here is to convert fractions such as 333333/10000000 to 1/30 using
  * 32 bit arithmetic only. The algorithm is not perfect and relies upon two
@@ -1198,9 +1244,19 @@
         * 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. */
diff -u old/uvc_v4l2.c new/uvc_v4l2.c
--- old/uvc_v4l2.c      2006-11-04 22:14:32.000000000 +0300
+++ new/uvc_v4l2.c      2006-11-04 21:30:52.000000000 +0300
@@ -434,6 +434,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);
diff -u old/uvc_video.c new/uvc_video.c
--- old/uvc_video.c     2006-11-04 22:14:32.000000000 +0300
+++ new/uvc_video.c     2006-11-04 22:22:42.000000000 +0300
@@ -45,6 +45,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;
        }

diff -u old/uvcvideo.h new/uvcvideo.h
--- old/uvcvideo.h      2006-11-04 22:14:32.000000000 +0300
+++ new/uvcvideo.h      2006-11-04 02:16:51.000000000 +0300
@@ -511,6 +511,7 @@

enum uvc_device_state {
        UVC_DEV_DISCONNECTED = 1,
+       UVC_DEV_IOERROR = 2,
};

struct uvc_device {
@@ -664,6 +665,10 @@
extern struct usb_host_endpoint *uvc_find_endpoint(
                struct usb_host_interface *alts, __u8 epaddr);

+
+extern int uvc_video_reinit(struct uvc_video_device *video);
+extern int uvc_usb_reset(struct uvc_device *dev);
+
#endif /* __KERNEL__ */

#endif




Regards, Evgeny
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to