Signed-off-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.p...@samsung.com>
---
 drivers/usb/gadget/storage_common.c |  122 +++++++++++++++++++++++++++-------
 1 files changed, 97 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/gadget/storage_common.c 
b/drivers/usb/gadget/storage_common.c
index b5da774..8f3e731 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -153,6 +153,63 @@ static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
        return curlun->filp != NULL;
 }
 
+CONFIGFS_ATTR_STRUCT(fsg_lun);
+
+#define FSG_LUN_ATTR_RW(_name)                                         \
+static struct fsg_lun_attribute fsg_lun_##_name =                      \
+       __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, fsg_lun_show_##_name, \
+                       fsg_lun_store_##_name)
+
+static ssize_t fsg_lun_show_ro(struct fsg_lun *curlun, char *buf);
+static ssize_t fsg_lun_show_nofua(struct fsg_lun *curlun, char *buf);
+static ssize_t fsg_lun_show_file(struct fsg_lun *curlun, char *buf);
+static ssize_t fsg_lun_store_ro(struct fsg_lun *curlun, const char *buf,
+                               size_t count);
+static ssize_t fsg_lun_store_nofua(struct fsg_lun *curlun, const char *buf,
+                                  size_t count);
+static ssize_t fsg_lun_store_file(struct fsg_lun *curlun, const char *buf,
+                                 size_t count);
+static ssize_t fsg_lun_show_removable(struct fsg_lun *curlun, char *buf);
+static ssize_t fsg_lun_store_removable(struct fsg_lun *curlun, const char *buf,
+                                      size_t count);
+
+FSG_LUN_ATTR_RW(ro);
+FSG_LUN_ATTR_RW(nofua);
+FSG_LUN_ATTR_RW(file);
+FSG_LUN_ATTR_RW(removable);
+
+static struct configfs_attribute *fsg_lun_attrs[] = {
+       &fsg_lun_ro.attr,
+       &fsg_lun_nofua.attr,
+       &fsg_lun_file.attr,
+       &fsg_lun_removable.attr,
+       NULL,
+};
+
+static struct fsg_lun *to_fsg_lun(struct config_item *item)
+{
+       return item ? container_of(item, struct fsg_lun, item) : NULL;
+}
+
+CONFIGFS_ATTR_OPS(fsg_lun);
+
+static void fsg_lun_item_release(struct config_item *item)
+{
+       kfree(to_fsg_lun(item));
+}
+
+static struct configfs_item_operations fsg_lun_ops = {
+       .show_attribute         = fsg_lun_attr_show,
+       .store_attribute        = fsg_lun_attr_store,
+       .release                = fsg_lun_item_release,
+};
+
+static struct config_item_type fsg_lun_item_type = {
+       .ct_attrs       = fsg_lun_attrs,
+       .ct_item_ops    = &fsg_lun_ops,
+       .ct_owner       = THIS_MODULE,
+};
+
 /* Big enough to hold our biggest descriptor */
 #define EP0_BUFSIZE    256
 #define DELAYED_STATUS (EP0_BUFSIZE + 999)     /* An impossibly large value */
@@ -430,6 +487,7 @@ static void fsg_lun_close(struct fsg_lun *curlun)
                fput(curlun->filp);
                curlun->filp = NULL;
        }
+       configfs_undepend_item(curlun->item.ci_group->cg_subsys, &curlun->item);
 }
 
 
@@ -445,6 +503,8 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char 
*filename)
        unsigned int                    blkbits;
        unsigned int                    blksize;
 
+       configfs_depend_item(curlun->item.ci_group->cg_subsys, &curlun->item);
+
        /* R/W if we can, R/O if we must */
        ro = curlun->initially_ro;
        if (!ro) {
@@ -528,6 +588,9 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char 
*filename)
 
 out:
        fput(filp);
+       if (rc)
+               configfs_undepend_item(curlun->item.ci_group->cg_subsys,
+                                      &curlun->item);
        return rc;
 }
 
@@ -569,29 +632,21 @@ static void store_cdrom_address(u8 *dest, int msf, u32 
addr)
 /*-------------------------------------------------------------------------*/
 
 
-static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
-                          char *buf)
+static ssize_t fsg_lun_show_ro(struct fsg_lun *curlun, char *buf)
 {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-
        return sprintf(buf, "%d\n", fsg_lun_is_open(curlun)
                                  ? curlun->ro
                                  : curlun->initially_ro);
 }
 
-static ssize_t fsg_show_nofua(struct device *dev, struct device_attribute 
*attr,
-                             char *buf)
+static ssize_t fsg_lun_show_nofua(struct fsg_lun *curlun, char *buf)
 {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-
        return sprintf(buf, "%u\n", curlun->nofua);
 }
 
-static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
-                            char *buf)
+static ssize_t fsg_lun_show_file(struct fsg_lun *curlun, char *buf)
 {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       struct rw_semaphore     *filesem = curlun->filesem;
        char            *p;
        ssize_t         rc;
 
@@ -614,13 +669,11 @@ static ssize_t fsg_show_file(struct device *dev, struct 
device_attribute *attr,
        return rc;
 }
 
-
-static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
-                           const char *buf, size_t count)
+static ssize_t fsg_lun_store_ro(struct fsg_lun *curlun, const char *buf,
+                               size_t count)
 {
        ssize_t         rc;
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       struct rw_semaphore     *filesem = curlun->filesem;
        unsigned        ro;
 
        rc = kstrtouint(buf, 2, &ro);
@@ -645,11 +698,9 @@ static ssize_t fsg_store_ro(struct device *dev, struct 
device_attribute *attr,
        return rc;
 }
 
-static ssize_t fsg_store_nofua(struct device *dev,
-                              struct device_attribute *attr,
-                              const char *buf, size_t count)
+static ssize_t fsg_lun_store_nofua(struct fsg_lun *curlun, const char *buf,
+                                  size_t count)
 {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
        unsigned        nofua;
        int             ret;
 
@@ -666,11 +717,10 @@ static ssize_t fsg_store_nofua(struct device *dev,
        return count;
 }
 
-static ssize_t fsg_store_file(struct device *dev, struct device_attribute 
*attr,
-                             const char *buf, size_t count)
+static ssize_t fsg_lun_store_file(struct fsg_lun *curlun, const char *buf,
+                                 size_t count)
 {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       struct rw_semaphore     *filesem = curlun->filesem;
        int             rc = 0;
 
        if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) {
@@ -697,3 +747,25 @@ static ssize_t fsg_store_file(struct device *dev, struct 
device_attribute *attr,
        up_write(filesem);
        return (rc < 0 ? rc : count);
 }
+
+static ssize_t fsg_lun_show_removable(struct fsg_lun *curlun, char *buf)
+{
+       return sprintf(buf, "%d\n", curlun->removable);
+}
+
+static ssize_t fsg_lun_store_removable(struct fsg_lun *curlun, const char *buf,
+                                      size_t count)
+{
+       if (fsg_lun_is_open(curlun)) {
+               LDBG(curlun, "media type change prevented\n");
+               return -EBUSY;
+       }
+
+       if (buf[0] != '0' && buf[0] != '1')
+               return -EINVAL;
+
+       curlun->removable = buf[0] == '1';
+
+       return count;
+}
+
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to