aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/composite.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/composite.c')
-rw-r--r--drivers/usb/gadget/composite.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 274facf..5f459005 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -678,6 +678,19 @@ int usb_add_config(struct usb_composite_dev *cdev,
status = bind(config);
if (status < 0) {
+ while (!list_empty(&config->functions)) {
+ struct usb_function *f;
+
+ f = list_first_entry(&config->functions,
+ struct usb_function, list);
+ list_del(&f->list);
+ if (f->unbind) {
+ DBG(cdev, "unbind function '%s'/%p\n",
+ f->name, f);
+ f->unbind(config, f);
+ /* may free memory for "f" */
+ }
+ }
list_del(&config->list);
config->cdev = NULL;
} else {
@@ -715,7 +728,7 @@ done:
return status;
}
-static int remove_config(struct usb_composite_dev *cdev,
+static int unbind_config(struct usb_composite_dev *cdev,
struct usb_configuration *config)
{
while (!list_empty(&config->functions)) {
@@ -730,7 +743,6 @@ static int remove_config(struct usb_composite_dev *cdev,
/* may free memory for "f" */
}
}
- list_del(&config->list);
if (config->unbind) {
DBG(cdev, "unbind config '%s'/%p\n", config->label, config);
config->unbind(config);
@@ -751,9 +763,11 @@ int usb_remove_config(struct usb_composite_dev *cdev,
if (cdev->config == config)
reset_config(cdev);
+ list_del(&config->list);
+
spin_unlock_irqrestore(&cdev->lock, flags);
- return remove_config(cdev, config);
+ return unbind_config(cdev, config);
}
/*-------------------------------------------------------------------------*/
@@ -1340,7 +1354,8 @@ composite_unbind(struct usb_gadget *gadget)
struct usb_configuration *c;
c = list_first_entry(&cdev->configs,
struct usb_configuration, list);
- remove_config(cdev, c);
+ list_del(&c->list);
+ unbind_config(cdev, c);
}
if (composite->unbind)
composite->unbind(cdev);