Re: [PATCH V3 4/5] usb: gadget/uvc: Add support for 'USB_GADGET_DELAYED_STATUS' response for a set_intf(alt-set 1) command

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux