summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/function/f_uvc.c
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2014-12-10 12:34:01 +0100
committerFelipe Balbi <balbi@ti.com>2015-01-12 12:13:26 -0600
commit6c25955ed632227d28b85db274e519b766e26ddd (patch)
tree1f4e689e4c0a02b254bc36b34e8bcd238c6bc856 /drivers/usb/gadget/function/f_uvc.c
parentbbea6de1bd12dd509f774f2a3165216eeac7bc54 (diff)
usb: gadget: uvc: verify descriptors presence
If the caller of uvc_alloc() does not provide enough descriptors, binding the function should fail, so appropriate code is returned from uvc_copy_descriptors(). uvc_function_bind() is modified accordingly to account for possible errors from uvc_copy_descriptors(). Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/function/f_uvc.c')
-rw-r--r--drivers/usb/gadget/function/f_uvc.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
index 5b4ab39cce44..62ca0c5c7f6e 100644
--- a/drivers/usb/gadget/function/f_uvc.c
+++ b/drivers/usb/gadget/function/f_uvc.c
@@ -509,6 +509,9 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
break;
}
+ if (!uvc_control_desc || !uvc_streaming_cls)
+ return ERR_PTR(-ENODEV);
+
/* Descriptors layout
*
* uvc_iad
@@ -700,10 +703,27 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
/* Copy descriptors */
f->fs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL);
- if (gadget_is_dualspeed(cdev->gadget))
+ if (IS_ERR(f->fs_descriptors)) {
+ ret = PTR_ERR(f->fs_descriptors);
+ f->fs_descriptors = NULL;
+ goto error;
+ }
+ if (gadget_is_dualspeed(cdev->gadget)) {
f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH);
- if (gadget_is_superspeed(c->cdev->gadget))
+ if (IS_ERR(f->hs_descriptors)) {
+ ret = PTR_ERR(f->hs_descriptors);
+ f->hs_descriptors = NULL;
+ goto error;
+ }
+ }
+ if (gadget_is_superspeed(c->cdev->gadget)) {
f->ss_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_SUPER);
+ if (IS_ERR(f->ss_descriptors)) {
+ ret = PTR_ERR(f->ss_descriptors);
+ f->ss_descriptors = NULL;
+ goto error;
+ }
+ }
/* Preallocate control endpoint request. */
uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL);