From dc1b6340394ef744e210247ab786df66639f5a33 Mon Sep 17 00:00:00 2001 From: Benoit Goby Date: Fri, 9 Dec 2011 18:05:00 -0800 Subject: [PATCH] usb: gadget: android: Don't allow changing the functions list if enabled Change-Id: I3ad39b420ce79a8602a7eca1daac1f56b30bad5c Signed-off-by: Benoit Goby --- drivers/usb/gadget/android.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c index 2b7631052ea7..00a446bce3f6 100644 --- a/drivers/usb/gadget/android.c +++ b/drivers/usb/gadget/android.c @@ -100,6 +100,7 @@ struct android_dev { struct device *dev; bool enabled; + struct mutex mutex; bool connected; bool sw_connected; struct work_struct work; @@ -774,8 +775,13 @@ functions_show(struct device *pdev, struct device_attribute *attr, char *buf) struct android_usb_function *f; char *buff = buf; + mutex_lock(&dev->mutex); + list_for_each_entry(f, &dev->enabled_functions, enabled_list) buff += sprintf(buff, "%s,", f->name); + + mutex_unlock(&dev->mutex); + if (buff != buf) *(buff-1) = '\n'; return buff - buf; @@ -790,6 +796,13 @@ functions_store(struct device *pdev, struct device_attribute *attr, char buf[256], *b; int err; + mutex_lock(&dev->mutex); + + if (dev->enabled) { + mutex_unlock(&dev->mutex); + return -EBUSY; + } + INIT_LIST_HEAD(&dev->enabled_functions); strncpy(buf, buff, sizeof(buf)); @@ -804,6 +817,8 @@ functions_store(struct device *pdev, struct device_attribute *attr, } } + mutex_unlock(&dev->mutex); + return size; } @@ -821,6 +836,8 @@ static ssize_t enable_store(struct device *pdev, struct device_attribute *attr, struct usb_composite_dev *cdev = dev->cdev; int enabled = 0; + mutex_lock(&dev->mutex); + sscanf(buff, "%d", &enabled); if (enabled && !dev->enabled) { cdev->next_string_id = 0; @@ -845,6 +862,8 @@ static ssize_t enable_store(struct device *pdev, struct device_attribute *attr, pr_err("android_usb: already %s\n", dev->enabled ? "enabled" : "disabled"); } + + mutex_unlock(&dev->mutex); return size; } @@ -878,9 +897,9 @@ field ## _show(struct device *dev, struct device_attribute *attr, \ } \ static ssize_t \ field ## _store(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t size) \ + const char *buf, size_t size) \ { \ - int value; \ + int value; \ if (sscanf(buf, format_string, &value) == 1) { \ device_desc.field = value; \ return size; \ @@ -898,10 +917,10 @@ field ## _show(struct device *dev, struct device_attribute *attr, \ } \ static ssize_t \ field ## _store(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t size) \ + const char *buf, size_t size) \ { \ if (size >= sizeof(buffer)) return -EINVAL; \ - if (sscanf(buf, "%s", buffer) == 1) { \ + if (sscanf(buf, "%s", buffer) == 1) { \ return size; \ } \ return -1; \ @@ -1136,6 +1155,7 @@ static int __init init(void) dev->functions = supported_functions; INIT_LIST_HEAD(&dev->enabled_functions); INIT_WORK(&dev->work, android_work); + mutex_init(&dev->mutex); err = android_create_device(dev); if (err) { -- 2.34.1