int usb_assign_descriptors(struct usb_function *f, struct usb_descriptor_header **fs, struct usb_descriptor_header **hs, struct usb_descriptor_header **ss) { struct usb_gadget *g = f->config->cdev->gadget; if (fs) { f->fs_descriptors = usb_copy_descriptors(fs); if (!f->fs_descriptors) goto err; } if (hs && gadget_is_dualspeed(g)) { f->hs_descriptors = usb_copy_descriptors(hs); if (!f->hs_descriptors) goto err; } if (ss && gadget_is_superspeed(g)) { f->ss_descriptors = usb_copy_descriptors(ss); if (!f->ss_descriptors) goto err; } return 0; err: usb_free_all_descriptors(f); return -ENOMEM; }
int rawbulk_function_bind(struct usb_configuration *c, struct usb_function *f) { int rc, ifnum; struct rawbulk_function *fn = function_to_rbf(f); struct usb_gadget *gadget = c->cdev->gadget; struct usb_ep *ep_out, *ep_in; printk("%s\n", __func__); rc = usb_interface_id(c, f); if (rc < 0) return rc; ifnum = rc; fn->interface.bInterfaceNumber = cpu_to_le16(ifnum); ep_out = usb_ep_autoconfig(gadget, (struct usb_endpoint_descriptor *) fn->fs_descs[BULKOUT_DESC]); if (!ep_out) { printk(KERN_ERR "%s %d config ep_out error \n", __FUNCTION__,__LINE__); return -ENOMEM; } ep_in = usb_ep_autoconfig(gadget, (struct usb_endpoint_descriptor *) fn->fs_descs[BULKIN_DESC]); if (!ep_in) { usb_ep_disable(ep_out); printk(KERN_ERR "%s %d config ep_in error \n", __FUNCTION__,__LINE__); return -ENOMEM; } ep_out->driver_data = fn; ep_in->driver_data = fn; fn->bulk_out = ep_out; fn->bulk_in = ep_in; #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 100)) f->fs_descriptors = usb_copy_descriptors(fn->fs_descs); if (unlikely(!f->fs_descriptors)) return -ENOMEM; #else f->descriptors = usb_copy_descriptors(fn->fs_descs); if (unlikely(!f->descriptors)) return -ENOMEM; #endif if (gadget_is_dualspeed(gadget)) { fn->hs_bulkin_endpoint.bEndpointAddress = fn->fs_bulkin_endpoint.bEndpointAddress; fn->hs_bulkout_endpoint.bEndpointAddress = fn->fs_bulkout_endpoint.bEndpointAddress; } fn->cdev = c->cdev; fn->activated = 0; return rawbulk_bind_function(fn->transfer_id, f, ep_out, ep_in, rawbulk_auto_reconnect); }
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; /* 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 /* copy descriptors, and track endpoint copies */ f->descriptors = usb_copy_descriptors(gser_fs_function); if (!f->descriptors) goto fail; /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ if (gadget_is_dualspeed(c->cdev->gadget)) { gser_hs_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress; gser_hs_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress; #ifdef CONFIG_MODEM_SUPPORT gser_hs_notify_desc.bEndpointAddress = gser_fs_notify_desc.bEndpointAddress; #endif /* copy descriptors, and track endpoint copies */ f->hs_descriptors = usb_copy_descriptors(gser_hs_function); if (!f->hs_descriptors) goto fail; } if (gadget_is_superspeed(c->cdev->gadget)) { gser_ss_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress; gser_ss_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress; /* copy descriptors, and track endpoint copies */ f->ss_descriptors = usb_copy_descriptors(gser_ss_function); if (!f->ss_descriptors) 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: if (f->descriptors) usb_free_descriptors(f->descriptors); #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; }
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; /* allocate instance-specific interface IDs */ #if defined(CONFIG_ANDROID_PANTECH_USB) // if((pantech_usb_carrier != CARRIER_QUALCOMM) && b_pantech_usb_module){ if(pantech_usb_carrier != CARRIER_QUALCOMM){ gser_fs_function = pantech_gser_fs_function; gser_hs_function = pantech_gser_hs_function; status = usb_interface_id(c, f); if (status < 0) goto fail; gser->data_id = status; //data_id : cdc interface number gser_acm_cdc_interface_desc.bInterfaceNumber = status; #if defined(FEATURE_ANDROID_PANTECH_USB_IAD) gser_interface_assoc_desc.bFirstInterface = status; #endif //acm interface status = usb_interface_id(c, f); if (status < 0) goto fail; gser_acm_data_interface_desc.bInterfaceNumber = status; }else{ gser_fs_function = qualcomm_gser_fs_function; gser_hs_function = qualcomm_gser_hs_function; status = usb_interface_id(c, f); if (status < 0) goto fail; gser->data_id = status; gser_interface_desc.bInterfaceNumber = status; } #else status = usb_interface_id(c, f); if (status < 0) goto fail; gser->data_id = status; gser_interface_desc.bInterfaceNumber = status; #endif 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 /* copy descriptors, and track endpoint copies */ f->descriptors = usb_copy_descriptors(gser_fs_function); if (!f->descriptors) goto fail; gser->fs.in = usb_find_endpoint(gser_fs_function, f->descriptors, &gser_fs_in_desc); gser->fs.out = usb_find_endpoint(gser_fs_function, f->descriptors, &gser_fs_out_desc); #ifdef CONFIG_MODEM_SUPPORT gser->fs.notify = usb_find_endpoint(gser_fs_function, f->descriptors, &gser_fs_notify_desc); #endif /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ if (gadget_is_dualspeed(c->cdev->gadget)) { gser_hs_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress; gser_hs_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress; #ifdef CONFIG_MODEM_SUPPORT gser_hs_notify_desc.bEndpointAddress = gser_fs_notify_desc.bEndpointAddress; #endif /* copy descriptors, and track endpoint copies */ f->hs_descriptors = usb_copy_descriptors(gser_hs_function); if (!f->hs_descriptors) goto fail; gser->hs.in = usb_find_endpoint(gser_hs_function, f->hs_descriptors, &gser_hs_in_desc); gser->hs.out = usb_find_endpoint(gser_hs_function, f->hs_descriptors, &gser_hs_out_desc); #ifdef CONFIG_MODEM_SUPPORT gser->hs.notify = usb_find_endpoint(gser_hs_function, f->hs_descriptors, &gser_hs_notify_desc); #endif } DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", gser->port_num, gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", gser->port.in->name, gser->port.out->name); return 0; fail: if (f->descriptors) usb_free_descriptors(f->descriptors); #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; }
static int hidg_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_ep *ep; struct f_hidg *hidg = func_to_hidg(f); int status; dev_t dev; pr_info("%s: creating device %p\n", __func__, hidg); /* allocate instance-specific interface IDs, and patch descriptors */ status = usb_interface_id(c, f); if (status < 0) goto fail; hidg_interface_desc.bInterfaceNumber = status; /* allocate instance-specific endpoints */ status = -ENODEV; ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc); if (!ep) goto fail; ep->driver_data = c->cdev; /* claim */ hidg->in_ep = ep; /* preallocate request and buffer */ status = -ENOMEM; hidg->req = usb_ep_alloc_request(hidg->in_ep, GFP_KERNEL); if (!hidg->req) goto fail; hidg->req->buf = kmalloc(hidg->report_length, GFP_KERNEL); if (!hidg->req->buf) goto fail; /* set descriptor dynamic values */ hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; hidg_hs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT; hidg_desc.desc[0].wDescriptorLength = cpu_to_le16(hidg->report_desc_length); hidg->set_report_buff = NULL; /* copy descriptors */ f->descriptors = usb_copy_descriptors(hidg_fs_descriptors); if (!f->descriptors) goto fail; if (gadget_is_dualspeed(c->cdev->gadget)) { hidg_hs_in_ep_desc.bEndpointAddress = hidg_fs_in_ep_desc.bEndpointAddress; f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors); if (!f->hs_descriptors) goto fail; } mutex_init(&hidg->lock); spin_lock_init(&hidg->spinlock); init_waitqueue_head(&hidg->write_queue); init_waitqueue_head(&hidg->read_queue); /* create char device */ cdev_init(&hidg->cdev, &f_hidg_fops); dev = MKDEV(major, hidg->minor); status = cdev_add(&hidg->cdev, dev, 1); if (status) goto fail; device_create(hidg_class, NULL, dev, NULL, "%s%d", "hidg", hidg->minor); hacky_device_list_add(hidg); return 0; fail: ERROR(f->config->cdev, "hidg_bind FAILED\n"); if (hidg->req != NULL) { kfree(hidg->req->buf); if (hidg->in_ep != NULL) usb_ep_free_request(hidg->in_ep, hidg->req); } usb_free_descriptors(f->hs_descriptors); usb_free_descriptors(f->descriptors); 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; status = usb_interface_id(c, f); if (status < 0) goto fail; gser->data_id = status; gser_interface_desc.bInterfaceNumber = status; status = -ENODEV; ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_in_desc); if (!ep) goto fail; gser->port.in = ep; ep->driver_data = cdev; ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_out_desc); if (!ep) goto fail; gser->port.out = ep; ep->driver_data = cdev; #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; 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 f->descriptors = usb_copy_descriptors(gser_fs_function); if (!f->descriptors) goto fail; if (gadget_is_dualspeed(c->cdev->gadget)) { gser_hs_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress; gser_hs_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress; #ifdef CONFIG_MODEM_SUPPORT gser_hs_notify_desc.bEndpointAddress = gser_fs_notify_desc.bEndpointAddress; #endif f->hs_descriptors = usb_copy_descriptors(gser_hs_function); if (!f->hs_descriptors) goto fail; } DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", gser->port_num, gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", gser->port.in->name, gser->port.out->name); return 0; fail: if (f->descriptors) usb_free_descriptors(f->descriptors); #ifdef CONFIG_MODEM_SUPPORT if (gser->notify_req) gs_free_req(gser->notify, gser->notify_req); if (gser->notify) gser->notify->driver_data = NULL; #endif 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; }
static int ecm_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct f_ecm *ecm = func_to_ecm(f); int status; struct usb_ep *ep; /* allocate instance-specific interface IDs */ status = usb_interface_id(c, f); if (status < 0) goto fail; ecm->ctrl_id = status; ecm_control_intf.bInterfaceNumber = status; #ifdef CONFIG_LGE_USB_GADGET_DRIVER ecm_iad.bFirstInterface = status; #endif ecm_union_desc.bMasterInterface0 = status; status = usb_interface_id(c, f); printk(KERN_DEBUG "[MSG]>>f_ecm > ecm_bind : interface = %d !! \n", status ); if (status < 0) goto fail; ecm->data_id = status; ecm_data_nop_intf.bInterfaceNumber = status; ecm_data_intf.bInterfaceNumber = status; ecm_union_desc.bSlaveInterface0 = status; status = -ENODEV; /* allocate instance-specific endpoints */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_in_desc); if (!ep) goto fail; ecm->port.in_ep = ep; ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc); if (!ep) goto fail; ecm->port.out_ep = ep; ep->driver_data = cdev; /* claim */ /* NOTE: a status/notification endpoint is *OPTIONAL* but we * don't treat it that way. It's simpler, and some newer CDC * profiles (wireless handsets) no longer treat it as optional. */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_notify_desc); if (!ep) goto fail; ecm->notify = ep; ep->driver_data = cdev; /* claim */ status = -ENOMEM; /* allocate notification request and buffer */ ecm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL); if (!ecm->notify_req) goto fail; ecm->notify_req->buf = kmalloc(ECM_STATUS_BYTECOUNT, GFP_KERNEL); if (!ecm->notify_req->buf) goto fail; ecm->notify_req->context = ecm; ecm->notify_req->complete = ecm_notify_complete; /* copy descriptors, and track endpoint copies */ f->descriptors = usb_copy_descriptors(ecm_fs_function); if (!f->descriptors) goto fail; ecm->fs.in = usb_find_endpoint(ecm_fs_function, f->descriptors, &fs_ecm_in_desc); ecm->fs.out = usb_find_endpoint(ecm_fs_function, f->descriptors, &fs_ecm_out_desc); ecm->fs.notify = usb_find_endpoint(ecm_fs_function, f->descriptors, &fs_ecm_notify_desc); /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ if (gadget_is_dualspeed(c->cdev->gadget)) { hs_ecm_in_desc.bEndpointAddress = fs_ecm_in_desc.bEndpointAddress; hs_ecm_out_desc.bEndpointAddress = fs_ecm_out_desc.bEndpointAddress; hs_ecm_notify_desc.bEndpointAddress = fs_ecm_notify_desc.bEndpointAddress; printk(KERN_ERR "[MSG]>> f_ecm > ecm_bind : IN EP = %d !! \n", hs_ecm_in_desc.bEndpointAddress ); printk(KERN_ERR "[MSG]>> f_ecm > ecm_bind : OUT EP= %d !! \n", hs_ecm_out_desc.bEndpointAddress); printk(KERN_ERR "[MSG]>> f_ecm > ecm_bind : NOT EP= %d !! \n", hs_ecm_notify_desc.bEndpointAddress); /* copy descriptors, and track endpoint copies */ f->hs_descriptors = usb_copy_descriptors(ecm_hs_function); if (!f->hs_descriptors) goto fail; ecm->hs.in = usb_find_endpoint(ecm_hs_function, f->hs_descriptors, &hs_ecm_in_desc); ecm->hs.out = usb_find_endpoint(ecm_hs_function, f->hs_descriptors, &hs_ecm_out_desc); ecm->hs.notify = usb_find_endpoint(ecm_hs_function, f->hs_descriptors, &hs_ecm_notify_desc); } /* NOTE: all that is done without knowing or caring about * the network link ... which is unavailable to this code * until we're activated via set_alt(). */ ecm->port.open = ecm_open; ecm->port.close = ecm_close; DBG(cdev, "CDC Ethernet: %s speed IN/%s OUT/%s NOTIFY/%s\n", gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", ecm->port.in_ep->name, ecm->port.out_ep->name, ecm->notify->name); return 0; fail: if (f->descriptors) usb_free_descriptors(f->descriptors); if (ecm->notify_req) { kfree(ecm->notify_req->buf); usb_ep_free_request(ecm->notify, ecm->notify_req); } /* we might as well release our claims on endpoints */ if (ecm->notify) ecm->notify->driver_data = NULL; if (ecm->port.out) ecm->port.out_ep->driver_data = NULL; if (ecm->port.in) ecm->port.in_ep->driver_data = NULL; ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); 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; /* allocate instance-specific interface IDs */ status = usb_interface_id(c, f); if (status < 0) goto fail; #ifdef CONFIG_LGE_USB_GADGET_DRIVER gser_iad_descriptor.bFirstInterface = status; gser_control_interface_desc.bInterfaceNumber = status; gser_union_desc .bMasterInterface0 = status; status = usb_interface_id(c, f); if (status < 0) goto fail; gser->data_id = status; // [START] seunghun.kim : temp_modify for using LG_USB_MODEM on ES3 by f_serial gser_data_interface_desc.bInterfaceNumber = status; gser_union_desc.bSlaveInterface0 = status; gser_call_mgmt_descriptor.bDataInterface = status; #else gser->data_id = status; gser_interface_desc.bInterfaceNumber = status; // [START] seunghun.kim : temp_modify for using LG_USB_MODEM on ES3 by f_serial #endif // [END] seunghun.kim : temp_modify for using LG_USB_MODEM on ES3 by f_serial 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 */ #ifdef CONFIG_LGE_USB_GADGET_DRIVER gser->notify_req = gs_alloc_req(ep, sizeof(struct usb_cdc_notification) + 8, GFP_KERNEL); #else gser->notify_req = gs_alloc_req(ep, sizeof(struct usb_cdc_notification) + 2, GFP_KERNEL); #endif if (!gser->notify_req) goto fail; gser->notify_req->complete = gser_notify_complete; gser->notify_req->context = gser; #endif /* copy descriptors, and track endpoint copies */ f->descriptors = usb_copy_descriptors(gser_fs_function); if (!f->descriptors) goto fail; gser->fs.in = usb_find_endpoint(gser_fs_function, f->descriptors, &gser_fs_in_desc); gser->fs.out = usb_find_endpoint(gser_fs_function, f->descriptors, &gser_fs_out_desc); #ifdef CONFIG_MODEM_SUPPORT gser->fs.notify = usb_find_endpoint(gser_fs_function, f->descriptors, &gser_fs_notify_desc); #endif /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ if (gadget_is_dualspeed(c->cdev->gadget)) { gser_hs_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress; gser_hs_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress; #ifdef CONFIG_MODEM_SUPPORT gser_hs_notify_desc.bEndpointAddress = gser_fs_notify_desc.bEndpointAddress; #endif /* copy descriptors, and track endpoint copies */ f->hs_descriptors = usb_copy_descriptors(gser_hs_function); gser->hs.in = usb_find_endpoint(gser_hs_function, f->hs_descriptors, &gser_hs_in_desc); gser->hs.out = usb_find_endpoint(gser_hs_function, f->hs_descriptors, &gser_hs_out_desc); #ifdef CONFIG_MODEM_SUPPORT gser->hs.notify = usb_find_endpoint(gser_hs_function, f->hs_descriptors, &gser_hs_notify_desc); #endif } DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", gser->port_num, 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; }