From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933649AbcBCMnL (ORCPT ); Wed, 3 Feb 2016 07:43:11 -0500 Received: from mailout2.samsung.com ([203.254.224.25]:58446 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933410AbcBCMmX (ORCPT ); Wed, 3 Feb 2016 07:42:23 -0500 X-AuditID: cbfee61b-f793c6d00000236c-98-56b1f5ae0827 From: Robert Baldyga To: balbi@ti.com Cc: gregkh@linuxfoundation.org, andrzej.p@samsung.com, m.szyprowski@samsung.com, b.zolnierkie@samsung.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Robert Baldyga Subject: [PATCH v4 43/43] usb: gadget: f_uvc: conversion to new API Date: Wed, 03 Feb 2016 13:39:51 +0100 Message-id: <1454503191-11796-44-git-send-email-r.baldyga@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1454503191-11796-1-git-send-email-r.baldyga@samsung.com> References: <1454503191-11796-1-git-send-email-r.baldyga@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprBLMWRmVeSWpSXmKPExsVy+t9jQd11XzeGGaxr5bOY9bKdxWLjjPWs Fgfv11s0L17PZnF51xw2i0XLWpkt1h65y27x4PBOdgcOj/1z17B79G1Zxehx/MZ2Jo/Pm+QC WKK4bFJSczLLUov07RK4Mr4cv8VW8HsOY8WB/4dYGxi7mxm7GDk5JARMJBrftLFC2GISF+6t Z+ti5OIQEpjFKLH38CxGCOcno8SWjg/sIFVsAjoSW75PAOsWERCQWP/iEjtIEbPAOUaJh3fa wBLCAs4SO+beB2tgEVCVuLv9FQuIzSvgJvF001t2iHVyEiePTQZazcHBCRR/eMwBJCwk4Cqx q/U74wRG3gWMDKsYJVILkguKk9JzjfJSy/WKE3OLS/PS9ZLzczcxgsPrmfQOxsO73A8xCnAw KvHwRvzaECbEmlhWXJl7iFGCg1lJhNfo88YwId6UxMqq1KL8+KLSnNTiQ4zSHCxK4ryP/68L ExJITyxJzU5NLUgtgskycXBKNTC26VxwauTe0z2xoyrQ+unVn5EhBX+Xi8p2SdbfWnHP0Vdg hsg9lZX1Nku/TTkfqx7cI3D6XIOBQfGaY+2fmyMS1arerD78/nqTbd2BKzreQdrRssdenYqZ ejl244KmrYZli+Ss447PjS31mZrQ3mys6H/PQ8HOeeeKS4tYVh/eaVY5Yb7o7UAlluKMREMt 5qLiRABKuVorKwIAAA== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Get rid of get_alt() callback, as now USB_REQ_GET_INTERFACE is handled automatically by composite framwework. Remove boilerplate code. Signed-off-by: Robert Baldyga --- drivers/usb/gadget/function/f_uvc.c | 478 ++++++++++++------------------------ drivers/usb/gadget/function/uvc.h | 3 - 2 files changed, 160 insertions(+), 321 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 0f554c4..04ca1f9 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -179,24 +179,19 @@ static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = { */ }; -static const struct usb_descriptor_header * const uvc_fs_streaming[] = { - (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, - (struct usb_descriptor_header *) &uvc_fs_streaming_ep, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_control, &uvc_control_ep, &uvc_control_ep, + &uvc_control_ep, &uvc_ss_control_comp); +USB_COMPOSITE_ENDPOINT(ep_streaming, &uvc_fs_streaming_ep, &uvc_hs_streaming_ep, + &uvc_ss_streaming_ep, &uvc_ss_streaming_comp); -static const struct usb_descriptor_header * const uvc_hs_streaming[] = { - (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, - (struct usb_descriptor_header *) &uvc_hs_streaming_ep, - NULL, -}; +USB_COMPOSITE_ALTSETTING(intf0alt0, &uvc_control_intf, &ep_control); +USB_COMPOSITE_ALTSETTING(intf1alt0, &uvc_streaming_intf_alt0); +USB_COMPOSITE_ALTSETTING(intf1alt1, &uvc_streaming_intf_alt1, &ep_streaming); -static const struct usb_descriptor_header * const uvc_ss_streaming[] = { - (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, - (struct usb_descriptor_header *) &uvc_ss_streaming_ep, - (struct usb_descriptor_header *) &uvc_ss_streaming_comp, - NULL, -}; +USB_COMPOSITE_INTERFACE(intf0, &intf0alt0); +USB_COMPOSITE_INTERFACE(intf1, &intf1alt0, &intf1alt1); + +USB_COMPOSITE_DESCRIPTORS(uvc_descs, &intf0, &intf1); void uvc_set_trace_param(unsigned int trace) { @@ -269,43 +264,34 @@ void uvc_function_setup_continue(struct uvc_device *uvc) } static int -uvc_function_get_alt(struct usb_function *f, unsigned interface) -{ - struct uvc_device *uvc = to_uvc(f); - - INFO(f->config->cdev, "uvc_function_get_alt(%u)\n", interface); - - if (interface == uvc->control_intf) - return 0; - else if (interface != uvc->streaming_intf) - return -EINVAL; - else - return uvc->video.ep->enabled ? 1 : 0; -} - -static int uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) { struct uvc_device *uvc = to_uvc(f); struct usb_composite_dev *cdev = f->config->cdev; struct v4l2_event v4l2_event; struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; - int ret; INFO(cdev, "uvc_function_set_alt(%u, %u)\n", interface, alt); - if (interface == uvc->control_intf) { - if (alt) - return -EINVAL; - - INFO(cdev, "reset UVC Control\n"); - usb_ep_disable(uvc->control_ep); - - if (!uvc->control_ep->desc) - if (config_ep_by_speed(cdev->gadget, f, uvc->control_ep)) - return -EINVAL; + if (interface == 0) { + uvc->control_ep = usb_function_get_ep(f, interface, 0); + if (!uvc->control_ep) + return -ENODEV; + + uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, + GFP_KERNEL); + if (!uvc->control_req) + return -ENOMEM; + uvc->control_buf = kmalloc(UVC_MAX_REQUEST_SIZE, GFP_KERNEL); + if (!uvc->control_buf) { + usb_ep_free_request(cdev->gadget->ep0, + uvc->control_req); + return -ENOMEM; + } - usb_ep_enable(uvc->control_ep); + uvc->control_req->buf = uvc->control_buf; + uvc->control_req->complete = uvc_function_ep0_complete; + uvc->control_req->context = uvc; if (uvc->state == UVC_STATE_DISCONNECTED) { memset(&v4l2_event, 0, sizeof(v4l2_event)); @@ -315,75 +301,59 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) uvc->state = UVC_STATE_CONNECTED; } + } else if (interface == 1) { + /* TODO + * if (usb_endpoint_xfer_bulk(&uvc->desc.vs_ep)) + * return alt ? -EINVAL : 0; + */ - return 0; - } + switch (alt) { + case 0: + if (uvc->state != UVC_STATE_STREAMING) + return 0; - if (interface != uvc->streaming_intf) - return -EINVAL; - - /* TODO - if (usb_endpoint_xfer_bulk(&uvc->desc.vs_ep)) - return alt ? -EINVAL : 0; - */ - - switch (alt) { - case 0: - if (uvc->state != UVC_STATE_STREAMING) - return 0; - - if (uvc->video.ep) - usb_ep_disable(uvc->video.ep); - - memset(&v4l2_event, 0, sizeof(v4l2_event)); - v4l2_event.type = UVC_EVENT_STREAMOFF; - v4l2_event_queue(&uvc->vdev, &v4l2_event); - - uvc->state = UVC_STATE_CONNECTED; - return 0; + memset(&v4l2_event, 0, sizeof(v4l2_event)); + v4l2_event.type = UVC_EVENT_STREAMOFF; + v4l2_event_queue(&uvc->vdev, &v4l2_event); - case 1: - if (uvc->state != UVC_STATE_CONNECTED) + uvc->state = UVC_STATE_CONNECTED; return 0; - if (!uvc->video.ep) - return -EINVAL; - - INFO(cdev, "reset UVC\n"); - usb_ep_disable(uvc->video.ep); - - ret = config_ep_by_speed(f->config->cdev->gadget, - &(uvc->func), uvc->video.ep); - if (ret) - return ret; - usb_ep_enable(uvc->video.ep); + case 1: + if (uvc->state != UVC_STATE_CONNECTED) + return 0; - memset(&v4l2_event, 0, sizeof(v4l2_event)); - v4l2_event.type = UVC_EVENT_STREAMON; - v4l2_event_queue(&uvc->vdev, &v4l2_event); - return USB_GADGET_DELAYED_STATUS; + uvc->video.ep = usb_function_get_ep(f, interface, 0); + if (!uvc->video.ep) + return -ENODEV; - default: - return -EINVAL; + memset(&v4l2_event, 0, sizeof(v4l2_event)); + v4l2_event.type = UVC_EVENT_STREAMON; + v4l2_event_queue(&uvc->vdev, &v4l2_event); + return USB_GADGET_DELAYED_STATUS; + } } + + return 0; } static void -uvc_function_disable(struct usb_function *f) +uvc_function_clear_alt(struct usb_function *f, unsigned interface, unsigned alt) { struct uvc_device *uvc = to_uvc(f); + struct usb_composite_dev *cdev = f->config->cdev; struct v4l2_event v4l2_event; - INFO(f->config->cdev, "uvc_function_disable\n"); - - memset(&v4l2_event, 0, sizeof(v4l2_event)); - v4l2_event.type = UVC_EVENT_DISCONNECT; - v4l2_event_queue(&uvc->vdev, &v4l2_event); + if (interface == 0) { + usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); + kfree(uvc->control_buf); - uvc->state = UVC_STATE_DISCONNECTED; + memset(&v4l2_event, 0, sizeof(v4l2_event)); + v4l2_event.type = UVC_EVENT_DISCONNECT; + v4l2_event_queue(&uvc->vdev, &v4l2_event); - usb_ep_disable(uvc->video.ep); - usb_ep_disable(uvc->control_ep); + uvc->state = UVC_STATE_DISCONNECTED; + } } /* -------------------------------------------------------------------------- @@ -433,142 +403,14 @@ uvc_register_video(struct uvc_device *uvc) return video_register_device(&uvc->vdev, VFL_TYPE_GRABBER, -1); } -#define UVC_COPY_DESCRIPTOR(mem, dst, desc) \ - do { \ - memcpy(mem, desc, (desc)->bLength); \ - *(dst)++ = mem; \ - mem += (desc)->bLength; \ - } while (0); - -#define UVC_COPY_DESCRIPTORS(mem, dst, src) \ - do { \ - const struct usb_descriptor_header * const *__src; \ - for (__src = src; *__src; ++__src) { \ - memcpy(mem, *__src, (*__src)->bLength); \ - *dst++ = mem; \ - mem += (*__src)->bLength; \ - } \ - } while (0) - -static struct usb_descriptor_header ** -uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) +static int uvc_function_prep_descs(struct usb_function *f) { - struct uvc_input_header_descriptor *uvc_streaming_header; - struct uvc_header_descriptor *uvc_control_header; - const struct uvc_descriptor_header * const *uvc_control_desc; - const struct uvc_descriptor_header * const *uvc_streaming_cls; - const struct usb_descriptor_header * const *uvc_streaming_std; - const struct usb_descriptor_header * const *src; - struct usb_descriptor_header **dst; - struct usb_descriptor_header **hdr; - unsigned int control_size; - unsigned int streaming_size; - unsigned int n_desc; - unsigned int bytes; - void *mem; - - uvc_control_desc = uvc->desc.control; - uvc_streaming_cls = uvc->desc.streaming; - uvc_streaming_std = uvc_ss_streaming; - - if (!uvc_control_desc || !uvc_streaming_cls) - return ERR_PTR(-ENODEV); - - /* Descriptors layout - * - * uvc_iad - * uvc_control_intf - * Class-specific UVC control descriptors - * uvc_control_ep - * uvc_control_cs_ep - * uvc_ss_control_comp (for SS only) - * uvc_streaming_intf_alt0 - * Class-specific UVC streaming descriptors - * uvc_{fs|hs}_streaming - */ - - /* Count descriptors and compute their size. */ - control_size = 0; - streaming_size = 0; - bytes = uvc_iad.bLength + uvc_control_intf.bLength - + uvc_control_ep.bLength + uvc_control_cs_ep.bLength - + uvc_streaming_intf_alt0.bLength; - - if (speed == USB_SPEED_SUPER) { - bytes += uvc_ss_control_comp.bLength; - n_desc = 6; - } else { - n_desc = 5; - } - - for (src = (const struct usb_descriptor_header **)uvc_control_desc; - *src; ++src) { - control_size += (*src)->bLength; - bytes += (*src)->bLength; - n_desc++; - } - for (src = (const struct usb_descriptor_header **)uvc_streaming_cls; - *src; ++src) { - streaming_size += (*src)->bLength; - bytes += (*src)->bLength; - n_desc++; - } - for (src = uvc_streaming_std; *src; ++src) { - bytes += (*src)->bLength; - n_desc++; - } - - mem = kmalloc((n_desc + 1) * sizeof(*src) + bytes, GFP_KERNEL); - if (mem == NULL) - return NULL; - - hdr = mem; - dst = mem; - mem += (n_desc + 1) * sizeof(*src); - - /* Copy the descriptors. */ - UVC_COPY_DESCRIPTOR(mem, dst, &uvc_iad); - UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_intf); - - uvc_control_header = mem; - UVC_COPY_DESCRIPTORS(mem, dst, - (const struct usb_descriptor_header **)uvc_control_desc); - uvc_control_header->wTotalLength = cpu_to_le16(control_size); - uvc_control_header->bInCollection = 1; - uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf; - - UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_ep); - if (speed == USB_SPEED_SUPER) - UVC_COPY_DESCRIPTOR(mem, dst, &uvc_ss_control_comp); - - UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_cs_ep); - UVC_COPY_DESCRIPTOR(mem, dst, &uvc_streaming_intf_alt0); - - uvc_streaming_header = mem; - UVC_COPY_DESCRIPTORS(mem, dst, - (const struct usb_descriptor_header**)uvc_streaming_cls); - uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size); - uvc_streaming_header->bEndpointAddress = uvc->video.ep->address; - - UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std); - - *dst = NULL; - return hdr; -} - -static int -uvc_function_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct usb_composite_dev *cdev = c->cdev; - struct uvc_device *uvc = to_uvc(f); + struct usb_composite_dev *cdev = f->config->cdev; struct usb_string *us; unsigned int max_packet_mult; unsigned int max_packet_size; - struct usb_ep *ep; struct f_uvc_opts *opts; - int ret = -EINVAL; - - INFO(cdev, "uvc_function_bind\n"); + int ret; opts = fi_to_f_uvc_opts(f->fi); /* Sanity check the streaming endpoint module parameters. @@ -610,96 +452,107 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) cpu_to_le16(max_packet_size * max_packet_mult * opts->streaming_maxburst); - /* Allocate endpoints. */ - ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); - if (!ep) { - INFO(cdev, "Unable to allocate control EP\n"); - goto error; - } - uvc->control_ep = ep; - - if (gadget_is_superspeed(c->cdev->gadget)) - ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep, - &uvc_ss_streaming_comp); - else if (gadget_is_dualspeed(cdev->gadget)) - ep = usb_ep_autoconfig(cdev->gadget, &uvc_hs_streaming_ep); - else - ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep); - - if (!ep) { - INFO(cdev, "Unable to allocate streaming EP\n"); - goto error; - } - uvc->video.ep = ep; - - uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address; - uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address; - uvc_ss_streaming_ep.bEndpointAddress = uvc->video.ep->address; - us = usb_gstrings_attach(cdev, uvc_function_strings, ARRAY_SIZE(uvc_en_us_strings)); - if (IS_ERR(us)) { - ret = PTR_ERR(us); - goto error; - } + if (IS_ERR(us)) + return PTR_ERR(us); uvc_iad.iFunction = us[UVC_STRING_CONTROL_IDX].id; uvc_control_intf.iInterface = us[UVC_STRING_CONTROL_IDX].id; ret = us[UVC_STRING_STREAMING_IDX].id; uvc_streaming_intf_alt0.iInterface = ret; uvc_streaming_intf_alt1.iInterface = ret; - /* Allocate interface IDs. */ - if ((ret = usb_interface_id(c, f)) < 0) - goto error; - uvc_iad.bFirstInterface = ret; - uvc_control_intf.bInterfaceNumber = ret; - uvc->control_intf = ret; + return usb_function_set_descs(f, &uvc_descs); +} - if ((ret = usb_interface_id(c, f)) < 0) - goto error; - uvc_streaming_intf_alt0.bInterfaceNumber = ret; - uvc_streaming_intf_alt1.bInterfaceNumber = ret; - uvc->streaming_intf = ret; - - /* Copy descriptors */ - f->fs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); - 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 (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; - } - } +static int uvc_function_prep_vendor_descs(struct usb_function *f) +{ + struct usb_composite_dev *cdev = f->config->cdev; + struct uvc_device *uvc = to_uvc(f); + const struct usb_descriptor_header * const *uvc_control_desc; + const struct usb_descriptor_header * const *uvc_streaming_cls; + const struct usb_descriptor_header * const *desc; + struct uvc_input_header_descriptor uvc_streaming_header; + struct uvc_header_descriptor uvc_control_header; + unsigned int control_size; + unsigned int streaming_size; + int intf0_id, intf1_id; + int ret = -EINVAL; - /* Preallocate control endpoint request. */ - uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL); - uvc->control_buf = kmalloc(UVC_MAX_REQUEST_SIZE, GFP_KERNEL); - if (uvc->control_req == NULL || uvc->control_buf == NULL) { - ret = -ENOMEM; - goto error; - } + intf0_id = usb_get_interface_id(f, 0); + intf1_id = usb_get_interface_id(f, 1); + + uvc_iad.bFirstInterface = intf0_id; + + uvc_control_desc = (const struct usb_descriptor_header * const *) + uvc->desc.control; + uvc_streaming_cls = (const struct usb_descriptor_header * const *) + uvc->desc.streaming; + + if (!uvc_control_desc || !uvc_streaming_cls) + return -ENODEV; + + /* Descriptors layout + * + * uvc_iad + * uvc_control_intf + * Class-specific UVC control descriptors + * uvc_control_ep + * uvc_control_cs_ep + * uvc_ss_control_comp (for SS only) + * uvc_streaming_intf_alt0 + * Class-specific UVC streaming descriptors + * uvc_{fs|hs}_streaming + */ + + /* Count descriptors and compute their size. */ + control_size = 0; + streaming_size = 0; + + for (desc = uvc_control_desc; *desc; ++desc) + control_size += (*desc)->bLength; + for (desc = uvc_streaming_cls; *desc; ++desc) + streaming_size += (*desc)->bLength; + + usb_function_add_vendor_desc(f, + (struct usb_descriptor_header *)&uvc_iad); + + /* uvc_control_intf */ + + memcpy(&uvc_control_header, uvc_control_desc[0], + uvc_control_desc[0]->bLength); + uvc_control_header.wTotalLength = cpu_to_le16(control_size); + uvc_control_header.bInCollection = 1; + uvc_control_header.baInterfaceNr[0] = intf1_id; + + usb_altset_add_vendor_desc(f, 0, 0, + (struct usb_descriptor_header *)&uvc_control_header); + + for (desc = uvc_control_desc + 1; *desc; ++desc) + usb_altset_add_vendor_desc(f, 0, 0, *desc); + + usb_ep_add_vendor_desc(f, 0, 0, 0, + (struct usb_descriptor_header *)&uvc_control_cs_ep); + + /* uvc_streaming_intf_alt0 */ - uvc->control_req->buf = uvc->control_buf; - uvc->control_req->complete = uvc_function_ep0_complete; - uvc->control_req->context = uvc; + memcpy(&uvc_streaming_header, uvc_streaming_cls[0], + uvc_streaming_cls[0]->bLength); + uvc_streaming_header.wTotalLength = cpu_to_le16(streaming_size); + uvc_streaming_header.bEndpointAddress = + usb_get_endpoint_address(f, 1, 1, 0); - if (v4l2_device_register(&cdev->gadget->dev, &uvc->v4l2_dev)) { + usb_altset_add_vendor_desc(f, 1, 0, + (struct usb_descriptor_header *)&uvc_streaming_header); + + for (desc = uvc_streaming_cls + 1; *desc; ++desc) + usb_altset_add_vendor_desc(f, 1, 0, *desc); + + + ret = v4l2_device_register(&cdev->gadget->dev, &uvc->v4l2_dev); + if (ret < 0) { printk(KERN_INFO "v4l2_device_register failed\n"); - goto error; + return ret; } /* Initialise video. */ @@ -715,15 +568,9 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) } return 0; - error: v4l2_device_unregister(&uvc->v4l2_dev); - if (uvc->control_req) - usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); - kfree(uvc->control_buf); - - usb_free_all_descriptors(f); return ret; } @@ -800,7 +647,7 @@ static struct usb_function_instance *uvc_alloc_inst(void) md->bTransferCharacteristics = 1; md->bMatrixCoefficients = 4; - /* Prepare hs control class descriptors for configfs-based gadgets */ + /* Prepare control class descriptors for configfs-based gadgets */ ctl_cls = opts->uvc_control_cls; ctl_cls[0] = NULL; /* assigned elsewhere by configfs */ ctl_cls[1] = (struct uvc_descriptor_header *)cd; @@ -835,11 +682,6 @@ static void uvc_unbind(struct usb_configuration *c, struct usb_function *f) video_unregister_device(&uvc->vdev); v4l2_device_unregister(&uvc->v4l2_dev); - - usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); - kfree(uvc->control_buf); - - usb_free_all_descriptors(f); } static struct usb_function *uvc_alloc(struct usb_function_instance *fi) @@ -870,11 +712,11 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi) /* Register the function. */ uvc->func.name = "uvc"; - uvc->func.bind = uvc_function_bind; + uvc->func.prep_descs = uvc_function_prep_descs; + uvc->func.prep_vendor_descs = uvc_function_prep_vendor_descs; uvc->func.unbind = uvc_unbind; - uvc->func.get_alt = uvc_function_get_alt; uvc->func.set_alt = uvc_function_set_alt; - uvc->func.disable = uvc_function_disable; + uvc->func.clear_alt = uvc_function_clear_alt; uvc->func.setup = uvc_function_setup; uvc->func.free_func = uvc_free; uvc->func.bind_deactivated = true; diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index bccdda2..ec69535 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -155,13 +155,10 @@ struct uvc_device const struct uvc_descriptor_header * const *streaming; } desc; - unsigned int control_intf; struct usb_ep *control_ep; struct usb_request *control_req; void *control_buf; - unsigned int streaming_intf; - /* Events */ unsigned int event_length; unsigned int event_setup_out : 1; -- 1.9.1