static int __init gs_bind(struct usb_composite_dev *cdev) { int status; struct usb_gadget *gadget = cdev->gadget; /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ if (gadget->vendor_id && gadget->product_id) { device_desc.idVendor = cpu_to_le16(gadget->vendor_id); device_desc.idProduct = cpu_to_le16(gadget->product_id); } else { device_desc.idVendor = cpu_to_le16(GS_VENDOR_ID); if (use_acm) device_desc.idProduct = cpu_to_le16(GS_CDC_PRODUCT_ID); else device_desc.idProduct = cpu_to_le16(GS_PRODUCT_ID); } strings_dev[USB_GADGET_MANUFACTURER_IDX].s = gadget->manufacturer; strings_dev[USB_GADGET_PRODUCT_IDX].s = gadget->productname; status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; 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; serial_config_driver.iConfiguration = status; if (gadget_is_otg(cdev->gadget)) { serial_config_driver.descriptors = otg_desc; serial_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } /* register our configuration */ if (use_acm) { status = serial_register_ports(cdev, &serial_config_driver, "acm"); usb_ep_autoconfig_reset(cdev->gadget); } else if (use_obex) status = serial_register_ports(cdev, &serial_config_driver, "obex"); else { status = serial_register_ports(cdev, &serial_config_driver, "gser"); } if (status < 0) goto fail; usb_composite_overwrite_options(cdev, &coverwrite); INFO(cdev, "%s\n", GS_VERSION_NAME); return 0; fail: return status; }
static int gs_bind(struct usb_composite_dev *cdev) { 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) goto fail; 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; serial_config_driver.iConfiguration = status; 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 fail; } usb_otg_descriptor_init(cdev->gadget, usb_desc); otg_desc[0] = usb_desc; otg_desc[1] = NULL; } serial_config_driver.descriptors = otg_desc; serial_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } /* register our configuration */ if (use_acm) { status = serial_register_ports(cdev, &serial_config_driver, "acm"); usb_ep_autoconfig_reset(cdev->gadget); } else if (use_obex) status = serial_register_ports(cdev, &serial_config_driver, "obex"); else { status = serial_register_ports(cdev, &serial_config_driver, "gser"); } if (status < 0) goto fail1; usb_composite_overwrite_options(cdev, &coverwrite); INFO(cdev, "%s\n", GS_VERSION_NAME); return 0; fail1: kfree(otg_desc[0]); otg_desc[0] = NULL; fail: return status; }
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 zero_bind(struct usb_gadget *gadget) { struct zero_dev *dev; struct usb_ep *ep; int gcnum; /* FIXME this can't yet work right with SH ... it has only * one configuration, numbered one. */ if (gadget_is_sh(gadget)) return -ENODEV; /* Bulk-only drivers like this one SHOULD be able to * autoconfigure on any sane usb controller driver, * but there may also be important quirks to address. */ usb_ep_autoconfig_reset(gadget); ep = usb_ep_autoconfig(gadget, &fs_source_desc); if (!ep) { autoconf_fail: pr_err("%s: can't autoconfigure on %s\n", shortname, gadget->name); return -ENODEV; } EP_IN_NAME = ep->name; ep->driver_data = ep; /* claim */ ep = usb_ep_autoconfig(gadget, &fs_sink_desc); if (!ep) goto autoconf_fail; EP_OUT_NAME = ep->name; ep->driver_data = ep; /* claim */ 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 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", shortname, gadget->name); device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); } /* ok, we made sense of the hardware ... */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; spin_lock_init(&dev->lock); dev->gadget = gadget; set_gadget_data(gadget, dev); init_timer(&dev->resume); dev->resume.function = zero_autoresume; dev->resume.data = (unsigned long) dev; /* preallocate control response and buffer */ dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); if (!dev->req) goto enomem; dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL); if (!dev->req->buf) goto enomem; dev->req->complete = zero_setup_complete; device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; if (gadget_is_dualspeed(gadget)) { /* assume ep0 uses the same value for both speeds ... */ dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; /* and that all endpoints are dual-speed */ hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; } if (gadget_is_otg(gadget)) { otg_descriptor.bmAttributes |= USB_OTG_HNP, source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } usb_gadget_set_selfpowered(gadget); if (autoresume) { source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } gadget->ep0->driver_data = dev; INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname); INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, EP_OUT_NAME, EP_IN_NAME); snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); return 0; enomem: zero_unbind(gadget); return -ENOMEM; }
static int fastboot_bind(struct usb_gadget *gadget) { struct fastboot_dev *dev = &l_fbdev; u8 cdc = 1, zlp = 1; struct usb_ep *in_ep, *out_ep; int gcnum; u8 tmp[7]; debug("%s controller :%s recognized\n", __func__, gadget->name); gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(0x0300 + gcnum); else { /* * can't assume CDC works. don't want to default to * anything less functional on CDC-capable hardware, * so we fail in this case. */ error("controller '%s' not recognized", gadget->name); return -ENODEV; } if (bcdDevice) device_desc.bcdDevice = cpu_to_le16(bcdDevice); if (iManufacturer) strlcpy(manufacturer, iManufacturer, sizeof manufacturer); if (iProduct) strlcpy(product_desc, iProduct, sizeof product_desc); iSerialNumber = get_product_sn(); device_desc.iSerialNumber = STRING_SERIALNUMBER, strlcpy(serial_number, iSerialNumber, sizeof serial_number); /* all we really need is bulk IN/OUT */ usb_ep_autoconfig_reset(gadget); in_ep = usb_ep_autoconfig(gadget, &fs_source_desc); if (!in_ep) { autoconf_fail: error("can't autoconfigure on %s\n", gadget->name); return -ENODEV; } in_ep->driver_data = in_ep; /* claim */ out_ep = usb_ep_autoconfig(gadget, &fs_sink_desc); if (!out_ep) goto autoconf_fail; out_ep->driver_data = out_ep; /* claim */ device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; usb_gadget_set_selfpowered(gadget); if (gadget_is_dualspeed(gadget)) { /* assumes ep0 uses the same value for both speeds ... */ dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; /* and that all endpoints are dual-speed */ hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; } dev->network_started = 0; dev->in_ep = in_ep; dev->out_ep = out_ep; /* preallocate control message data and buffer */ dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); if (!dev->req) goto fail; dev->req->buf = control_req; dev->req->complete = fastboot_setup_complete; /* ... and maybe likewise for status transfer */ /* finish hookup to lower layer ... */ dev->gadget = gadget; set_gadget_data(gadget, dev); gadget->ep0->driver_data = dev; debug("bind controller with the driver\n"); /* * two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ return 0; fail: error("%s failed", __func__); fastboot_unbind(gadget); return -ENOMEM; }