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; }
void gport_cleanup(void) { int i; for (i = 0; i < no_tty_ports; i++) gserial_free_line(gserial_ports[i].client_port_num); }
static void acm_free_instance(struct usb_function_instance *fi) { struct f_serial_opts *opts; opts = container_of(fi, struct f_serial_opts, func_inst); gserial_free_line(opts->port_num); kfree(opts); }
static void gser_free_inst(struct usb_function_instance *f) { struct f_serial_opts *opts; opts = container_of(f, struct f_serial_opts, func_inst); if (!nr_ports) gserial_free_line(opts->port_num); kfree(opts); }
static int __init acm_ms_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; int status; void *retp; /* set up serial link layer */ status = gserial_alloc_line(&tty_line); if (status < 0) return status; /* set up mass storage function */ retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data); if (IS_ERR(retp)) { status = PTR_ERR(retp); goto fail0; } /* * 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) goto fail1; device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; /* register our configuration */ status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config); if (status < 0) goto fail1; usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC); fsg_common_put(&fsg_common); return 0; /* error recovery */ fail1: fsg_common_put(&fsg_common); fail0: gserial_free_line(tty_line); return status; }