Signed-off-by: Michal Nazarewicz <m.nazarewicz@xxxxxxxxxxx> --- drivers/usb/gadget/file_storage.c | 108 +++-------------------------------- drivers/usb/gadget/storage_common.c | 106 ++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 100 deletions(-) diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 9e99f07..66201af 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -3150,104 +3150,10 @@ static int fsg_main_thread(void *fsg_) /*-------------------------------------------------------------------------*/ -static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct fsg_lun *curlun = fsg_lun_from_dev(dev); - - return sprintf(buf, "%d\n", curlun->ro); -} - -static ssize_t show_file(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct fsg_lun *curlun = fsg_lun_from_dev(dev); - struct fsg_dev *fsg = dev_get_drvdata(dev); - char *p; - ssize_t rc; - - down_read(&fsg->filesem); - if (fsg_lun_is_open(curlun)) { // Get the complete pathname - p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1); - if (IS_ERR(p)) - rc = PTR_ERR(p); - else { - rc = strlen(p); - memmove(buf, p, rc); - buf[rc] = '\n'; // Add a newline - buf[++rc] = 0; - } - } else { // No file, return 0 bytes - *buf = 0; - rc = 0; - } - up_read(&fsg->filesem); - return rc; -} - - -static ssize_t store_ro(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - ssize_t rc = count; - struct fsg_lun *curlun = fsg_lun_from_dev(dev); - struct fsg_dev *fsg = dev_get_drvdata(dev); - int i; - - if (sscanf(buf, "%d", &i) != 1) - return -EINVAL; - - /* Allow the write-enable status to change only while the backing file - * is closed. */ - down_read(&fsg->filesem); - if (fsg_lun_is_open(curlun)) { - LDBG(curlun, "read-only status change prevented\n"); - rc = -EBUSY; - } else { - curlun->ro = !!i; - LDBG(curlun, "read-only status set to %d\n", curlun->ro); - } - up_read(&fsg->filesem); - return rc; -} - -static ssize_t store_file(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct fsg_lun *curlun = fsg_lun_from_dev(dev); - struct fsg_dev *fsg = dev_get_drvdata(dev); - int rc = 0; - - if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) { - LDBG(curlun, "eject attempt prevented\n"); - return -EBUSY; // "Door is locked" - } - - /* Remove a trailing newline */ - if (count > 0 && buf[count-1] == '\n') - ((char *) buf)[count-1] = 0; // Ugh! - - /* Eject current medium */ - down_write(&fsg->filesem); - if (fsg_lun_is_open(curlun)) { - fsg_lun_close(curlun); - curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; - } - - /* Load new medium */ - if (count > 0 && buf[0]) { - rc = fsg_lun_open(curlun, buf); - if (rc == 0) - curlun->unit_attention_data = - SS_NOT_READY_TO_READY_TRANSITION; - } - up_write(&fsg->filesem); - return (rc < 0 ? rc : count); -} - /* The write permissions and store_xxx pointers are set in fsg_bind() */ -static DEVICE_ATTR(ro, 0444, show_ro, NULL); -static DEVICE_ATTR(file, 0444, show_file, NULL); +static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL); +static DEVICE_ATTR(file, 0444, fsg_show_file, NULL); /*-------------------------------------------------------------------------*/ @@ -3262,7 +3168,9 @@ static void fsg_release(struct kref *ref) static void lun_release(struct device *dev) { - struct fsg_dev *fsg = dev_get_drvdata(dev); + struct rw_semaphore *filesem = dev_get_drvdata(dev); + struct fsg_dev *fsg = + container_of(filesem, struct fsg_dev, filesem); kref_put(&fsg->ref, fsg_release); } @@ -3421,10 +3329,10 @@ static int __init fsg_bind(struct usb_gadget *gadget) if (mod_data.removable) { // Enable the store_xxx attributes dev_attr_file.attr.mode = 0644; - dev_attr_file.store = store_file; + dev_attr_file.store = fsg_store_file; if (!mod_data.cdrom) { dev_attr_ro.attr.mode = 0644; - dev_attr_ro.store = store_ro; + dev_attr_ro.store = fsg_store_ro; } } @@ -3455,7 +3363,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) curlun->dev.release = lun_release; curlun->dev.parent = &gadget->dev; curlun->dev.driver = &fsg_driver.driver; - dev_set_drvdata(&curlun->dev, fsg); + dev_set_drvdata(&curlun->dev, &fsg->filesem); dev_set_name(&curlun->dev,"%s-lun%d", dev_name(&gadget->dev), i); diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 6efb061..e3c37e0 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -577,3 +577,109 @@ static void store_cdrom_address(u8 *dest, int msf, u32 addr) put_unaligned_be32(addr, dest); } } + + +/*-------------------------------------------------------------------------*/ + +static ssize_t fsg_show_ro(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + + return sprintf(buf, "%d\n", curlun->ro); +} + +static ssize_t fsg_show_file(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + struct rw_semaphore *filesem = dev_get_drvdata(dev); + char *p; + ssize_t rc; + + down_read(filesem); + if (fsg_lun_is_open(curlun)) { // Get the complete pathname + p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1); + if (IS_ERR(p)) + rc = PTR_ERR(p); + else { + rc = strlen(p); + memmove(buf, p, rc); + buf[rc] = '\n'; // Add a newline + buf[++rc] = 0; + } + } else { // No file, return 0 bytes + *buf = 0; + rc = 0; + } + up_read(filesem); + return rc; +} + + +static ssize_t fsg_store_ro(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t rc = count; + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + struct rw_semaphore *filesem = dev_get_drvdata(dev); + int i; + + if (curlun->cdrom) + return -EPERM; + + if (sscanf(buf, "%d", &i) != 1) + return -EINVAL; + + /* Allow the write-enable status to change only while the 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 = !!i; + LDBG(curlun, "read-only status set to %d\n", curlun->ro); + } + up_read(filesem); + return rc; +} + +static ssize_t fsg_store_file(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + struct rw_semaphore *filesem = dev_get_drvdata(dev); + int rc = 0; + + if (!curlun->removable) + return -EPERM; + + if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) { + LDBG(curlun, "eject attempt prevented\n"); + return -EBUSY; // "Door is locked" + } + + /* Remove a trailing newline */ + if (count > 0 && buf[count-1] == '\n') + ((char *) buf)[count-1] = 0; // Ugh! + + /* Eject current medium */ + down_write(filesem); + if (fsg_lun_is_open(curlun)) { + fsg_lun_close(curlun); + curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; + } + + /* Load new medium */ + if (count > 0 && buf[0]) { + rc = fsg_lun_open(curlun, buf); + if (rc == 0) + curlun->unit_attention_data = + SS_NOT_READY_TO_READY_TRANSITION; + } + up_write(filesem); + return (rc < 0 ? rc : count); +} -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html