aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/composite.c8
-rw-r--r--drivers/usb/gadget/config.c39
-rw-r--r--drivers/usb/gadget/f_acm.c45
-rw-r--r--drivers/usb/gadget/f_ecm.c57
-rw-r--r--drivers/usb/gadget/f_eem.c46
-rw-r--r--drivers/usb/gadget/f_fs.c4
-rw-r--r--drivers/usb/gadget/f_hid.c30
-rw-r--r--drivers/usb/gadget/f_loopback.c28
-rw-r--r--drivers/usb/gadget/f_mass_storage.c59
-rw-r--r--drivers/usb/gadget/f_midi.c8
-rw-r--r--drivers/usb/gadget/f_ncm.c32
-rw-r--r--drivers/usb/gadget/f_obex.c23
-rw-r--r--drivers/usb/gadget/f_phonet.c15
-rw-r--r--drivers/usb/gadget/f_rndis.c55
-rw-r--r--drivers/usb/gadget/f_serial.c38
-rw-r--r--drivers/usb/gadget/f_sourcesink.c104
-rw-r--r--drivers/usb/gadget/f_subset.c48
-rw-r--r--drivers/usb/gadget/f_uac1.c22
-rw-r--r--drivers/usb/gadget/f_uac2.c16
-rw-r--r--drivers/usb/gadget/f_uvc.c79
-rw-r--r--drivers/usb/gadget/printer.c12
-rw-r--r--drivers/usb/gadget/tcm_usb_gadget.c10
-rw-r--r--include/linux/usb/composite.h2
-rw-r--r--include/linux/usb/gadget.h7
24 files changed, 307 insertions, 480 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 957f973dd96..2a6bfe759c2 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -107,7 +107,7 @@ int config_ep_by_speed(struct usb_gadget *g,
}
/* else: fall through */
default:
- speed_desc = f->descriptors;
+ speed_desc = f->fs_descriptors;
}
/* find descriptors */
for_each_ep_desc(speed_desc, d_spd) {
@@ -200,7 +200,7 @@ int usb_add_function(struct usb_configuration *config,
* as full speed ... it's the function drivers that will need
* to avoid bulk and ISO transfers.
*/
- if (!config->fullspeed && function->descriptors)
+ if (!config->fullspeed && function->fs_descriptors)
config->fullspeed = true;
if (!config->highspeed && function->hs_descriptors)
config->highspeed = true;
@@ -363,7 +363,7 @@ static int config_buf(struct usb_configuration *config,
descriptors = f->hs_descriptors;
break;
default:
- descriptors = f->descriptors;
+ descriptors = f->fs_descriptors;
}
if (!descriptors)
@@ -620,7 +620,7 @@ static int set_config(struct usb_composite_dev *cdev,
descriptors = f->hs_descriptors;
break;
default:
- descriptors = f->descriptors;
+ descriptors = f->fs_descriptors;
}
for (; *descriptors; ++descriptors) {
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index e3a98929d34..34e12fc52c2 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -19,7 +19,7 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
-
+#include <linux/usb/composite.h>
/**
* usb_descriptor_fillbuf - fill buffer with descriptors
@@ -158,3 +158,40 @@ usb_copy_descriptors(struct usb_descriptor_header **src)
return ret;
}
EXPORT_SYMBOL_GPL(usb_copy_descriptors);
+
+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;
+}
+EXPORT_SYMBOL_GPL(usb_assign_descriptors);
+
+void usb_free_all_descriptors(struct usb_function *f)
+{
+ usb_free_descriptors(f->fs_descriptors);
+ usb_free_descriptors(f->hs_descriptors);
+ usb_free_descriptors(f->ss_descriptors);
+}
+EXPORT_SYMBOL_GPL(usb_free_all_descriptors);
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index 7c30bb49850..308242b5d6e 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -658,37 +658,22 @@ 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 */
- f->descriptors = usb_copy_descriptors(acm_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)) {
- acm_hs_in_desc.bEndpointAddress =
- acm_fs_in_desc.bEndpointAddress;
- acm_hs_out_desc.bEndpointAddress =
- acm_fs_out_desc.bEndpointAddress;
- acm_hs_notify_desc.bEndpointAddress =
- acm_fs_notify_desc.bEndpointAddress;
-
- /* copy descriptors */
- f->hs_descriptors = usb_copy_descriptors(acm_hs_function);
- }
- if (gadget_is_superspeed(c->cdev->gadget)) {
- acm_ss_in_desc.bEndpointAddress =
- acm_fs_in_desc.bEndpointAddress;
- acm_ss_out_desc.bEndpointAddress =
- acm_fs_out_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->ss_descriptors = usb_copy_descriptors(acm_ss_function);
- if (!f->ss_descriptors)
- goto fail;
- }
+ acm_hs_in_desc.bEndpointAddress = acm_fs_in_desc.bEndpointAddress;
+ acm_hs_out_desc.bEndpointAddress = acm_fs_out_desc.bEndpointAddress;
+ acm_hs_notify_desc.bEndpointAddress =
+ acm_fs_notify_desc.bEndpointAddress;
+
+ acm_ss_in_desc.bEndpointAddress = acm_fs_in_desc.bEndpointAddress;
+ acm_ss_out_desc.bEndpointAddress = acm_fs_out_desc.bEndpointAddress;
+
+ status = usb_assign_descriptors(f, acm_fs_function, acm_hs_function,
+ acm_ss_function);
+ if (status)
+ goto fail;
DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n",
acm->port_num,
@@ -720,11 +705,7 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_acm *acm = func_to_acm(f);
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- if (gadget_is_superspeed(c->cdev->gadget))
- usb_free_descriptors(f->ss_descriptors);
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
gs_free_req(acm->notify, acm->notify_req);
kfree(acm);
}
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index a158740255c..2d3c5a46de8 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -743,42 +743,24 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
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;
-
/* 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;
-
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(ecm_hs_function);
- if (!f->hs_descriptors)
- goto fail;
- }
-
- if (gadget_is_superspeed(c->cdev->gadget)) {
- ss_ecm_in_desc.bEndpointAddress =
- fs_ecm_in_desc.bEndpointAddress;
- ss_ecm_out_desc.bEndpointAddress =
- fs_ecm_out_desc.bEndpointAddress;
- ss_ecm_notify_desc.bEndpointAddress =
- fs_ecm_notify_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->ss_descriptors = usb_copy_descriptors(ecm_ss_function);
- if (!f->ss_descriptors)
- goto fail;
- }
+ 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;
+
+ ss_ecm_in_desc.bEndpointAddress = fs_ecm_in_desc.bEndpointAddress;
+ ss_ecm_out_desc.bEndpointAddress = fs_ecm_out_desc.bEndpointAddress;
+ ss_ecm_notify_desc.bEndpointAddress =
+ fs_ecm_notify_desc.bEndpointAddress;
+
+ status = usb_assign_descriptors(f, ecm_fs_function, ecm_hs_function,
+ ecm_ss_function);
+ if (status)
+ goto fail;
/* NOTE: all that is done without knowing or caring about
* the network link ... which is unavailable to this code
@@ -796,11 +778,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
- if (f->descriptors)
- usb_free_descriptors(f->descriptors);
- if (f->hs_descriptors)
- usb_free_descriptors(f->hs_descriptors);
-
if (ecm->notify_req) {
kfree(ecm->notify_req->buf);
usb_ep_free_request(ecm->notify, ecm->notify_req);
@@ -826,11 +803,7 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f)
DBG(c->cdev, "ecm unbind\n");
- if (gadget_is_superspeed(c->cdev->gadget))
- usb_free_descriptors(f->ss_descriptors);
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
kfree(ecm->notify_req->buf);
usb_ep_free_request(ecm->notify, ecm->notify_req);
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
index a9cf20522ff..cf0ebee8556 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -274,38 +274,20 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
status = -ENOMEM;
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(eem_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)) {
- eem_hs_in_desc.bEndpointAddress =
- eem_fs_in_desc.bEndpointAddress;
- eem_hs_out_desc.bEndpointAddress =
- eem_fs_out_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(eem_hs_function);
- if (!f->hs_descriptors)
- goto fail;
- }
+ eem_hs_in_desc.bEndpointAddress = eem_fs_in_desc.bEndpointAddress;
+ eem_hs_out_desc.bEndpointAddress = eem_fs_out_desc.bEndpointAddress;
- if (gadget_is_superspeed(c->cdev->gadget)) {
- eem_ss_in_desc.bEndpointAddress =
- eem_fs_in_desc.bEndpointAddress;
- eem_ss_out_desc.bEndpointAddress =
- eem_fs_out_desc.bEndpointAddress;
+ eem_ss_in_desc.bEndpointAddress = eem_fs_in_desc.bEndpointAddress;
+ eem_ss_out_desc.bEndpointAddress = eem_fs_out_desc.bEndpointAddress;
- /* copy descriptors, and track endpoint copies */
- f->ss_descriptors = usb_copy_descriptors(eem_ss_function);
- if (!f->ss_descriptors)
- goto fail;
- }
+ status = usb_assign_descriptors(f, eem_fs_function, eem_hs_function,
+ eem_ss_function);
+ if (status)
+ goto fail;
DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n",
gadget_is_superspeed(c->cdev->gadget) ? "super" :
@@ -314,11 +296,7 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
- if (f->descriptors)
- usb_free_descriptors(f->descriptors);
- if (f->hs_descriptors)
- usb_free_descriptors(f->hs_descriptors);
-
+ usb_free_all_descriptors(f);
if (eem->port.out_ep)
eem->port.out_ep->driver_data = NULL;
if (eem->port.in_ep)
@@ -336,11 +314,7 @@ eem_unbind(struct usb_configuration *c, struct usb_function *f)
DBG(c->cdev, "eem unbind\n");
- if (gadget_is_superspeed(c->cdev->gadget))
- usb_free_descriptors(f->ss_descriptors);
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
kfree(eem);
}
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 64c4ec10d1f..4a6961c517f 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -2097,7 +2097,7 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
if (isHS)
func->function.hs_descriptors[(long)valuep] = desc;
else
- func->function.descriptors[(long)valuep] = desc;
+ func->function.fs_descriptors[(long)valuep] = desc;
if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT)
return 0;
@@ -2249,7 +2249,7 @@ static int ffs_func_bind(struct usb_configuration *c,
* numbers without worrying that it may be described later on.
*/
if (likely(full)) {
- func->function.descriptors = data->fs_descs;
+ func->function.fs_descriptors = data->fs_descs;
ret = ffs_do_descs(ffs->fs_descs_count,
data->raw_descs,
sizeof data->raw_descs,
diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c
index 511e527178e..6e69a8e8d22 100644
--- a/drivers/usb/gadget/f_hid.c
+++ b/drivers/usb/gadget/f_hid.c
@@ -573,7 +573,6 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
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);
@@ -609,20 +608,15 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
hidg_desc.desc[0].wDescriptorLength =
cpu_to_le16(hidg->report_desc_length);
- /* copy descriptors */
- f->descriptors = usb_copy_descriptors(hidg_fs_descriptors);
- if (!f->descriptors)
- goto fail;
+ hidg_hs_in_ep_desc.bEndpointAddress =
+ hidg_fs_in_ep_desc.bEndpointAddress;
+ hidg_hs_out_ep_desc.bEndpointAddress =
+ hidg_fs_out_ep_desc.bEndpointAddress;
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- hidg_hs_in_ep_desc.bEndpointAddress =
- hidg_fs_in_ep_desc.bEndpointAddress;
- hidg_hs_out_ep_desc.bEndpointAddress =
- hidg_fs_out_ep_desc.bEndpointAddress;
- f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors);
- if (!f->hs_descriptors)
- goto fail;
- }
+ status = usb_assign_descriptors(f, hidg_fs_descriptors,
+ hidg_hs_descriptors, NULL);
+ if (status)
+ goto fail;
mutex_init(&hidg->lock);
spin_lock_init(&hidg->spinlock);
@@ -649,9 +643,7 @@ fail:
usb_ep_free_request(hidg->in_ep, hidg->req);
}
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
-
+ usb_free_all_descriptors(f);
return status;
}
@@ -668,9 +660,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
kfree(hidg->req->buf);
usb_ep_free_request(hidg->in_ep, hidg->req);
- /* free descriptors copies */
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
kfree(hidg->report_desc);
kfree(hidg);
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 7275706caeb..bb39cb2bb3a 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -177,6 +177,7 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_composite_dev *cdev = c->cdev;
struct f_loopback *loop = func_to_loop(f);
int id;
+ int ret;
/* allocate interface ID(s) */
id = usb_interface_id(c, f);
@@ -201,22 +202,19 @@ autoconf_fail:
loop->out_ep->driver_data = cdev; /* claim */
/* support high speed hardware */
- if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_loop_source_desc.bEndpointAddress =
- fs_loop_source_desc.bEndpointAddress;
- hs_loop_sink_desc.bEndpointAddress =
- fs_loop_sink_desc.bEndpointAddress;
- f->hs_descriptors = hs_loopback_descs;
- }
+ hs_loop_source_desc.bEndpointAddress =
+ fs_loop_source_desc.bEndpointAddress;
+ hs_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress;
/* support super speed hardware */
- if (gadget_is_superspeed(c->cdev->gadget)) {
- ss_loop_source_desc.bEndpointAddress =
- fs_loop_source_desc.bEndpointAddress;
- ss_loop_sink_desc.bEndpointAddress =
- fs_loop_sink_desc.bEndpointAddress;
- f->ss_descriptors = ss_loopback_descs;
- }
+ ss_loop_source_desc.bEndpointAddress =
+ fs_loop_source_desc.bEndpointAddress;
+ ss_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress;
+
+ ret = usb_assign_descriptors(f, fs_loopback_descs, hs_loopback_descs,
+ ss_loopback_descs);
+ if (ret)
+ return ret;
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
(gadget_is_superspeed(c->cdev->gadget) ? "super" :
@@ -228,6 +226,7 @@ autoconf_fail:
static void
loopback_unbind(struct usb_configuration *c, struct usb_function *f)
{
+ usb_free_all_descriptors(f);
kfree(func_to_loop(f));
}
@@ -379,7 +378,6 @@ static int __init loopback_bind_config(struct usb_configuration *c)
return -ENOMEM;
loop->function.name = "loopback";
- loop->function.descriptors = fs_loopback_descs;
loop->function.bind = loopback_bind;
loop->function.unbind = loopback_unbind;
loop->function.set_alt = loopback_set_alt;
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 3a7668bde3e..3433e432a4a 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2904,9 +2904,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
}
fsg_common_put(common);
- usb_free_descriptors(fsg->function.descriptors);
- usb_free_descriptors(fsg->function.hs_descriptors);
- usb_free_descriptors(fsg->function.ss_descriptors);
+ usb_free_all_descriptors(&fsg->function);
kfree(fsg);
}
@@ -2916,6 +2914,8 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_gadget *gadget = c->cdev->gadget;
int i;
struct usb_ep *ep;
+ unsigned max_burst;
+ int ret;
fsg->gadget = gadget;
@@ -2939,45 +2939,27 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
ep->driver_data = fsg->common; /* claim the endpoint */
fsg->bulk_out = ep;
- /* Copy descriptors */
- f->descriptors = usb_copy_descriptors(fsg_fs_function);
- if (unlikely(!f->descriptors))
- return -ENOMEM;
-
- if (gadget_is_dualspeed(gadget)) {
- /* Assume endpoint addresses are the same for both speeds */
- fsg_hs_bulk_in_desc.bEndpointAddress =
- fsg_fs_bulk_in_desc.bEndpointAddress;
- fsg_hs_bulk_out_desc.bEndpointAddress =
- fsg_fs_bulk_out_desc.bEndpointAddress;
- f->hs_descriptors = usb_copy_descriptors(fsg_hs_function);
- if (unlikely(!f->hs_descriptors)) {
- usb_free_descriptors(f->descriptors);
- return -ENOMEM;
- }
- }
-
- if (gadget_is_superspeed(gadget)) {
- unsigned max_burst;
+ /* Assume endpoint addresses are the same for both speeds */
+ fsg_hs_bulk_in_desc.bEndpointAddress =
+ fsg_fs_bulk_in_desc.bEndpointAddress;
+ fsg_hs_bulk_out_desc.bEndpointAddress =
+ fsg_fs_bulk_out_desc.bEndpointAddress;
- /* Calculate bMaxBurst, we know packet size is 1024 */
- max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
+ /* Calculate bMaxBurst, we know packet size is 1024 */
+ max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
- fsg_ss_bulk_in_desc.bEndpointAddress =
- fsg_fs_bulk_in_desc.bEndpointAddress;
- fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
+ fsg_ss_bulk_in_desc.bEndpointAddress =
+ fsg_fs_bulk_in_desc.bEndpointAddress;
+ fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
- fsg_ss_bulk_out_desc.bEndpointAddress =
- fsg_fs_bulk_out_desc.bEndpointAddress;
- fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
+ fsg_ss_bulk_out_desc.bEndpointAddress =
+ fsg_fs_bulk_out_desc.bEndpointAddress;
+ fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
- f->ss_descriptors = usb_copy_descriptors(fsg_ss_function);
- if (unlikely(!f->ss_descriptors)) {
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
- return -ENOMEM;
- }
- }
+ ret = usb_assign_descriptors(f, fsg_fs_function, fsg_hs_function,
+ fsg_ss_function);
+ if (ret)
+ goto autoconf_fail;
return 0;
@@ -2986,7 +2968,6 @@ autoconf_fail:
return -ENOTSUPP;
}
-
/****************************** ADD FUNCTION ******************************/
static struct usb_gadget_strings *fsg_strings_array[] = {
diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c
index b265ee8fa5a..263e721c269 100644
--- a/drivers/usb/gadget/f_midi.c
+++ b/drivers/usb/gadget/f_midi.c
@@ -414,8 +414,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
kfree(midi->id);
midi->id = NULL;
- usb_free_descriptors(f->descriptors);
- usb_free_descriptors(f->hs_descriptors);
+ usb_free_all_descriptors(f);
kfree(midi);
}
@@ -882,9 +881,10 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
* both speeds
*/
/* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(midi_function);
- if (!f->descriptors)
+ f->fs_descriptors = usb_copy_descriptors(midi_function);
+ if (!f->fs_descriptors)
goto fail_f_midi;
+
if (gadget_is_dualspeed(c->cdev->gadget)) {
bulk_in_desc.wMaxPacketSize = cpu_to_le16(512);
bulk_out_desc.wMaxPacketSize = cpu_to_le16(512);
diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
index 424fc3d1cc3..326d7e6c297 100644
--- a/drivers/usb/gadget/f_ncm.c
+++ b/drivers/usb/gadget/f_ncm.c
@@ -1208,30 +1208,18 @@ ncm_bind(struct usb_configuration *c, struct usb_function *f)
ncm->notify_req->context = ncm;
ncm->notify_req->complete = ncm_notify_complete;
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(ncm_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)) {
- hs_ncm_in_desc.bEndpointAddress =
- fs_ncm_in_desc.bEndpointAddress;
- hs_ncm_out_desc.bEndpointAddress =
- fs_ncm_out_desc.bEndpointAddress;
- hs_ncm_notify_desc.bEndpointAddress =
- fs_ncm_notify_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(ncm_hs_function);
- if (!f->hs_descriptors)
- goto fail;
- }
+ hs_ncm_in_desc.bEndpointAddress = fs_ncm_in_desc.bEndpointAddress;
+ hs_ncm_out_desc.bEndpointAddress = fs_ncm_out_desc.bEndpointAddress;
+ hs_ncm_notify_desc.bEndpointAddress =
+ fs_ncm_notify_desc.bEndpointAddress;
+ status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function,
+ NULL);
/*
* NOTE: all that is done without knowing or caring about
* the network link ... which is unavailable to this code
@@ -1248,9 +1236,7 @@ ncm_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
- if (f->descriptors)
- usb_free_descriptors(f->descriptors);
-
+ usb_free_all_descriptors(f);
if (ncm->notify_req) {
kfree(ncm->notify_req->buf);
usb_ep_free_request(ncm->notify, ncm->notify_req);
@@ -1276,9 +1262,7 @@ ncm_unbind(struct usb_configuration *c, struct usb_function *f)
DBG(c->cdev, "ncm unbind\n");
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
kfree(ncm->notify_req->buf);
usb_ep_free_request(ncm->notify, ncm->notify_req);
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
index 5f400f66aa9..d74491ad82c 100644
--- a/drivers/usb/gadget/f_obex.c
+++ b/drivers/usb/gadget/f_obex.c
@@ -331,23 +331,19 @@ obex_bind(struct usb_configuration *c, struct usb_function *f)
obex->port.out = ep;
ep->driver_data = cdev; /* claim */
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(fs_function);
-
/* 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)) {
- obex_hs_ep_in_desc.bEndpointAddress =
- obex_fs_ep_in_desc.bEndpointAddress;
- obex_hs_ep_out_desc.bEndpointAddress =
- obex_fs_ep_out_desc.bEndpointAddress;
+ obex_hs_ep_in_desc.bEndpointAddress =
+ obex_fs_ep_in_desc.bEndpointAddress;
+ obex_hs_ep_out_desc.bEndpointAddress =
+ obex_fs_ep_out_desc.bEndpointAddress;
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(hs_function);
- }
+ status = usb_assign_descriptors(f, fs_function, hs_function, NULL);
+ if (status)
+ goto fail;
/* Avoid letting this gadget enumerate until the userspace
* OBEX server is active.
@@ -368,6 +364,7 @@ obex_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
+ usb_free_all_descriptors(f);
/* we might as well release our claims on endpoints */
if (obex->port.out)
obex->port.out->driver_data = NULL;
@@ -382,9 +379,7 @@ fail:
static void
obex_unbind(struct usb_configuration *c, struct usb_function *f)
{
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
kfree(func_to_obex(f));
}
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
index a6c19a486d5..b21ab558b6c 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -515,14 +515,14 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f)
fp->in_ep = ep;
ep->driver_data = fp; /* Claim */
- pn_hs_sink_desc.bEndpointAddress =
- pn_fs_sink_desc.bEndpointAddress;
- pn_hs_source_desc.bEndpointAddress =
- pn_fs_source_desc.bEndpointAddress;
+ pn_hs_sink_desc.bEndpointAddress = pn_fs_sink_desc.bEndpointAddress;
+ pn_hs_source_desc.bEndpointAddress = pn_fs_source_desc.bEndpointAddress;
/* Do not try to bind Phonet twice... */
- fp->function.descriptors = fs_pn_function;
- fp->function.hs_descriptors = hs_pn_function;
+ status = usb_assign_descriptors(f, fs_pn_function, hs_pn_function,
+ NULL);
+ if (status)
+ goto err;
/* Incoming USB requests */
status = -ENOMEM;
@@ -551,7 +551,7 @@ err_req:
for (i = 0; i < phonet_rxq_size && fp->out_reqv[i]; i++)
usb_ep_free_request(fp->out_ep, fp->out_reqv[i]);
err:
-
+ usb_free_all_descriptors(f);
if (fp->out_ep)
fp->out_ep->driver_data = NULL;
if (fp->in_ep)
@@ -573,6 +573,7 @@ pn_unbind(struct usb_configuration *c, struct usb_function *f)
if (fp->out_reqv[i])
usb_ep_free_request(fp->out_ep, fp->out_reqv[i]);
+ usb_free_all_descriptors(f);
kfree(fp);
}
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 7c27626f023..e7c25105bd8 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -722,42 +722,22 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
rndis->notify_req->context = rndis;
rndis->notify_req->complete = rndis_response_complete;
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(eth_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)) {
- hs_in_desc.bEndpointAddress =
- fs_in_desc.bEndpointAddress;
- hs_out_desc.bEndpointAddress =
- fs_out_desc.bEndpointAddress;
- hs_notify_desc.bEndpointAddress =
- fs_notify_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(eth_hs_function);
- if (!f->hs_descriptors)
- goto fail;
- }
+ hs_in_desc.bEndpointAddress = fs_in_desc.bEndpointAddress;
+ hs_out_desc.bEndpointAddress = fs_out_desc.bEndpointAddress;
+ hs_notify_desc.bEndpointAddress = fs_notify_desc.bEndpointAddress;
- if (gadget_is_superspeed(c->cdev->gadget)) {
- ss_in_desc.bEndpointAddress =
- fs_in_desc.bEndpointAddress;
- ss_out_desc.bEndpointAddress =
- fs_out_desc.bEndpointAddress;
- ss_notify_desc.bEndpointAddress =
- fs_notify_desc.bEndpointAddress;
-
- /* copy descriptors, and track endpoint copies */
- f->ss_descriptors = usb_copy_descriptors(eth_ss_function);
- if (!f->ss_descriptors)
- goto fail;
- }
+ ss_in_desc.bEndpointAddress = fs_in_desc.bEndpointAddress;
+ ss_out_desc.bEndpointAddress = fs_out_desc.bEndpointAddress;
+ ss_notify_desc.bEndpointAddress = fs_notify_desc.bEndpointAddress;
+
+ status = usb_assign_descriptors(f, eth_fs_function, eth_hs_function,
+ eth_ss_function);
+ if (status)
+ goto fail;
rndis->port.open = rndis_open;
rndis->port.close = rndis_close;
@@ -788,12 +768,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
- if (gadget_is_superspeed(c->cdev->gadget) && f->ss_descriptors)
- usb_free_descriptors(f->ss_descriptors);
- if (gadget_is_dualspeed(c->cdev->gadget) && f->hs_descriptors)
- usb_free_descriptors(f->hs_descriptors);
- if (f->descriptors)
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
if (rndis->notify_req) {
kfree(rndis->notify_req->buf);
@@ -822,11 +797,7 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f)
rndis_exit();
rndis_string_defs[0].id = 0;
- if (gadget_is_superspeed(c->cdev->gadget))
- usb_free_descriptors(f->ss_descriptors);
- if (gadget_is_dualspeed(c->cdev->gadget))
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
+ usb_free_all_descriptors(f);
kfree(rndis->notify_req->buf);
usb_ep_free_request(rndis->notify, rndis->notify_req);
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index 07197d63d9b..98fa7795df5 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -213,34 +213,20 @@ gser_bind(struct usb_configuration *c, struct usb_function *f)
gser->port.out = ep;
ep->driver_data = cdev; /* claim */
- /* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(gser_fs_function);