usb: gadget: android: Don't allow changing the functions list if enabled
Benoit Goby [Sat, 10 Dec 2011 02:05:00 +0000 (18:05 -0800)]
cherry-pick I3ad39b420ce79a8602a7eca1daac1f56b30bad5c from
https://android.googlesource.com/kernel/common.git

Change-Id: Icb16df8b5227e471a202c8207ecfbb1b8414a7c6
Signed-off-by: Benoit Goby <benoit@android.com>
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/75464
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Rakesh Bodla <rbodla@nvidia.com>

drivers/usb/gadget/android.c

index 034672f..c643fda 100644 (file)
@@ -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;                                                      \
@@ -1137,6 +1156,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) {