[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1302636896-12717-6-git-send-email-bigeasy@linutronix.de>
Date: Tue, 12 Apr 2011 21:34:56 +0200
From: Sebastian Andrzej Siewior <bigeasy@...utronix.de>
To: Tatyana Brokhman <tlinder@...eaurora.org>
Cc: gregkh@...e.de, linux-arm-msm@...r.kernel.org, balbi@...com,
ablay@...eaurora.org, linux-usb@...r.kernel.org,
linux-kernel@...r.kernel.org,
Sebastian Andrzej Siewior <bigeasy@...utronix.de>
Subject: [PATCH 5/5] usb/gadget: don't auto-create SS descriptors if HS are avilable
Instead every gadget driver has to requests this to be done for him. A
gadget driver may use usb_create_ss_descriptors() if it wants a
descriptor based on its HS descriptor.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@...utronix.de>
---
drivers/usb/gadget/composite.c | 29 ++++++++++++++++-------------
drivers/usb/gadget/f_acm.c | 5 ++---
drivers/usb/gadget/f_audio.c | 4 ++--
drivers/usb/gadget/f_ecm.c | 11 ++++-------
drivers/usb/gadget/f_eem.c | 10 ++++------
drivers/usb/gadget/f_hid.c | 9 +++------
drivers/usb/gadget/f_loopback.c | 2 ++
drivers/usb/gadget/f_mass_storage.c | 9 +++++----
drivers/usb/gadget/f_ncm.c | 10 ++++------
drivers/usb/gadget/f_obex.c | 5 ++---
drivers/usb/gadget/f_phonet.c | 3 +++
drivers/usb/gadget/f_rndis.c | 14 ++++----------
drivers/usb/gadget/f_serial.c | 5 ++---
drivers/usb/gadget/f_sourcesink.c | 2 ++
drivers/usb/gadget/f_subset.c | 5 ++---
drivers/usb/gadget/f_uvc.c | 5 ++---
include/linux/usb/composite.h | 9 ---------
17 files changed, 59 insertions(+), 78 deletions(-)
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index ac30e2f..c3c6cb1 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -187,7 +187,6 @@ void usb_create_ss_descriptors(struct usb_function *f)
* vector is NULL
*/
*tmp = NULL;
- f->ss_desc_allocated = true;
#endif
}
@@ -304,6 +303,21 @@ ep_found:
}
/**
+ * usb_free_all_descriptors - free all allocated descriptors
+ * @f: function driver
+ *
+ * Simply remove all three usb descriptors which were dynamically allocated.
+ */
+void usb_free_all_descriptors(struct usb_function *f)
+{
+ usb_free_descriptors(f->ss_descriptors);
+ usb_free_descriptors(f->hs_descriptors);
+ usb_free_descriptors(f->descriptors);
+
+ f->ss_descriptors = f->hs_descriptors = f->descriptors = NULL;
+}
+
+/**
* usb_add_function() - add a function to a configuration
* @config: the configuration
* @function: the function being added
@@ -339,14 +353,6 @@ int usb_add_function(struct usb_configuration *config,
list_del(&function->list);
function->config = NULL;
}
- /*
- * Add SS descriptors if there are any. This has to be done
- * after the bind since we need the hs_descriptors to be set in
- * usb_function and some of the FDs does it in the bind.
- */
- if ((gadget_is_superspeed(config->cdev->gadget)) &&
- (!function->ss_not_capable) && (!function->ss_descriptors))
- create_ss_descriptors(function);
} else
value = 0;
@@ -1437,11 +1443,8 @@ composite_unbind(struct usb_gadget *gadget)
DBG(cdev, "unbind function '%s'/%p\n",
f->name, f);
f->unbind(c, f);
+ /* may free memory for "f" */
}
- /* Free memory allocated for ss descriptors */
- if (f->ss_desc_allocated && f->ss_descriptors)
- usb_free_descriptors(f->ss_descriptors);
- /* may free memory for "f" */
}
list_del(&c->list);
if (c->unbind) {
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index 3f88493..aa2ceb4 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -642,6 +642,7 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
/* copy descriptors */
f->hs_descriptors = usb_copy_descriptors(acm_hs_function);
+ usb_create_ss_descriptors(f);
}
DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n",
@@ -673,9 +674,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);
- 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_audio.c b/drivers/usb/gadget/f_audio.c
index fdaa0a5..b9c054d 100644
--- a/drivers/usb/gadget/f_audio.c
+++ b/drivers/usb/gadget/f_audio.c
@@ -689,6 +689,7 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)
if (gadget_is_dualspeed(c->cdev->gadget)) {
c->highspeed = true;
f->hs_descriptors = usb_copy_descriptors(f_audio_desc);
+ usb_create_ss_descriptors(f);
} else
f->descriptors = usb_copy_descriptors(f_audio_desc);
@@ -704,8 +705,7 @@ f_audio_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_audio *audio = func_to_audio(f);
- usb_free_descriptors(f->descriptors);
- usb_free_descriptors(f->hs_descriptors);
+ usb_free_all_descriptors(f);
kfree(audio);
}
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index ddedbc83..3899036 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -675,7 +675,8 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(ecm_hs_function);
- if (!f->hs_descriptors)
+ usb_create_ss_descriptors(f);
+ if (!f->hs_descriptors || !f->ss_descriptors)
goto fail;
}
@@ -694,8 +695,7 @@ ecm_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 (ecm->notify_req) {
kfree(ecm->notify_req->buf);
@@ -722,10 +722,7 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f)
DBG(c->cdev, "ecm 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(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 d28e61f..5a09eef 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -261,7 +261,8 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(eem_hs_function);
- if (!f->hs_descriptors)
+ usb_create_ss_descriptors(f);
+ if (!f->hs_descriptors || !f->ss_descriptors)
goto fail;
}
@@ -271,8 +272,7 @@ eem_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);
/* we might as well release our claims on endpoints */
if (eem->port.out_ep->desc)
@@ -292,9 +292,7 @@ eem_unbind(struct usb_configuration *c, struct usb_function *f)
DBG(c->cdev, "eem 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(eem);
}
diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c
index 403a48b..642a6bc 100644
--- a/drivers/usb/gadget/f_hid.c
+++ b/drivers/usb/gadget/f_hid.c
@@ -503,7 +503,7 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
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)
+ if (!f->hs_descriptors || !f->ss_descriptors)
goto fail;
}
@@ -531,9 +531,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;
}
@@ -551,8 +549,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
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->set_report_buff);
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 3756326..622a0df 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -173,6 +173,7 @@ autoconf_fail:
hs_loop_sink_desc.bEndpointAddress =
fs_loop_sink_desc.bEndpointAddress;
f->hs_descriptors = hs_loopback_descs;
+ usb_create_ss_descriptors(f);
}
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
@@ -184,6 +185,7 @@ autoconf_fail:
static void
loopback_unbind(struct usb_configuration *c, struct usb_function *f)
{
+ usb_free_descriptors(f->ss_descriptors);
kfree(func_to_loop(f));
}
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index a688d04..a2da410 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2989,8 +2989,8 @@ 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_all_descriptors(f);
+
kfree(fsg);
}
@@ -3035,8 +3035,9 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
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);
+ usb_create_ss_descriptors(f);
+ if (!f->hs_descriptors || !f->ss_descriptors) {
+ usb_free_all_descriptors(f);
return -ENOMEM;
}
}
diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
index 681e5fc..f9ee06b 100644
--- a/drivers/usb/gadget/f_ncm.c
+++ b/drivers/usb/gadget/f_ncm.c
@@ -1237,7 +1237,8 @@ ncm_bind(struct usb_configuration *c, struct usb_function *f)
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(ncm_hs_function);
- if (!f->hs_descriptors)
+ usb_create_ss_descriptors(f);
+ if (!f->hs_descriptors || !f->ss_descriptors)
goto fail;
}
@@ -1257,8 +1258,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);
@@ -1285,9 +1285,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 394502a..2aa8366 100644
--- a/drivers/usb/gadget/f_obex.c
+++ b/drivers/usb/gadget/f_obex.c
@@ -355,6 +355,7 @@ obex_bind(struct usb_configuration *c, struct usb_function *f)
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(hs_function);
+ usb_create_ss_descriptors(f);
}
/* Avoid letting this gadget enumerate until the userspace
@@ -390,9 +391,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 0d6d260..47310d4 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -532,6 +532,7 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f)
/* Do not try to bind Phonet twice... */
fp->function.descriptors = fs_pn_function;
fp->function.hs_descriptors = hs_pn_function;
+ usb_create_ss_descriptors(f);
/* Incoming USB requests */
status = -ENOMEM;
@@ -557,6 +558,7 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
err:
+ usb_free_descriptors(f->ss_descriptors);
if (fp->out_ep)
fp->out_ep->driver_data = NULL;
if (fp->in_ep)
@@ -578,6 +580,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_descriptors(f->ss_descriptors);
kfree(fp);
}
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 775a97d..46c859d 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -671,8 +671,8 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(eth_hs_function);
-
- if (!f->hs_descriptors)
+ usb_create_ss_descriptors(f);
+ if (!f->hs_descriptors || !f->ss_descriptors)
goto fail;
}
@@ -706,10 +706,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
- 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);
@@ -737,10 +734,7 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f)
rndis_deregister(rndis->config);
rndis_exit();
- 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 91fdf79..d9cb150 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -200,6 +200,7 @@ gser_bind(struct usb_configuration *c, struct usb_function *f)
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(gser_hs_function);
+ usb_create_ss_descriptors(f);
}
DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n",
@@ -223,9 +224,7 @@ fail:
static void
gser_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_gser(f));
}
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index caf2f95..bf1c595 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -185,6 +185,7 @@ autoconf_fail:
hs_sink_desc.bEndpointAddress =
fs_sink_desc.bEndpointAddress;
f->hs_descriptors = hs_source_sink_descs;
+ usb_create_ss_descriptors(f);
}
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
@@ -196,6 +197,7 @@ autoconf_fail:
static void
sourcesink_unbind(struct usb_configuration *c, struct usb_function *f)
{
+ usb_free_descriptors(f->ss_descriptors);
kfree(func_to_ss(f));
}
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index 93bf676..ada5b76 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -303,6 +303,7 @@ 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);
+ usb_create_ss_descriptors(f);
}
/* NOTE: all that is done without knowing or caring about
@@ -330,9 +331,7 @@ fail:
static void
geth_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);
geth_string_defs[1].s = NULL;
kfree(func_to_geth(f));
}
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index df74d03..f8c7673 100644
--- a/drivers/usb/gadget/f_uvc.c
+++ b/drivers/usb/gadget/f_uvc.c
@@ -481,9 +481,7 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f)
kfree(uvc->control_buf);
}
- kfree(f->descriptors);
- kfree(f->hs_descriptors);
-
+ usb_free_all_descriptors(f);
kfree(uvc);
}
@@ -530,6 +528,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
/* Copy descriptors. */
f->descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL);
f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH);
+ usb_create_ss_descriptors(f);
/* Preallocate control endpoint request. */
uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL);
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index e9fa7d8..9f2254c 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -57,12 +57,6 @@ struct usb_configuration;
* default values while working in superspeed mode. If this
* pointer is null after initiation, the function will not
* be available at super speed.
- * @ss_not_capable: This flag is used by the FD to indicate if
- * this function is SS capble. Meaning: if SS descriptors
- * weren't supplied by the FD, and the flag is set ss
- * descriptors will NOT be automatically generated
- * @ss_desc_allocated: This flag indicates whether the ss descriptors were
- * dynamically allocated (and needs to be released).
* @config: assigned when @usb_add_function() is called; this is the
* configuration with which this function is associated.
* @bind: Before the gadget can register, all of its functions bind() to the
@@ -116,9 +110,6 @@ struct usb_function {
struct usb_descriptor_header **hs_descriptors;
struct usb_descriptor_header **ss_descriptors;
- unsigned ss_desc_allocated:1;
- unsigned ss_not_capable:1;
-
struct usb_configuration *config;
/* REVISIT: bind() functions can be marked __init, which
--
1.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists