From d8e96c4bf6e3cdb6580381fdad2bfd93fae36ff1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 17 Feb 2015 05:44:06 -0300 Subject: [media] uvc gadget: switch to v4l2 core locking Switch this driver over to the V4L2 core locking mechanism in preparation for switching to unlocked_ioctl. Suggested by Laurent Pinchart. This patch introduces a new mutex at the struct uvc_video level and drops the old mutex at the queue level. The new lock is now used for all ioctl locking and in the release file operation (the driver always has to take care of locking in file operations, the core only serializes ioctls). Note that the mmap and get_unmapped_area file operations no longer take a lock. Commit f035eb4e976ef5a059e30bc91cfd310ff030a7d3 fixed a AB-BA deadlock by moving all the locking down into vb2, so the mmap and get_unmapped_area file operations should no longer do any locking before calling into vb2. Signed-off-by: Hans Verkuil Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/usb/gadget/function/uvc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb/gadget/function/uvc.h') diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index f67695cb28f8..3390ecd1a1f3 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -115,6 +115,7 @@ struct uvc_video unsigned int width; unsigned int height; unsigned int imagesize; + struct mutex mutex; /* protects frame parameters */ /* Requests */ unsigned int req_size; -- cgit v1.2.3 From dbe98b30d3a0d703369fef9712482e12fc685805 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 9 Mar 2015 13:34:08 -0300 Subject: [media] gadget/uvc: embed video_device Embed the video_device struct to simplify the error handling and in order to (eventually) get rid of video_device_alloc/release. Signed-off-by: Hans Verkuil Cc: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/usb/gadget/function/f_uvc.c | 44 +++++++++++++++---------------------- drivers/usb/gadget/function/uvc.h | 2 +- 2 files changed, 19 insertions(+), 27 deletions(-) (limited to 'drivers/usb/gadget/function/uvc.h') diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 3242bc684e2d..cf0df8fbba89 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -222,7 +222,7 @@ uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req) v4l2_event.type = UVC_EVENT_DATA; uvc_event->data.length = req->actual; memcpy(&uvc_event->data.data, req->buf, req->actual); - v4l2_event_queue(uvc->vdev, &v4l2_event); + v4l2_event_queue(&uvc->vdev, &v4l2_event); } } @@ -256,7 +256,7 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_SETUP; memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req)); - v4l2_event_queue(uvc->vdev, &v4l2_event); + v4l2_event_queue(&uvc->vdev, &v4l2_event); return 0; } @@ -315,7 +315,7 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_CONNECT; uvc_event->speed = cdev->gadget->speed; - v4l2_event_queue(uvc->vdev, &v4l2_event); + v4l2_event_queue(&uvc->vdev, &v4l2_event); uvc->state = UVC_STATE_CONNECTED; } @@ -343,7 +343,7 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_STREAMOFF; - v4l2_event_queue(uvc->vdev, &v4l2_event); + v4l2_event_queue(&uvc->vdev, &v4l2_event); uvc->state = UVC_STATE_CONNECTED; return 0; @@ -370,7 +370,7 @@ 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); + v4l2_event_queue(&uvc->vdev, &v4l2_event); return USB_GADGET_DELAYED_STATUS; default: @@ -388,7 +388,7 @@ uvc_function_disable(struct usb_function *f) memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_DISCONNECT; - v4l2_event_queue(uvc->vdev, &v4l2_event); + v4l2_event_queue(&uvc->vdev, &v4l2_event); uvc->state = UVC_STATE_DISCONNECTED; @@ -435,25 +435,19 @@ static int uvc_register_video(struct uvc_device *uvc) { struct usb_composite_dev *cdev = uvc->func.config->cdev; - struct video_device *video; /* TODO reference counting. */ - video = video_device_alloc(); - if (video == NULL) - return -ENOMEM; - - video->v4l2_dev = &uvc->v4l2_dev; - video->fops = &uvc_v4l2_fops; - video->ioctl_ops = &uvc_v4l2_ioctl_ops; - video->release = video_device_release; - video->vfl_dir = VFL_DIR_TX; - video->lock = &uvc->video.mutex; - strlcpy(video->name, cdev->gadget->name, sizeof(video->name)); - - uvc->vdev = video; - video_set_drvdata(video, uvc); - - return video_register_device(video, VFL_TYPE_GRABBER, -1); + uvc->vdev.v4l2_dev = &uvc->v4l2_dev; + uvc->vdev.fops = &uvc_v4l2_fops; + uvc->vdev.ioctl_ops = &uvc_v4l2_ioctl_ops; + uvc->vdev.release = video_device_release_empty; + uvc->vdev.vfl_dir = VFL_DIR_TX; + uvc->vdev.lock = &uvc->video.mutex; + strlcpy(uvc->vdev.name, cdev->gadget->name, sizeof(uvc->vdev.name)); + + video_set_drvdata(&uvc->vdev, uvc); + + return video_register_device(&uvc->vdev, VFL_TYPE_GRABBER, -1); } #define UVC_COPY_DESCRIPTOR(mem, dst, desc) \ @@ -766,8 +760,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) error: v4l2_device_unregister(&uvc->v4l2_dev); - if (uvc->vdev) - video_device_release(uvc->vdev); if (uvc->control_ep) uvc->control_ep->driver_data = NULL; @@ -898,7 +890,7 @@ static void uvc_unbind(struct usb_configuration *c, struct usb_function *f) INFO(cdev, "%s\n", __func__); - video_unregister_device(uvc->vdev); + video_unregister_device(&uvc->vdev); v4l2_device_unregister(&uvc->v4l2_dev); uvc->control_ep->driver_data = NULL; uvc->video.ep->driver_data = NULL; diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 3390ecd1a1f3..ebe409b9e419 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -144,7 +144,7 @@ enum uvc_state struct uvc_device { - struct video_device *vdev; + struct video_device vdev; struct v4l2_device v4l2_dev; enum uvc_state state; struct usb_function func; -- cgit v1.2.3