usb: gadget: mass_storage: optional SCSI WRITE FUA bit
authorMichal Nazarewicz <m.nazarewicz@samsung.com>
Thu, 12 Aug 2010 15:43:51 +0000 (17:43 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 22 Oct 2010 17:21:22 +0000 (10:21 -0700)
The nofua parameter (optionally ignore SCSI WRITE FUA) was added
to the File Storage Gadget some time ago.  This patch adds the
same functionality to the Mass Storage Function.

Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Cc: Andy Shevchenko <ext-andriy.shevchenko@nokia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/gadget/f_mass_storage.c

index 32cce029f65c8ea366d1789e54067948fea6f509..44e5ffed5c08506eef598f7df64bae6b644e5e35 100644 (file)
@@ -73,6 +73,8 @@
  *                             being removable.
  *     ->cdrom         Flag specifying that LUN shall be reported as
  *                             being a CD-ROM.
+ *     ->nofua         Flag specifying that FUA flag in SCSI WRITE(10,12)
+ *                             commands for this LUN shall be ignored.
  *
  *     lun_name_format A printf-like format for names of the LUN
  *                             devices.  This determines how the
  *                     Default true, boolean for removable media.
  *     cdrom=b[,b...]  Default false, boolean for whether to emulate
  *                             a CD-ROM drive.
+ *     nofua=b[,b...]  Default false, booleans for ignore FUA flag
+ *                             in SCSI WRITE(10,12) commands
  *     luns=N          Default N = number of filenames, number of
  *                             LUNs to support.
  *     stall           Default determined according to the type of
@@ -409,6 +413,7 @@ struct fsg_config {
                char ro;
                char removable;
                char cdrom;
+               char nofua;
        } luns[FSG_MAX_LUNS];
 
        const char              *lun_name_format;
@@ -887,7 +892,7 @@ static int do_write(struct fsg_common *common)
                        curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
                        return -EINVAL;
                }
-               if (common->cmnd[1] & 0x08) {   /* FUA */
+               if (!curlun->nofua && (common->cmnd[1] & 0x08)) { /* FUA */
                        spin_lock(&curlun->filp->f_lock);
                        curlun->filp->f_flags |= O_SYNC;
                        spin_unlock(&curlun->filp->f_lock);
@@ -2662,6 +2667,7 @@ static int fsg_main_thread(void *common_)
 
 /* Write permission is checked per LUN in store_*() functions. */
 static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
+static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua);
 static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
 
 
@@ -2766,6 +2772,9 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
                if (rc)
                        goto error_luns;
                rc = device_create_file(&curlun->dev, &dev_attr_file);
+               if (rc)
+                       goto error_luns;
+               rc = device_create_file(&curlun->dev, &dev_attr_nofua);
                if (rc)
                        goto error_luns;
 
@@ -2911,6 +2920,7 @@ static void fsg_common_release(struct kref *ref)
 
                /* In error recovery common->nluns may be zero. */
                for (; i; --i, ++lun) {
+                       device_remove_file(&lun->dev, &dev_attr_nofua);
                        device_remove_file(&lun->dev, &dev_attr_ro);
                        device_remove_file(&lun->dev, &dev_attr_file);
                        fsg_lun_close(lun);
@@ -3069,8 +3079,10 @@ struct fsg_module_parameters {
        int             ro[FSG_MAX_LUNS];
        int             removable[FSG_MAX_LUNS];
        int             cdrom[FSG_MAX_LUNS];
+       int             nofua[FSG_MAX_LUNS];
 
        unsigned int    file_count, ro_count, removable_count, cdrom_count;
+       unsigned int    nofua_count;
        unsigned int    luns;   /* nluns */
        int             stall;  /* can_stall */
 };
@@ -3096,6 +3108,8 @@ struct fsg_module_parameters {
                                "true to simulate removable media");    \
        _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool,            \
                                "true to simulate CD-ROM instead of disk"); \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool,            \
+                               "true to ignore SCSI WRITE(10,12) FUA bit"); \
        _FSG_MODULE_PARAM(prefix, params, luns, uint,                   \
                          "number of LUNs");                            \
        _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \