Lines Matching +full:composite +full:- +full:in
1 // SPDX-License-Identifier: GPL-2.0+
3 * composite.c - infrastructure for Composite USB Gadgets
5 * Copyright (C) 2006-2008 David Brownell
17 #include <linux/usb/composite.h>
24 * struct usb_os_string - represents OS String to be reported by a gadget
40 * The code in this file is utility code, used to build a gadget driver
43 * with the relevant device-wide data.
49 return (struct usb_gadget_strings **)uc->stash; in get_containers_gs()
53 * function_descriptors() - get function descriptors for speed
72 descriptors = f->ssp_descriptors; in function_descriptors()
77 descriptors = f->ss_descriptors; in function_descriptors()
82 descriptors = f->hs_descriptors; in function_descriptors()
87 descriptors = f->fs_descriptors; in function_descriptors()
99 * next_desc() - advance to the next desc_type descriptor
112 if ((*t)->bDescriptorType == desc_type) in next_desc()
119 * for_each_desc() - iterate over desc_type descriptors in the
130 * config_ep_by_speed_and_alt() - configures the given endpoint
140 * endpoint according to gadget speed and saves it in the
142 * assigned to it - overwrites it with currently corresponding
163 return -EIO; in config_ep_by_speed_and_alt()
166 switch (g->speed) { in config_ep_by_speed_and_alt()
169 speed_desc = f->ssp_descriptors; in config_ep_by_speed_and_alt()
176 speed_desc = f->ss_descriptors; in config_ep_by_speed_and_alt()
183 speed_desc = f->hs_descriptors; in config_ep_by_speed_and_alt()
188 speed_desc = f->fs_descriptors; in config_ep_by_speed_and_alt()
195 if (int_desc->bAlternateSetting == alt) { in config_ep_by_speed_and_alt()
200 return -EIO; in config_ep_by_speed_and_alt()
206 if (chosen_desc->bEndpointAddress == _ep->address) in config_ep_by_speed_and_alt()
209 return -EIO; in config_ep_by_speed_and_alt()
213 _ep->maxpacket = usb_endpoint_maxp(chosen_desc); in config_ep_by_speed_and_alt()
214 _ep->desc = chosen_desc; in config_ep_by_speed_and_alt()
215 _ep->comp_desc = NULL; in config_ep_by_speed_and_alt()
216 _ep->maxburst = 0; in config_ep_by_speed_and_alt()
217 _ep->mult = 1; in config_ep_by_speed_and_alt()
219 if (g->speed == USB_SPEED_HIGH && (usb_endpoint_xfer_isoc(_ep->desc) || in config_ep_by_speed_and_alt()
220 usb_endpoint_xfer_int(_ep->desc))) in config_ep_by_speed_and_alt()
221 _ep->mult = usb_endpoint_maxp_mult(_ep->desc); in config_ep_by_speed_and_alt()
232 (comp_desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP)) in config_ep_by_speed_and_alt()
233 return -EIO; in config_ep_by_speed_and_alt()
234 _ep->comp_desc = comp_desc; in config_ep_by_speed_and_alt()
235 if (g->speed >= USB_SPEED_SUPER) { in config_ep_by_speed_and_alt()
236 switch (usb_endpoint_type(_ep->desc)) { in config_ep_by_speed_and_alt()
239 _ep->mult = (comp_desc->bmAttributes & 0x3) + 1; in config_ep_by_speed_and_alt()
243 _ep->maxburst = comp_desc->bMaxBurst + 1; in config_ep_by_speed_and_alt()
246 if (comp_desc->bMaxBurst != 0) { in config_ep_by_speed_and_alt()
252 _ep->maxburst = 1; in config_ep_by_speed_and_alt()
261 * config_ep_by_speed() - configures the given endpoint
270 * endpoint according to gadget speed and saves it in the
272 * assigned to it - overwrites it with currently corresponding
287 * usb_add_function() - add a function to a configuration
303 int value = -EINVAL; in usb_add_function()
305 DBG(config->cdev, "adding '%s'/%p to config '%s'/%p\n", in usb_add_function()
306 function->name, function, in usb_add_function()
307 config->label, config); in usb_add_function()
309 if (!function->set_alt || !function->disable) in usb_add_function()
312 function->config = config; in usb_add_function()
313 list_add_tail(&function->list, &config->functions); in usb_add_function()
315 if (function->bind_deactivated) { in usb_add_function()
321 /* REVISIT *require* function->bind? */ in usb_add_function()
322 if (function->bind) { in usb_add_function()
323 value = function->bind(config, function); in usb_add_function()
325 list_del(&function->list); in usb_add_function()
326 function->config = NULL; in usb_add_function()
336 if (!config->fullspeed && function->fs_descriptors) in usb_add_function()
337 config->fullspeed = true; in usb_add_function()
338 if (!config->highspeed && function->hs_descriptors) in usb_add_function()
339 config->highspeed = true; in usb_add_function()
340 if (!config->superspeed && function->ss_descriptors) in usb_add_function()
341 config->superspeed = true; in usb_add_function()
342 if (!config->superspeed_plus && function->ssp_descriptors) in usb_add_function()
343 config->superspeed_plus = true; in usb_add_function()
347 DBG(config->cdev, "adding '%s'/%p --> %d\n", in usb_add_function()
348 function->name, function, value); in usb_add_function()
355 if (f->disable) in usb_remove_function()
356 f->disable(f); in usb_remove_function()
358 bitmap_zero(f->endpoints, 32); in usb_remove_function()
359 list_del(&f->list); in usb_remove_function()
360 if (f->unbind) in usb_remove_function()
361 f->unbind(c, f); in usb_remove_function()
363 if (f->bind_deactivated) in usb_remove_function()
369 * usb_function_deactivate - prevent function and gadget enumeration
389 struct usb_composite_dev *cdev = function->config->cdev; in usb_function_deactivate()
393 spin_lock_irqsave(&cdev->lock, flags); in usb_function_deactivate()
395 if (cdev->deactivations == 0) { in usb_function_deactivate()
396 spin_unlock_irqrestore(&cdev->lock, flags); in usb_function_deactivate()
397 status = usb_gadget_deactivate(cdev->gadget); in usb_function_deactivate()
398 spin_lock_irqsave(&cdev->lock, flags); in usb_function_deactivate()
401 cdev->deactivations++; in usb_function_deactivate()
403 spin_unlock_irqrestore(&cdev->lock, flags); in usb_function_deactivate()
409 * usb_function_activate - allow function and gadget enumeration
420 struct usb_composite_dev *cdev = function->config->cdev; in usb_function_activate()
424 spin_lock_irqsave(&cdev->lock, flags); in usb_function_activate()
426 if (WARN_ON(cdev->deactivations == 0)) in usb_function_activate()
427 status = -EINVAL; in usb_function_activate()
429 cdev->deactivations--; in usb_function_activate()
430 if (cdev->deactivations == 0) { in usb_function_activate()
431 spin_unlock_irqrestore(&cdev->lock, flags); in usb_function_activate()
432 status = usb_gadget_activate(cdev->gadget); in usb_function_activate()
433 spin_lock_irqsave(&cdev->lock, flags); in usb_function_activate()
437 spin_unlock_irqrestore(&cdev->lock, flags); in usb_function_activate()
443 * usb_interface_id() - allocate an unused interface ID
450 * ID in interface, association, CDC union, and other descriptors. It
453 * also be class-specific or vendor-specific requests to handle.
458 * identifiers are configuration-specific, functions used in more than
459 * one configuration (or more than once in a given configuration) need
462 * Returns the interface ID which was allocated; or -ENODEV if no
468 unsigned id = config->next_interface_id; in usb_interface_id()
471 config->interface[id] = function; in usb_interface_id()
472 config->next_interface_id = id + 1; in usb_interface_id()
475 return -ENODEV; in usb_interface_id()
484 if (c->MaxPower || (c->bmAttributes & USB_CONFIG_ATT_SELFPOWER)) in encode_bMaxPower()
485 val = c->MaxPower; in encode_bMaxPower()
509 len = USB_COMP_EP0_BUFSIZ - USB_DT_CONFIG_SIZE; in config_buf()
512 c->bLength = USB_DT_CONFIG_SIZE; in config_buf()
513 c->bDescriptorType = type; in config_buf()
515 c->bNumInterfaces = config->next_interface_id; in config_buf()
516 c->bConfigurationValue = config->bConfigurationValue; in config_buf()
517 c->iConfiguration = config->iConfiguration; in config_buf()
518 c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes; in config_buf()
519 c->bMaxPower = encode_bMaxPower(speed, config); in config_buf()
522 if (config->descriptors) { in config_buf()
524 config->descriptors); in config_buf()
527 len -= status; in config_buf()
532 list_for_each_entry(f, &config->functions, list) { in config_buf()
542 len -= status; in config_buf()
546 len = next - buf; in config_buf()
547 c->wTotalLength = cpu_to_le16(len); in config_buf()
553 struct usb_gadget *gadget = cdev->gadget; in config_desc()
559 if (gadget->speed >= USB_SPEED_SUPER) in config_desc()
560 speed = gadget->speed; in config_desc()
563 if (gadget->speed == USB_SPEED_HIGH) in config_desc()
575 pos = &cdev->configs; in config_desc()
576 c = cdev->os_desc_config; in config_desc()
580 while ((pos = pos->next) != &cdev->configs) { in config_desc()
584 if (c == cdev->os_desc_config) in config_desc()
591 if (!c->superspeed_plus) in config_desc()
595 if (!c->superspeed) in config_desc()
599 if (!c->highspeed) in config_desc()
603 if (!c->fullspeed) in config_desc()
608 return config_buf(c, speed, cdev->req->buf, type); in config_desc()
609 w_value--; in config_desc()
611 return -EINVAL; in config_desc()
616 struct usb_gadget *gadget = cdev->gadget; in count_configs()
624 if (gadget->speed == USB_SPEED_HIGH) in count_configs()
626 if (gadget->speed == USB_SPEED_SUPER) in count_configs()
628 if (gadget->speed == USB_SPEED_SUPER_PLUS) in count_configs()
633 list_for_each_entry(c, &cdev->configs, list) { in count_configs()
636 if (!c->superspeed_plus) in count_configs()
639 if (!c->superspeed) in count_configs()
642 if (!c->highspeed) in count_configs()
645 if (!c->fullspeed) in count_configs()
654 * bos_desc() - prepares the BOS descriptor.
666 struct usb_bos_descriptor *bos = cdev->req->buf; in bos_desc()
669 bos->bLength = USB_DT_BOS_SIZE; in bos_desc()
670 bos->bDescriptorType = USB_DT_BOS; in bos_desc()
672 bos->wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE); in bos_desc()
673 bos->bNumDeviceCaps = 0; in bos_desc()
676 if (cdev->gadget->ops->get_config_params) { in bos_desc()
677 cdev->gadget->ops->get_config_params(cdev->gadget, in bos_desc()
700 * and shall support LPM when operating in USB2.0 HS mode. in bos_desc()
702 usb_ext = cdev->req->buf + le16_to_cpu(bos->wTotalLength); in bos_desc()
703 bos->bNumDeviceCaps++; in bos_desc()
704 le16_add_cpu(&bos->wTotalLength, USB_DT_USB_EXT_CAP_SIZE); in bos_desc()
705 usb_ext->bLength = USB_DT_USB_EXT_CAP_SIZE; in bos_desc()
706 usb_ext->bDescriptorType = USB_DT_DEVICE_CAPABILITY; in bos_desc()
707 usb_ext->bDevCapabilityType = USB_CAP_TYPE_EXT; in bos_desc()
708 usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT | in bos_desc()
715 if (gadget_is_superspeed(cdev->gadget)) { in bos_desc()
718 ss_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength); in bos_desc()
719 bos->bNumDeviceCaps++; in bos_desc()
720 le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SS_CAP_SIZE); in bos_desc()
721 ss_cap->bLength = USB_DT_USB_SS_CAP_SIZE; in bos_desc()
722 ss_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY; in bos_desc()
723 ss_cap->bDevCapabilityType = USB_SS_CAP_TYPE; in bos_desc()
724 ss_cap->bmAttributes = 0; /* LTM is not supported yet */ in bos_desc()
725 ss_cap->wSpeedSupported = cpu_to_le16(USB_LOW_SPEED_OPERATION | in bos_desc()
729 ss_cap->bFunctionalitySupport = USB_LOW_SPEED_OPERATION; in bos_desc()
730 ss_cap->bU1devExitLat = dcd_config_params.bU1devExitLat; in bos_desc()
731 ss_cap->bU2DevExitLat = dcd_config_params.bU2DevExitLat; in bos_desc()
735 if (gadget_is_superspeed_plus(cdev->gadget)) { in bos_desc()
738 ssp_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength); in bos_desc()
739 bos->bNumDeviceCaps++; in bos_desc()
745 le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SSP_CAP_SIZE(1)); in bos_desc()
746 ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(1); in bos_desc()
747 ssp_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY; in bos_desc()
748 ssp_cap->bDevCapabilityType = USB_SSP_CAP_TYPE; in bos_desc()
749 ssp_cap->bReserved = 0; in bos_desc()
750 ssp_cap->wReserved = 0; in bos_desc()
753 ssp_cap->bmAttributes = cpu_to_le32(1); in bos_desc()
756 ssp_cap->wFunctionalitySupport = in bos_desc()
766 ssp_cap->bmSublinkSpeedAttr[0] = in bos_desc()
775 ssp_cap->bmSublinkSpeedAttr[1] = in bos_desc()
780 return le16_to_cpu(bos->wTotalLength); in bos_desc()
785 struct usb_qualifier_descriptor *qual = cdev->req->buf; in device_qual()
787 qual->bLength = sizeof(*qual); in device_qual()
788 qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER; in device_qual()
790 qual->bcdUSB = cdev->desc.bcdUSB; in device_qual()
791 qual->bDeviceClass = cdev->desc.bDeviceClass; in device_qual()
792 qual->bDeviceSubClass = cdev->desc.bDeviceSubClass; in device_qual()
793 qual->bDeviceProtocol = cdev->desc.bDeviceProtocol; in device_qual()
795 qual->bMaxPacketSize0 = cdev->gadget->ep0->maxpacket; in device_qual()
796 qual->bNumConfigurations = count_configs(cdev, USB_DT_DEVICE_QUALIFIER); in device_qual()
797 qual->bRESERVED = 0; in device_qual()
800 /*-------------------------------------------------------------------------*/
808 list_for_each_entry(f, &cdev->config->functions, list) { in reset_config()
809 if (f->disable) in reset_config()
810 f->disable(f); in reset_config()
812 bitmap_zero(f->endpoints, 32); in reset_config()
814 cdev->config = NULL; in reset_config()
815 cdev->delayed_status = 0; in reset_config()
821 struct usb_gadget *gadget = cdev->gadget; in set_config()
823 int result = -EINVAL; in set_config()
828 list_for_each_entry(c, &cdev->configs, list) { in set_config()
829 if (c->bConfigurationValue == number) { in set_config()
835 if (cdev->config) in set_config()
843 } else { /* Zero configuration value - need to reset the config */ in set_config()
844 if (cdev->config) in set_config()
850 usb_speed_string(gadget->speed), in set_config()
851 number, c ? c->label : "unconfigured"); in set_config()
857 cdev->config = c; in set_config()
861 struct usb_function *f = c->interface[tmp]; in set_config()
873 descriptors = function_descriptors(f, gadget->speed); in set_config()
879 if ((*descriptors)->bDescriptorType != USB_DT_ENDPOINT) in set_config()
883 addr = ((ep->bEndpointAddress & 0x80) >> 3) in set_config()
884 | (ep->bEndpointAddress & 0x0f); in set_config()
885 set_bit(addr, f->endpoints); in set_config()
888 result = f->set_alt(f, tmp, 0); in set_config()
890 DBG(cdev, "interface %d (%s/%p) alt 0 --> %d\n", in set_config()
891 tmp, f->name, f, result); in set_config()
900 __func__, tmp, f->name); in set_config()
901 cdev->delayed_status++; in set_config()
903 cdev->delayed_status); in set_config()
908 if (c->MaxPower || (c->bmAttributes & USB_CONFIG_ATT_SELFPOWER)) in set_config()
909 power = c->MaxPower; in set_config()
913 if (gadget->speed < USB_SPEED_SUPER) in set_config()
924 if (result >= 0 && cdev->delayed_status) in set_config()
934 if (!config->bConfigurationValue) in usb_add_config_only()
935 return -EINVAL; in usb_add_config_only()
938 list_for_each_entry(c, &cdev->configs, list) { in usb_add_config_only()
939 if (c->bConfigurationValue == config->bConfigurationValue) in usb_add_config_only()
940 return -EBUSY; in usb_add_config_only()
943 config->cdev = cdev; in usb_add_config_only()
944 list_add_tail(&config->list, &cdev->configs); in usb_add_config_only()
946 INIT_LIST_HEAD(&config->functions); in usb_add_config_only()
947 config->next_interface_id = 0; in usb_add_config_only()
948 memset(config->interface, 0, sizeof(config->interface)); in usb_add_config_only()
955 * usb_add_config() - add a configuration to a device.
961 * One of the main tasks of a composite @bind() routine is to
966 * assigns global resources including string IDs, and per-configuration
973 int status = -EINVAL; in usb_add_config()
979 config->bConfigurationValue, in usb_add_config()
980 config->label, config); in usb_add_config()
988 while (!list_empty(&config->functions)) { in usb_add_config()
991 f = list_first_entry(&config->functions, in usb_add_config()
993 list_del(&f->list); in usb_add_config()
994 if (f->unbind) { in usb_add_config()
996 f->name, f); in usb_add_config()
997 f->unbind(config, f); in usb_add_config()
1001 list_del(&config->list); in usb_add_config()
1002 config->cdev = NULL; in usb_add_config()
1007 config->bConfigurationValue, config, in usb_add_config()
1008 config->superspeed_plus ? " superplus" : "", in usb_add_config()
1009 config->superspeed ? " super" : "", in usb_add_config()
1010 config->highspeed ? " high" : "", in usb_add_config()
1011 config->fullspeed in usb_add_config()
1012 ? (gadget_is_dualspeed(cdev->gadget) in usb_add_config()
1018 struct usb_function *f = config->interface[i]; in usb_add_config()
1023 i, f->name, f); in usb_add_config()
1027 /* set_alt(), or next bind(), sets up ep->claimed as needed */ in usb_add_config()
1028 usb_ep_autoconfig_reset(cdev->gadget); in usb_add_config()
1032 DBG(cdev, "added config '%s'/%u --> %d\n", config->label, in usb_add_config()
1033 config->bConfigurationValue, status); in usb_add_config()
1041 while (!list_empty(&config->functions)) { in remove_config()
1044 f = list_first_entry(&config->functions, in remove_config()
1049 list_del(&config->list); in remove_config()
1050 if (config->unbind) { in remove_config()
1051 DBG(cdev, "unbind config '%s'/%p\n", config->label, config); in remove_config()
1052 config->unbind(config); in remove_config()
1058 * usb_remove_config() - remove a configuration from a device.
1071 spin_lock_irqsave(&cdev->lock, flags); in usb_remove_config()
1073 if (cdev->config == config) in usb_remove_config()
1076 spin_unlock_irqrestore(&cdev->lock, flags); in usb_remove_config()
1081 /*-------------------------------------------------------------------------*/
1083 /* We support strings in multiple languages ... string descriptor zero
1097 language = cpu_to_le16(s->language); in collect_langs()
1120 if (s->language != language) in lookup_string()
1126 return -EINVAL; in lookup_string()
1132 struct usb_composite_driver *composite = cdev->driver; in get_string() local
1149 s->bDescriptorType = USB_DT_STRING; in get_string()
1151 sp = composite->strings; in get_string()
1153 collect_langs(sp, s->wData); in get_string()
1155 list_for_each_entry(c, &cdev->configs, list) { in get_string()
1156 sp = c->strings; in get_string()
1158 collect_langs(sp, s->wData); in get_string()
1160 list_for_each_entry(f, &c->functions, list) { in get_string()
1161 sp = f->strings; in get_string()
1163 collect_langs(sp, s->wData); in get_string()
1166 list_for_each_entry(uc, &cdev->gstrings, list) { in get_string()
1170 collect_langs(sp, s->wData); in get_string()
1173 for (len = 0; len <= USB_MAX_STRING_LEN && s->wData[len]; len++) in get_string()
1176 return -EINVAL; in get_string()
1178 s->bLength = 2 * (len + 1); in get_string()
1179 return s->bLength; in get_string()
1182 if (cdev->use_os_string && language == 0 && id == OS_STRING_IDX) { in get_string()
1184 b->bLength = sizeof(*b); in get_string()
1185 b->bDescriptorType = USB_DT_STRING; in get_string()
1187 sizeof(b->qwSignature) == sizeof(cdev->qw_sign), in get_string()
1189 memcpy(&b->qwSignature, cdev->qw_sign, sizeof(b->qwSignature)); in get_string()
1190 b->bMS_VendorCode = cdev->b_vendor_code; in get_string()
1191 b->bPad = 0; in get_string()
1195 list_for_each_entry(uc, &cdev->gstrings, list) { in get_string()
1204 /* String IDs are device-scoped, so we look up each string in get_string()
1206 * simpler-is-better here. in get_string()
1208 if (composite->strings) { in get_string()
1209 len = lookup_string(composite->strings, buf, language, id); in get_string()
1213 list_for_each_entry(c, &cdev->configs, list) { in get_string()
1214 if (c->strings) { in get_string()
1215 len = lookup_string(c->strings, buf, language, id); in get_string()
1219 list_for_each_entry(f, &c->functions, list) { in get_string()
1220 if (!f->strings) in get_string()
1222 len = lookup_string(f->strings, buf, language, id); in get_string()
1227 return -EINVAL; in get_string()
1231 * usb_string_id() - allocate an unused string ID
1237 * then store that ID in the appropriate descriptors and string table.
1246 if (cdev->next_string_id < 254) { in usb_string_id()
1249 /* 255 reserved as well? -- mina86 */ in usb_string_id()
1250 cdev->next_string_id++; in usb_string_id()
1251 return cdev->next_string_id; in usb_string_id()
1253 return -ENODEV; in usb_string_id()
1258 * usb_string_ids_tab() - allocate unused string IDs in batch
1275 int next = cdev->next_string_id; in usb_string_ids_tab()
1277 for (; str->s; ++str) { in usb_string_ids_tab()
1279 return -ENODEV; in usb_string_ids_tab()
1280 str->id = ++next; in usb_string_ids_tab()
1283 cdev->next_string_id = next; in usb_string_ids_tab()
1308 return ERR_PTR(-ENOMEM); in copy_gadget_strings()
1310 stash = uc->stash; in copy_gadget_strings()
1318 gs->language = sp[n_gs]->language; in copy_gadget_strings()
1319 gs->strings = stash; in copy_gadget_strings()
1320 org_s = sp[n_gs]->strings; in copy_gadget_strings()
1325 if (org_s->s) in copy_gadget_strings()
1326 s->s = org_s->s; in copy_gadget_strings()
1328 s->s = ""; in copy_gadget_strings()
1332 s->s = NULL; in copy_gadget_strings()
1341 * usb_gstrings_attach() - attach gadget strings to a cdev and assign ids
1345 * @n_strings: number of entries in each usb_strings array (sp[]->strings)
1351 * The ->language pointer of each struct usb_gadget_strings has to contain the
1353 * For instance: sp[0] is en-US, sp[1] is es-ES. It is expected that the first
1354 * usb_string entry of es-ES contains the translation of the first usb_string
1355 * entry of en-US. Therefore both entries become the same id assign.
1370 return ERR_PTR(-EINVAL); in usb_gstrings_attach()
1377 ret = usb_string_ids_tab(cdev, n_gs[0]->strings); in usb_gstrings_attach()
1386 m_s = n_gs[0]->strings; in usb_gstrings_attach()
1387 s = n_gs[i]->strings; in usb_gstrings_attach()
1389 s->id = m_s->id; in usb_gstrings_attach()
1394 list_add_tail(&uc->list, &cdev->gstrings); in usb_gstrings_attach()
1395 return n_gs[0]->strings; in usb_gstrings_attach()
1403 * usb_string_ids_n() - allocate unused string IDs in batch
1408 * Returns the first requested ID. This ID and next @n-1 IDs are now
1409 * valid IDs. At least provided that @n is non-zero because if it
1414 * then store that ID in the appropriate descriptors and string table.
1423 unsigned next = c->next_string_id; in usb_string_ids_n()
1425 return -ENODEV; in usb_string_ids_n()
1426 c->next_string_id += n; in usb_string_ids_n()
1431 /*-------------------------------------------------------------------------*/
1437 if (req->status || req->actual != req->length) in composite_setup_complete()
1438 DBG((struct usb_composite_dev *) ep->driver_data, in composite_setup_complete()
1439 "setup complete --> %d, %d/%d\n", in composite_setup_complete()
1440 req->status, req->actual, req->length); in composite_setup_complete()
1444 * so they don't have to maintain the same ->complete() stubs. in composite_setup_complete()
1446 * Because of that, we need to check for the validity of ->context in composite_setup_complete()
1449 if (!req->context) in composite_setup_complete()
1452 cdev = req->context; in composite_setup_complete()
1454 if (cdev->req == req) in composite_setup_complete()
1455 cdev->setup_pending = false; in composite_setup_complete()
1456 else if (cdev->os_desc_req == req) in composite_setup_complete()
1457 cdev->os_desc_pending = false; in composite_setup_complete()
1467 ret = usb_ep_queue(cdev->gadget->ep0, req, gfp_flags); in composite_ep0_queue()
1469 if (cdev->req == req) in composite_ep0_queue()
1470 cdev->setup_pending = true; in composite_ep0_queue()
1471 else if (cdev->os_desc_req == req) in composite_ep0_queue()
1472 cdev->os_desc_pending = true; in composite_ep0_queue()
1485 for (i = 0; i < c->next_interface_id; ++i) { in count_ext_compat()
1489 f = c->interface[i]; in count_ext_compat()
1490 for (j = 0; j < f->os_desc_n; ++j) { in count_ext_compat()
1493 if (i != f->os_desc_table[j].if_id) in count_ext_compat()
1495 d = f->os_desc_table[j].os_desc; in count_ext_compat()
1496 if (d && d->ext_compat_id) in count_ext_compat()
1510 for (i = 0; i < c->next_interface_id; ++i) { in fill_ext_compat()
1514 f = c->interface[i]; in fill_ext_compat()
1515 for (j = 0; j < f->os_desc_n; ++j) { in fill_ext_compat()
1518 if (i != f->os_desc_table[j].if_id) in fill_ext_compat()
1520 d = f->os_desc_table[j].os_desc; in fill_ext_compat()
1521 if (d && d->ext_compat_id) { in fill_ext_compat()
1524 memcpy(buf, d->ext_compat_id, 16); in fill_ext_compat()
1545 f = c->interface[interface]; in count_ext_prop()
1546 for (j = 0; j < f->os_desc_n; ++j) { in count_ext_prop()
1549 if (interface != f->os_desc_table[j].if_id) in count_ext_prop()
1551 d = f->os_desc_table[j].os_desc; in count_ext_prop()
1552 if (d && d->ext_compat_id) in count_ext_prop()
1553 return d->ext_prop_count; in count_ext_prop()
1565 f = c->interface[interface]; in len_ext_prop()
1566 for (j = 0; j < f->os_desc_n; ++j) { in len_ext_prop()
1567 if (interface != f->os_desc_table[j].if_id) in len_ext_prop()
1569 d = f->os_desc_table[j].os_desc; in len_ext_prop()
1571 return min(res + d->ext_prop_len, 4096); in len_ext_prop()
1583 f = c->interface[interface]; in fill_ext_prop()
1586 for (j = 0; j < f->os_desc_n; ++j) { in fill_ext_prop()
1587 if (interface != f->os_desc_table[j].if_id) in fill_ext_prop()
1589 d = f->os_desc_table[j].os_desc; in fill_ext_prop()
1591 list_for_each_entry(ext_prop, &d->ext_prop, entry) { in fill_ext_prop()
1592 n = ext_prop->data_len + in fill_ext_prop()
1593 ext_prop->name_len + 14; in fill_ext_prop()
1597 usb_ext_prop_put_type(buf, ext_prop->type); in fill_ext_prop()
1598 ret = usb_ext_prop_put_name(buf, ext_prop->name, in fill_ext_prop()
1599 ext_prop->name_len); in fill_ext_prop()
1602 switch (ext_prop->type) { in fill_ext_prop()
1607 ext_prop->data, in fill_ext_prop()
1608 ext_prop->data_len); in fill_ext_prop()
1612 ext_prop->data, in fill_ext_prop()
1613 ext_prop->data_len); in fill_ext_prop()
1620 return -EINVAL; in fill_ext_prop()
1632 * not handled lower down, in hardware or the hardware driver(like
1635 * the work is in config and function specific setup.
1641 struct usb_request *req = cdev->req; in composite_setup()
1642 int value = -EOPNOTSUPP; in composite_setup()
1644 u16 w_index = le16_to_cpu(ctrl->wIndex); in composite_setup()
1646 u16 w_value = le16_to_cpu(ctrl->wValue); in composite_setup()
1647 u16 w_length = le16_to_cpu(ctrl->wLength); in composite_setup()
1652 if (ctrl->bRequestType & USB_DIR_IN) { in composite_setup()
1654 __le16 *temp = (__le16 *)&ctrl->wLength; in composite_setup()
1663 /* partial re-init of the response message; the function or the in composite_setup()
1664 * gadget might need to intercept e.g. a control-OUT completion in composite_setup()
1667 req->zero = 0; in composite_setup()
1668 req->context = cdev; in composite_setup()
1669 req->complete = composite_setup_complete; in composite_setup()
1670 req->length = 0; in composite_setup()
1671 gadget->ep0->driver_data = cdev; in composite_setup()
1674 * Don't let non-standard requests match any of the cases below in composite_setup()
1677 if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) in composite_setup()
1680 switch (ctrl->bRequest) { in composite_setup()
1684 if (ctrl->bRequestType != USB_DIR_IN) in composite_setup()
1689 cdev->desc.bNumConfigurations = in composite_setup()
1691 cdev->desc.bMaxPacketSize0 = in composite_setup()
1692 cdev->gadget->ep0->maxpacket; in composite_setup()
1694 if (gadget->speed >= USB_SPEED_SUPER) { in composite_setup()
1695 cdev->desc.bcdUSB = cpu_to_le16(0x0320); in composite_setup()
1696 cdev->desc.bMaxPacketSize0 = 9; in composite_setup()
1698 cdev->desc.bcdUSB = cpu_to_le16(0x0210); in composite_setup()
1701 if (gadget->lpm_capable) in composite_setup()
1702 cdev->desc.bcdUSB = cpu_to_le16(0x0201); in composite_setup()
1704 cdev->desc.bcdUSB = cpu_to_le16(0x0200); in composite_setup()
1707 value = min(w_length, (u16) sizeof cdev->desc); in composite_setup()
1708 memcpy(req->buf, &cdev->desc, value); in composite_setup()
1712 gadget->speed >= USB_SPEED_SUPER) in composite_setup()
1720 gadget->speed >= USB_SPEED_SUPER) in composite_setup()
1729 value = get_string(cdev, req->buf, in composite_setup()
1736 gadget->lpm_capable) { in composite_setup()
1746 if (cdev->config) in composite_setup()
1747 config = cdev->config; in composite_setup()
1750 &cdev->configs, in composite_setup()
1755 if (gadget->otg_caps && in composite_setup()
1756 (gadget->otg_caps->otg_rev >= 0x0200)) in composite_setup()
1764 memcpy(req->buf, config->descriptors[0], value); in composite_setup()
1772 if (ctrl->bRequestType != 0) in composite_setup()
1775 if (gadget->a_hnp_support) in composite_setup()
1777 else if (gadget->a_alt_hnp_support) in composite_setup()
1782 spin_lock(&cdev->lock); in composite_setup()
1784 spin_unlock(&cdev->lock); in composite_setup()
1787 if (ctrl->bRequestType != USB_DIR_IN) in composite_setup()
1789 if (cdev->config) in composite_setup()
1790 *(u8 *)req->buf = cdev->config->bConfigurationValue; in composite_setup()
1792 *(u8 *)req->buf = 0; in composite_setup()
1798 if (ctrl->bRequestType != USB_RECIP_INTERFACE) in composite_setup()
1800 if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) in composite_setup()
1802 f = cdev->config->interface[intf]; in composite_setup()
1809 * as we check this in usb_add_function(). in composite_setup()
1811 if (w_value && !f->get_alt) in composite_setup()
1814 spin_lock(&cdev->lock); in composite_setup()
1815 value = f->set_alt(f, w_index, w_value); in composite_setup()
1819 __func__, intf, f->name); in composite_setup()
1820 cdev->delayed_status++; in composite_setup()
1822 cdev->delayed_status); in composite_setup()
1824 spin_unlock(&cdev->lock); in composite_setup()
1827 if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) in composite_setup()
1829 if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) in composite_setup()
1831 f = cdev->config->interface[intf]; in composite_setup()
1835 value = f->get_alt ? f->get_alt(f, w_index) : 0; in composite_setup()
1838 *((u8 *)req->buf) = value; in composite_setup()
1842 if (gadget_is_otg(gadget) && gadget->hnp_polling_support && in composite_setup()
1844 if (ctrl->bRequestType != (USB_DIR_IN | in composite_setup()
1847 *((u8 *)req->buf) = gadget->host_request_flag; in composite_setup()
1861 if (ctrl->bRequestType != (USB_DIR_IN | USB_RECIP_INTERFACE)) in composite_setup()
1864 put_unaligned_le16(0, req->buf); in composite_setup()
1865 if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) in composite_setup()
1867 f = cdev->config->interface[intf]; in composite_setup()
1870 status = f->get_status ? f->get_status(f) : 0; in composite_setup()
1873 put_unaligned_le16(status & 0x0000ffff, req->buf); in composite_setup()
1884 if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_INTERFACE)) in composite_setup()
1888 if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) in composite_setup()
1890 f = cdev->config->interface[intf]; in composite_setup()
1894 if (f->func_suspend) in composite_setup()
1895 value = f->func_suspend(f, w_index >> 8); in composite_setup()
1910 if (cdev->use_os_string && cdev->os_desc_config && in composite_setup()
1911 (ctrl->bRequestType & USB_TYPE_VENDOR) && in composite_setup()
1912 ctrl->bRequest == cdev->b_vendor_code) { in composite_setup()
1918 req = cdev->os_desc_req; in composite_setup()
1919 req->context = cdev; in composite_setup()
1920 req->complete = composite_setup_complete; in composite_setup()
1921 buf = req->buf; in composite_setup()
1922 os_desc_cfg = cdev->os_desc_config; in composite_setup()
1926 switch (ctrl->bRequestType & USB_RECIP_MASK) { in composite_setup()
1948 !os_desc_cfg->interface[interface]) in composite_setup()
1971 "non-core control req%02x.%02x v%04x i%04x l%d\n", in composite_setup()
1972 ctrl->bRequestType, ctrl->bRequest, in composite_setup()
1979 if (cdev->config) { in composite_setup()
1980 list_for_each_entry(f, &cdev->config->functions, list) in composite_setup()
1981 if (f->req_match && in composite_setup()
1982 f->req_match(f, ctrl, false)) in composite_setup()
1986 list_for_each_entry(c, &cdev->configs, list) in composite_setup()
1987 list_for_each_entry(f, &c->functions, list) in composite_setup()
1988 if (f->req_match && in composite_setup()
1989 f->req_match(f, ctrl, true)) in composite_setup()
1994 switch (ctrl->bRequestType & USB_RECIP_MASK) { in composite_setup()
1996 if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) in composite_setup()
1998 f = cdev->config->interface[intf]; in composite_setup()
2002 if (!cdev->config) in composite_setup()
2005 list_for_each_entry(f, &cdev->config->functions, list) { in composite_setup()
2006 if (test_bit(endp, f->endpoints)) in composite_setup()
2009 if (&f->list == &cdev->config->functions) in composite_setup()
2014 if (f && f->setup) in composite_setup()
2015 value = f->setup(f, ctrl); in composite_setup()
2019 c = cdev->config; in composite_setup()
2024 if (c->setup) { in composite_setup()
2025 value = c->setup(c, ctrl); in composite_setup()
2029 /* try the only function in the current config */ in composite_setup()
2030 if (!list_is_singular(&c->functions)) in composite_setup()
2032 f = list_first_entry(&c->functions, struct usb_function, in composite_setup()
2034 if (f->setup) in composite_setup()
2035 value = f->setup(f, ctrl); in composite_setup()
2044 req->length = value; in composite_setup()
2045 req->context = cdev; in composite_setup()
2046 req->zero = value < w_length; in composite_setup()
2049 DBG(cdev, "ep_queue --> %d\n", value); in composite_setup()
2050 req->status = 0; in composite_setup()
2051 composite_setup_complete(gadget->ep0, req); in composite_setup()
2072 spin_lock_irqsave(&cdev->lock, flags); in composite_disconnect()
2073 cdev->suspended = 0; in composite_disconnect()
2074 if (cdev->config) in composite_disconnect()
2076 if (cdev->driver->disconnect) in composite_disconnect()
2077 cdev->driver->disconnect(cdev); in composite_disconnect()
2078 spin_unlock_irqrestore(&cdev->lock, flags); in composite_disconnect()
2081 /*-------------------------------------------------------------------------*/
2089 return sprintf(buf, "%d\n", cdev->suspended); in suspended_show()
2096 struct usb_gadget_strings *gstr = cdev->driver->strings[0]; in __composite_unbind()
2097 struct usb_string *dev_str = gstr->strings; in __composite_unbind()
2102 * state protected by cdev->lock. in __composite_unbind()
2104 WARN_ON(cdev->config); in __composite_unbind()
2106 while (!list_empty(&cdev->configs)) { in __composite_unbind()
2108 c = list_first_entry(&cdev->configs, in __composite_unbind()
2112 if (cdev->driver->unbind && unbind_driver) in __composite_unbind()
2113 cdev->driver->unbind(cdev); in __composite_unbind()
2117 if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer) in __composite_unbind()
2120 kfree(cdev->def_manufacturer); in __composite_unbind()
2141 * these variables may have been set in in update_unchanged_dev_desc()
2144 idVendor = new->idVendor; in update_unchanged_dev_desc()
2145 idProduct = new->idProduct; in update_unchanged_dev_desc()
2146 bcdDevice = new->bcdDevice; in update_unchanged_dev_desc()
2147 iSerialNumber = new->iSerialNumber; in update_unchanged_dev_desc()
2148 iManufacturer = new->iManufacturer; in update_unchanged_dev_desc()
2149 iProduct = new->iProduct; in update_unchanged_dev_desc()
2153 new->idVendor = idVendor; in update_unchanged_dev_desc()
2155 new->idProduct = idProduct; in update_unchanged_dev_desc()
2157 new->bcdDevice = bcdDevice; in update_unchanged_dev_desc()
2159 new->bcdDevice = cpu_to_le16(get_default_bcdDevice()); in update_unchanged_dev_desc()
2161 new->iSerialNumber = iSerialNumber; in update_unchanged_dev_desc()
2163 new->iManufacturer = iManufacturer; in update_unchanged_dev_desc()
2165 new->iProduct = iProduct; in update_unchanged_dev_desc()
2168 int composite_dev_prepare(struct usb_composite_driver *composite, in composite_dev_prepare() argument
2171 struct usb_gadget *gadget = cdev->gadget; in composite_dev_prepare()
2172 int ret = -ENOMEM; in composite_dev_prepare()
2175 cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); in composite_dev_prepare()
2176 if (!cdev->req) in composite_dev_prepare()
2177 return -ENOMEM; in composite_dev_prepare()
2179 cdev->req->buf = kzalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL); in composite_dev_prepare()
2180 if (!cdev->req->buf) in composite_dev_prepare()
2183 ret = device_create_file(&gadget->dev, &dev_attr_suspended); in composite_dev_prepare()
2187 cdev->req->complete = composite_setup_complete; in composite_dev_prepare()
2188 cdev->req->context = cdev; in composite_dev_prepare()
2189 gadget->ep0->driver_data = cdev; in composite_dev_prepare()
2191 cdev->driver = composite; in composite_dev_prepare()
2195 * more than 100mA from USB must report itself as bus-powered in in composite_dev_prepare()
2203 * drivers will zero ep->driver_data. in composite_dev_prepare()
2208 kfree(cdev->req->buf); in composite_dev_prepare()
2210 usb_ep_free_request(gadget->ep0, cdev->req); in composite_dev_prepare()
2211 cdev->req = NULL; in composite_dev_prepare()
2220 cdev->os_desc_req = usb_ep_alloc_request(ep0, GFP_KERNEL); in composite_os_desc_req_prepare()
2221 if (!cdev->os_desc_req) { in composite_os_desc_req_prepare()
2222 ret = -ENOMEM; in composite_os_desc_req_prepare()
2226 cdev->os_desc_req->buf = kmalloc(USB_COMP_EP0_OS_DESC_BUFSIZ, in composite_os_desc_req_prepare()
2228 if (!cdev->os_desc_req->buf) { in composite_os_desc_req_prepare()
2229 ret = -ENOMEM; in composite_os_desc_req_prepare()
2230 usb_ep_free_request(ep0, cdev->os_desc_req); in composite_os_desc_req_prepare()
2233 cdev->os_desc_req->context = cdev; in composite_os_desc_req_prepare()
2234 cdev->os_desc_req->complete = composite_setup_complete; in composite_os_desc_req_prepare()
2244 list_for_each_entry_safe(uc, tmp, &cdev->gstrings, list) { in composite_dev_cleanup()
2245 list_del(&uc->list); in composite_dev_cleanup()
2248 if (cdev->os_desc_req) { in composite_dev_cleanup()
2249 if (cdev->os_desc_pending) in composite_dev_cleanup()
2250 usb_ep_dequeue(cdev->gadget->ep0, cdev->os_desc_req); in composite_dev_cleanup()
2252 kfree(cdev->os_desc_req->buf); in composite_dev_cleanup()
2253 cdev->os_desc_req->buf = NULL; in composite_dev_cleanup()
2254 usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req); in composite_dev_cleanup()
2255 cdev->os_desc_req = NULL; in composite_dev_cleanup()
2257 if (cdev->req) { in composite_dev_cleanup()
2258 if (cdev->setup_pending) in composite_dev_cleanup()
2259 usb_ep_dequeue(cdev->gadget->ep0, cdev->req); in composite_dev_cleanup()
2261 kfree(cdev->req->buf); in composite_dev_cleanup()
2262 cdev->req->buf = NULL; in composite_dev_cleanup()
2263 usb_ep_free_request(cdev->gadget->ep0, cdev->req); in composite_dev_cleanup()
2264 cdev->req = NULL; in composite_dev_cleanup()
2266 cdev->next_string_id = 0; in composite_dev_cleanup()
2267 device_remove_file(&cdev->gadget->dev, &dev_attr_suspended); in composite_dev_cleanup()
2272 * In that case, the dispose() callback is used to notify the in composite_dev_cleanup()
2273 * backend that the EPs are no longer in use. in composite_dev_cleanup()
2279 &cdev->gadget->ep_list, ep_list) { in composite_dev_cleanup()
2280 if (ep->ops->dispose) in composite_dev_cleanup()
2281 ep->ops->dispose(ep); in composite_dev_cleanup()
2289 struct usb_composite_driver *composite = to_cdriver(gdriver); in composite_bind() local
2290 int status = -ENOMEM; in composite_bind()
2296 spin_lock_init(&cdev->lock); in composite_bind()
2297 cdev->gadget = gadget; in composite_bind()
2299 INIT_LIST_HEAD(&cdev->configs); in composite_bind()
2300 INIT_LIST_HEAD(&cdev->gstrings); in composite_bind()
2302 status = composite_dev_prepare(composite, cdev); in composite_bind()
2306 /* composite gadget needs to assign strings for whole device (like in composite_bind()
2310 status = composite->bind(cdev); in composite_bind()
2314 if (cdev->use_os_string) { in composite_bind()
2315 status = composite_os_desc_req_prepare(cdev, gadget->ep0); in composite_bind()
2320 update_unchanged_dev_desc(&cdev->desc, composite->dev); in composite_bind()
2323 if (composite->needs_serial && !cdev->desc.iSerialNumber) in composite_bind()
2326 INFO(cdev, "%s ready\n", composite->name); in composite_bind()
2334 /*-------------------------------------------------------------------------*/
2345 if (cdev->config) { in composite_suspend()
2346 list_for_each_entry(f, &cdev->config->functions, list) { in composite_suspend()
2347 if (f->suspend) in composite_suspend()
2348 f->suspend(f); in composite_suspend()
2351 if (cdev->driver->suspend) in composite_suspend()
2352 cdev->driver->suspend(cdev); in composite_suspend()
2354 cdev->suspended = 1; in composite_suspend()
2370 if (cdev->driver->resume) in composite_resume()
2371 cdev->driver->resume(cdev); in composite_resume()
2372 if (cdev->config) { in composite_resume()
2373 list_for_each_entry(f, &cdev->config->functions, list) { in composite_resume()
2374 if (f->resume) in composite_resume()
2375 f->resume(f); in composite_resume()
2378 maxpower = cdev->config->MaxPower ? in composite_resume()
2379 cdev->config->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW; in composite_resume()
2380 if (gadget->speed < USB_SPEED_SUPER) in composite_resume()
2391 cdev->suspended = 0; in composite_resume()
2394 /*-------------------------------------------------------------------------*/
2413 * usb_composite_probe() - register a composite driver
2418 * This function is used to register drivers using the composite driver
2425 * while it was binding. That would usually be done in order to wait for
2432 if (!driver || !driver->dev || !driver->bind) in usb_composite_probe()
2433 return -EINVAL; in usb_composite_probe()
2435 if (!driver->name) in usb_composite_probe()
2436 driver->name = "composite"; in usb_composite_probe()
2438 driver->gadget_driver = composite_driver_template; in usb_composite_probe()
2439 gadget_driver = &driver->gadget_driver; in usb_composite_probe()
2441 gadget_driver->function = (char *) driver->name; in usb_composite_probe()
2442 gadget_driver->driver.name = driver->name; in usb_composite_probe()
2443 gadget_driver->max_speed = driver->max_speed; in usb_composite_probe()
2450 * usb_composite_unregister() - unregister a composite driver
2453 * This function is used to unregister drivers using the composite
2458 usb_gadget_unregister_driver(&driver->gadget_driver); in usb_composite_unregister()
2463 * usb_composite_setup_continue() - Continue with the control transfer
2464 * @cdev: the composite device who's control transfer was kept waiting
2467 * with the control transfer's data/status stage in case it had requested to
2469 * can request the composite framework to delay the setup request's data/status
2475 struct usb_request *req = cdev->req; in usb_composite_setup_continue()
2479 spin_lock_irqsave(&cdev->lock, flags); in usb_composite_setup_continue()
2481 if (cdev->delayed_status == 0) { in usb_composite_setup_continue()
2484 } else if (--cdev->delayed_status == 0) { in usb_composite_setup_continue()
2486 req->length = 0; in usb_composite_setup_continue()
2487 req->context = cdev; in usb_composite_setup_continue()
2490 DBG(cdev, "ep_queue --> %d\n", value); in usb_composite_setup_continue()
2491 req->status = 0; in usb_composite_setup_continue()
2492 composite_setup_complete(cdev->gadget->ep0, req); in usb_composite_setup_continue()
2496 spin_unlock_irqrestore(&cdev->lock, flags); in usb_composite_setup_continue()
2502 return kasprintf(GFP_KERNEL, "%s %s with %s", init_utsname()->sysname, in composite_default_mfr()
2503 init_utsname()->release, gadget->name); in composite_default_mfr()
2509 struct usb_device_descriptor *desc = &cdev->desc; in usb_composite_overwrite_options()
2510 struct usb_gadget_strings *gstr = cdev->driver->strings[0]; in usb_composite_overwrite_options()
2511 struct usb_string *dev_str = gstr->strings; in usb_composite_overwrite_options()
2513 if (covr->idVendor) in usb_composite_overwrite_options()
2514 desc->idVendor = cpu_to_le16(covr->idVendor); in usb_composite_overwrite_options()
2516 if (covr->idProduct) in usb_composite_overwrite_options()
2517 desc->idProduct = cpu_to_le16(covr->idProduct); in usb_composite_overwrite_options()
2519 if (covr->bcdDevice) in usb_composite_overwrite_options()
2520 desc->bcdDevice = cpu_to_le16(covr->bcdDevice); in usb_composite_overwrite_options()
2522 if (covr->serial_number) { in usb_composite_overwrite_options()
2523 desc->iSerialNumber = dev_str[USB_GADGET_SERIAL_IDX].id; in usb_composite_overwrite_options()
2524 dev_str[USB_GADGET_SERIAL_IDX].s = covr->serial_number; in usb_composite_overwrite_options()
2526 if (covr->manufacturer) { in usb_composite_overwrite_options()
2527 desc->iManufacturer = dev_str[USB_GADGET_MANUFACTURER_IDX].id; in usb_composite_overwrite_options()
2528 dev_str[USB_GADGET_MANUFACTURER_IDX].s = covr->manufacturer; in usb_composite_overwrite_options()
2531 desc->iManufacturer = dev_str[USB_GADGET_MANUFACTURER_IDX].id; in usb_composite_overwrite_options()
2532 cdev->def_manufacturer = composite_default_mfr(cdev->gadget); in usb_composite_overwrite_options()
2533 dev_str[USB_GADGET_MANUFACTURER_IDX].s = cdev->def_manufacturer; in usb_composite_overwrite_options()
2536 if (covr->product) { in usb_composite_overwrite_options()
2537 desc->iProduct = dev_str[USB_GADGET_PRODUCT_IDX].id; in usb_composite_overwrite_options()
2538 dev_str[USB_GADGET_PRODUCT_IDX].s = covr->product; in usb_composite_overwrite_options()