aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget12
-rw-r--r--drivers/usb/gadget/file_storage.c31
-rw-r--r--drivers/usb/gadget/storage_common.c28
3 files changed, 64 insertions, 7 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget b/Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget
index 34034027b13c..d548eaac230a 100644
--- a/Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget
+++ b/Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget
@@ -7,3 +7,15 @@ Description:
7 0 -> resumed 7 0 -> resumed
8 8
9 (_UDC_ is the name of the USB Device Controller driver) 9 (_UDC_ is the name of the USB Device Controller driver)
10
11What: /sys/devices/platform/_UDC_/gadget/gadget-lunX/nofua
12Date: July 2010
13Contact: Andy Shevchenko <andy.shevchenko@gmail.com>
14Description:
15 Show or set the reaction on the FUA (Force Unit Access) bit in
16 the SCSI WRITE(10,12) commands when a gadget in USB Mass
17 Storage mode.
18
19 Possible values are:
20 1 -> ignore the FUA flag
21 0 -> obey the FUA flag
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index d57c09f764d6..88e5ad2bc710 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -93,6 +93,8 @@
93 * removable Default false, boolean for removable media 93 * removable Default false, boolean for removable media
94 * luns=N Default N = number of filenames, number of 94 * luns=N Default N = number of filenames, number of
95 * LUNs to support 95 * LUNs to support
96 * nofua=b[,b...] Default false, booleans for ignore FUA flag
97 * in SCSI WRITE(10,12) commands
96 * stall Default determined according to the type of 98 * stall Default determined according to the type of
97 * USB device controller (usually true), 99 * USB device controller (usually true),
98 * boolean to permit the driver to halt 100 * boolean to permit the driver to halt
@@ -112,12 +114,12 @@
112 * PAGE_CACHE_SIZE) 114 * PAGE_CACHE_SIZE)
113 * 115 *
114 * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro", 116 * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro",
115 * "removable", "luns", "stall", and "cdrom" options are available; default 117 * "removable", "luns", "nofua", "stall", and "cdrom" options are available;
116 * values are used for everything else. 118 * default values are used for everything else.
117 * 119 *
118 * The pathnames of the backing files and the ro settings are available in 120 * The pathnames of the backing files and the ro settings are available in
119 * the attribute files "file" and "ro" in the lun<n> subdirectory of the 121 * the attribute files "file", "nofua", and "ro" in the lun<n> subdirectory of
120 * gadget's sysfs directory. If the "removable" option is set, writing to 122 * the gadget's sysfs directory. If the "removable" option is set, writing to
121 * these files will simulate ejecting/loading the medium (writing an empty 123 * these files will simulate ejecting/loading the medium (writing an empty
122 * line means eject) and adjusting a write-enable tab. Changes to the ro 124 * line means eject) and adjusting a write-enable tab. Changes to the ro
123 * setting are not allowed when the medium is loaded or if CD-ROM emulation 125 * setting are not allowed when the medium is loaded or if CD-ROM emulation
@@ -304,8 +306,10 @@ MODULE_LICENSE("Dual BSD/GPL");
304static struct { 306static struct {
305 char *file[FSG_MAX_LUNS]; 307 char *file[FSG_MAX_LUNS];
306 int ro[FSG_MAX_LUNS]; 308 int ro[FSG_MAX_LUNS];
309 int nofua[FSG_MAX_LUNS];
307 unsigned int num_filenames; 310 unsigned int num_filenames;
308 unsigned int num_ros; 311 unsigned int num_ros;
312 unsigned int num_nofuas;
309 unsigned int nluns; 313 unsigned int nluns;
310 314
311 int removable; 315 int removable;
@@ -345,6 +349,10 @@ MODULE_PARM_DESC(file, "names of backing files or devices");
345module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); 349module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO);
346MODULE_PARM_DESC(ro, "true to force read-only"); 350MODULE_PARM_DESC(ro, "true to force read-only");
347 351
352module_param_array_named(nofua, mod_data.nofua, bool, &mod_data.num_nofuas,
353 S_IRUGO);
354MODULE_PARM_DESC(nofua, "true to ignore SCSI WRITE(10,12) FUA bit");
355
348module_param_named(luns, mod_data.nluns, uint, S_IRUGO); 356module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
349MODULE_PARM_DESC(luns, "number of LUNs"); 357MODULE_PARM_DESC(luns, "number of LUNs");
350 358
@@ -1279,7 +1287,8 @@ static int do_write(struct fsg_dev *fsg)
1279 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1287 curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
1280 return -EINVAL; 1288 return -EINVAL;
1281 } 1289 }
1282 if (fsg->cmnd[1] & 0x08) { // FUA 1290 /* FUA */
1291 if (!curlun->nofua && (fsg->cmnd[1] & 0x08)) {
1283 spin_lock(&curlun->filp->f_lock); 1292 spin_lock(&curlun->filp->f_lock);
1284 curlun->filp->f_flags |= O_DSYNC; 1293 curlun->filp->f_flags |= O_DSYNC;
1285 spin_unlock(&curlun->filp->f_lock); 1294 spin_unlock(&curlun->filp->f_lock);
@@ -3133,6 +3142,7 @@ static int fsg_main_thread(void *fsg_)
3133 3142
3134/* The write permissions and store_xxx pointers are set in fsg_bind() */ 3143/* The write permissions and store_xxx pointers are set in fsg_bind() */
3135static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL); 3144static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL);
3145static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, NULL);
3136static DEVICE_ATTR(file, 0444, fsg_show_file, NULL); 3146static DEVICE_ATTR(file, 0444, fsg_show_file, NULL);
3137 3147
3138 3148
@@ -3362,6 +3372,10 @@ static int __ref fsg_bind(struct usb_gadget *gadget)
3362 } 3372 }
3363 } 3373 }
3364 3374
3375 /* Only for removable media? */
3376 dev_attr_nofua.attr.mode = 0644;
3377 dev_attr_nofua.store = fsg_store_nofua;
3378
3365 /* Find out how many LUNs there should be */ 3379 /* Find out how many LUNs there should be */
3366 i = mod_data.nluns; 3380 i = mod_data.nluns;
3367 if (i == 0) 3381 if (i == 0)
@@ -3387,6 +3401,7 @@ static int __ref fsg_bind(struct usb_gadget *gadget)
3387 curlun->ro = mod_data.cdrom || mod_data.ro[i]; 3401 curlun->ro = mod_data.cdrom || mod_data.ro[i];
3388 curlun->initially_ro = curlun->ro; 3402 curlun->initially_ro = curlun->ro;
3389 curlun->removable = mod_data.removable; 3403 curlun->removable = mod_data.removable;
3404 curlun->nofua = mod_data.nofua[i];
3390 curlun->dev.release = lun_release; 3405 curlun->dev.release = lun_release;
3391 curlun->dev.parent = &gadget->dev; 3406 curlun->dev.parent = &gadget->dev;
3392 curlun->dev.driver = &fsg_driver.driver; 3407 curlun->dev.driver = &fsg_driver.driver;
@@ -3401,6 +3416,8 @@ static int __ref fsg_bind(struct usb_gadget *gadget)
3401 if ((rc = device_create_file(&curlun->dev, 3416 if ((rc = device_create_file(&curlun->dev,
3402 &dev_attr_ro)) != 0 || 3417 &dev_attr_ro)) != 0 ||
3403 (rc = device_create_file(&curlun->dev, 3418 (rc = device_create_file(&curlun->dev,
3419 &dev_attr_nofua)) != 0 ||
3420 (rc = device_create_file(&curlun->dev,
3404 &dev_attr_file)) != 0) { 3421 &dev_attr_file)) != 0) {
3405 device_unregister(&curlun->dev); 3422 device_unregister(&curlun->dev);
3406 goto out; 3423 goto out;
@@ -3525,8 +3542,8 @@ static int __ref fsg_bind(struct usb_gadget *gadget)
3525 if (IS_ERR(p)) 3542 if (IS_ERR(p))
3526 p = NULL; 3543 p = NULL;
3527 } 3544 }
3528 LINFO(curlun, "ro=%d, file: %s\n", 3545 LINFO(curlun, "ro=%d, nofua=%d, file: %s\n",
3529 curlun->ro, (p ? p : "(error)")); 3546 curlun->ro, curlun->nofua, (p ? p : "(error)"));
3530 } 3547 }
3531 } 3548 }
3532 kfree(pathbuf); 3549 kfree(pathbuf);
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 3bbddab72e57..484acfb1a7c5 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -284,6 +284,7 @@ struct fsg_lun {
284 unsigned int prevent_medium_removal:1; 284 unsigned int prevent_medium_removal:1;
285 unsigned int registered:1; 285 unsigned int registered:1;
286 unsigned int info_valid:1; 286 unsigned int info_valid:1;
287 unsigned int nofua:1;
287 288
288 u32 sense_data; 289 u32 sense_data;
289 u32 sense_data_info; 290 u32 sense_data_info;
@@ -714,6 +715,14 @@ static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
714 : curlun->initially_ro); 715 : curlun->initially_ro);
715} 716}
716 717
718static ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
719 char *buf)
720{
721 struct fsg_lun *curlun = fsg_lun_from_dev(dev);
722
723 return sprintf(buf, "%u\n", curlun->nofua);
724}
725
717static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr, 726static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
718 char *buf) 727 char *buf)
719{ 728{
@@ -770,6 +779,25 @@ static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
770 return rc; 779 return rc;
771} 780}
772 781
782static ssize_t fsg_store_nofua(struct device *dev,
783 struct device_attribute *attr,
784 const char *buf, size_t count)
785{
786 struct fsg_lun *curlun = fsg_lun_from_dev(dev);
787 unsigned long nofua;
788
789 if (strict_strtoul(buf, 2, &nofua))
790 return -EINVAL;
791
792 /* Sync data when switching from async mode to sync */
793 if (!nofua && curlun->nofua)
794 fsg_lun_fsync_sub(curlun);
795
796 curlun->nofua = nofua;
797
798 return count;
799}
800
773static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr, 801static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
774 const char *buf, size_t count) 802 const char *buf, size_t count)
775{ 803{