static int __init nokia_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; printk("nokia_bind called!!!!\n"); status = gphonet_setup(cdev->gadget); if (status < 0) goto err_phonet; status = gserial_setup(cdev->gadget, 3); if (status < 0) goto err_serial; status = gether_setup(cdev->gadget, hostaddr); if (status < 0) goto err_ether; status = usb_string_id(cdev); if (status < 0) goto err_usb; strings_dev[STRING_MANUFACTURER_IDX].id = status; device_desc.iManufacturer = status; status = usb_string_id(cdev); if (status < 0) goto err_usb; strings_dev[STRING_PRODUCT_IDX].id = status; device_desc.iProduct = status; /* config description */ status = usb_string_id(cdev); if (status < 0) goto err_usb; strings_dev[STRING_DESCRIPTION_IDX].id = status; nokia_config_500ma_driver.iConfiguration = status; nokia_config_100ma_driver.iConfiguration = status; /* set up other descriptors */ gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM); else { /* this should only work with hw that supports altsettings * and several endpoints, anything else, panic. */ pr_err("nokia_bind: controller '%s' not recognized\n", gadget->name); goto err_usb; } /* finally register the configuration */ status = usb_add_config(cdev, &nokia_config_500ma_driver, nokia_bind_config); if (status < 0) goto err_usb; status = usb_add_config(cdev, &nokia_config_100ma_driver, nokia_bind_config); if (status < 0) goto err_usb; // usb_gadget_connect(cdev->gadget); // dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME); return 0; err_usb: gether_cleanup(); err_ether: gserial_cleanup(); err_serial: gphonet_cleanup(); err_phonet: return status; }
static int __init gs_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; status = gserial_setup(cdev->gadget, n_ports); if (status < 0) return status; /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ /* device description: manufacturer, product */ snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); status = usb_string_id(cdev); if (status < 0) goto fail; strings_dev[STRING_MANUFACTURER_IDX].id = status; device_desc.iManufacturer = status; status = usb_string_id(cdev); if (status < 0) goto fail; strings_dev[STRING_PRODUCT_IDX].id = status; device_desc.iProduct = status; /* config description */ status = usb_string_id(cdev); if (status < 0) goto fail; strings_dev[STRING_DESCRIPTION_IDX].id = status; serial_config_driver.iConfiguration = status; /* set up other descriptors */ gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(GS_VERSION_NUM | gcnum); else { /* this is so simple (for now, no altsettings) that it * SHOULD NOT have problems with bulk-capable hardware. * so warn about unrcognized controllers -- don't panic. * * things like configuration and altsetting numbering * can need hardware-specific attention though. */ pr_warning("gs_bind: controller '%s' not recognized\n", gadget->name); device_desc.bcdDevice = cpu_to_le16(GS_VERSION_NUM | 0x0099); } if (gadget_is_otg(cdev->gadget)) { serial_config_driver.descriptors = otg_desc; serial_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } /* register our configuration */ status = usb_add_config(cdev, &serial_config_driver); if (status < 0) goto fail; INFO(cdev, "%s\n", GS_VERSION_NAME); return 0; fail: gserial_cleanup(); return status; }
static int __init gncm_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; /* set up network link layer */ status = gether_setup(cdev->gadget, hostaddr); if (status < 0) return status; gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); else { /* We assume that can_support_ecm() tells the truth; * but if the controller isn't recognized at all then * that assumption is a bit more likely to be wrong. */ dev_warn(&gadget->dev, "controller '%s' not recognized; trying %s\n", gadget->name, ncm_config_driver.label); device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099); } /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ /* device descriptor strings: manufacturer, product */ snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); status = usb_string_id(cdev); if (status < 0) goto fail; strings_dev[STRING_MANUFACTURER_IDX].id = status; device_desc.iManufacturer = status; status = usb_string_id(cdev); if (status < 0) goto fail; strings_dev[STRING_PRODUCT_IDX].id = status; device_desc.iProduct = status; status = usb_add_config(cdev, &ncm_config_driver, ncm_do_config); if (status < 0) goto fail; dev_info(&gadget->dev, "%s\n", DRIVER_DESC); return 0; fail: gether_cleanup(); return status; }
static int __init eth_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; /* set up network link layer */ status = gether_setup(cdev->gadget, hostaddr); if (status < 0) return status; /* set up main config label and device descriptor */ if (use_eem) { /* EEM */ eth_config_driver.label = "CDC Ethernet (EEM)"; device_desc.idVendor = cpu_to_le16(EEM_VENDOR_NUM); device_desc.idProduct = cpu_to_le16(EEM_PRODUCT_NUM); } else if (can_support_ecm(cdev->gadget)) { /* ECM */ eth_config_driver.label = "CDC Ethernet (ECM)"; } else { /* CDC Subset */ eth_config_driver.label = "CDC Subset/SAFE"; device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM); device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM); if (!has_rndis()) device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; } if (has_rndis()) { /* RNDIS plus ECM-or-Subset */ device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM); device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM); device_desc.bNumConfigurations = 2; } gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); else { /* We assume that can_support_ecm() tells the truth; * but if the controller isn't recognized at all then * that assumption is a bit more likely to be wrong. */ dev_warn(&gadget->dev, "controller '%s' not recognized; trying %s\n", gadget->name, eth_config_driver.label); device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099); } /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ /* device descriptor strings: manufacturer, product */ snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); status = usb_string_id(cdev); if (status < 0) goto fail; strings_dev[STRING_MANUFACTURER_IDX].id = status; device_desc.iManufacturer = status; status = usb_string_id(cdev); if (status < 0) goto fail; strings_dev[STRING_PRODUCT_IDX].id = status; device_desc.iProduct = status; /* register our configuration(s); RNDIS first, if it's used */ if (has_rndis()) { status = usb_add_config(cdev, &rndis_config_driver); if (status < 0) goto fail; } status = usb_add_config(cdev, ð_config_driver); if (status < 0) goto fail; dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC); return 0; fail: gether_cleanup(); return status; }
static int __init acm_ms_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; void *retp; status = gserial_setup(cdev->gadget, 1); if (status < 0) return status; retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data); if (IS_ERR(retp)) { status = PTR_ERR(retp); goto fail0; } gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) { device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); } else { WARNING(cdev, "controller '%s' not recognized; trying %s\n", gadget->name, acm_ms_config_driver.label); device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099); } snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); status = usb_string_id(cdev); if (status < 0) goto fail1; strings_dev[STRING_MANUFACTURER_IDX].id = status; device_desc.iManufacturer = status; status = usb_string_id(cdev); if (status < 0) goto fail1; strings_dev[STRING_PRODUCT_IDX].id = status; device_desc.iProduct = status; status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config); if (status < 0) goto fail1; dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC); fsg_common_put(&fsg_common); return 0; fail1: fsg_common_put(&fsg_common); fail0: gserial_cleanup(); return status; }
static int gser_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct f_gser *gser = func_to_gser(f); int status; struct usb_ep *ep; /* REVISIT might want instance-specific strings to help * distinguish instances ... */ /* maybe allocate device-global string ID */ if (gser_string_defs[0].id == 0) { status = usb_string_id(c->cdev); if (status < 0) return status; gser_string_defs[0].id = status; } /* allocate instance-specific interface IDs */ status = usb_interface_id(c, f); if (status < 0) goto fail; gser->data_id = status; gser_interface_desc.bInterfaceNumber = status; status = -ENODEV; /* allocate instance-specific endpoints */ ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_in_desc); if (!ep) goto fail; gser->port.in = ep; ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_out_desc); if (!ep) goto fail; gser->port.out = ep; ep->driver_data = cdev; /* claim */ #ifdef CONFIG_MODEM_SUPPORT ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_notify_desc); if (!ep) goto fail; gser->notify = ep; ep->driver_data = cdev; /* claim */ /* allocate notification */ gser->notify_req = gs_alloc_req(ep, sizeof(struct usb_cdc_notification) + 2, GFP_KERNEL); if (!gser->notify_req) goto fail; gser->notify_req->complete = gser_notify_complete; gser->notify_req->context = gser; #endif /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ gser_hs_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress; gser_hs_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress; gser_ss_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress; gser_ss_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress; if (gadget_is_dualspeed(c->cdev->gadget)) { #ifdef CONFIG_MODEM_SUPPORT gser_hs_notify_desc.bEndpointAddress = gser_fs_notify_desc.bEndpointAddress; #endif } if (gadget_is_superspeed(c->cdev->gadget)) { #ifdef CONFIG_MODEM_SUPPORT gser_ss_notify_desc.bEndpointAddress = gser_fs_notify_desc.bEndpointAddress; #endif } status = usb_assign_descriptors(f, gser_fs_function, gser_hs_function, gser_ss_function); if (status) goto fail; DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", gser->port_num, gadget_is_superspeed(c->cdev->gadget) ? "super" : gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", gser->port.in->name, gser->port.out->name); return 0; fail: #ifdef CONFIG_MODEM_SUPPORT if (gser->notify_req) gs_free_req(gser->notify, gser->notify_req); /* we might as well release our claims on endpoints */ if (gser->notify) gser->notify->driver_data = NULL; #endif /* we might as well release our claims on endpoints */ if (gser->port.out) gser->port.out->driver_data = NULL; if (gser->port.in) gser->port.in->driver_data = NULL; ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; }
int mtp_function_add(struct usb_composite_dev *cdev, struct usb_configuration *c) #endif { int ret = 0; int status; init_waitqueue_head(&g_usb_mtp_context.rx_wq); init_waitqueue_head(&g_usb_mtp_context.tx_wq); init_waitqueue_head(&g_usb_mtp_context.ctl_rx_wq); init_waitqueue_head(&g_usb_mtp_context.ctl_tx_wq); INIT_LIST_HEAD(&g_usb_mtp_context.rx_reqs); INIT_LIST_HEAD(&g_usb_mtp_context.rx_done_reqs); INIT_LIST_HEAD(&g_usb_mtp_context.tx_reqs); INIT_LIST_HEAD(&g_usb_mtp_context.ctl_rx_reqs); INIT_LIST_HEAD(&g_usb_mtp_context.ctl_rx_done_reqs); status = usb_string_id(c->cdev); if (status >= 0) { mtp_string_defs[STRING_INTERFACE].id = status; intf_desc.iInterface = status; } mtp_string_defs[STRING_MTP].id = mtp_ext_str_idx; #ifdef CONFIG_LGE_USB_GADGET_FUNC_BIND_ONLY_INIT g_usb_mtp_context.cdev = c->cdev; #else g_usb_mtp_context.cdev = cdev; #endif g_usb_mtp_context.function.name = "mtp"; g_usb_mtp_context.function.descriptors = fs_mtp_descs; g_usb_mtp_context.function.hs_descriptors = hs_mtp_descs; g_usb_mtp_context.function.strings = mtp_strings; g_usb_mtp_context.function.bind = mtp_function_bind; g_usb_mtp_context.function.unbind = mtp_function_unbind; g_usb_mtp_context.function.setup = mtp_function_setup; g_usb_mtp_context.function.set_alt = mtp_function_set_alt; g_usb_mtp_context.function.disable = mtp_function_disable; #ifndef CONFIG_LGE_USB_GADGET_FUNC_BIND_ONLY_INIT ret = mtp_function_init(); if (ret) goto mtp_exit; ret = misc_register(&mtp_enable_device); if (ret) goto misc_deregister; #endif #ifdef CONFIG_LGE_USB_GADGET_FUNC_BIND_ONLY_INIT /* start disabled */ g_usb_mtp_context.function.disabled = 1; #endif ret = usb_add_function(c, &g_usb_mtp_context.function); if (ret) { mtp_err("MTP gadget driver failed to initialize\n"); return ret; } return 0; #ifndef CONFIG_LGE_USB_GADGET_FUNC_BIND_ONLY_INIT mtp_misc_deregister: misc_deregister(&mtp_enable_device); mtp_exit: mtp_function_exit(); return ret; #endif }
static int g_dnl_config_register(struct usb_composite_dev *cdev) { static struct usb_configuration config = { .label = "usb_dnload", .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, .bConfigurationValue = CONFIGURATION_NUMBER, .iConfiguration = STRING_USBDOWN, .bind = g_dnl_do_config, }; return usb_add_config(cdev, &config); } __weak int g_dnl_bind_fixup(struct usb_device_descriptor *dev) { return 0; } static int g_dnl_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; int id, ret; int gcnum; debug("%s: gadget: 0x%p cdev: 0x%p\n", __func__, gadget, cdev); id = usb_string_id(cdev); if (id < 0) return id; g_dnl_string_defs[0].id = id; device_desc.iManufacturer = id; id = usb_string_id(cdev); if (id < 0) return id; g_dnl_string_defs[1].id = id; device_desc.iProduct = id; g_dnl_bind_fixup(&device_desc); ret = g_dnl_config_register(cdev); if (ret) goto error; gcnum = usb_gadget_controller_number(gadget); debug("gcnum: %d\n", gcnum); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); else { debug("%s: controller '%s' not recognized\n", shortname, gadget->name); device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); } debug("%s: calling usb_gadget_connect for " "controller '%s'\n", shortname, gadget->name); usb_gadget_connect(gadget); return 0; error: g_dnl_unbind(cdev); return -ENOMEM; } static struct usb_composite_driver g_dnl_driver = { .name = NULL, .dev = &device_desc, .strings = g_dnl_composite_strings, .bind = g_dnl_bind, .unbind = g_dnl_unbind, }; int g_dnl_register(const char *type) { /* We only allow "dfu" atm, so 3 should be enough */ static char name[sizeof(shortname) + 3]; int ret; if (!strcmp(type, "dfu")) { strcpy(name, shortname); strcat(name, type); } else if (!strcmp(type, "ums")) { strcpy(name, shortname); strcat(name, type); } else { printf("%s: unknown command: %s\n", __func__, type); return -EINVAL; } g_dnl_driver.name = name; debug("%s: g_dnl_driver.name: %s\n", __func__, g_dnl_driver.name); ret = usb_composite_register(&g_dnl_driver); if (ret) { printf("%s: failed!, error: %d\n", __func__, ret); return ret; } return 0; } void g_dnl_unregister(void) { usb_composite_unregister(&g_dnl_driver); }
static int __init gncm_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; /* */ status = gether_setup(cdev->gadget, hostaddr); if (status < 0) return status; gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); else { /* */ dev_warn(&gadget->dev, "controller '%s' not recognized; trying %s\n", gadget->name, ncm_config_driver.label); device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099); } /* */ /* */ snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); status = usb_string_id(cdev); if (status < 0) goto fail; strings_dev[STRING_MANUFACTURER_IDX].id = status; device_desc.iManufacturer = status; status = usb_string_id(cdev); if (status < 0) goto fail; strings_dev[STRING_PRODUCT_IDX].id = status; device_desc.iProduct = status; status = usb_add_config(cdev, &ncm_config_driver, ncm_do_config); if (status < 0) goto fail; dev_info(&gadget->dev, "%s\n", DRIVER_DESC); return 0; fail: gether_cleanup(); return status; }
/** * ecm_bind_config - add CDC Ethernet network link to a configuration * @c: the configuration to support the network link * @ethaddr: a buffer in which the ethernet address of the host side * side of the link was recorded * Context: single threaded during gadget setup * * Returns zero on success, else negative errno. * * Caller must have called @gether_setup(). Caller is also responsible * for calling @gether_cleanup() before module unload. */ int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) { struct f_ecm *ecm; int status; if (!can_support_ecm(c->cdev->gadget) || !ethaddr) return -EINVAL; /* maybe allocate device-global string IDs */ if (ecm_string_defs[0].id == 0) { /* control interface label */ status = 5; if (status < 0) return status; ecm_string_defs[0].id = status; ecm_control_intf.iInterface = status; #ifdef CONFIG_LGE_USB_GADGET_DRIVER /* MAC address */ status = usb_string_id(c->cdev); if (status < 0) return status; ecm_string_defs[1].id = status; pr_info("%s: iMACAddress = %d\n", __func__, status); ecm_desc.iMACAddress = status; #endif /* data interface label */ status = usb_string_id(c->cdev); if (status < 0) return status; ecm_string_defs[2].id = status; ecm_data_intf.iInterface = status; /* NOTE : if NOT defined */ #ifndef CONFIG_LGE_USB_GADGET_DRIVER /* MAC address */ status = usb_string_id(c->cdev); if (status < 0) return status; ecm_string_defs[1].id = status; ecm_desc.iMACAddress = status; #endif } /* allocate and initialize one new instance */ ecm = kzalloc(sizeof *ecm, GFP_KERNEL); if (!ecm) return -ENOMEM; /* export host's Ethernet address in CDC format */ snprintf(ecm->ethaddr, sizeof ecm->ethaddr, "%02X%02X%02X%02X%02X%02X", ethaddr[0], ethaddr[1], ethaddr[2], ethaddr[3], ethaddr[4], ethaddr[5]); ecm_string_defs[1].s = ecm->ethaddr; ecm->port.cdc_filter = DEFAULT_FILTER; #ifdef CONFIG_LGE_USB_GADGET_DRIVER ecm->port.func.name = "ecm"; #else ecm->port.func.name = "cdc_ethernet"; #endif ecm->port.func.strings = ecm_strings; /* descriptors are per-instance copies */ ecm->port.func.bind = ecm_bind; ecm->port.func.unbind = ecm_unbind; ecm->port.func.set_alt = ecm_set_alt; ecm->port.func.get_alt = ecm_get_alt; ecm->port.func.setup = ecm_setup; ecm->port.func.disable = ecm_disable; ecm->port.func.suspend = ecm_suspend; ecm->port.func.resume = ecm_resume; status = usb_add_function(c, &ecm->port.func); if (status) { ecm_string_defs[1].s = NULL; kfree(ecm); } return status; }
/** * uvc_bind_config - add a UVC function to a configuration * @c: the configuration to support the UVC instance * Context: single threaded during gadget setup * * Returns zero on success, else negative errno. * * Caller must have called @uvc_setup(). Caller is also responsible for * calling @uvc_cleanup() before module unload. */ int __init uvc_bind_config(struct usb_configuration *c, const struct uvc_descriptor_header * const *control, const struct uvc_descriptor_header * const *fs_streaming, const struct uvc_descriptor_header * const *hs_streaming) { struct uvc_device *uvc; int ret = 0; /* TODO Check if the USB device controller supports the required * features. */ if (!gadget_is_dualspeed(c->cdev->gadget)) return -EINVAL; uvc = kzalloc(sizeof(*uvc), GFP_KERNEL); if (uvc == NULL) return -ENOMEM; uvc->state = UVC_STATE_DISCONNECTED; /* Validate the descriptors. */ if (control == NULL || control[0] == NULL || control[0]->bDescriptorSubType != UVC_VC_HEADER) goto error; if (fs_streaming == NULL || fs_streaming[0] == NULL || fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) goto error; if (hs_streaming == NULL || hs_streaming[0] == NULL || hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) goto error; uvc->desc.control = control; uvc->desc.fs_streaming = fs_streaming; uvc->desc.hs_streaming = hs_streaming; /* Allocate string descriptor numbers. */ if ((ret = usb_string_id(c->cdev)) < 0) goto error; uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = ret; uvc_iad.iFunction = ret; if ((ret = usb_string_id(c->cdev)) < 0) goto error; uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = ret; uvc_control_intf.iInterface = ret; if ((ret = usb_string_id(c->cdev)) < 0) goto error; uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id = ret; uvc_streaming_intf_alt0.iInterface = ret; uvc_streaming_intf_alt1.iInterface = ret; /* Register the function. */ uvc->func.name = "uvc"; uvc->func.strings = uvc_function_strings; uvc->func.bind = uvc_function_bind; uvc->func.unbind = uvc_function_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.setup = uvc_function_setup; ret = usb_add_function(c, &uvc->func); if (ret) kfree(uvc); return 0; error: kfree(uvc); return ret; }
/** * gser_bind_config - add a generic serial function to a configuration * @c: the configuration to support the serial instance * @port_num: /dev/ttyGS* port this interface will use * Context: single threaded during gadget setup * * Returns zero on success, else negative errno. * * Caller must have called @gserial_setup() with enough ports to * handle all the ones it binds. Caller is also responsible * for calling @gserial_cleanup() before module unload. */ int gser_bind_config(struct usb_configuration *c, u8 port_num) { struct f_gser *gser; int status; /* REVISIT might want instance-specific strings to help * distinguish instances ... */ // << FerryWu, 2012/08/07, Fix strings table of USB descriptor #ifdef CONFIG_MODEM_SUPPORT if ((modem_string_defs[0].id == 0) && (port_num == 0)) { status = usb_string_id(c->cdev); if (status < 0) return status; modem_string_defs[0].id = status; gser_interface_desc.iInterface = status; } if ((nmea_string_defs[0].id == 0) && (port_num != 0)) { status = usb_string_id(c->cdev); if (status < 0) return status; nmea_string_defs[0].id = status; gser_interface_desc.iInterface = status; } #else /* maybe allocate device-global string ID */ if (gser_string_defs[0].id == 0) { status = usb_string_id(c->cdev); if (status < 0) return status; gser_string_defs[0].id = status; gser_interface_desc.iInterface = status; } #endif // >> FerryWu, 2012/08/07, Fix strings table of USB descriptor /* allocate and initialize one new instance */ gser = kzalloc(sizeof *gser, GFP_KERNEL); if (!gser) return -ENOMEM; #ifdef CONFIG_MODEM_SUPPORT spin_lock_init(&gser->lock); #endif gser->port_num = port_num; gser->port.func.name = "gser"; gser->port.func.strings = gser_strings; // << FerryWu, 2012/08/07, Fix strings table of USB descriptor #ifdef CONFIG_MODEM_SUPPORT if (port_num == 0) gser->port.func.strings = modem_strings; else gser->port.func.strings = nmea_strings; #endif // >> FerryWu, 2012/08/07, Fix strings table of USB descriptor gser->port.func.bind = gser_bind; gser->port.func.unbind = gser_unbind; gser->port.func.set_alt = gser_set_alt; gser->port.func.disable = gser_disable; gser->transport = gserial_ports[port_num].transport; #ifdef CONFIG_MODEM_SUPPORT /* We support only two ports for now */ if (port_num == 0) gser->port.func.name = "modem"; else gser->port.func.name = "nmea"; gser->port.func.setup = gser_setup; gser->port.connect = gser_connect; gser->port.get_dtr = gser_get_dtr; gser->port.get_rts = gser_get_rts; gser->port.send_carrier_detect = gser_send_carrier_detect; gser->port.send_ring_indicator = gser_send_ring_indicator; gser->port.send_modem_ctrl_bits = gser_send_modem_ctrl_bits; gser->port.disconnect = gser_disconnect; gser->port.send_break = gser_send_break; #endif status = usb_add_function(c, &gser->port.func); if (status) kfree(gser); return status; }
static int __init multi_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; int status, gcnum; if (!can_support_ecm(cdev->gadget)) { dev_err(&gadget->dev, "controller '%s' not usable\n", gadget->name); return -EINVAL; } /* set up network link layer */ status = gether_setup(cdev->gadget, hostaddr); if (status < 0) return status; /* set up serial link layer */ status = gserial_setup(cdev->gadget, 1); if (status < 0) goto fail0; /* set up mass storage function */ fsg_common = fsg_common_from_params(0, cdev, &mod_data); if (IS_ERR(fsg_common)) { status = PTR_ERR(fsg_common); goto fail1; } gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); else { /* We assume that can_support_ecm() tells the truth; * but if the controller isn't recognized at all then * that assumption is a bit more likely to be wrong. */ WARNING(cdev, "controller '%s' not recognized\n", gadget->name); device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099); } /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ /* device descriptor strings: manufacturer, product */ snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); status = usb_string_id(cdev); if (status < 0) goto fail2; strings_dev[STRING_MANUFACTURER_IDX].id = status; device_desc.iManufacturer = status; status = usb_string_id(cdev); if (status < 0) goto fail2; strings_dev[STRING_PRODUCT_IDX].id = status; device_desc.iProduct = status; #ifdef USB_ETH_RNDIS /* register our first configuration */ status = usb_add_config(cdev, &rndis_config_driver); if (status < 0) goto fail2; #endif #ifdef CONFIG_USB_G_MULTI_CDC /* register our second configuration */ status = usb_add_config(cdev, &cdc_config_driver); if (status < 0) goto fail2; #endif dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); fsg_common_put(fsg_common); return 0; fail2: fsg_common_put(fsg_common); fail1: gserial_cleanup(); fail0: gether_cleanup(); return status; }
static int gfs_bind(struct usb_composite_dev *cdev) { int ret; ENTER(); if (WARN_ON(!gfs_ffs_data)) return -ENODEV; ret = gether_setup(cdev->gadget, gfs_hostaddr); if (unlikely(ret < 0)) goto error_quick; gfs_dev_desc.idVendor = cpu_to_le16(gfs_vendor_id); gfs_dev_desc.idProduct = cpu_to_le16(gfs_product_id); snprintf(gfs_manufacturer, sizeof gfs_manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, cdev->gadget->name); ret = usb_string_id(cdev); if (unlikely(ret < 0)) goto error; gfs_strings[GFS_STRING_MANUFACTURER_IDX].id = ret; gfs_dev_desc.iManufacturer = ret; ret = usb_string_id(cdev); if (unlikely(ret < 0)) goto error; gfs_strings[GFS_STRING_PRODUCT_IDX].id = ret; gfs_dev_desc.iProduct = ret; #ifdef CONFIG_USB_FUNCTIONFS_RNDIS ret = usb_string_id(cdev); if (unlikely(ret < 0)) goto error; gfs_strings[GFS_STRING_RNDIS_CONFIG_IDX].id = ret; gfs_rndis_config_driver.iConfiguration = ret; #endif #ifdef CONFIG_USB_FUNCTIONFS_ETH ret = usb_string_id(cdev); if (unlikely(ret < 0)) goto error; gfs_strings[GFS_STRING_ECM_CONFIG_IDX].id = ret; gfs_ecm_config_driver.iConfiguration = ret; #endif #ifdef CONFIG_USB_FUNCTIONFS_GENERIC ret = usb_string_id(cdev); if (unlikely(ret < 0)) goto error; gfs_strings[GFS_STRING_GENERIC_CONFIG_IDX].id = ret; gfs_generic_config_driver.iConfiguration = ret; #endif ret = functionfs_bind(gfs_ffs_data, cdev); if (unlikely(ret < 0)) goto error; ret = gfs_add_rndis_config(cdev); if (unlikely(ret < 0)) goto error_unbind; ret = gfs_add_ecm_config(cdev); if (unlikely(ret < 0)) goto error_unbind; ret = gfs_add_generic_config(cdev); if (unlikely(ret < 0)) goto error_unbind; return 0; error_unbind: functionfs_unbind(gfs_ffs_data); error: gether_cleanup(); error_quick: gfs_ffs_data = NULL; return ret; }
static int __ref zero_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; int id; /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ id = usb_string_id(cdev); if (id < 0) return id; strings_dev[STRING_MANUFACTURER_IDX].id = id; device_desc.iManufacturer = id; id = usb_string_id(cdev); if (id < 0) return id; strings_dev[STRING_PRODUCT_IDX].id = id; device_desc.iProduct = id; id = usb_string_id(cdev); if (id < 0) return id; strings_dev[STRING_SERIAL_IDX].id = id; device_desc.iSerialNumber = id; setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); /* Register primary, then secondary configuration. Note that * SH3 only allows one config... */ if (loopdefault) { loopback_add(cdev, autoresume != 0); sourcesink_add(cdev, autoresume != 0); } else { sourcesink_add(cdev, autoresume != 0); loopback_add(cdev, autoresume != 0); } gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); else { /* gadget zero is so simple (for now, no altsettings) that * it SHOULD NOT have problems with bulk-capable hardware. * so just warn about unrcognized controllers -- don't panic. * * things like configuration and altsetting numbering * can need hardware-specific attention though. */ pr_warning("%s: controller '%s' not recognized\n", longname, gadget->name); device_desc.bcdDevice = cpu_to_le16(0x9999); } INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname); snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); startms = autoresume; if (autoresume > 0 && autoresume < 5) pr_warning("%s: time before sending remote wakeup is less than 5ms, should not send resume signal.\n", longname); return 0; }
/** * gser_bind_config - add a generic serial function to a configuration * @c: the configuration to support the serial instance * @port_num: /dev/ttyGS* port this interface will use * Context: single threaded during gadget setup * * Returns zero on success, else negative errno. * * Caller must have called @gserial_setup() with enough ports to * handle all the ones it binds. Caller is also responsible * for calling @gserial_cleanup() before module unload. */ int gser_bind_config(struct usb_configuration *c, u8 port_num) { struct f_gser *gser; int status; /* REVISIT might want instance-specific strings to help * distinguish instances ... */ /* maybe allocate device-global string ID */ #ifndef CONFIG_LGE_USB_GADGET_DRIVER if (gser_string_defs[0].id == 0) { status = usb_string_id(c->cdev); if (status < 0) return status; gser_string_defs[0].id = status; } #endif /* allocate and initialize one new instance */ gser = kzalloc(sizeof *gser, GFP_KERNEL); if (!gser) return -ENOMEM; #ifdef CONFIG_MODEM_SUPPORT spin_lock_init(&gser->lock); #endif gser->port_num = port_num; gser->port.func.name = "gser"; gser->port.func.strings = gser_strings; gser->port.func.bind = gser_bind; gser->port.func.unbind = gser_unbind; gser->port.func.set_alt = gser_set_alt; gser->port.func.disable = gser_disable; gser->transport = gserial_ports[port_num].transport; #ifdef CONFIG_MODEM_SUPPORT /* We support only three ports for now */ if (port_num == 0) gser->port.func.name = "modem"; else if (port_num == 1) gser->port.func.name = "nmea"; else gser->port.func.name = "modem2"; gser->port.func.setup = gser_setup; gser->port.connect = gser_connect; gser->port.get_dtr = gser_get_dtr; gser->port.get_rts = gser_get_rts; gser->port.send_carrier_detect = gser_send_carrier_detect; gser->port.send_ring_indicator = gser_send_ring_indicator; #ifndef CONFIG_LGE_USB_GADGET_DRIVER gser->port.send_modem_ctrl_bits = gser_send_modem_ctrl_bits; #endif gser->port.disconnect = gser_disconnect; gser->port.send_break = gser_send_break; #endif status = usb_add_function(c, &gser->port.func); if (status) kfree(gser); return status; }
static int maemo_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; int status, gcnum; /* set up diag channel */ diag_ch = diag_setup(&usb_diag_pdata); if (IS_ERR(diag_ch)) return PTR_ERR(diag_ch); /* set up network link layer */ status = gether_setup(cdev->gadget, hostaddr); if (status < 0) goto diag_clean; /* set up serial link layer */ status = gserial_setup(cdev->gadget, 2); if (status < 0) goto fail0; /* set up mass storage function */ fsg_common = fsg_common_from_params(0, cdev, &mod_data); if (IS_ERR(fsg_common)) { status = PTR_ERR(fsg_common); goto fail1; } gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); else { /* gadget zero is so simple (for now, no altsettings) that * it SHOULD NOT have problems with bulk-capable hardware. * so just warn about unrcognized controllers -- don't panic. * * things like configuration and altsetting numbering * can need hardware-specific attention though. */ WARNING(cdev, "controller '%s' not recognized\n", gadget->name); device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); } /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ status = usb_string_id(cdev); if (status < 0) goto fail2; strings_dev[STRING_MANUFACTURER_IDX].id = status; device_desc.iManufacturer = status; status = usb_string_id(cdev); if (status < 0) goto fail2; strings_dev[STRING_PRODUCT_IDX].id = status; device_desc.iProduct = status; if (!usb_gadget_set_selfpowered(gadget)) maemo_config_driver.bmAttributes |= USB_CONFIG_ATT_SELFPOWER; if (gadget->ops->wakeup) maemo_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; /* register our first configuration */ status = usb_add_config(cdev, &maemo_config_driver); if (status < 0) goto fail2; usb_gadget_set_selfpowered(gadget); dev_info(&gadget->dev, DRIVER_DESC "\n"); fsg_common_put(fsg_common); return 0; fail2: fsg_common_put(fsg_common); fail1: gserial_cleanup(); fail0: gether_cleanup(); diag_clean: diag_cleanup(diag_ch); return status; }
/** * gser_bind_config - add a generic serial function to a configuration * @c: the configuration to support the serial instance * @port_num: /dev/ttyGS* port this interface will use * Context: single threaded during gadget setup * * Returns zero on success, else negative errno. * * Caller must have called @gserial_setup() with enough ports to * handle all the ones it binds. Caller is also responsible * for calling @gserial_cleanup() before module unload. */ int gser_bind_config(struct usb_configuration *c, u8 port_num) { struct f_gser *gser; int status; struct port_info *p = &gserial_ports[port_num]; if (p->func_type == USB_FSER_FUNC_NONE) { pr_info("%s: non function port : %d\n", __func__, port_num); return 0; } pr_info("%s: type:%d, trasport: %s\n", __func__, p->func_type, transport_to_str(p->transport)); /* REVISIT might want instance-specific strings to help * distinguish instances ... */ /* maybe allocate device-global string ID */ /* HTC modem port_num is 0 */ #if 0 if (port_num != 0) { if (gser_string_defs[0].id == 0) { status = usb_string_id(c->cdev); if (status < 0) return status; gser_string_defs[0].id = status; } } #endif if (modem_string_defs[0].id == 0 && p->func_type == USB_FSER_FUNC_MODEM) { status = usb_string_id(c->cdev); if (status < 0) { printk(KERN_ERR "%s: return %d\n", __func__, status); return status; } modem_string_defs[0].id = status; } if (modem_string_defs[1].id == 0 && p->func_type == USB_FSER_FUNC_MODEM_MDM) { status = usb_string_id(c->cdev); if (status < 0) { printk(KERN_ERR "%s: return %d\n", __func__, status); return status; } modem_string_defs[1].id = status; } if (gser_string_defs[0].id == 0 && (p->func_type == USB_FSER_FUNC_SERIAL || p->func_type == USB_FSER_FUNC_AUTOBOT)) { status = usb_string_id(c->cdev); if (status < 0) { printk(KERN_ERR "%s: return %d\n", __func__, status); return status; } gser_string_defs[0].id = status; } /* allocate and initialize one new instance */ gser = kzalloc(sizeof *gser, GFP_KERNEL); if (!gser) return -ENOMEM; #ifdef CONFIG_MODEM_SUPPORT spin_lock_init(&gser->lock); #endif gser->port_num = port_num; gser->port.func.name = "gser"; gser->port.func.strings = gser_strings; gser->port.func.bind = gser_bind; gser->port.func.unbind = gser_unbind; gser->port.func.set_alt = gser_set_alt; gser->port.func.disable = gser_disable; gser->transport = gserial_ports[port_num].transport; #ifdef CONFIG_MODEM_SUPPORT /* We support only two ports for now */ if (port_num == 0) { gser->port.func.name = "modem"; } else gser->port.func.name = "nmea"; gser->port.func.setup = gser_setup; gser->port.connect = gser_connect; gser->port.get_dtr = gser_get_dtr; gser->port.get_rts = gser_get_rts; gser->port.send_carrier_detect = gser_send_carrier_detect; gser->port.send_ring_indicator = gser_send_ring_indicator; gser->port.send_modem_ctrl_bits = gser_send_modem_ctrl_bits; gser->port.disconnect = gser_disconnect; gser->port.send_break = gser_send_break; #endif switch (p->func_type) { case USB_FSER_FUNC_MODEM: gser->port.func.name = "modem"; gser->port.func.strings = modem_strings; gser_interface_desc.iInterface = modem_string_defs[0].id; break; case USB_FSER_FUNC_MODEM_MDM: gser->port.func.name = "modem_mdm"; gser->port.func.strings = modem_strings; gser_interface_desc.iInterface = modem_string_defs[1].id; break; case USB_FSER_FUNC_SERIAL: case USB_FSER_FUNC_AUTOBOT: gser->port.func.name = "serial"; gser->port.func.strings = gser_strings; gser_interface_desc.iInterface = gser_string_defs[0].id; break; case USB_FSER_FUNC_NONE: default : break; } status = usb_add_function(c, &gser->port.func); if (status) kfree(gser); return status; }
static int __init eth_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; status = gether_setup(cdev->gadget, hostaddr); if (status < 0) return status; if (use_eem) { eth_config_driver.label = "CDC Ethernet (EEM)"; device_desc.idVendor = cpu_to_le16(EEM_VENDOR_NUM); device_desc.idProduct = cpu_to_le16(EEM_PRODUCT_NUM); } else if (can_support_ecm(cdev->gadget)) { eth_config_driver.label = "CDC Ethernet (ECM)"; } else { eth_config_driver.label = "CDC Subset/SAFE"; device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM); device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM); if (!has_rndis()) device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; } if (has_rndis()) { device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM); device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM); device_desc.bNumConfigurations = 2; } gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); else { dev_warn(&gadget->dev, "controller '%s' not recognized; trying %s\n", gadget->name, eth_config_driver.label); device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099); } snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); status = usb_string_id(cdev); if (status < 0) goto fail; strings_dev[STRING_MANUFACTURER_IDX].id = status; device_desc.iManufacturer = status; status = usb_string_id(cdev); if (status < 0) goto fail; strings_dev[STRING_PRODUCT_IDX].id = status; device_desc.iProduct = status; if (has_rndis()) { status = usb_add_config(cdev, &rndis_config_driver); if (status < 0) goto fail; } status = usb_add_config(cdev, ð_config_driver); if (status < 0) goto fail; dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC); return 0; fail: gether_cleanup(); return status; }