usb: gadget: f_uvc: Store EP0 control request state during setup stage
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Mon, 8 Sep 2014 08:18:14 +0000 (11:18 +0300)
committerFelipe Balbi <balbi@ti.com>
Mon, 8 Sep 2014 13:49:28 +0000 (08:49 -0500)
To handle class requests received on ep0, the driver needs to access the
length and direction of the request after the setup stage. It currently
stores them in a v4l2 event during the setup stage, and then copies them
from the event structure to the driver internal state structure when the
event is dequeued.

This two-steps approach isn't necessary. Simplify the driver by storing
the needed information in the driver internal state structure directly
during the setup stage.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/function/f_uvc.c
drivers/usb/gadget/function/uvc_v4l2.c

index ff4340a1b4b3f17d7168eccfeb535f5aefac5a4e..e9d625b3575142ca4735cd6ce7b6c76373ccdf2c 100644 (file)
@@ -251,6 +251,12 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
        if (le16_to_cpu(ctrl->wLength) > UVC_MAX_REQUEST_SIZE)
                return -EINVAL;
 
+       /* Tell the complete callback to generate an event for the next request
+        * that will be enqueued by UVCIOC_SEND_RESPONSE.
+        */
+       uvc->event_setup_out = !(ctrl->bRequestType & USB_DIR_IN);
+       uvc->event_length = le16_to_cpu(ctrl->wLength);
+
        memset(&v4l2_event, 0, sizeof(v4l2_event));
        v4l2_event.type = UVC_EVENT_SETUP;
        memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req));
index bcd71cee7b5126c5edf1ba10145f16eeecaba78a..f22b878f163a3db016223a60cefba5b200792fdc 100644 (file)
@@ -271,25 +271,8 @@ uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 
        /* Events */
        case VIDIOC_DQEVENT:
-       {
-               struct v4l2_event *event = arg;
-
-               ret = v4l2_event_dequeue(&handle->vfh, event,
+               return v4l2_event_dequeue(&handle->vfh, arg,
                                         file->f_flags & O_NONBLOCK);
-               if (ret == 0 && event->type == UVC_EVENT_SETUP) {
-                       struct uvc_event *uvc_event = (void *)&event->u.data;
-
-                       /* Tell the complete callback to generate an event for
-                        * the next request that will be enqueued by
-                        * uvc_event_write.
-                        */
-                       uvc->event_setup_out =
-                               !(uvc_event->req.bRequestType & USB_DIR_IN);
-                       uvc->event_length = uvc_event->req.wLength;
-               }
-
-               return ret;
-       }
 
        case VIDIOC_SUBSCRIBE_EVENT:
        {