]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
uvcvideo: Set alternate setting 0 on resume if the bus has been reset
authorMing Lei <tom.leiming@gmail.com>
Sat, 16 Jul 2011 03:51:00 +0000 (00:51 -0300)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 7 Nov 2011 21:47:31 +0000 (13:47 -0800)
commit d59a7b1dbce8b972ec2dc9fcaaae0bfa23687423 upstream.

If the bus has been reset on resume, set the alternate setting to 0.
This should be the default value, but some devices crash or otherwise
misbehave if they don't receive a SET_INTERFACE request before any other
video control request.

Microdia's 0c45:6437 camera has been found to require this change or it
will stop sending video data after resume.

uvc_video.c]

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/media/video/uvc/uvc_driver.c
drivers/media/video/uvc/uvc_video.c
drivers/media/video/uvc/uvcvideo.h

index 86699b11dbd02c08f6f857f500ede308db06515a..860e82361e11185ef7f9f737cb64d86102316513 100644 (file)
@@ -1891,7 +1891,7 @@ static int __uvc_resume(struct usb_interface *intf, int reset)
 
        list_for_each_entry(stream, &dev->streams, list) {
                if (stream->intf == intf)
-                       return uvc_video_resume(stream);
+                       return uvc_video_resume(stream, reset);
        }
 
        uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface "
index 253eed80c0a89f19f4283d2346aa7c6e0e39b6ed..a463b480b3660c110f15eadce9bcedb9c3aa9157 100644 (file)
@@ -1045,10 +1045,18 @@ int uvc_video_suspend(struct uvc_streaming *stream)
  * buffers, making sure userspace applications are notified of the problem
  * instead of waiting forever.
  */
-int uvc_video_resume(struct uvc_streaming *stream)
+int uvc_video_resume(struct uvc_streaming *stream, int reset)
 {
        int ret;
 
+       /* If the bus has been reset on resume, set the alternate setting to 0.
+        * This should be the default value, but some devices crash or otherwise
+        * misbehave if they don't receive a SET_INTERFACE request before any
+        * other video control request.
+        */
+       if (reset)
+               usb_set_interface(stream->dev->udev, stream->intfnum, 0);
+
        stream->frozen = 0;
 
        ret = uvc_commit_video(stream, &stream->ctrl);
index b6f6f38516403a67897f85581e2e56cab3dac3a3..f5925f6b3fe58c71d2e257d453d088d3ec490676 100644 (file)
@@ -604,7 +604,7 @@ extern const struct v4l2_file_operations uvc_fops;
 /* Video */
 extern int uvc_video_init(struct uvc_streaming *stream);
 extern int uvc_video_suspend(struct uvc_streaming *stream);
-extern int uvc_video_resume(struct uvc_streaming *stream);
+extern int uvc_video_resume(struct uvc_streaming *stream, int reset);
 extern int uvc_video_enable(struct uvc_streaming *stream, int enable);
 extern int uvc_probe_video(struct uvc_streaming *stream,
                struct uvc_streaming_control *probe);