diff options
author | Benoit Goby <benoit@android.com> | 2012-05-15 20:44:33 -0700 |
---|---|---|
committer | Benoit Goby <benoit@android.com> | 2012-05-21 18:55:25 -0700 |
commit | 8b5855f54d63b3f05b8efe96ffa00ba109a45dcf (patch) | |
tree | adf9a85fda67c2393c988e4a96511abde51829b5 /drivers/usb/gadget | |
parent | 605a493298348eb2e9e2efc8a6c1b0297c13fe46 (diff) | |
download | kernel_samsung_aries-8b5855f54d63b3f05b8efe96ffa00ba109a45dcf.zip kernel_samsung_aries-8b5855f54d63b3f05b8efe96ffa00ba109a45dcf.tar.gz kernel_samsung_aries-8b5855f54d63b3f05b8efe96ffa00ba109a45dcf.tar.bz2 |
usb: gadget: composite: Fix corruption when changing configuration
Remove the config from the configs list before releasing the spinlock.
Otherwise the other cpu might be processing a SET_CONFIGURATION that
will switch to the configuration that is being released.
Bug: 6521576
Change-Id: Id4da0d0e18ead63e20cb236cd1d3e8e6d116acce
Signed-off-by: Benoit Goby <benoit@android.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/composite.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index dc06da6..1d88a80 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -564,7 +564,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)) { @@ -579,7 +579,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); @@ -598,9 +597,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); } /*-------------------------------------------------------------------------*/ @@ -1084,7 +1085,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); |