Hi Bhupesh, Thank you for the patch. On Thursday 17 January 2013 16:23:52 Bhupesh Sharma wrote: > This patch adds the support in UVC webcam gadget design for providing > USB_GADGET_DELAYED_STATUS in response to a set_interface(alt setting 1) > command issue by the Host. > > The current UVC webcam gadget design generates a STREAMON event > corresponding to a set_interface(alt setting 1) command from the Host. > This STREAMON event will eventually be routed to a real V4L2 device. > > To start video streaming, it may be required to perform some register writes > to a camera sensor device over slow external busses like I2C or SPI. So, it > makes sense to ensure that we delay the STATUS stage of the set_interface > (alt setting 1) command. > > Otherwise, a lot of ISOC IN tokens sent by the Host will be replied to by > zero-length packets by the webcam device. On certain Hosts this may even > lead to ISOC URBs been cancelled from the Host side. > > So, as soon as we finish doing all the "streaming" related stuff on the > real V4L2 device, we call a STREAMON ioctl on the UVC side and from here we > call the 'usb_composite_setup_continue' function to complete the status > stage of the set_interface(alt setting 1) command. > > Further, we need to ensure that we queue no video buffers on the UVC webcam > gadget, until we de-queue a video buffer from the V4L2 device. > So, the application should call the STREAMON on UVC side only when it has > dequeued sufficient buffers from the V4L2 side and queued them to the > UVC gadget. > > Signed-off-by: Bhupesh Sharma <bhupesh.sharma@xxxxxx> This looks good to me, Acked-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> I've applied it to my tree with the commit message reflowed to fit into git's 72 characters default line length. > --- > drivers/usb/gadget/f_uvc.c | 15 +++++++++------ > drivers/usb/gadget/uvc.h | 1 + > drivers/usb/gadget/uvc_v4l2.c | 14 +++++++++++++- > 3 files changed, 23 insertions(+), 7 deletions(-) > > diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c > index 1769f3e..34612b0 100644 > --- a/drivers/usb/gadget/f_uvc.c > +++ b/drivers/usb/gadget/f_uvc.c > @@ -265,6 +265,13 @@ uvc_function_setup(struct usb_function *f, const struct > usb_ctrlrequest *ctrl) return 0; > } > > +void uvc_function_setup_continue(struct uvc_device *uvc) > +{ > + struct usb_composite_dev *cdev = uvc->func.config->cdev; > + > + usb_composite_setup_continue(cdev); > +} > + > static int > uvc_function_get_alt(struct usb_function *f, unsigned interface) > { > @@ -327,7 +334,7 @@ uvc_function_set_alt(struct usb_function *f, unsigned > interface, unsigned alt) v4l2_event_queue(uvc->vdev, &v4l2_event); > > uvc->state = UVC_STATE_CONNECTED; > - break; > + return 0; > > case 1: > if (uvc->state != UVC_STATE_CONNECTED) > @@ -344,15 +351,11 @@ uvc_function_set_alt(struct usb_function *f, unsigned > interface, unsigned alt) memset(&v4l2_event, 0, sizeof(v4l2_event)); > v4l2_event.type = UVC_EVENT_STREAMON; > v4l2_event_queue(uvc->vdev, &v4l2_event); > - > - uvc->state = UVC_STATE_STREAMING; > - break; > + return USB_GADGET_DELAYED_STATUS; > > default: > return -EINVAL; > } > - > - return 0; > } > > static void > diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h > index 93b0c11..9391993 100644 > --- a/drivers/usb/gadget/uvc.h > +++ b/drivers/usb/gadget/uvc.h > @@ -190,6 +190,7 @@ struct uvc_file_handle > * Functions > */ > > +extern void uvc_function_setup_continue(struct uvc_device *uvc); > extern void uvc_endpoint_stream(struct uvc_device *dev); > > extern void uvc_function_connect(struct uvc_device *uvc); > diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c > index 134bfe5..d03e6c7 100644 > --- a/drivers/usb/gadget/uvc_v4l2.c > +++ b/drivers/usb/gadget/uvc_v4l2.c > @@ -245,7 +245,19 @@ uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, > void *arg) if (*type != video->queue.queue.type) > return -EINVAL; > > - return uvc_video_enable(video, 1); > + /* Enable UVC video. */ > + ret = uvc_video_enable(video, 1); > + if (ret < 0) > + return ret; > + > + /* > + * Complete the alternate setting selection setup phase now that > + * userspace is ready to provide video frames. > + */ > + uvc_function_setup_continue(uvc); > + uvc->state = UVC_STATE_STREAMING; > + > + return 0; > } > > case VIDIOC_STREAMOFF: -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html