Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 208047
b: refs/heads/master
c: a93917d
h: refs/heads/master
i:
  208045: 482ec5e
  208043: 14ff108
  208039: 0a0840e
  208031: f99281b
v: v3
  • Loading branch information
Andy Shevchenko authored and Greg Kroah-Hartman committed Aug 10, 2010
1 parent 20352ec commit 6f4ced7
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8156d158efa6370a8183f47327f122edbb4f2cb6
refs/heads/master: a93917d39fc388c4761d2530af82513e2d3bf9f6
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,15 @@ Description:
0 -> resumed

(_UDC_ is the name of the USB Device Controller driver)

What: /sys/devices/platform/_UDC_/gadget/gadget-lunX/nofua
Date: July 2010
Contact: Andy Shevchenko <andy.shevchenko@gmail.com>
Description:
Show or set the reaction on the FUA (Force Unit Access) bit in
the SCSI WRITE(10,12) commands when a gadget in USB Mass
Storage mode.

Possible values are:
1 -> ignore the FUA flag
0 -> obey the FUA flag
31 changes: 24 additions & 7 deletions trunk/drivers/usb/gadget/file_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@
* removable Default false, boolean for removable media
* luns=N Default N = number of filenames, number of
* LUNs to support
* nofua=b[,b...] Default false, booleans for ignore FUA flag
* in SCSI WRITE(10,12) commands
* stall Default determined according to the type of
* USB device controller (usually true),
* boolean to permit the driver to halt
Expand All @@ -112,12 +114,12 @@
* PAGE_CACHE_SIZE)
*
* If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro",
* "removable", "luns", "stall", and "cdrom" options are available; default
* values are used for everything else.
* "removable", "luns", "nofua", "stall", and "cdrom" options are available;
* default values are used for everything else.
*
* The pathnames of the backing files and the ro settings are available in
* the attribute files "file" and "ro" in the lun<n> subdirectory of the
* gadget's sysfs directory. If the "removable" option is set, writing to
* the attribute files "file", "nofua", and "ro" in the lun<n> subdirectory of
* the gadget's sysfs directory. If the "removable" option is set, writing to
* these files will simulate ejecting/loading the medium (writing an empty
* line means eject) and adjusting a write-enable tab. Changes to the ro
* setting are not allowed when the medium is loaded or if CD-ROM emulation
Expand Down Expand Up @@ -304,8 +306,10 @@ MODULE_LICENSE("Dual BSD/GPL");
static struct {
char *file[FSG_MAX_LUNS];
int ro[FSG_MAX_LUNS];
int nofua[FSG_MAX_LUNS];
unsigned int num_filenames;
unsigned int num_ros;
unsigned int num_nofuas;
unsigned int nluns;

int removable;
Expand Down Expand Up @@ -345,6 +349,10 @@ MODULE_PARM_DESC(file, "names of backing files or devices");
module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO);
MODULE_PARM_DESC(ro, "true to force read-only");

module_param_array_named(nofua, mod_data.nofua, bool, &mod_data.num_nofuas,
S_IRUGO);
MODULE_PARM_DESC(nofua, "true to ignore SCSI WRITE(10,12) FUA bit");

module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
MODULE_PARM_DESC(luns, "number of LUNs");

Expand Down Expand Up @@ -1279,7 +1287,8 @@ static int do_write(struct fsg_dev *fsg)
curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
return -EINVAL;
}
if (fsg->cmnd[1] & 0x08) { // FUA
/* FUA */
if (!curlun->nofua && (fsg->cmnd[1] & 0x08)) {
spin_lock(&curlun->filp->f_lock);
curlun->filp->f_flags |= O_DSYNC;
spin_unlock(&curlun->filp->f_lock);
Expand Down Expand Up @@ -3133,6 +3142,7 @@ static int fsg_main_thread(void *fsg_)

/* The write permissions and store_xxx pointers are set in fsg_bind() */
static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL);
static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, NULL);
static DEVICE_ATTR(file, 0444, fsg_show_file, NULL);


Expand Down Expand Up @@ -3362,6 +3372,10 @@ static int __ref fsg_bind(struct usb_gadget *gadget)
}
}

/* Only for removable media? */
dev_attr_nofua.attr.mode = 0644;
dev_attr_nofua.store = fsg_store_nofua;

/* Find out how many LUNs there should be */
i = mod_data.nluns;
if (i == 0)
Expand All @@ -3387,6 +3401,7 @@ static int __ref fsg_bind(struct usb_gadget *gadget)
curlun->ro = mod_data.cdrom || mod_data.ro[i];
curlun->initially_ro = curlun->ro;
curlun->removable = mod_data.removable;
curlun->nofua = mod_data.nofua[i];
curlun->dev.release = lun_release;
curlun->dev.parent = &gadget->dev;
curlun->dev.driver = &fsg_driver.driver;
Expand All @@ -3400,6 +3415,8 @@ static int __ref fsg_bind(struct usb_gadget *gadget)
}
if ((rc = device_create_file(&curlun->dev,
&dev_attr_ro)) != 0 ||
(rc = device_create_file(&curlun->dev,
&dev_attr_nofua)) != 0 ||
(rc = device_create_file(&curlun->dev,
&dev_attr_file)) != 0) {
device_unregister(&curlun->dev);
Expand Down Expand Up @@ -3525,8 +3542,8 @@ static int __ref fsg_bind(struct usb_gadget *gadget)
if (IS_ERR(p))
p = NULL;
}
LINFO(curlun, "ro=%d, file: %s\n",
curlun->ro, (p ? p : "(error)"));
LINFO(curlun, "ro=%d, nofua=%d, file: %s\n",
curlun->ro, curlun->nofua, (p ? p : "(error)"));
}
}
kfree(pathbuf);
Expand Down
28 changes: 28 additions & 0 deletions trunk/drivers/usb/gadget/storage_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ struct fsg_lun {
unsigned int prevent_medium_removal:1;
unsigned int registered:1;
unsigned int info_valid:1;
unsigned int nofua:1;

u32 sense_data;
u32 sense_data_info;
Expand Down Expand Up @@ -714,6 +715,14 @@ static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
: curlun->initially_ro);
}

static ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
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)
{
Expand Down Expand Up @@ -770,6 +779,25 @@ 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)
{
struct fsg_lun *curlun = fsg_lun_from_dev(dev);
unsigned long nofua;

if (strict_strtoul(buf, 2, &nofua))
return -EINVAL;

/* Sync data when switching from async mode to sync */
if (!nofua && curlun->nofua)
fsg_lun_fsync_sub(curlun);

curlun->nofua = nofua;

return count;
}

static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
Expand Down

0 comments on commit 6f4ced7

Please sign in to comment.