|
@@ -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
|
|
@@ -127,6 +129,8 @@
|
|
|
* 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, \
|