Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 303883
b: refs/heads/master
c: 51cce6f
h: refs/heads/master
i:
  303881: 5c3c3f5
  303879: e019ea2
v: v3
  • Loading branch information
Benoit Goby authored and Greg Kroah-Hartman committed May 10, 2012
1 parent a2b648b commit f0f3dbe
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 56d95f3174450d22a3b8d936bea2cb414262ce8f
refs/heads/master: 51cce6fc155c4d7eea2ff975ee7c82b89332c6d9
68 changes: 48 additions & 20 deletions trunk/drivers/usb/gadget/composite.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,53 @@ int usb_add_config(struct usb_composite_dev *cdev,
return status;
}

static void remove_config(struct usb_composite_dev *cdev,
struct usb_configuration *config)
{
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);
if (config->unbind) {
DBG(cdev, "unbind config '%s'/%p\n", config->label, config);
config->unbind(config);
/* may free memory for "c" */
}
}

/**
* usb_remove_config() - remove a configuration from a device.
* @cdev: wraps the USB gadget
* @config: the configuration
*
* Drivers must call usb_gadget_disconnect before calling this function
* to disconnect the device from the host and make sure the host will not
* try to enumerate the device while we are changing the config list.
*/
void usb_remove_config(struct usb_composite_dev *cdev,
struct usb_configuration *config)
{
unsigned long flags;

spin_lock_irqsave(&cdev->lock, flags);

if (cdev->config == config)
reset_config(cdev);

spin_unlock_irqrestore(&cdev->lock, flags);

remove_config(cdev, config);
}

/*-------------------------------------------------------------------------*/

/* We support strings in multiple languages ... string descriptor zero
Expand Down Expand Up @@ -1341,28 +1388,9 @@ composite_unbind(struct usb_gadget *gadget)

while (!list_empty(&cdev->configs)) {
struct usb_configuration *c;

c = list_first_entry(&cdev->configs,
struct usb_configuration, list);
while (!list_empty(&c->functions)) {
struct usb_function *f;

f = list_first_entry(&c->functions,
struct usb_function, list);
list_del(&f->list);
if (f->unbind) {
DBG(cdev, "unbind function '%s'/%p\n",
f->name, f);
f->unbind(c, f);
/* may free memory for "f" */
}
}
list_del(&c->list);
if (c->unbind) {
DBG(cdev, "unbind config '%s'/%p\n", c->label, c);
c->unbind(c);
/* may free memory for "c" */
}
remove_config(cdev, c);
}
if (composite->unbind)
composite->unbind(cdev);
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/usb/composite.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ int usb_add_config(struct usb_composite_dev *,
struct usb_configuration *,
int (*)(struct usb_configuration *));

void usb_remove_config(struct usb_composite_dev *,
struct usb_configuration *);

/**
* struct usb_composite_driver - groups configurations into a gadget
* @name: For diagnostics, identifies the driver.
Expand Down

0 comments on commit f0f3dbe

Please sign in to comment.