From ebd3f395ba89ec38a9c04f2a4e2d284bf2409bb4 Mon Sep 17 00:00:00 2001 From: Tatyana Brokhman Date: Tue, 28 Jun 2011 16:33:50 +0300 Subject: [PATCH] usb: gadget: use config_ep_by_speed() instead of ep_choose() Remove obsolete functions: 1. ep_choose() 2. usb_find_endpoint() Signed-off-by: Tatyana Brokhman Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman [idos@codeaurora.org: Changed also the following files to comply with this commit: f_accessory.c,f_adb.c,f_diag.c,f_mtp.c, f_rmnet.c,f_rmnet_sdio,f_rmnet_smd,f_rmnet_smd_sdio,f_serial.f_ccid.c. Also merged a patch in f_serial.c for correct checking of the return value of config_ep_by_speed. See "usb: gadget: fix g_serial regression". Also fix a bug in ci13xxx_udc. Since f_serial is now checking if the endpoint descriptors are null in the set_alt function, need to set them to null on ep_disable in case of cable disconnect. Since the ep descriptor was inserted to struct usb_ep in "usb: gadget: add usb_endpoint_descriptor to struct usb_ep" then simply convert the ci13xxx_udc to work with mEp->ep.desc instead of mEp->desc, this will ensure that the correct descriptor will be cleared on endpoint disable. I will upstream it to Linux community soon, I will name it: "usb: gadget: use usb ep descriptor of struct usb_ep instead of wrapper desc"] Signed-off-by: Ido Shayevitz --- drivers/usb/gadget/ci13xxx_udc.c | 16 +++---- drivers/usb/gadget/ci13xxx_udc.h | 1 - drivers/usb/gadget/config.c | 26 ----------- drivers/usb/gadget/f_accessory.c | 38 ++++++++++------ drivers/usb/gadget/f_acm.c | 46 ++++++------------- drivers/usb/gadget/f_adb.c | 36 ++++++++++----- drivers/usb/gadget/f_ccid.c | 54 +++++++++-------------- drivers/usb/gadget/f_diag.c | 13 +++--- drivers/usb/gadget/f_ecm.c | 45 ++++++------------- drivers/usb/gadget/f_eem.c | 32 ++++---------- drivers/usb/gadget/f_hid.c | 19 +++----- drivers/usb/gadget/f_loopback.c | 11 +++-- drivers/usb/gadget/f_mass_storage.c | 46 ++++++++----------- drivers/usb/gadget/f_mtp.c | 36 ++++++++++----- drivers/usb/gadget/f_ncm.c | 49 +++++++-------------- drivers/usb/gadget/f_obex.c | 32 ++++---------- drivers/usb/gadget/f_phonet.c | 12 ++--- drivers/usb/gadget/f_rmnet.c | 48 +++++++------------- drivers/usb/gadget/f_rmnet_sdio.c | 62 +++++++++++++++++++++----- drivers/usb/gadget/f_rmnet_smd.c | 38 ++++++++++++---- drivers/usb/gadget/f_rmnet_smd_sdio.c | 63 ++++++++++++++++++++++----- drivers/usb/gadget/f_rndis.c | 48 ++++++-------------- drivers/usb/gadget/f_serial.c | 55 ++++++++--------------- drivers/usb/gadget/f_sourcesink.c | 8 +++- drivers/usb/gadget/f_subset.c | 29 +++--------- drivers/usb/gadget/file_storage.c | 12 +++++ drivers/usb/gadget/storage_common.c | 11 ----- include/linux/usb/composite.h | 15 ------- include/linux/usb/gadget.h | 6 --- 29 files changed, 411 insertions(+), 496 deletions(-) diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index f5444cbd446..406b2386096 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -2182,7 +2182,7 @@ __acquires(udc->lock) int type, num, dir, err = -EINVAL; struct usb_ctrlrequest req; - if (mEp->desc == NULL) + if (mEp->ep.desc == NULL) continue; /* not configured */ if (hw_test_and_clear_complete(i)) { @@ -2381,7 +2381,7 @@ static int ep_enable(struct usb_ep *ep, /* only internal SW should enable ctrl endpts */ - mEp->desc = desc; + mEp->ep.desc = desc; if (!list_empty(&mEp->qh.queue)) warn("enabling a non-empty endpoint!"); @@ -2436,7 +2436,7 @@ static int ep_disable(struct usb_ep *ep) if (ep == NULL) return -EINVAL; - else if (mEp->desc == NULL) + else if (mEp->ep.desc == NULL) return -EBUSY; spin_lock_irqsave(mEp->lock, flags); @@ -2455,7 +2455,7 @@ static int ep_disable(struct usb_ep *ep) } while (mEp->dir != direction); - mEp->desc = NULL; + mEp->ep.desc = NULL; spin_unlock_irqrestore(mEp->lock, flags); return retval; @@ -2543,7 +2543,7 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, trace("%p, %p, %X", ep, req, gfp_flags); - if (ep == NULL || req == NULL || mEp->desc == NULL) + if (ep == NULL || req == NULL || mEp->ep.desc == NULL) return -EINVAL; spin_lock_irqsave(mEp->lock, flags); @@ -2616,7 +2616,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) trace("%p, %p", ep, req); if (ep == NULL || req == NULL || mReq->req.status != -EALREADY || - mEp->desc == NULL || list_empty(&mReq->queue) || + mEp->ep.desc == NULL || list_empty(&mReq->queue) || list_empty(&mEp->qh.queue)) return -EINVAL; @@ -2662,7 +2662,7 @@ static int ep_set_halt(struct usb_ep *ep, int value) trace("%p, %i", ep, value); - if (ep == NULL || mEp->desc == NULL) + if (ep == NULL || mEp->ep.desc == NULL) return -EINVAL; spin_lock_irqsave(mEp->lock, flags); @@ -2705,7 +2705,7 @@ static int ep_set_wedge(struct usb_ep *ep) trace("%p", ep); - if (ep == NULL || mEp->desc == NULL) + if (ep == NULL || mEp->ep.desc == NULL) return -EINVAL; spin_lock_irqsave(mEp->lock, flags); diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h index fce611ab9ac..54b8790d52e 100644 --- a/drivers/usb/gadget/ci13xxx_udc.h +++ b/drivers/usb/gadget/ci13xxx_udc.h @@ -97,7 +97,6 @@ struct ci13xxx_req { /* Extension of usb_ep */ struct ci13xxx_ep { struct usb_ep ep; - const struct usb_endpoint_descriptor *desc; u8 dir; u8 num; u8 type; diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index 09084fd646a..7b3ae7651ee 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -164,29 +164,3 @@ usb_copy_descriptors(struct usb_descriptor_header **src) return ret; } - -/** - * usb_find_endpoint - find a copy of an endpoint descriptor - * @src: original vector of descriptors - * @copy: copy of @src - * @match: endpoint descriptor found in @src - * - * This returns the copy of the @match descriptor made for @copy. Its - * intended use is to help remembering the endpoint descriptor to use - * when enabling a given endpoint. - */ -struct usb_endpoint_descriptor * -usb_find_endpoint( - struct usb_descriptor_header **src, - struct usb_descriptor_header **copy, - struct usb_endpoint_descriptor *match -) -{ - while (*src) { - if (*src == (void *) match) - return (void *)*copy; - src++; - copy++; - } - return NULL; -} diff --git a/drivers/usb/gadget/f_accessory.c b/drivers/usb/gadget/f_accessory.c index 999291f74b6..0187b691709 100644 --- a/drivers/usb/gadget/f_accessory.c +++ b/drivers/usb/gadget/f_accessory.c @@ -687,20 +687,32 @@ static int acc_function_set_alt(struct usb_function *f, DBG(cdev, "acc_function_set_alt intf: %d alt: %d\n", intf, alt); - dev->ep_in->desc = ep_choose(cdev->gadget, - &acc_highspeed_in_desc, - &acc_fullspeed_in_desc); - ret = usb_ep_enable(dev->ep_in); - ; - if (ret) - return ret; - - dev->ep_out->desc = ep_choose(cdev->gadget, - &acc_highspeed_out_desc, - &acc_fullspeed_out_desc); - ret = usb_ep_enable(dev->ep_out); - + ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in); if (ret) { + dev->ep_in->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->ep_in->name, ret); + return ret; + } + ret = usb_ep_enable(dev->ep_in); + if (ret) { + ERROR(cdev, "failed to enable ep %s, result %d\n", + dev->ep_in->name, ret); + return ret; + } + + ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out); + if (ret) { + dev->ep_out->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->ep_out->name, ret); + usb_ep_disable(dev->ep_in); + return ret; + } + ret = usb_ep_enable(dev->ep_out); + if (ret) { + ERROR(cdev, "failed to enable ep %s, result %d\n", + dev->ep_out->name, ret); usb_ep_disable(dev->ep_in); return ret; } diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index d207a7f4aed..a30126f5ec8 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -42,12 +42,6 @@ * descriptors (roughly equivalent to CDC Unions) may sometimes help. */ -struct acm_ep_descs { - struct usb_endpoint_descriptor *in; - struct usb_endpoint_descriptor *out; - struct usb_endpoint_descriptor *notify; -}; - struct f_acm { struct gserial port; u8 ctrl_id, data_id; @@ -62,9 +56,6 @@ struct f_acm { */ spinlock_t lock; - struct acm_ep_descs fs; - struct acm_ep_descs hs; - struct usb_ep *notify; struct usb_request *notify_req; @@ -496,9 +487,9 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } else { VDBG(cdev, "init acm ctrl interface %d\n", intf); } - acm->notify->desc = ep_choose(cdev->gadget, - acm->hs.notify, - acm->fs.notify); + if (config_ep_by_speed(cdev->gadget, f, acm->notify)) + return -EINVAL; + usb_ep_enable(acm->notify); acm->notify->driver_data = acm; @@ -509,10 +500,15 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } else { DBG(cdev, "activate acm ttyGS%d\n", acm->port_num); } - acm->port.in->desc = ep_choose(cdev->gadget, - acm->hs.in, acm->fs.in); - acm->port.out->desc = ep_choose(cdev->gadget, - acm->hs.out, acm->fs.out); + if (config_ep_by_speed(cdev->gadget, f, + acm->port.in) || + config_ep_by_speed(cdev->gadget, f, + acm->port.out)) { + acm->port.in->desc = NULL; + acm->port.out->desc = NULL; + return -EINVAL; + } + acm_port_connect(acm); } else @@ -728,18 +724,11 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) acm->notify_req->complete = acm_cdc_notify_complete; acm->notify_req->context = acm; - /* copy descriptors, and track endpoint copies */ + /* copy descriptors */ f->descriptors = usb_copy_descriptors(acm_fs_function); if (!f->descriptors) goto fail; - acm->fs.in = usb_find_endpoint(acm_fs_function, - f->descriptors, &acm_fs_in_desc); - acm->fs.out = usb_find_endpoint(acm_fs_function, - f->descriptors, &acm_fs_out_desc); - acm->fs.notify = usb_find_endpoint(acm_fs_function, - f->descriptors, &acm_fs_notify_desc); - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds @@ -752,15 +741,8 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) acm_hs_notify_desc.bEndpointAddress = acm_fs_notify_desc.bEndpointAddress; - /* copy descriptors, and track endpoint copies */ + /* copy descriptors */ f->hs_descriptors = usb_copy_descriptors(acm_hs_function); - - acm->hs.in = usb_find_endpoint(acm_hs_function, - f->hs_descriptors, &acm_hs_in_desc); - acm->hs.out = usb_find_endpoint(acm_hs_function, - f->hs_descriptors, &acm_hs_out_desc); - acm->hs.notify = usb_find_endpoint(acm_hs_function, - f->hs_descriptors, &acm_hs_notify_desc); } DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c index b248573ab5f..0cf6d488240 100644 --- a/drivers/usb/gadget/f_adb.c +++ b/drivers/usb/gadget/f_adb.c @@ -510,19 +510,33 @@ static int adb_function_set_alt(struct usb_function *f, int ret; DBG(cdev, "adb_function_set_alt intf: %d alt: %d\n", intf, alt); - dev->ep_in->desc = ep_choose(cdev->gadget, - &adb_highspeed_in_desc, - &adb_fullspeed_in_desc); - ret = usb_ep_enable(dev->ep_in); - - if (ret) - return ret; - dev->ep_out->desc = ep_choose(cdev->gadget, - &adb_highspeed_out_desc, - &adb_fullspeed_out_desc); - ret = usb_ep_enable(dev->ep_out); + ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in); if (ret) { + dev->ep_in->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->ep_in->name, ret); + return ret; + } + ret = usb_ep_enable(dev->ep_in); + if (ret) { + ERROR(cdev, "failed to enable ep %s, result %d\n", + dev->ep_in->name, ret); + return ret; + } + + ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out); + if (ret) { + dev->ep_out->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->ep_out->name, ret); + usb_ep_disable(dev->ep_in); + return ret; + } + ret = usb_ep_enable(dev->ep_out); + if (ret) { + ERROR(cdev, "failed to enable ep %s, result %d\n", + dev->ep_out->name, ret); usb_ep_disable(dev->ep_in); return ret; } diff --git a/drivers/usb/gadget/f_ccid.c b/drivers/usb/gadget/f_ccid.c index b72e85443b6..c8f144abaf9 100644 --- a/drivers/usb/gadget/f_ccid.c +++ b/drivers/usb/gadget/f_ccid.c @@ -33,12 +33,6 @@ /* number of tx requests to allocate */ #define TX_REQ_MAX 4 -struct ccid_descs { - struct usb_endpoint_descriptor *in; - struct usb_endpoint_descriptor *out; - struct usb_endpoint_descriptor *notify; -}; - struct ccid_ctrl_dev { atomic_t opened; struct list_head tx_q; @@ -64,9 +58,6 @@ struct f_ccid { int ifc_id; spinlock_t lock; atomic_t online; - /* usb descriptors */ - struct ccid_descs fs; - struct ccid_descs hs; /* usb eps*/ struct usb_ep *notify; struct usb_ep *in; @@ -433,9 +424,13 @@ ccid_function_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } /* choose the descriptors and enable endpoints */ - ccid_dev->notify->desc = ep_choose(cdev->gadget, - ccid_dev->hs.notify, - ccid_dev->fs.notify); + ret = config_ep_by_speed(cdev->gadget, f, ccid_dev->notify); + if (ret) { + ccid_dev->notify->desc = NULL; + pr_err("%s: config_ep_by_speed failed for ep#%s, err#%d\n", + __func__, ccid_dev->notify->name, ret); + goto free_bulk_in; + } ret = usb_ep_enable(ccid_dev->notify); if (ret) { pr_err("%s: usb ep#%s enable failed, err#%d\n", @@ -444,8 +439,13 @@ ccid_function_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } ccid_dev->notify->driver_data = ccid_dev; - ccid_dev->in->desc = ep_choose(cdev->gadget, - ccid_dev->hs.in, ccid_dev->fs.in); + ret = config_ep_by_speed(cdev->gadget, f, ccid_dev->in); + if (ret) { + ccid_dev->in->desc = NULL; + pr_err("%s: config_ep_by_speed failed for ep#%s, err#%d\n", + __func__, ccid_dev->in->name, ret); + goto disable_ep_notify; + } ret = usb_ep_enable(ccid_dev->in); if (ret) { pr_err("%s: usb ep#%s enable failed, err#%d\n", @@ -453,8 +453,13 @@ ccid_function_set_alt(struct usb_function *f, unsigned intf, unsigned alt) goto disable_ep_notify; } - ccid_dev->out->desc = ep_choose(cdev->gadget, - ccid_dev->hs.out, ccid_dev->fs.out); + ret = config_ep_by_speed(cdev->gadget, f, ccid_dev->out); + if (ret) { + ccid_dev->out->desc = NULL; + pr_err("%s: config_ep_by_speed failed for ep#%s, err#%d\n", + __func__, ccid_dev->out->name, ret); + goto disable_ep_in; + } ret = usb_ep_enable(ccid_dev->out); if (ret) { pr_err("%s: usb ep#%s enable failed, err#%d\n", @@ -535,16 +540,6 @@ static int ccid_function_bind(struct usb_configuration *c, if (!f->descriptors) goto ep_auto_out_fail; - ccid_dev->fs.in = usb_find_endpoint(ccid_fs_descs, - f->descriptors, - &ccid_fs_in_desc); - ccid_dev->fs.out = usb_find_endpoint(ccid_fs_descs, - f->descriptors, - &ccid_fs_out_desc); - ccid_dev->fs.notify = usb_find_endpoint(ccid_fs_descs, - f->descriptors, - &ccid_fs_notify_desc); - if (gadget_is_dualspeed(cdev->gadget)) { ccid_hs_in_desc.bEndpointAddress = ccid_fs_in_desc.bEndpointAddress; @@ -557,13 +552,6 @@ static int ccid_function_bind(struct usb_configuration *c, f->hs_descriptors = usb_copy_descriptors(ccid_hs_descs); if (!f->hs_descriptors) goto ep_auto_out_fail; - - ccid_dev->hs.in = usb_find_endpoint(ccid_hs_descs, - f->hs_descriptors, &ccid_hs_in_desc); - ccid_dev->hs.out = usb_find_endpoint(ccid_hs_descs, - f->hs_descriptors, &ccid_hs_out_desc); - ccid_dev->hs.notify = usb_find_endpoint(ccid_hs_descs, - f->hs_descriptors, &ccid_hs_notify_desc); } pr_debug("%s: CCID %s Speed, IN:%s OUT:%s\n", __func__, diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c index 464a45b528a..3c121272483 100644 --- a/drivers/usb/gadget/f_diag.c +++ b/drivers/usb/gadget/f_diag.c @@ -512,12 +512,13 @@ static int diag_function_set_alt(struct usb_function *f, unsigned long flags; int rc = 0; - dev->in->desc = ep_choose(cdev->gadget, - (struct usb_endpoint_descriptor *)f->hs_descriptors[1], - (struct usb_endpoint_descriptor *)f->descriptors[1]); - dev->out->desc = ep_choose(cdev->gadget, - (struct usb_endpoint_descriptor *)f->hs_descriptors[2], - (struct usb_endpoint_descriptor *)f->descriptors[2]); + if (config_ep_by_speed(cdev->gadget, f, dev->in) || + config_ep_by_speed(cdev->gadget, f, dev->out)) { + dev->in->desc = NULL; + dev->out->desc = NULL; + return -EINVAL; + } + dev->in->driver_data = dev; rc = usb_ep_enable(dev->in); if (rc) { diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 7c996f271cc..ddedbc83bc3 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -46,11 +46,6 @@ * and also means that a get_alt() method is required. */ -struct ecm_ep_descs { - struct usb_endpoint_descriptor *in; - struct usb_endpoint_descriptor *out; - struct usb_endpoint_descriptor *notify; -}; enum ecm_notify_state { ECM_NOTIFY_NONE, /* don't notify */ @@ -64,9 +59,6 @@ struct f_ecm { char ethaddr[14]; - struct ecm_ep_descs fs; - struct ecm_ep_descs hs; - struct usb_ep *notify; struct usb_request *notify_req; u8 notify_state; @@ -463,11 +455,11 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (ecm->notify->driver_data) { VDBG(cdev, "reset ecm control %d\n", intf); usb_ep_disable(ecm->notify); - } else { + } + if (!(ecm->notify->desc)) { VDBG(cdev, "init ecm ctrl %d\n", intf); - ecm->notify->desc = ep_choose(cdev->gadget, - ecm->hs.notify, - ecm->fs.notify); + if (config_ep_by_speed(cdev->gadget, f, ecm->notify)) + goto fail; } usb_ep_enable(ecm->notify); ecm->notify->driver_data = ecm; @@ -482,12 +474,17 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) gether_disconnect(&ecm->port); } - if (!ecm->port.in_ep->desc) { + if (!ecm->port.in_ep->desc || + !ecm->port.out_ep->desc) { DBG(cdev, "init ecm\n"); - ecm->port.in_ep->desc = ep_choose(cdev->gadget, - ecm->hs.in, ecm->fs.in); - ecm->port.out_ep->desc = ep_choose(cdev->gadget, - ecm->hs.out, ecm->fs.out); + if (config_ep_by_speed(cdev->gadget, f, + ecm->port.in_ep) || + config_ep_by_speed(cdev->gadget, f, + ecm->port.out_ep)) { + ecm->port.in_ep->desc = NULL; + ecm->port.out_ep->desc = NULL; + goto fail; + } } /* CDC Ethernet only sends data in non-default altsettings. @@ -664,13 +661,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) 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 @@ -687,13 +677,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) 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 diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c index fea8e3b08b5..3e412740e2e 100644 --- a/drivers/usb/gadget/f_eem.c +++ b/drivers/usb/gadget/f_eem.c @@ -35,17 +35,9 @@ * Ethernet link. */ -struct eem_ep_descs { - struct usb_endpoint_descriptor *in; - struct usb_endpoint_descriptor *out; -}; - struct f_eem { struct gether port; u8 ctrl_id; - - struct eem_ep_descs fs; - struct eem_ep_descs hs; }; static inline struct f_eem *func_to_eem(struct usb_function *f) @@ -176,12 +168,16 @@ static int eem_set_alt(struct usb_function *f, unsigned intf, unsigned alt) gether_disconnect(&eem->port); } - if (!eem->port.in_ep->desc) { + if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) { DBG(cdev, "init eem\n"); - eem->port.in_ep->desc = ep_choose(cdev->gadget, - eem->hs.in, eem->fs.in); - eem->port.out_ep->desc = ep_choose(cdev->gadget, - eem->hs.out, eem->fs.out); + if (config_ep_by_speed(cdev->gadget, f, + eem->port.in_ep) || + config_ep_by_speed(cdev->gadget, f, + eem->port.out_ep)) { + eem->port.in_ep->desc = NULL; + eem->port.out_ep->desc = NULL; + goto fail; + } } /* zlps should not occur because zero-length EEM packets @@ -253,11 +249,6 @@ eem_bind(struct usb_configuration *c, struct usb_function *f) if (!f->descriptors) goto fail; - eem->fs.in = usb_find_endpoint(eem_fs_function, - f->descriptors, &eem_fs_in_desc); - eem->fs.out = usb_find_endpoint(eem_fs_function, - f->descriptors, &eem_fs_out_desc); - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds @@ -272,11 +263,6 @@ eem_bind(struct usb_configuration *c, struct usb_function *f) f->hs_descriptors = usb_copy_descriptors(eem_hs_function); if (!f->hs_descriptors) goto fail; - - eem->hs.in = usb_find_endpoint(eem_hs_function, - f->hs_descriptors, &eem_hs_in_desc); - eem->hs.out = usb_find_endpoint(eem_hs_function, - f->hs_descriptors, &eem_hs_out_desc); } DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n", diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c index 12879b6f787..403a48bcf56 100644 --- a/drivers/usb/gadget/f_hid.c +++ b/drivers/usb/gadget/f_hid.c @@ -59,8 +59,6 @@ struct f_hidg { struct cdev cdev; struct usb_function func; struct usb_ep *in_ep; - struct usb_endpoint_descriptor *fs_in_ep_desc; - struct usb_endpoint_descriptor *hs_in_ep_desc; }; static inline struct f_hidg *func_to_hidg(struct usb_function *f) @@ -425,8 +423,12 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (hidg->in_ep->driver_data != NULL) usb_ep_disable(hidg->in_ep); - hidg->in_ep->desc = ep_choose(f->config->cdev->gadget, - hidg->hs_in_ep_desc, hidg->fs_in_ep_desc); + status = config_ep_by_speed(f->config->cdev->gadget, f, + hidg->in_ep); + if (status) { + ERROR(cdev, "config_ep_by_speed FAILED!\n"); + goto fail; + } status = usb_ep_enable(hidg->in_ep); if (status < 0) { ERROR(cdev, "Enable endpoint FAILED!\n"); @@ -497,21 +499,12 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) if (!f->descriptors) goto fail; - hidg->fs_in_ep_desc = usb_find_endpoint(hidg_fs_descriptors, - f->descriptors, - &hidg_fs_in_ep_desc); - 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; - hidg->hs_in_ep_desc = usb_find_endpoint(hidg_hs_descriptors, - f->hs_descriptors, - &hidg_hs_in_ep_desc); - } else { - hidg->hs_in_ep_desc = NULL; } mutex_init(&hidg->lock); diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index 34e3ccaf088..375632659a0 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c @@ -256,8 +256,9 @@ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop) /* one endpoint writes data back IN to the host */ ep = loop->in_ep; - ep->desc = ep_choose(cdev->gadget, - &hs_loop_source_desc, &fs_loop_source_desc); + result = config_ep_by_speed(cdev->gadget, &(loop->function), ep); + if (result) + return result; result = usb_ep_enable(ep); if (result < 0) return result; @@ -265,8 +266,10 @@ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop) /* one endpoint just reads OUT packets */ ep = loop->out_ep; - ep->desc = ep_choose(cdev->gadget, - &hs_loop_sink_desc, &fs_loop_sink_desc); + result = config_ep_by_speed(cdev->gadget, &(loop->function), ep); + if (result) + goto fail0; + result = usb_ep_enable(ep); if (result < 0) { fail0: diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index a15fa637ddf..1fde7440a6d 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2405,19 +2405,6 @@ static int get_next_command(struct fsg_common *common) /*-------------------------------------------------------------------------*/ -static int enable_endpoint(struct fsg_common *common, struct usb_ep *ep, - const struct usb_endpoint_descriptor *d) -{ - int rc; - - ep->driver_data = common; - ep->desc = (struct usb_endpoint_descriptor *)d; - rc = usb_ep_enable(ep); - if (rc) - ERROR(common, "can't enable %s, result %d\n", ep->name, rc); - return rc; -} - static int alloc_request(struct fsg_common *common, struct usb_ep *ep, struct usb_request **preq) { @@ -2467,7 +2454,6 @@ reset: common->fsg = new_fsg; fsg = common->fsg; - /* Allocate the requests */ for (i = 0; i < FSG_NUM_BUFFERS; ++i) { struct fsg_buffhd *bh = &common->buffhds[i]; @@ -2497,31 +2483,37 @@ static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct fsg_dev *fsg = fsg_from_func(f); struct fsg_common *common = fsg->common; - const struct usb_endpoint_descriptor *d; int rc; /* Enable the endpoints */ - d = fsg_ep_desc(common->gadget, - &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc); - rc = enable_endpoint(common, fsg->bulk_in, d); + rc = config_ep_by_speed(common->gadget, &(fsg->function), fsg->bulk_in); if (rc) return rc; + rc = usb_ep_enable(fsg->bulk_in); + if (rc) + return rc; + fsg->bulk_in->driver_data = common; fsg->bulk_in_enabled = 1; - d = fsg_ep_desc(common->gadget, - &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc); - rc = enable_endpoint(common, fsg->bulk_out, d); - if (rc) { - usb_ep_disable(fsg->bulk_in); - fsg->bulk_in_enabled = 0; - return rc; - } + rc = config_ep_by_speed(common->gadget, &(fsg->function), + fsg->bulk_out); + if (rc) + goto reset_bulk_int; + rc = usb_ep_enable(fsg->bulk_out); + if (rc) + goto reset_bulk_int; + fsg->bulk_out->driver_data = common; fsg->bulk_out_enabled = 1; - common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize); + common->bulk_out_maxpacket = le16_to_cpu(fsg->bulk_in->desc->wMaxPacketSize); clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); fsg->common->new_fsg = fsg; raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); return USB_GADGET_DELAYED_STATUS; + +reset_bulk_int: + usb_ep_disable(fsg->bulk_in); + fsg->bulk_in_enabled = 0; + return rc; } static void fsg_disable(struct usb_function *f) diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c index e99df1a3970..447e8150c21 100644 --- a/drivers/usb/gadget/f_mtp.c +++ b/drivers/usb/gadget/f_mtp.c @@ -1132,19 +1132,33 @@ static int mtp_function_set_alt(struct usb_function *f, int ret; DBG(cdev, "mtp_function_set_alt intf: %d alt: %d\n", intf, alt); - dev->ep_in->desc = ep_choose(cdev->gadget, - &mtp_highspeed_in_desc, - &mtp_fullspeed_in_desc); - ret = usb_ep_enable(dev->ep_in); - - if (ret) - return ret; - dev->ep_out->desc = ep_choose(cdev->gadget, - &mtp_highspeed_out_desc, - &mtp_fullspeed_out_desc); - ret = usb_ep_enable(dev->ep_out); + ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in); if (ret) { + dev->ep_in->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->ep_in->name, ret); + return ret; + } + ret = usb_ep_enable(dev->ep_in); + if (ret) { + ERROR(cdev, "failed to enable ep %s, result %d\n", + dev->ep_in->name, ret); + return ret; + } + + ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out); + if (ret) { + dev->ep_out->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->ep_out->name, ret); + usb_ep_disable(dev->ep_in); + return ret; + } + ret = usb_ep_enable(dev->ep_out); + if (ret) { + ERROR(cdev, "failed to enable ep %s, result %d\n", + dev->ep_out->name, ret); usb_ep_disable(dev->ep_in); return ret; } diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c index 06daa1bc9ff..ae69ed7e6b9 100644 --- a/drivers/usb/gadget/f_ncm.c +++ b/drivers/usb/gadget/f_ncm.c @@ -48,12 +48,6 @@ #define NCM_NDP_HDR_CRC 0x01000000 #define NCM_NDP_HDR_NOCRC 0x00000000 -struct ncm_ep_descs { - struct usb_endpoint_descriptor *in; - struct usb_endpoint_descriptor *out; - struct usb_endpoint_descriptor *notify; -}; - enum ncm_notify_state { NCM_NOTIFY_NONE, /* don't notify */ NCM_NOTIFY_CONNECT, /* issue CONNECT next */ @@ -66,9 +60,6 @@ struct f_ncm { char ethaddr[14]; - struct ncm_ep_descs fs; - struct ncm_ep_descs hs; - struct usb_ep *notify; struct usb_request *notify_req; u8 notify_state; @@ -801,11 +792,12 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (ncm->notify->driver_data) { DBG(cdev, "reset ncm control %d\n", intf); usb_ep_disable(ncm->notify); - } else { + } + + if (!(ncm->notify->desc)) { DBG(cdev, "init ncm ctrl %d\n", intf); - ncm->notify->desc = ep_choose(cdev->gadget, - ncm->hs.notify, - ncm->fs.notify); + if (config_ep_by_speed(cdev->gadget, f, ncm->notify)) + goto fail; } usb_ep_enable(ncm->notify); ncm->notify->driver_data = ncm; @@ -828,14 +820,17 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt == 1) { struct net_device *net; - if (!ncm->port.in_ep->desc) { + if (!ncm->port.in_ep->desc || + !ncm->port.out_ep->desc) { DBG(cdev, "init ncm\n"); - ncm->port.in_ep->desc = ep_choose(cdev->gadget, - ncm->hs.in, - ncm->fs.in); - ncm->port.out_ep->desc = ep_choose(cdev->gadget, - ncm->hs.out, - ncm->fs.out); + if (config_ep_by_speed(cdev->gadget, f, + ncm->port.in_ep) || + config_ep_by_speed(cdev->gadget, f, + ncm->port.out_ep)) { + ncm->port.in_ep->desc = NULL; + ncm->port.out_ep->desc = NULL; + goto fail; + } } /* TODO */ @@ -1227,13 +1222,6 @@ ncm_bind(struct usb_configuration *c, struct usb_function *f) if (!f->descriptors) goto fail; - ncm->fs.in = usb_find_endpoint(ncm_fs_function, - f->descriptors, &fs_ncm_in_desc); - ncm->fs.out = usb_find_endpoint(ncm_fs_function, - f->descriptors, &fs_ncm_out_desc); - ncm->fs.notify = usb_find_endpoint(ncm_fs_function, - f->descriptors, &fs_ncm_notify_desc); - /* * support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at @@ -1251,13 +1239,6 @@ ncm_bind(struct usb_configuration *c, struct usb_function *f) f->hs_descriptors = usb_copy_descriptors(ncm_hs_function); if (!f->hs_descriptors) goto fail; - - ncm->hs.in = usb_find_endpoint(ncm_hs_function, - f->hs_descriptors, &hs_ncm_in_desc); - ncm->hs.out = usb_find_endpoint(ncm_hs_function, - f->hs_descriptors, &hs_ncm_out_desc); - ncm->hs.notify = usb_find_endpoint(ncm_hs_function, - f->hs_descriptors, &hs_ncm_notify_desc); } /* diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c index a6dbda090ca..394502abeb9 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/f_obex.c @@ -39,20 +39,12 @@ * ready to handle the commands. */ -struct obex_ep_descs { - struct usb_endpoint_descriptor *obex_in; - struct usb_endpoint_descriptor *obex_out; -}; - struct f_obex { struct gserial port; u8 ctrl_id; u8 data_id; u8 port_num; u8 can_activate; - - struct obex_ep_descs fs; - struct obex_ep_descs hs; }; static inline struct f_obex *func_to_obex(struct usb_function *f) @@ -227,12 +219,16 @@ static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt) gserial_disconnect(&obex->port); } - if (!obex->port.in->desc) { + if (!obex->port.in->desc || !obex->port.out->desc) { DBG(cdev, "init obex ttyGS%d\n", obex->port_num); - obex->port.in->desc = ep_choose(cdev->gadget, - obex->hs.obex_in, obex->fs.obex_in); - obex->port.out->desc = ep_choose(cdev->gadget, - obex->hs.obex_out, obex->fs.obex_out); + if (config_ep_by_speed(cdev->gadget, f, + obex->port.in) || + config_ep_by_speed(cdev->gadget, f, + obex->port.out)) { + obex->port.out->desc = NULL; + obex->port.in->desc = NULL; + goto fail; + } } if (alt == 1) { @@ -346,11 +342,6 @@ obex_bind(struct usb_configuration *c, struct usb_function *f) /* copy descriptors, and track endpoint copies */ f->descriptors = usb_copy_descriptors(fs_function); - obex->fs.obex_in = usb_find_endpoint(fs_function, - f->descriptors, &obex_fs_ep_in_desc); - obex->fs.obex_out = usb_find_endpoint(fs_function, - f->descriptors, &obex_fs_ep_out_desc); - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds @@ -364,11 +355,6 @@ obex_bind(struct usb_configuration *c, struct usb_function *f) /* copy descriptors, and track endpoint copies */ f->hs_descriptors = usb_copy_descriptors(hs_function); - - obex->hs.obex_in = usb_find_endpoint(hs_function, - f->hs_descriptors, &obex_hs_ep_in_desc); - obex->hs.obex_out = usb_find_endpoint(hs_function, - f->hs_descriptors, &obex_hs_ep_out_desc); } /* Avoid letting this gadget enumerate until the userspace diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index dc63f161a10..0d6d26090da 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -429,12 +429,12 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt == 1) { int i; - fp->out_ep->desc = ep_choose(gadget, - &pn_hs_sink_desc, - &pn_fs_sink_desc); - fp->in_ep->desc = ep_choose(gadget, - &pn_hs_source_desc, - &pn_fs_source_desc); + if (config_ep_by_speed(gadget, f, fp->in_ep) || + config_ep_by_speed(gadget, f, fp->out_ep)) { + fp->in_ep->desc = NULL; + fp->out_ep->desc = NULL; + return -EINVAL; + } usb_ep_enable(fp->out_ep); usb_ep_enable(fp->in_ep); diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c index 84fbd07fd05..7e4eee17d62 100644 --- a/drivers/usb/gadget/f_rmnet.c +++ b/drivers/usb/gadget/f_rmnet.c @@ -25,11 +25,6 @@ #define RMNET_NOTIFY_INTERVAL 5 #define RMNET_MAX_NOTIFY_SIZE sizeof(struct usb_cdc_notification) -struct rmnet_descs { - struct usb_endpoint_descriptor *in; - struct usb_endpoint_descriptor *out; - struct usb_endpoint_descriptor *notify; -}; #define ACM_CTRL_DTR (1 << 0) @@ -46,10 +41,6 @@ struct f_rmnet { spinlock_t lock; - /* usb descriptors */ - struct rmnet_descs fs; - struct rmnet_descs hs; - /* usb eps*/ struct usb_ep *notify; struct usb_request *notify_req; @@ -482,10 +473,16 @@ frmnet_set_alt(struct usb_function *f, unsigned intf, unsigned alt) pr_debug("%s: reset port:%d\n", __func__, dev->port_num); usb_ep_disable(dev->notify); } - dev->notify->desc = ep_choose(cdev->gadget, - dev->hs.notify, - dev->fs.notify); + + ret = config_ep_by_speed(cdev->gadget, f, dev->notify); + if (ret) { + dev->notify->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->notify->name, ret); + return ret; + } ret = usb_ep_enable(dev->notify); + if (ret) { pr_err("%s: usb ep#%s enable failed, err#%d\n", __func__, dev->notify->name, ret); @@ -498,10 +495,12 @@ frmnet_set_alt(struct usb_function *f, unsigned intf, unsigned alt) gport_rmnet_disconnect(dev); } - dev->port.in->desc = ep_choose(cdev->gadget, - dev->hs.in, dev->fs.in); - dev->port.out->desc = ep_choose(cdev->gadget, - dev->hs.out, dev->fs.out); + if (config_ep_by_speed(cdev->gadget, f, dev->port.in) || + config_ep_by_speed(cdev->gadget, f, dev->port.out)) { + dev->port.in->desc = NULL; + dev->port.out->desc = NULL; + return -EINVAL; + } ret = gport_rmnet_connect(dev); @@ -855,16 +854,6 @@ static int frmnet_bind(struct usb_configuration *c, struct usb_function *f) if (!f->descriptors) goto fail; - dev->fs.in = usb_find_endpoint(rmnet_fs_function, - f->descriptors, - &rmnet_fs_in_desc); - dev->fs.out = usb_find_endpoint(rmnet_fs_function, - f->descriptors, - &rmnet_fs_out_desc); - dev->fs.notify = usb_find_endpoint(rmnet_fs_function, - f->descriptors, - &rmnet_fs_notify_desc); - if (gadget_is_dualspeed(cdev->gadget)) { rmnet_hs_in_desc.bEndpointAddress = rmnet_fs_in_desc.bEndpointAddress; @@ -878,13 +867,6 @@ static int frmnet_bind(struct usb_configuration *c, struct usb_function *f) if (!f->hs_descriptors) goto fail; - - dev->hs.in = usb_find_endpoint(rmnet_hs_function, - f->hs_descriptors, &rmnet_hs_in_desc); - dev->hs.out = usb_find_endpoint(rmnet_hs_function, - f->hs_descriptors, &rmnet_hs_out_desc); - dev->hs.notify = usb_find_endpoint(rmnet_hs_function, - f->hs_descriptors, &rmnet_hs_notify_desc); } pr_info("%s: RmNet(%d) %s Speed, IN:%s OUT:%s\n", diff --git a/drivers/usb/gadget/f_rmnet_sdio.c b/drivers/usb/gadget/f_rmnet_sdio.c index 1379191c0ae..80193563dd4 100644 --- a/drivers/usb/gadget/f_rmnet_sdio.c +++ b/drivers/usb/gadget/f_rmnet_sdio.c @@ -1255,20 +1255,58 @@ static int rmnet_sdio_set_alt(struct usb_function *f, struct usb_composite_dev *cdev = dev->cdev; int ret = 0; + /* Enable epin */ dev->epin->driver_data = dev; - dev->epin->desc = ep_choose(cdev->gadget, - &rmnet_sdio_hs_in_desc, - &rmnet_sdio_fs_in_desc); - usb_ep_enable(dev->epin); + ret = config_ep_by_speed(cdev->gadget, f, dev->epin); + if (ret) { + dev->epin->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->epin->name, ret); + return ret; + } + ret = usb_ep_enable(dev->epin); + if (ret) { + ERROR(cdev, "can't enable %s, result %d\n", + dev->epin->name, ret); + return ret; + } + + /* Enable epout */ dev->epout->driver_data = dev; - dev->epout->desc = ep_choose(cdev->gadget, - &rmnet_sdio_hs_out_desc, - &rmnet_sdio_fs_out_desc); - usb_ep_enable(dev->epout); - dev->epnotify->desc = ep_choose(cdev->gadget, - &rmnet_sdio_hs_notify_desc, - &rmnet_sdio_fs_notify_desc); - usb_ep_enable(dev->epnotify); + ret = config_ep_by_speed(cdev->gadget, f, dev->epout); + if (ret) { + dev->epout->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->epout->name, ret); + usb_ep_disable(dev->epin); + return ret; + } + ret = usb_ep_enable(dev->epout); + if (ret) { + ERROR(cdev, "can't enable %s, result %d\n", + dev->epout->name, ret); + usb_ep_disable(dev->epin); + return ret; + } + + /* Enable epnotify */ + ret = config_ep_by_speed(cdev->gadget, f, dev->epnotify); + if (ret) { + dev->epnotify->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->epnotify->name, ret); + usb_ep_disable(dev->epin); + usb_ep_disable(dev->epout); + return ret; + } + ret = usb_ep_enable(dev->epnotify); + if (ret) { + ERROR(cdev, "can't enable %s, result %d\n", + dev->epnotify->name, ret); + usb_ep_disable(dev->epin); + usb_ep_disable(dev->epout); + return ret; + } /* allocate notification */ dev->notify_req = rmnet_sdio_alloc_req(dev->epnotify, diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c index eb7536b3cb2..b71f6468678 100644 --- a/drivers/usb/gadget/f_rmnet_smd.c +++ b/drivers/usb/gadget/f_rmnet_smd.c @@ -956,19 +956,32 @@ static int rmnet_smd_set_alt(struct usb_function *f, struct usb_composite_dev *cdev = dev->cdev; int ret = 0; - dev->epin->desc = ep_choose(cdev->gadget, - &rmnet_smd_hs_in_desc, - &rmnet_smd_fs_in_desc); + /* Enable epin endpoint */ + ret = config_ep_by_speed(cdev->gadget, f, dev->epin); + if (ret) { + dev->epin->desc = NULL; + ERROR(cdev, "config_ep_by_speed failed for ep %s, result %d\n", + dev->epin->name, ret); + return ret; + } ret = usb_ep_enable(dev->epin); if (ret) { ERROR(cdev, "can't enable %s, result %d\n", dev->epin->name, ret); return ret; } - dev->epout->desc = ep_choose(cdev->gadget, - &rmnet_smd_hs_out_desc, - &rmnet_smd_fs_out_desc); + + /* Enable epout endpoint */ + ret = config_ep_by_speed(cdev->gadget, f, dev->epout); + if (ret) { + dev->epout->desc = NULL; + ERROR(cdev, "config_ep_by_speed failed for ep %s, result %d\n", + dev->epout->name, ret); + usb_ep_disable(dev->epin); + return ret; + } ret = usb_ep_enable(dev->epout); + if (ret) { ERROR(cdev, "can't enable %s, result %d\n", dev->epout->name, ret); @@ -976,9 +989,16 @@ static int rmnet_smd_set_alt(struct usb_function *f, return ret; } - dev->epnotify->desc = ep_choose(cdev->gadget, - &rmnet_smd_hs_notify_desc, - &rmnet_smd_fs_notify_desc); + /* Enable epnotify endpoint */ + ret = config_ep_by_speed(cdev->gadget, f, dev->epnotify); + if (ret) { + dev->epnotify->desc = NULL; + ERROR(cdev, "config_ep_by_speed failed for ep %s, result %d\n", + dev->epnotify->name, ret); + usb_ep_disable(dev->epin); + usb_ep_disable(dev->epout); + return ret; + } ret = usb_ep_enable(dev->epnotify); if (ret) { ERROR(cdev, "can't enable %s, result %d\n", diff --git a/drivers/usb/gadget/f_rmnet_smd_sdio.c b/drivers/usb/gadget/f_rmnet_smd_sdio.c index fdfc810b473..175afe324d9 100644 --- a/drivers/usb/gadget/f_rmnet_smd_sdio.c +++ b/drivers/usb/gadget/f_rmnet_smd_sdio.c @@ -1354,6 +1354,7 @@ static int rmnet_mux_set_alt(struct usb_function *f, function); struct rmnet_mux_sdio_dev *sdio_dev = &dev->sdio_dev; struct usb_composite_dev *cdev = dev->cdev; + int ret = 0; /* allocate notification */ dev->notify_req = rmnet_mux_alloc_req(dev->epnotify, @@ -1365,21 +1366,59 @@ static int rmnet_mux_set_alt(struct usb_function *f, dev->notify_req->complete = rmnet_mux_notify_complete; dev->notify_req->context = dev; dev->notify_req->length = RMNET_MUX_SDIO_MAX_NFY_SZE; - dev->epnotify->desc = ep_choose(cdev->gadget, - &rmnet_mux_hs_notify_desc, - &rmnet_mux_fs_notify_desc); - usb_ep_enable(dev->epnotify); + /* Enable epin */ dev->epin->driver_data = dev; - dev->epin->desc = ep_choose(cdev->gadget, - &rmnet_mux_hs_in_desc, - &rmnet_mux_fs_in_desc); - usb_ep_enable(dev->epin); + ret = config_ep_by_speed(cdev->gadget, f, dev->epin); + if (ret) { + dev->epin->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->epin->name, ret); + return ret; + } + ret = usb_ep_enable(dev->epin); + if (ret) { + ERROR(cdev, "can't enable %s, result %d\n", + dev->epin->name, ret); + return ret; + } + + /* Enable epout */ dev->epout->driver_data = dev; - dev->epout->desc = ep_choose(cdev->gadget, - &rmnet_mux_hs_out_desc, - &rmnet_mux_fs_out_desc); - usb_ep_enable(dev->epout); + ret = config_ep_by_speed(cdev->gadget, f, dev->epout); + if (ret) { + dev->epout->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->epout->name, ret); + usb_ep_disable(dev->epin); + return ret; + } + ret = usb_ep_enable(dev->epout); + if (ret) { + ERROR(cdev, "can't enable %s, result %d\n", + dev->epout->name, ret); + usb_ep_disable(dev->epin); + return ret; + } + + /* Enable epnotify */ + ret = config_ep_by_speed(cdev->gadget, f, dev->epnotify); + if (ret) { + dev->epnotify->desc = NULL; + ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", + dev->epnotify->name, ret); + usb_ep_disable(dev->epin); + usb_ep_disable(dev->epout); + return ret; + } + ret = usb_ep_enable(dev->epnotify); + if (ret) { + ERROR(cdev, "can't enable %s, result %d\n", + dev->epnotify->name, ret); + usb_ep_disable(dev->epin); + usb_ep_disable(dev->epout); + return ret; + } dev->dpkts_tolaptop = 0; dev->cpkts_tolaptop = 0; diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 25d5022ca2e..4a74dcf9a59 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -76,12 +76,6 @@ * - MS-Windows drivers sometimes emit undocumented requests. */ -struct rndis_ep_descs { - struct usb_endpoint_descriptor *in; - struct usb_endpoint_descriptor *out; - struct usb_endpoint_descriptor *notify; -}; - struct f_rndis { struct gether port; u8 ctrl_id, data_id; @@ -90,10 +84,6 @@ struct f_rndis { const char *manufacturer; int config; - - struct rndis_ep_descs fs; - struct rndis_ep_descs hs; - struct usb_ep *notify; struct usb_request *notify_req; atomic_t notify_count; @@ -485,12 +475,12 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (rndis->notify->driver_data) { VDBG(cdev, "reset rndis control %d\n", intf); usb_ep_disable(rndis->notify); - } else { - VDBG(cdev, "init rndis ctrl %d\n", intf); } - rndis->notify->desc = ep_choose(cdev->gadget, - rndis->hs.notify, - rndis->fs.notify); + if (!rndis->notify->desc) { + VDBG(cdev, "init rndis ctrl %d\n", intf); + if (config_ep_by_speed(cdev->gadget, f, rndis->notify)) + goto fail; + } usb_ep_enable(rndis->notify); rndis->notify->driver_data = rndis; @@ -502,13 +492,17 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) gether_disconnect(&rndis->port); } - if (!rndis->port.in_ep->desc) { + if (!rndis->port.in_ep->desc || !rndis->port.out_ep->desc) { DBG(cdev, "init rndis\n"); + if (config_ep_by_speed(cdev->gadget, f, + rndis->port.in_ep) || + config_ep_by_speed(cdev->gadget, f, + rndis->port.out_ep)) { + rndis->port.in_ep->desc = NULL; + rndis->port.out_ep->desc = NULL; + goto fail; + } } - rndis->port.in_ep->desc = ep_choose(cdev->gadget, - rndis->hs.in, rndis->fs.in); - rndis->port.out_ep->desc = ep_choose(cdev->gadget, - rndis->hs.out, rndis->fs.out); /* Avoid ZLPs; they can be troublesome. */ rndis->port.is_zlp_ok = false; @@ -663,13 +657,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) if (!f->descriptors) goto fail; - rndis->fs.in = usb_find_endpoint(eth_fs_function, - f->descriptors, &fs_in_desc); - rndis->fs.out = usb_find_endpoint(eth_fs_function, - f->descriptors, &fs_out_desc); - rndis->fs.notify = usb_find_endpoint(eth_fs_function, - f->descriptors, &fs_notify_desc); - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds @@ -687,13 +674,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) if (!f->hs_descriptors) goto fail; - - rndis->hs.in = usb_find_endpoint(eth_hs_function, - f->hs_descriptors, &hs_in_desc); - rndis->hs.out = usb_find_endpoint(eth_hs_function, - f->hs_descriptors, &hs_out_desc); - rndis->hs.notify = usb_find_endpoint(eth_hs_function, - f->hs_descriptors, &hs_notify_desc); } rndis->port.open = rndis_open; diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index fefbbe6d7bf..1d7cb93854b 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c @@ -29,21 +29,12 @@ */ #define GSERIAL_NO_PORTS 2 -struct gser_descs { - struct usb_endpoint_descriptor *in; - struct usb_endpoint_descriptor *out; -#ifdef CONFIG_MODEM_SUPPORT - struct usb_endpoint_descriptor *notify; -#endif -}; struct f_gser { struct gserial port; u8 data_id; u8 port_num; - struct gser_descs fs; - struct gser_descs hs; u8 online; enum transport_type transport; @@ -478,10 +469,16 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt) usb_ep_disable(gser->notify); gser->notify->driver_data = NULL; } - gser->notify->desc = ep_choose(cdev->gadget, - gser->hs.notify, - gser->fs.notify); + + if (!gser->notify->desc) { + if (config_ep_by_speed(cdev->gadget, f, gser->notify)) { + gser->notify->desc = NULL; + return -EINVAL; + } + } + rc = usb_ep_enable(gser->notify); + if (rc) { ERROR(cdev, "can't enable %s, result %d\n", gser->notify->name, rc); @@ -493,14 +490,16 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (gser->port.in->driver_data) { DBG(cdev, "reset generic data ttyGS%d\n", gser->port_num); gport_disconnect(gser); - } else { - DBG(cdev, "activate generic data ttyGS%d\n", gser->port_num); } - gser->port.in->desc = ep_choose(cdev->gadget, - gser->hs.in, gser->fs.in); - gser->port.out->desc = ep_choose(cdev->gadget, - gser->hs.out, gser->fs.out); - + if (!gser->port.in->desc || !gser->port.out->desc) { + DBG(cdev, "activate generic ttyGS%d\n", gser->port_num); + if (config_ep_by_speed(cdev->gadget, f, gser->port.in) || + config_ep_by_speed(cdev->gadget, f, gser->port.out)) { + gser->port.in->desc = NULL; + gser->port.out->desc = NULL; + return -EINVAL; + } + } gport_connect(gser); gser->online = 1; @@ -745,16 +744,6 @@ gser_bind(struct usb_configuration *c, struct usb_function *f) 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 @@ -775,14 +764,6 @@ gser_bind(struct usb_configuration *c, struct usb_function *f) 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", diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index 0ffddd33a55..caf2f95e034 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c @@ -347,7 +347,9 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss) /* one endpoint writes (sources) zeroes IN (to the host) */ ep = ss->in_ep; - ep->desc = ep_choose(cdev->gadget, &hs_source_desc, &fs_source_desc); + result = config_ep_by_speed(cdev->gadget, &(ss->function), ep); + if (result) + return result; result = usb_ep_enable(ep); if (result < 0) return result; @@ -364,7 +366,9 @@ fail: /* one endpoint reads (sinks) anything OUT (from the host) */ ep = ss->out_ep; - ep->desc = ep_choose(cdev->gadget, &hs_sink_desc, &fs_sink_desc); + result = config_ep_by_speed(cdev->gadget, &(ss->function), ep); + if (result) + goto fail; result = usb_ep_enable(ep); if (result < 0) goto fail; diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index aecaed1724a..93bf676ef50 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c @@ -57,18 +57,10 @@ * caring about specific product and vendor IDs. */ -struct geth_descs { - struct usb_endpoint_descriptor *in; - struct usb_endpoint_descriptor *out; -}; - struct f_gether { struct gether port; char ethaddr[14]; - - struct geth_descs fs; - struct geth_descs hs; }; static inline struct f_gether *func_to_geth(struct usb_function *f) @@ -243,10 +235,12 @@ static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } DBG(cdev, "init + activate cdc subset\n"); - geth->port.in_ep->desc = ep_choose(cdev->gadget, - geth->hs.in, geth->fs.in); - geth->port.out_ep->desc = ep_choose(cdev->gadget, - geth->hs.out, geth->fs.out); + if (config_ep_by_speed(cdev->gadget, f, geth->port.in_ep) || + config_ep_by_speed(cdev->gadget, f, geth->port.out_ep)) { + geth->port.in_ep->desc = NULL; + geth->port.out_ep->desc = NULL; + return -EINVAL; + } net = gether_connect(&geth->port); return IS_ERR(net) ? PTR_ERR(net) : 0; @@ -297,12 +291,6 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) /* copy descriptors, and track endpoint copies */ f->descriptors = usb_copy_descriptors(fs_eth_function); - geth->fs.in = usb_find_endpoint(fs_eth_function, - f->descriptors, &fs_subset_in_desc); - geth->fs.out = usb_find_endpoint(fs_eth_function, - f->descriptors, &fs_subset_out_desc); - - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds @@ -315,11 +303,6 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) /* copy descriptors, and track endpoint copies */ f->hs_descriptors = usb_copy_descriptors(hs_eth_function); - - geth->hs.in = usb_find_endpoint(hs_eth_function, - f->hs_descriptors, &hs_subset_in_desc); - geth->hs.out = usb_find_endpoint(hs_eth_function, - f->hs_descriptors, &hs_subset_out_desc); } /* NOTE: all that is done without knowing or caring about diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index eb0c8e1abec..6354c92bbf2 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -531,6 +531,18 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) } +/*-------------------------------------------------------------------------*/ + +/* Maxpacket and other transfer characteristics vary by speed. */ +static struct usb_endpoint_descriptor * +fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, + struct usb_endpoint_descriptor *hs) +{ + if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) + return hs; + return fs; +} + /*-------------------------------------------------------------------------*/ /* diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 15059670b40..990a1fd161a 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -509,17 +509,6 @@ static struct usb_descriptor_header *fsg_hs_function[] = { NULL, }; -/* Maxpacket and other transfer characteristics vary by speed. */ -static struct usb_endpoint_descriptor * -fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, - struct usb_endpoint_descriptor *hs) -{ - if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) - return hs; - return fs; -} - - /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ static struct usb_string fsg_strings[] = { #ifndef FSG_NO_DEVICE_STRINGS diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 925486ea487..768d47ce655 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -148,21 +148,6 @@ int usb_interface_id(struct usb_configuration *, struct usb_function *); int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f, struct usb_ep *_ep); -/** - * ep_choose - select descriptor endpoint at current device speed - * @g: gadget, connected and running at some speed - * @hs: descriptor to use for high speed operation - * @fs: descriptor to use for full or low speed operation - */ -static inline struct usb_endpoint_descriptor * -ep_choose(struct usb_gadget *g, struct usb_endpoint_descriptor *hs, - struct usb_endpoint_descriptor *fs) -{ - if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) - return hs; - return fs; -} - #define MAX_CONFIG_INTERFACES 16 /* arbitrary; max 255 */ /** diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index a3b71c75ce5..f403118d838 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -880,12 +880,6 @@ int usb_gadget_config_buf(const struct usb_config_descriptor *config, struct usb_descriptor_header **usb_copy_descriptors( struct usb_descriptor_header **); -/* return copy of endpoint descriptor given original descriptor set */ -struct usb_endpoint_descriptor *usb_find_endpoint( - struct usb_descriptor_header **src, - struct usb_descriptor_header **copy, - struct usb_endpoint_descriptor *match); - /** * usb_free_descriptors - free descriptors returned by usb_copy_descriptors() * @v: vector of descriptors