static int __exit multi_unbind(struct usb_composite_dev *cdev) { #ifdef CONFIG_USB_G_MULTI_CDC usb_put_function(f_acm_multi); #endif #ifdef USB_ETH_RNDIS usb_put_function(f_acm_rndis); #endif usb_put_function_instance(fi_acm); gether_cleanup(the_dev); return 0; }
static int zero_unbind(struct usb_composite_dev *cdev) { del_timer_sync(&autoresume_timer); if (!IS_ERR_OR_NULL(func_ss)) usb_put_function(func_ss); usb_put_function_instance(func_inst_ss); if (!IS_ERR_OR_NULL(func_lb)) usb_put_function(func_lb); usb_put_function_instance(func_inst_lb); kfree(otg_desc[0]); otg_desc[0] = NULL; return 0; }
static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) { usb_put_function(f_acm); usb_put_function_instance(f_acm_inst); gserial_free_line(tty_line); return 0; }
static int guas_unbind(struct usb_composite_dev *cdev) { if (!IS_ERR_OR_NULL(f_tcm)) usb_put_function(f_tcm); return 0; }
static int msg_do_config(struct usb_configuration *c) { struct fsg_opts *opts; int ret; if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } opts = fsg_opts_from_func_inst(fi_msg); f_msg = usb_get_function(fi_msg); if (IS_ERR(f_msg)) return PTR_ERR(f_msg); ret = fsg_common_run_thread(opts->common); if (ret) goto put_func; ret = usb_add_function(c, f_msg); if (ret) goto put_func; return 0; put_func: usb_put_function(f_msg); return ret; }
static int __init ncm_do_config(struct usb_configuration *c) { int status; /* FIXME alloc iConfiguration string, set it in c->strings */ if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } f_ncm = usb_get_function(f_ncm_inst); if (IS_ERR(f_ncm)) { status = PTR_ERR(f_ncm); return status; } status = usb_add_function(c, f_ncm); if (status < 0) { usb_put_function(f_ncm); return status; } return 0; }
static __init int cdc_do_config(struct usb_configuration *c) { int ret; if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } ret = ecm_bind_config(c, host_mac, the_dev); if (ret < 0) return ret; /* implicit port_num is zero */ f_acm_multi = usb_get_function(fi_acm); if (IS_ERR(f_acm_multi)) return PTR_ERR(f_acm_multi); ret = usb_add_function(c, f_acm_multi); if (ret) goto err_conf; ret = fsg_bind_config(c->cdev, c, &fsg_common); if (ret < 0) goto err_fsg; return 0; err_fsg: usb_remove_function(c, f_acm_multi); err_conf: usb_put_function(f_acm_multi); return ret; }
static int serial_register_ports(struct usb_composite_dev *cdev, struct usb_configuration *c, const char *f_name) { int i; int ret; ret = usb_add_config_only(cdev, c); if (ret) goto out; for (i = 0; i < n_ports; i++) { fi_serial[i] = usb_get_function_instance(f_name); if (IS_ERR(fi_serial[i])) { ret = PTR_ERR(fi_serial[i]); goto fail; } f_serial[i] = usb_get_function(fi_serial[i]); if (IS_ERR(f_serial[i])) { ret = PTR_ERR(f_serial[i]); goto err_get_func; } ret = usb_add_function(c, f_serial[i]); if (ret) goto err_add_func; } return 0; err_add_func: usb_put_function(f_serial[i]); err_get_func: usb_put_function_instance(fi_serial[i]); fail: i--; while (i >= 0) { usb_remove_function(c, f_serial[i]); usb_put_function(f_serial[i]); usb_put_function_instance(fi_serial[i]); i--; } out: return ret; }
static int __exit gncm_unbind(struct usb_composite_dev *cdev) { if (!IS_ERR_OR_NULL(f_ncm)) usb_put_function(f_ncm); if (!IS_ERR_OR_NULL(f_ncm_inst)) usb_put_function_instance(f_ncm_inst); return 0; }
static int audio_unbind(struct usb_composite_dev *cdev) { #ifdef CONFIG_GADGET_UAC1 if (!IS_ERR_OR_NULL(f_uac1)) usb_put_function(f_uac1); if (!IS_ERR_OR_NULL(fi_uac1)) usb_put_function_instance(fi_uac1); #else if (!IS_ERR_OR_NULL(f_uac2)) usb_put_function(f_uac2); if (!IS_ERR_OR_NULL(fi_uac2)) usb_put_function_instance(fi_uac2); #endif kfree(otg_desc[0]); otg_desc[0] = NULL; return 0; }
/* * We _always_ have an ECM, CDC Subset, or EEM configuration. */ static int __init eth_do_config(struct usb_configuration *c) { int status = 0; /* FIXME alloc iConfiguration string, set it in c->strings */ if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } if (use_eem) { f_eem = usb_get_function(fi_eem); if (IS_ERR(f_eem)) return PTR_ERR(f_eem); status = usb_add_function(c, f_eem); if (status < 0) usb_put_function(f_eem); return status; } else if (can_support_ecm(c->cdev->gadget)) { f_ecm = usb_get_function(fi_ecm); if (IS_ERR(f_ecm)) return PTR_ERR(f_ecm); status = usb_add_function(c, f_ecm); if (status < 0) usb_put_function(f_ecm); return status; } else { f_geth = usb_get_function(fi_geth); if (IS_ERR(f_geth)) return PTR_ERR(f_geth); status = usb_add_function(c, f_geth); if (status < 0) usb_put_function(f_geth); return status; } }
/* * We _always_ have both ACM and mass storage functions. */ static int acm_ms_do_config(struct usb_configuration *c) { struct fsg_opts *opts; int status; if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } opts = fsg_opts_from_func_inst(fi_msg); f_acm = usb_get_function(f_acm_inst); if (IS_ERR(f_acm)) return PTR_ERR(f_acm); f_msg = usb_get_function(fi_msg); if (IS_ERR(f_msg)) { status = PTR_ERR(f_msg); goto put_acm; } status = usb_add_function(c, f_acm); if (status < 0) goto put_msg; status = fsg_common_run_thread(opts->common); if (status) goto remove_acm; status = usb_add_function(c, f_msg); if (status) goto remove_acm; return 0; remove_acm: usb_remove_function(c, f_acm); put_msg: usb_put_function(f_msg); put_acm: usb_put_function(f_acm); return status; }
static int msg_unbind(struct usb_composite_dev *cdev) { if (!IS_ERR(f_msg)) usb_put_function(f_msg); if (!IS_ERR(fi_msg)) usb_put_function_instance(fi_msg); return 0; }
static int gs_unbind(struct usb_composite_dev *cdev) { int i; for (i = 0; i < n_ports; i++) { usb_put_function(f_serial[i]); usb_put_function_instance(fi_serial[i]); } return 0; }
static int __exit multi_unbind(struct usb_composite_dev *cdev) { #ifdef CONFIG_USB_G_MULTI_CDC usb_put_function(f_msg_multi); #endif #ifdef USB_ETH_RNDIS usb_put_function(f_msg_rndis); #endif usb_put_function_instance(fi_msg); #ifdef CONFIG_USB_G_MULTI_CDC usb_put_function(f_acm_multi); #endif #ifdef USB_ETH_RNDIS usb_put_function(f_acm_rndis); #endif usb_put_function_instance(fi_acm); #ifdef USB_ETH_RNDIS usb_put_function(f_rndis); usb_put_function_instance(fi_rndis); #endif #ifdef CONFIG_USB_G_MULTI_CDC usb_put_function(f_ecm); usb_put_function_instance(fi_ecm); #endif return 0; }
static int msg_unbind(struct usb_composite_dev *cdev) { if (!IS_ERR(f_msg)) usb_put_function(f_msg); if (!IS_ERR(fi_msg)) usb_put_function_instance(fi_msg); kfree(otg_desc[0]); otg_desc[0] = NULL; return 0; }
static int audio_do_config(struct usb_configuration *c) { int status; /* FIXME alloc iConfiguration string, set it in c->strings */ if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } #ifdef CONFIG_GADGET_UAC1 f_uac1 = usb_get_function(fi_uac1); if (IS_ERR(f_uac1)) { status = PTR_ERR(f_uac1); return status; } status = usb_add_function(c, f_uac1); if (status < 0) { usb_put_function(f_uac1); return status; } #else f_uac2 = usb_get_function(fi_uac2); if (IS_ERR(f_uac2)) { status = PTR_ERR(f_uac2); return status; } status = usb_add_function(c, f_uac2); if (status < 0) { usb_put_function(f_uac2); return status; } #endif return 0; }
/* * We _always_ have both CDC ECM and CDC ACM functions. */ static int __init cdc_do_config(struct usb_configuration *c) { int status; if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } f_ecm = usb_get_function(fi_ecm); if (IS_ERR(f_ecm)) { status = PTR_ERR(f_ecm); goto err_get_ecm; } status = usb_add_function(c, f_ecm); if (status) goto err_add_ecm; f_acm = usb_get_function(fi_serial); if (IS_ERR(f_acm)) { status = PTR_ERR(f_acm); goto err_get_acm; } status = usb_add_function(c, f_acm); if (status) goto err_add_acm; return 0; err_add_acm: usb_put_function(f_acm); err_get_acm: usb_remove_function(c, f_ecm); err_add_ecm: usb_put_function(f_ecm); err_get_ecm: return status; }
static int midi_bind_config(struct usb_configuration *c) { int status; f_midi = usb_get_function(fi_midi); if (IS_ERR(f_midi)) return PTR_ERR(f_midi); status = usb_add_function(c, f_midi); if (status < 0) { usb_put_function(f_midi); return status; } return 0; }
static int tcm_do_config(struct usb_configuration *c) { int status; f_tcm = usb_get_function(fi_tcm); if (IS_ERR(f_tcm)) return PTR_ERR(f_tcm); status = usb_add_function(c, f_tcm); if (status < 0) { usb_put_function(f_tcm); return status; } return 0; }
/* * We _always_ have both ACM and mass storage functions. */ static int __init acm_ms_do_config(struct usb_configuration *c) { struct f_serial_opts *opts; int status; if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } f_acm_inst = usb_get_function_instance("acm"); if (IS_ERR(f_acm_inst)) return PTR_ERR(f_acm_inst); opts = container_of(f_acm_inst, struct f_serial_opts, func_inst); opts->port_num = tty_line; f_acm = usb_get_function(f_acm_inst); if (IS_ERR(f_acm)) { status = PTR_ERR(f_acm); goto err_func; } status = usb_add_function(c, f_acm); if (status < 0) goto err_conf; status = fsg_bind_config(c->cdev, c, &fsg_common); if (status < 0) goto err_fsg; return 0; err_fsg: usb_remove_function(c, f_acm); err_conf: usb_put_function(f_acm); err_func: usb_put_function_instance(f_acm_inst); return status; }
static int __init nokia_bind_config(struct usb_configuration *c) { struct usb_function *f_acm; struct usb_function *f_phonet = NULL; struct usb_function *f_obex1 = NULL; struct usb_function *f_ecm; struct usb_function *f_obex2 = NULL; int status = 0; int obex1_stat = -1; int obex2_stat = -1; int phonet_stat = -1; if (!IS_ERR(fi_phonet)) { f_phonet = usb_get_function(fi_phonet); if (IS_ERR(f_phonet)) pr_debug("could not get phonet function\n"); } if (!IS_ERR(fi_obex1)) { f_obex1 = usb_get_function(fi_obex1); if (IS_ERR(f_obex1)) pr_debug("could not get obex function 0\n"); } if (!IS_ERR(fi_obex2)) { f_obex2 = usb_get_function(fi_obex2); if (IS_ERR(f_obex2)) pr_debug("could not get obex function 1\n"); } f_acm = usb_get_function(fi_acm); if (IS_ERR(f_acm)) { status = PTR_ERR(f_acm); goto err_get_acm; } f_ecm = usb_get_function(fi_ecm); if (IS_ERR(f_ecm)) { status = PTR_ERR(f_ecm); goto err_get_ecm; } if (!IS_ERR_OR_NULL(f_phonet)) { phonet_stat = usb_add_function(c, f_phonet); if (phonet_stat) pr_debug("could not add phonet function\n"); } if (!IS_ERR_OR_NULL(f_obex1)) { obex1_stat = usb_add_function(c, f_obex1); if (obex1_stat) pr_debug("could not add obex function 0\n"); } if (!IS_ERR_OR_NULL(f_obex2)) { obex2_stat = usb_add_function(c, f_obex2); if (obex2_stat) pr_debug("could not add obex function 1\n"); } status = usb_add_function(c, f_acm); if (status) goto err_conf; status = usb_add_function(c, f_ecm); if (status) { pr_debug("could not bind ecm config %d\n", status); goto err_ecm; } if (c == &nokia_config_500ma_driver) { f_acm_cfg1 = f_acm; f_ecm_cfg1 = f_ecm; f_phonet_cfg1 = f_phonet; f_obex1_cfg1 = f_obex1; f_obex2_cfg1 = f_obex2; } else { f_acm_cfg2 = f_acm; f_ecm_cfg2 = f_ecm; f_phonet_cfg2 = f_phonet; f_obex1_cfg2 = f_obex1; f_obex2_cfg2 = f_obex2; } return status; err_ecm: usb_remove_function(c, f_acm); err_conf: if (!obex2_stat) usb_remove_function(c, f_obex2); if (!obex1_stat) usb_remove_function(c, f_obex1); if (!phonet_stat) usb_remove_function(c, f_phonet); usb_put_function(f_ecm); err_get_ecm: usb_put_function(f_acm); err_get_acm: if (!IS_ERR_OR_NULL(f_obex2)) usb_put_function(f_obex2); if (!IS_ERR_OR_NULL(f_obex1)) usb_put_function(f_obex1); if (!IS_ERR_OR_NULL(f_phonet)) usb_put_function(f_phonet); return status; }
static int nokia_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; struct fsg_opts *fsg_opts; struct fsg_config fsg_config; int status; status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto err_usb; device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; status = strings_dev[STRING_DESCRIPTION_IDX].id; nokia_config_500ma_driver.iConfiguration = status; nokia_config_100ma_driver.iConfiguration = status; if (!gadget_is_altset_supported(gadget)) { status = -ENODEV; goto err_usb; } fi_phonet = usb_get_function_instance("phonet"); if (IS_ERR(fi_phonet)) pr_debug("could not find phonet function\n"); fi_obex1 = usb_get_function_instance("obex"); if (IS_ERR(fi_obex1)) pr_debug("could not find obex function 1\n"); fi_obex2 = usb_get_function_instance("obex"); if (IS_ERR(fi_obex2)) pr_debug("could not find obex function 2\n"); fi_acm = usb_get_function_instance("acm"); if (IS_ERR(fi_acm)) { status = PTR_ERR(fi_acm); goto err_obex2_inst; } fi_ecm = usb_get_function_instance("ecm"); if (IS_ERR(fi_ecm)) { status = PTR_ERR(fi_ecm); goto err_acm_inst; } fi_msg = usb_get_function_instance("mass_storage"); if (IS_ERR(fi_msg)) { status = PTR_ERR(fi_msg); goto err_ecm_inst; } /* set up mass storage function */ fsg_config_from_params(&fsg_config, &fsg_mod_data, fsg_num_buffers); fsg_config.vendor_name = "Nokia"; fsg_config.product_name = "N900"; fsg_opts = fsg_opts_from_func_inst(fi_msg); fsg_opts->no_configfs = true; status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers); if (status) goto err_msg_inst; status = fsg_common_set_cdev(fsg_opts->common, cdev, fsg_config.can_stall); if (status) goto err_msg_buf; fsg_common_set_sysfs(fsg_opts->common, true); status = fsg_common_create_luns(fsg_opts->common, &fsg_config); if (status) goto err_msg_buf; fsg_common_set_inquiry_string(fsg_opts->common, fsg_config.vendor_name, fsg_config.product_name); /* finally register the configuration */ status = usb_add_config(cdev, &nokia_config_500ma_driver, nokia_bind_config); if (status < 0) goto err_msg_luns; status = usb_add_config(cdev, &nokia_config_100ma_driver, nokia_bind_config); if (status < 0) goto err_put_cfg1; usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME); return 0; err_put_cfg1: usb_put_function(f_acm_cfg1); if (!IS_ERR_OR_NULL(f_obex1_cfg1)) usb_put_function(f_obex1_cfg1); if (!IS_ERR_OR_NULL(f_obex2_cfg1)) usb_put_function(f_obex2_cfg1); if (!IS_ERR_OR_NULL(f_phonet_cfg1)) usb_put_function(f_phonet_cfg1); usb_put_function(f_ecm_cfg1); err_msg_luns: fsg_common_remove_luns(fsg_opts->common); err_msg_buf: fsg_common_free_buffers(fsg_opts->common); err_msg_inst: usb_put_function_instance(fi_msg); err_ecm_inst: usb_put_function_instance(fi_ecm); err_acm_inst: usb_put_function_instance(fi_acm); err_obex2_inst: if (!IS_ERR(fi_obex2)) usb_put_function_instance(fi_obex2); if (!IS_ERR(fi_obex1)) usb_put_function_instance(fi_obex1); if (!IS_ERR(fi_phonet)) usb_put_function_instance(fi_phonet); err_usb: return status; }
static int midi_unbind(struct usb_composite_dev *dev) { usb_put_function(f_midi); usb_put_function_instance(fi_midi); return 0; }
static int nokia_unbind(struct usb_composite_dev *cdev) { if (!IS_ERR_OR_NULL(f_obex1_cfg2)) usb_put_function(f_obex1_cfg2); if (!IS_ERR_OR_NULL(f_obex2_cfg2)) usb_put_function(f_obex2_cfg2); if (!IS_ERR_OR_NULL(f_obex1_cfg1)) usb_put_function(f_obex1_cfg1); if (!IS_ERR_OR_NULL(f_obex2_cfg1)) usb_put_function(f_obex2_cfg1); if (!IS_ERR_OR_NULL(f_phonet_cfg1)) usb_put_function(f_phonet_cfg1); if (!IS_ERR_OR_NULL(f_phonet_cfg2)) usb_put_function(f_phonet_cfg2); usb_put_function(f_acm_cfg1); usb_put_function(f_acm_cfg2); usb_put_function(f_ecm_cfg1); usb_put_function(f_ecm_cfg2); usb_put_function(f_msg_cfg1); usb_put_function(f_msg_cfg2); usb_put_function_instance(fi_msg); usb_put_function_instance(fi_ecm); if (!IS_ERR(fi_obex2)) usb_put_function_instance(fi_obex2); if (!IS_ERR(fi_obex1)) usb_put_function_instance(fi_obex1); if (!IS_ERR(fi_phonet)) usb_put_function_instance(fi_phonet); usb_put_function_instance(fi_acm); return 0; }
static int zero_bind(struct usb_composite_dev *cdev) { struct f_ss_opts *ss_opts; struct f_lb_opts *lb_opts; int status; /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) return status; device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; device_desc.iSerialNumber = strings_dev[USB_GADGET_SERIAL_IDX].id; setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); func_inst_ss = usb_get_function_instance("SourceSink"); if (IS_ERR(func_inst_ss)) return PTR_ERR(func_inst_ss); ss_opts = container_of(func_inst_ss, struct f_ss_opts, func_inst); ss_opts->pattern = gzero_options.pattern; ss_opts->isoc_interval = gzero_options.isoc_interval; ss_opts->isoc_maxpacket = gzero_options.isoc_maxpacket; ss_opts->isoc_mult = gzero_options.isoc_mult; ss_opts->isoc_maxburst = gzero_options.isoc_maxburst; ss_opts->bulk_buflen = gzero_options.bulk_buflen; func_ss = usb_get_function(func_inst_ss); if (IS_ERR(func_ss)) { status = PTR_ERR(func_ss); goto err_put_func_inst_ss; } func_inst_lb = usb_get_function_instance("Loopback"); if (IS_ERR(func_inst_lb)) { status = PTR_ERR(func_inst_lb); goto err_put_func_ss; } lb_opts = container_of(func_inst_lb, struct f_lb_opts, func_inst); lb_opts->bulk_buflen = gzero_options.bulk_buflen; lb_opts->qlen = gzero_options.qlen; func_lb = usb_get_function(func_inst_lb); if (IS_ERR(func_lb)) { status = PTR_ERR(func_lb); goto err_put_func_inst_lb; } sourcesink_driver.iConfiguration = strings_dev[USB_GZERO_SS_DESC].id; loopback_driver.iConfiguration = strings_dev[USB_GZERO_LB_DESC].id; /* support autoresume for remote wakeup testing */ sourcesink_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP; loopback_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP; sourcesink_driver.descriptors = NULL; loopback_driver.descriptors = NULL; if (autoresume) { sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; autoresume_step_ms = autoresume * 1000; } /* support OTG systems */ if (gadget_is_otg(cdev->gadget)) { if (!otg_desc[0]) { struct usb_descriptor_header *usb_desc; usb_desc = usb_otg_descriptor_alloc(cdev->gadget); if (!usb_desc) { status = -ENOMEM; goto err_conf_flb; } usb_otg_descriptor_init(cdev->gadget, usb_desc); otg_desc[0] = usb_desc; otg_desc[1] = NULL; } sourcesink_driver.descriptors = otg_desc; sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; loopback_driver.descriptors = otg_desc; loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } /* Register primary, then secondary configuration. Note that * SH3 only allows one config... */ if (loopdefault) { usb_add_config_only(cdev, &loopback_driver); usb_add_config_only(cdev, &sourcesink_driver); } else { usb_add_config_only(cdev, &sourcesink_driver); usb_add_config_only(cdev, &loopback_driver); } status = usb_add_function(&sourcesink_driver, func_ss); if (status) goto err_free_otg_desc; usb_ep_autoconfig_reset(cdev->gadget); status = usb_add_function(&loopback_driver, func_lb); if (status) goto err_free_otg_desc; usb_ep_autoconfig_reset(cdev->gadget); usb_composite_overwrite_options(cdev, &coverwrite); INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname); return 0; err_free_otg_desc: kfree(otg_desc[0]); otg_desc[0] = NULL; err_conf_flb: usb_put_function(func_lb); func_lb = NULL; err_put_func_inst_lb: usb_put_function_instance(func_inst_lb); func_inst_lb = NULL; err_put_func_ss: usb_put_function(func_ss); func_ss = NULL; err_put_func_inst_ss: usb_put_function_instance(func_inst_ss); func_inst_ss = NULL; return status; }
static int __init nokia_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; int status; status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto err_usb; device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; status = strings_dev[STRING_DESCRIPTION_IDX].id; nokia_config_500ma_driver.iConfiguration = status; nokia_config_100ma_driver.iConfiguration = status; if (!gadget_supports_altsettings(gadget)) { status = -ENODEV; goto err_usb; } fi_phonet = usb_get_function_instance("phonet"); if (IS_ERR(fi_phonet)) pr_debug("could not find phonet function\n"); fi_obex1 = usb_get_function_instance("obex"); if (IS_ERR(fi_obex1)) pr_debug("could not find obex function 1\n"); fi_obex2 = usb_get_function_instance("obex"); if (IS_ERR(fi_obex2)) pr_debug("could not find obex function 2\n"); fi_acm = usb_get_function_instance("acm"); if (IS_ERR(fi_acm)) { status = PTR_ERR(fi_acm); goto err_obex2_inst; } fi_ecm = usb_get_function_instance("ecm"); if (IS_ERR(fi_ecm)) { status = PTR_ERR(fi_ecm); goto err_acm_inst; } /* finally register the configuration */ status = usb_add_config(cdev, &nokia_config_500ma_driver, nokia_bind_config); if (status < 0) goto err_ecm_inst; status = usb_add_config(cdev, &nokia_config_100ma_driver, nokia_bind_config); if (status < 0) goto err_put_cfg1; usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME); return 0; err_put_cfg1: usb_put_function(f_acm_cfg1); if (!IS_ERR_OR_NULL(f_obex1_cfg1)) usb_put_function(f_obex1_cfg1); if (!IS_ERR_OR_NULL(f_obex2_cfg1)) usb_put_function(f_obex2_cfg1); if (!IS_ERR_OR_NULL(f_phonet_cfg1)) usb_put_function(f_phonet_cfg1); usb_put_function(f_ecm_cfg1); err_ecm_inst: usb_put_function_instance(fi_ecm); err_acm_inst: usb_put_function_instance(fi_acm); err_obex2_inst: if (!IS_ERR(fi_obex2)) usb_put_function_instance(fi_obex2); if (!IS_ERR(fi_obex1)) usb_put_function_instance(fi_obex1); if (!IS_ERR(fi_phonet)) usb_put_function_instance(fi_phonet); err_usb: return status; }