aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorBenoit Goby <benoit@android.com>2012-05-15 20:44:33 -0700
committerBenoit Goby <benoit@android.com>2012-05-21 18:55:25 -0700
commit8b5855f54d63b3f05b8efe96ffa00ba109a45dcf (patch)
treeadf9a85fda67c2393c988e4a96511abde51829b5 /drivers/usb/gadget
parent605a493298348eb2e9e2efc8a6c1b0297c13fe46 (diff)
downloadkernel_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.c10
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);