> this results in the following output
Very strange. I can apply it against clean split branch from revision 64
without any problems.
Please try to use the same patch attached to this message.
Also try to use "patch -p1 < split-reset.patch" to strip "new" and "old"
directory names.
Remember to update files from svn before patching to be sure that you have
clean working copy.
In case all of this will not help, fill free to send me *.rej files
Regards, Evgeny
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
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel