Lines Matching +full:ctrl +full:- +full:ids
1 // SPDX-License-Identifier: GPL-2.0+
3 * uvc_gadget.c -- USB Video Class Gadget driver
5 * Copyright (C) 2009-2010
24 #include <media/v4l2-dev.h>
25 #include <media/v4l2-event.h>
36 /* --------------------------------------------------------------------------
40 /* string IDs are assigned dynamically */
49 .language = 0x0409, /* en-us */
200 /* --------------------------------------------------------------------------
207 struct uvc_device *uvc = req->context; in uvc_function_ep0_complete()
211 if (uvc->event_setup_out) { in uvc_function_ep0_complete()
212 uvc->event_setup_out = 0; in uvc_function_ep0_complete()
216 uvc_event->data.length = min_t(unsigned int, req->actual, in uvc_function_ep0_complete()
217 sizeof(uvc_event->data.data)); in uvc_function_ep0_complete()
218 memcpy(&uvc_event->data.data, req->buf, uvc_event->data.length); in uvc_function_ep0_complete()
219 v4l2_event_queue(&uvc->vdev, &v4l2_event); in uvc_function_ep0_complete()
224 uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) in uvc_function_setup() argument
229 unsigned int interface = le16_to_cpu(ctrl->wIndex) & 0xff; in uvc_function_setup()
232 if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) { in uvc_function_setup()
234 return -EINVAL; in uvc_function_setup()
238 if (le16_to_cpu(ctrl->wLength) > UVC_MAX_REQUEST_SIZE) in uvc_function_setup()
239 return -EINVAL; in uvc_function_setup()
245 uvc->event_setup_out = !(ctrl->bRequestType & USB_DIR_IN); in uvc_function_setup()
246 uvc->event_length = le16_to_cpu(ctrl->wLength); in uvc_function_setup()
250 memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req)); in uvc_function_setup()
253 * the ctrl request so the userspace doesn't have to bother with in uvc_function_setup()
256 mctrl = &uvc_event->req; in uvc_function_setup()
257 mctrl->wIndex &= ~cpu_to_le16(0xff); in uvc_function_setup()
258 if (interface == uvc->streaming_intf) in uvc_function_setup()
259 mctrl->wIndex = cpu_to_le16(UVC_STRING_STREAMING_IDX); in uvc_function_setup()
261 v4l2_event_queue(&uvc->vdev, &v4l2_event); in uvc_function_setup()
268 struct usb_composite_dev *cdev = uvc->func.config->cdev; in uvc_function_setup_continue()
270 if (disable_ep && uvc->video.ep) in uvc_function_setup_continue()
271 usb_ep_disable(uvc->video.ep); in uvc_function_setup_continue()
283 if (interface == uvc->control_intf) in uvc_function_get_alt()
285 else if (interface != uvc->streaming_intf) in uvc_function_get_alt()
286 return -EINVAL; in uvc_function_get_alt()
288 return uvc->video.ep->enabled ? 1 : 0; in uvc_function_get_alt()
295 struct usb_composite_dev *cdev = f->config->cdev; in uvc_function_set_alt()
302 if (interface == uvc->control_intf) { in uvc_function_set_alt()
304 return -EINVAL; in uvc_function_set_alt()
306 if (uvc->enable_interrupt_ep) { in uvc_function_set_alt()
308 usb_ep_disable(uvc->interrupt_ep); in uvc_function_set_alt()
310 if (!uvc->interrupt_ep->desc) in uvc_function_set_alt()
311 if (config_ep_by_speed(cdev->gadget, f, in uvc_function_set_alt()
312 uvc->interrupt_ep)) in uvc_function_set_alt()
313 return -EINVAL; in uvc_function_set_alt()
315 usb_ep_enable(uvc->interrupt_ep); in uvc_function_set_alt()
318 if (uvc->state == UVC_STATE_DISCONNECTED) { in uvc_function_set_alt()
321 uvc_event->speed = cdev->gadget->speed; in uvc_function_set_alt()
322 v4l2_event_queue(&uvc->vdev, &v4l2_event); in uvc_function_set_alt()
324 uvc->state = UVC_STATE_CONNECTED; in uvc_function_set_alt()
330 if (interface != uvc->streaming_intf) in uvc_function_set_alt()
331 return -EINVAL; in uvc_function_set_alt()
334 if (usb_endpoint_xfer_bulk(&uvc->desc.vs_ep)) in uvc_function_set_alt()
335 return alt ? -EINVAL : 0; in uvc_function_set_alt()
340 if (uvc->state != UVC_STATE_STREAMING) in uvc_function_set_alt()
345 v4l2_event_queue(&uvc->vdev, &v4l2_event); in uvc_function_set_alt()
350 if (uvc->state != UVC_STATE_CONNECTED) in uvc_function_set_alt()
353 if (!uvc->video.ep) in uvc_function_set_alt()
354 return -EINVAL; in uvc_function_set_alt()
357 usb_ep_disable(uvc->video.ep); in uvc_function_set_alt()
359 ret = config_ep_by_speed(f->config->cdev->gadget, in uvc_function_set_alt()
360 &(uvc->func), uvc->video.ep); in uvc_function_set_alt()
363 usb_ep_enable(uvc->video.ep); in uvc_function_set_alt()
367 v4l2_event_queue(&uvc->vdev, &v4l2_event); in uvc_function_set_alt()
371 return -EINVAL; in uvc_function_set_alt()
385 v4l2_event_queue(&uvc->vdev, &v4l2_event); in uvc_function_disable()
387 uvc->state = UVC_STATE_DISCONNECTED; in uvc_function_disable()
389 usb_ep_disable(uvc->video.ep); in uvc_function_disable()
390 if (uvc->enable_interrupt_ep) in uvc_function_disable()
391 usb_ep_disable(uvc->interrupt_ep); in uvc_function_disable()
394 /* --------------------------------------------------------------------------
403 if ((ret = usb_function_activate(&uvc->func)) < 0) in uvc_function_connect()
404 uvcg_info(&uvc->func, "UVC connect failed with %d\n", ret); in uvc_function_connect()
412 if ((ret = usb_function_deactivate(&uvc->func)) < 0) in uvc_function_disconnect()
413 uvcg_info(&uvc->func, "UVC disconnect failed with %d\n", ret); in uvc_function_disconnect()
416 /* --------------------------------------------------------------------------
425 return sprintf(buf, "%s\n", uvc->func.fi->group.cg_item.ci_name); in function_name_show()
433 struct usb_composite_dev *cdev = uvc->func.config->cdev; in uvc_register_video()
437 memset(&uvc->vdev, 0, sizeof(uvc->vdev)); in uvc_register_video()
438 uvc->vdev.v4l2_dev = &uvc->v4l2_dev; in uvc_register_video()
439 uvc->vdev.v4l2_dev->dev = &cdev->gadget->dev; in uvc_register_video()
440 uvc->vdev.fops = &uvc_v4l2_fops; in uvc_register_video()
441 uvc->vdev.ioctl_ops = &uvc_v4l2_ioctl_ops; in uvc_register_video()
442 uvc->vdev.release = video_device_release_empty; in uvc_register_video()
443 uvc->vdev.vfl_dir = VFL_DIR_TX; in uvc_register_video()
444 uvc->vdev.lock = &uvc->video.mutex; in uvc_register_video()
445 uvc->vdev.device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; in uvc_register_video()
446 strscpy(uvc->vdev.name, cdev->gadget->name, sizeof(uvc->vdev.name)); in uvc_register_video()
448 video_set_drvdata(&uvc->vdev, uvc); in uvc_register_video()
450 ret = video_register_device(&uvc->vdev, VFL_TYPE_VIDEO, -1); in uvc_register_video()
454 ret = device_create_file(&uvc->vdev.dev, &dev_attr_function_name); in uvc_register_video()
456 video_unregister_device(&uvc->vdev); in uvc_register_video()
465 memcpy(mem, desc, (desc)->bLength); \
467 mem += (desc)->bLength; \
474 memcpy(mem, *__src, (*__src)->bLength); \
476 mem += (*__src)->bLength; \
486 memcpy(mem, (desc)->baSourceID, (desc)->bNrInPins); \
487 mem += (desc)->bNrInPins; \
489 memcpy(mem, &(desc)->bControlSize, 1); \
492 memcpy(mem, (desc)->bmControls, (desc)->bControlSize); \
493 mem += (desc)->bControlSize; \
495 memcpy(mem, &(desc)->iExtension, 1); \
520 uvc_control_desc = uvc->desc.ss_control; in uvc_copy_descriptors()
521 uvc_streaming_cls = uvc->desc.ss_streaming; in uvc_copy_descriptors()
526 uvc_control_desc = uvc->desc.fs_control; in uvc_copy_descriptors()
527 uvc_streaming_cls = uvc->desc.hs_streaming; in uvc_copy_descriptors()
533 uvc_control_desc = uvc->desc.fs_control; in uvc_copy_descriptors()
534 uvc_streaming_cls = uvc->desc.fs_streaming; in uvc_copy_descriptors()
540 return ERR_PTR(-ENODEV); in uvc_copy_descriptors()
547 * Class-specific UVC control descriptors in uvc_copy_descriptors()
552 * Class-specific UVC streaming descriptors in uvc_copy_descriptors()
563 if (uvc->enable_interrupt_ep) { in uvc_copy_descriptors()
576 control_size += (*src)->bLength; in uvc_copy_descriptors()
577 bytes += (*src)->bLength; in uvc_copy_descriptors()
581 list_for_each_entry(xu, uvc->desc.extension_units, list) { in uvc_copy_descriptors()
582 control_size += xu->desc.bLength; in uvc_copy_descriptors()
583 bytes += xu->desc.bLength; in uvc_copy_descriptors()
589 streaming_size += (*src)->bLength; in uvc_copy_descriptors()
590 bytes += (*src)->bLength; in uvc_copy_descriptors()
594 bytes += (*src)->bLength; in uvc_copy_descriptors()
614 list_for_each_entry(xu, uvc->desc.extension_units, list) in uvc_copy_descriptors()
615 UVC_COPY_XU_DESCRIPTOR(mem, dst, &xu->desc); in uvc_copy_descriptors()
617 uvc_control_header->wTotalLength = cpu_to_le16(control_size); in uvc_copy_descriptors()
618 uvc_control_header->bInCollection = 1; in uvc_copy_descriptors()
619 uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf; in uvc_copy_descriptors()
621 if (uvc->enable_interrupt_ep) { in uvc_copy_descriptors()
635 uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size); in uvc_copy_descriptors()
636 uvc_streaming_header->bEndpointAddress = uvc->video.ep->address; in uvc_copy_descriptors()
647 struct usb_composite_dev *cdev = c->cdev; in uvc_function_bind()
655 int ret = -EINVAL; in uvc_function_bind()
659 opts = fi_to_f_uvc_opts(f->fi); in uvc_function_bind()
661 opts->streaming_interval = clamp(opts->streaming_interval, 1U, 16U); in uvc_function_bind()
662 opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U); in uvc_function_bind()
663 opts->streaming_maxburst = min(opts->streaming_maxburst, 15U); in uvc_function_bind()
666 if (opts->streaming_maxburst && in uvc_function_bind()
667 (opts->streaming_maxpacket % 1024) != 0) { in uvc_function_bind()
668 opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024); in uvc_function_bind()
670 opts->streaming_maxpacket); in uvc_function_bind()
680 if (opts->streaming_maxpacket <= 1024) { in uvc_function_bind()
682 max_packet_size = opts->streaming_maxpacket; in uvc_function_bind()
683 } else if (opts->streaming_maxpacket <= 2048) { in uvc_function_bind()
685 max_packet_size = opts->streaming_maxpacket / 2; in uvc_function_bind()
688 max_packet_size = opts->streaming_maxpacket / 3; in uvc_function_bind()
692 cpu_to_le16(min(opts->streaming_maxpacket, 1023U)); in uvc_function_bind()
693 uvc_fs_streaming_ep.bInterval = opts->streaming_interval; in uvc_function_bind()
696 cpu_to_le16(max_packet_size | ((max_packet_mult - 1) << 11)); in uvc_function_bind()
698 /* A high-bandwidth endpoint must specify a bInterval value of 1 */ in uvc_function_bind()
702 uvc_hs_streaming_ep.bInterval = opts->streaming_interval; in uvc_function_bind()
705 uvc_ss_streaming_ep.bInterval = opts->streaming_interval; in uvc_function_bind()
706 uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1; in uvc_function_bind()
707 uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst; in uvc_function_bind()
710 (opts->streaming_maxburst + 1)); in uvc_function_bind()
713 if (opts->enable_interrupt_ep) { in uvc_function_bind()
714 ep = usb_ep_autoconfig(cdev->gadget, &uvc_interrupt_ep); in uvc_function_bind()
719 uvc->interrupt_ep = ep; in uvc_function_bind()
722 uvc->enable_interrupt_ep = opts->enable_interrupt_ep; in uvc_function_bind()
732 if (gadget_is_superspeed(c->cdev->gadget)) in uvc_function_bind()
733 ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep, in uvc_function_bind()
735 else if (gadget_is_dualspeed(cdev->gadget)) in uvc_function_bind()
736 ep = usb_ep_autoconfig(cdev->gadget, &uvc_hs_streaming_ep); in uvc_function_bind()
738 ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep); in uvc_function_bind()
744 uvc->video.ep = ep; in uvc_function_bind()
746 uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address; in uvc_function_bind()
747 uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address; in uvc_function_bind()
748 uvc_ss_streaming_ep.bEndpointAddress = uvc->video.ep->address; in uvc_function_bind()
754 list_for_each_entry(xu, &opts->extension_units, list) in uvc_function_bind()
755 if (xu->string_descriptor_index) in uvc_function_bind()
756 xu->desc.iExtension = cdev->usb_strings[xu->string_descriptor_index].id; in uvc_function_bind()
759 * We attach the hard-coded defaults incase the user does not provide in uvc_function_bind()
762 uvc_en_us_strings[UVC_STRING_CONTROL_IDX].s = opts->function_name; in uvc_function_bind()
770 uvc_iad.iFunction = opts->iad_index ? cdev->usb_strings[opts->iad_index].id : in uvc_function_bind()
772 uvc_streaming_intf_alt0.iInterface = opts->vs0_index ? in uvc_function_bind()
773 cdev->usb_strings[opts->vs0_index].id : in uvc_function_bind()
775 uvc_streaming_intf_alt1.iInterface = opts->vs1_index ? in uvc_function_bind()
776 cdev->usb_strings[opts->vs1_index].id : in uvc_function_bind()
779 /* Allocate interface IDs. */ in uvc_function_bind()
784 uvc->control_intf = ret; in uvc_function_bind()
785 opts->control_interface = ret; in uvc_function_bind()
791 uvc->streaming_intf = ret; in uvc_function_bind()
792 opts->streaming_interface = ret; in uvc_function_bind()
795 f->fs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); in uvc_function_bind()
796 if (IS_ERR(f->fs_descriptors)) { in uvc_function_bind()
797 ret = PTR_ERR(f->fs_descriptors); in uvc_function_bind()
798 f->fs_descriptors = NULL; in uvc_function_bind()
802 f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH); in uvc_function_bind()
803 if (IS_ERR(f->hs_descriptors)) { in uvc_function_bind()
804 ret = PTR_ERR(f->hs_descriptors); in uvc_function_bind()
805 f->hs_descriptors = NULL; in uvc_function_bind()
809 f->ss_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_SUPER); in uvc_function_bind()
810 if (IS_ERR(f->ss_descriptors)) { in uvc_function_bind()
811 ret = PTR_ERR(f->ss_descriptors); in uvc_function_bind()
812 f->ss_descriptors = NULL; in uvc_function_bind()
816 f->ssp_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_SUPER_PLUS); in uvc_function_bind()
817 if (IS_ERR(f->ssp_descriptors)) { in uvc_function_bind()
818 ret = PTR_ERR(f->ssp_descriptors); in uvc_function_bind()
819 f->ssp_descriptors = NULL; in uvc_function_bind()
824 uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL); in uvc_function_bind()
825 uvc->control_buf = kmalloc(UVC_MAX_REQUEST_SIZE, GFP_KERNEL); in uvc_function_bind()
826 if (uvc->control_req == NULL || uvc->control_buf == NULL) { in uvc_function_bind()
827 ret = -ENOMEM; in uvc_function_bind()
831 uvc->control_req->buf = uvc->control_buf; in uvc_function_bind()
832 uvc->control_req->complete = uvc_function_ep0_complete; in uvc_function_bind()
833 uvc->control_req->context = uvc; in uvc_function_bind()
835 if (v4l2_device_register(&cdev->gadget->dev, &uvc->v4l2_dev)) { in uvc_function_bind()
841 ret = uvcg_video_init(&uvc->video, uvc); in uvc_function_bind()
855 v4l2_device_unregister(&uvc->v4l2_dev); in uvc_function_bind()
857 if (uvc->control_req) in uvc_function_bind()
858 usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); in uvc_function_bind()
859 kfree(uvc->control_buf); in uvc_function_bind()
865 /* --------------------------------------------------------------------------
873 mutex_destroy(&opts->lock); in uvc_free_inst()
888 return ERR_PTR(-ENOMEM); in uvc_alloc_inst()
889 opts->func_inst.free_func_inst = uvc_free_inst; in uvc_alloc_inst()
890 mutex_init(&opts->lock); in uvc_alloc_inst()
892 cd = &opts->uvc_camera_terminal; in uvc_alloc_inst()
893 cd->bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3); in uvc_alloc_inst()
894 cd->bDescriptorType = USB_DT_CS_INTERFACE; in uvc_alloc_inst()
895 cd->bDescriptorSubType = UVC_VC_INPUT_TERMINAL; in uvc_alloc_inst()
896 cd->bTerminalID = 1; in uvc_alloc_inst()
897 cd->wTerminalType = cpu_to_le16(0x0201); in uvc_alloc_inst()
898 cd->bAssocTerminal = 0; in uvc_alloc_inst()
899 cd->iTerminal = 0; in uvc_alloc_inst()
900 cd->wObjectiveFocalLengthMin = cpu_to_le16(0); in uvc_alloc_inst()
901 cd->wObjectiveFocalLengthMax = cpu_to_le16(0); in uvc_alloc_inst()
902 cd->wOcularFocalLength = cpu_to_le16(0); in uvc_alloc_inst()
903 cd->bControlSize = 3; in uvc_alloc_inst()
904 cd->bmControls[0] = 2; in uvc_alloc_inst()
905 cd->bmControls[1] = 0; in uvc_alloc_inst()
906 cd->bmControls[2] = 0; in uvc_alloc_inst()
908 pd = &opts->uvc_processing; in uvc_alloc_inst()
909 pd->bLength = UVC_DT_PROCESSING_UNIT_SIZE(2); in uvc_alloc_inst()
910 pd->bDescriptorType = USB_DT_CS_INTERFACE; in uvc_alloc_inst()
911 pd->bDescriptorSubType = UVC_VC_PROCESSING_UNIT; in uvc_alloc_inst()
912 pd->bUnitID = 2; in uvc_alloc_inst()
913 pd->bSourceID = 1; in uvc_alloc_inst()
914 pd->wMaxMultiplier = cpu_to_le16(16*1024); in uvc_alloc_inst()
915 pd->bControlSize = 2; in uvc_alloc_inst()
916 pd->bmControls[0] = 1; in uvc_alloc_inst()
917 pd->bmControls[1] = 0; in uvc_alloc_inst()
918 pd->iProcessing = 0; in uvc_alloc_inst()
919 pd->bmVideoStandards = 0; in uvc_alloc_inst()
921 od = &opts->uvc_output_terminal; in uvc_alloc_inst()
922 od->bLength = UVC_DT_OUTPUT_TERMINAL_SIZE; in uvc_alloc_inst()
923 od->bDescriptorType = USB_DT_CS_INTERFACE; in uvc_alloc_inst()
924 od->bDescriptorSubType = UVC_VC_OUTPUT_TERMINAL; in uvc_alloc_inst()
925 od->bTerminalID = 3; in uvc_alloc_inst()
926 od->wTerminalType = cpu_to_le16(0x0101); in uvc_alloc_inst()
927 od->bAssocTerminal = 0; in uvc_alloc_inst()
928 od->bSourceID = 2; in uvc_alloc_inst()
929 od->iTerminal = 0; in uvc_alloc_inst()
933 * able to allocate unique unit IDs to them. The IDs are 1-based, with in uvc_alloc_inst()
936 opts->last_unit_id = 3; in uvc_alloc_inst()
938 /* Prepare fs control class descriptors for configfs-based gadgets */ in uvc_alloc_inst()
939 ctl_cls = opts->uvc_fs_control_cls; in uvc_alloc_inst()
944 ctl_cls[4] = NULL; /* NULL-terminate */ in uvc_alloc_inst()
945 opts->fs_control = in uvc_alloc_inst()
948 /* Prepare hs control class descriptors for configfs-based gadgets */ in uvc_alloc_inst()
949 ctl_cls = opts->uvc_ss_control_cls; in uvc_alloc_inst()
954 ctl_cls[4] = NULL; /* NULL-terminate */ in uvc_alloc_inst()
955 opts->ss_control = in uvc_alloc_inst()
958 INIT_LIST_HEAD(&opts->extension_units); in uvc_alloc_inst()
960 opts->streaming_interval = 1; in uvc_alloc_inst()
961 opts->streaming_maxpacket = 1024; in uvc_alloc_inst()
962 snprintf(opts->function_name, sizeof(opts->function_name), "UVC Camera"); in uvc_alloc_inst()
970 return &opts->func_inst; in uvc_alloc_inst()
976 struct f_uvc_opts *opts = container_of(f->fi, struct f_uvc_opts, in uvc_free()
978 if (!opts->header) in uvc_free()
979 config_item_put(&uvc->header->item); in uvc_free()
980 --opts->refcnt; in uvc_free()
987 struct usb_composite_dev *cdev = c->cdev; in uvc_function_unbind()
989 struct uvc_video *video = &uvc->video; in uvc_function_unbind()
994 if (video->async_wq) in uvc_function_unbind()
995 destroy_workqueue(video->async_wq); in uvc_function_unbind()
1003 if (uvc->func_connected) { in uvc_function_unbind()
1005 wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue, in uvc_function_unbind()
1006 uvc->func_connected == false, msecs_to_jiffies(500)); in uvc_function_unbind()
1010 device_remove_file(&uvc->vdev.dev, &dev_attr_function_name); in uvc_function_unbind()
1011 video_unregister_device(&uvc->vdev); in uvc_function_unbind()
1012 v4l2_device_unregister(&uvc->v4l2_dev); in uvc_function_unbind()
1014 if (uvc->func_connected) { in uvc_function_unbind()
1021 wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue, in uvc_function_unbind()
1022 uvc->func_connected == false, msecs_to_jiffies(1000)); in uvc_function_unbind()
1026 usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); in uvc_function_unbind()
1027 kfree(uvc->control_buf); in uvc_function_unbind()
1041 return ERR_PTR(-ENOMEM); in uvc_alloc()
1043 mutex_init(&uvc->video.mutex); in uvc_alloc()
1044 uvc->state = UVC_STATE_DISCONNECTED; in uvc_alloc()
1045 init_waitqueue_head(&uvc->func_connected_queue); in uvc_alloc()
1048 mutex_lock(&opts->lock); in uvc_alloc()
1049 if (opts->uvc_fs_streaming_cls) { in uvc_alloc()
1050 strm_cls = opts->uvc_fs_streaming_cls; in uvc_alloc()
1051 opts->fs_streaming = in uvc_alloc()
1054 if (opts->uvc_hs_streaming_cls) { in uvc_alloc()
1055 strm_cls = opts->uvc_hs_streaming_cls; in uvc_alloc()
1056 opts->hs_streaming = in uvc_alloc()
1059 if (opts->uvc_ss_streaming_cls) { in uvc_alloc()
1060 strm_cls = opts->uvc_ss_streaming_cls; in uvc_alloc()
1061 opts->ss_streaming = in uvc_alloc()
1065 uvc->desc.fs_control = opts->fs_control; in uvc_alloc()
1066 uvc->desc.ss_control = opts->ss_control; in uvc_alloc()
1067 uvc->desc.fs_streaming = opts->fs_streaming; in uvc_alloc()
1068 uvc->desc.hs_streaming = opts->hs_streaming; in uvc_alloc()
1069 uvc->desc.ss_streaming = opts->ss_streaming; in uvc_alloc()
1071 if (opts->header) { in uvc_alloc()
1072 uvc->header = opts->header; in uvc_alloc()
1074 streaming = config_group_find_item(&opts->func_inst.group, "streaming"); in uvc_alloc()
1088 uvc->header = to_uvcg_streaming_header(h); in uvc_alloc()
1089 if (!uvc->header->linked) { in uvc_alloc()
1090 mutex_unlock(&opts->lock); in uvc_alloc()
1092 return ERR_PTR(-EBUSY); in uvc_alloc()
1096 uvc->desc.extension_units = &opts->extension_units; in uvc_alloc()
1098 ++opts->refcnt; in uvc_alloc()
1099 mutex_unlock(&opts->lock); in uvc_alloc()
1102 uvc->func.name = "uvc"; in uvc_alloc()
1103 uvc->func.bind = uvc_function_bind; in uvc_alloc()
1104 uvc->func.unbind = uvc_function_unbind; in uvc_alloc()
1105 uvc->func.get_alt = uvc_function_get_alt; in uvc_alloc()
1106 uvc->func.set_alt = uvc_function_set_alt; in uvc_alloc()
1107 uvc->func.disable = uvc_function_disable; in uvc_alloc()
1108 uvc->func.setup = uvc_function_setup; in uvc_alloc()
1109 uvc->func.free_func = uvc_free; in uvc_alloc()
1110 uvc->func.bind_deactivated = true; in uvc_alloc()
1112 return &uvc->func; in uvc_alloc()
1115 mutex_unlock(&opts->lock); in uvc_alloc()
1117 return ERR_PTR(-ENOENT); in uvc_alloc()