usb: gadget: storage_common: pass filesem to fsg_store_cdrom
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>
Tue, 15 Oct 2013 06:33:13 +0000 (08:33 +0200)
committerFelipe Balbi <balbi@ti.com>
Tue, 15 Oct 2013 11:52:08 +0000 (06:52 -0500)
If cdrom flag is set ro flag is implied. Try setting the ro first, and
only if it succeeds set the cdrom flag.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/f_mass_storage.c
drivers/usb/gadget/storage_common.c
drivers/usb/gadget/storage_common.h

index 6e5a6daf1a12c8582954133fb07ee6e8311a9ac8..6b5f45144cdfa881927a3d63882e7891ceac0d53 100644 (file)
@@ -3281,7 +3281,12 @@ static ssize_t fsg_lun_opts_cdrom_show(struct fsg_lun_opts *opts, char *page)
 static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts,
                                       const char *page, size_t len)
 {
-       return fsg_store_cdrom(opts->lun, page, len);
+       struct fsg_opts *fsg_opts;
+
+       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+
+       return fsg_store_cdrom(opts->lun, &fsg_opts->common->filesem, page,
+                              len);
 }
 
 static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom =
index 8bd5f2d838db11f5fd6ffa0f14f02395185d6dc1..ec20a1f50c2d702e56f6e6a79f03485607a36189 100644 (file)
@@ -371,6 +371,23 @@ ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf)
 }
 EXPORT_SYMBOL(fsg_show_removable);
 
+/*
+ * The caller must hold fsg->filesem for reading when calling this function.
+ */
+static ssize_t _fsg_store_ro(struct fsg_lun *curlun, bool ro)
+{
+       if (fsg_lun_is_open(curlun)) {
+               LDBG(curlun, "read-only status change prevented\n");
+               return -EBUSY;
+       }
+
+       curlun->ro = ro;
+       curlun->initially_ro = ro;
+       LDBG(curlun, "read-only status set to %d\n", curlun->ro);
+
+       return 0;
+}
+
 ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
                     const char *buf, size_t count)
 {
@@ -386,16 +403,11 @@ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
         * backing file is closed.
         */
        down_read(filesem);
-       if (fsg_lun_is_open(curlun)) {
-               LDBG(curlun, "read-only status change prevented\n");
-               rc = -EBUSY;
-       } else {
-               curlun->ro = ro;
-               curlun->initially_ro = ro;
-               LDBG(curlun, "read-only status set to %d\n", curlun->ro);
+       rc = _fsg_store_ro(curlun, ro);
+       if (!rc)
                rc = count;
-       }
        up_read(filesem);
+
        return rc;
 }
 EXPORT_SYMBOL(fsg_store_ro);
@@ -450,7 +462,8 @@ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
 }
 EXPORT_SYMBOL(fsg_store_file);
 
-ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count)
+ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                       const char *buf, size_t count)
 {
        bool            cdrom;
        int             ret;
@@ -459,9 +472,16 @@ ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count)
        if (ret)
                return ret;
 
-       curlun->cdrom = cdrom;
+       down_read(filesem);
+       ret = cdrom ? _fsg_store_ro(curlun, true) : 0;
 
-       return count;
+       if (!ret) {
+               curlun->cdrom = cdrom;
+               ret = count;
+       }
+       up_read(filesem);
+
+       return ret;
 }
 EXPORT_SYMBOL(fsg_store_cdrom);
 
index e0f7aa69c7ed2cf137f7513c6cf9cfc62f419b19..c74c2fdbd56eda5683a13995a96b6221711c30ef 100644 (file)
@@ -221,7 +221,8 @@ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
 ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count);
 ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
                       const char *buf, size_t count);
-ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count);
+ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                       const char *buf, size_t count);
 ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
                            size_t count);