diff options
| author | FrozenCow <frozencow@gmail.com> | 2013-07-04 12:36:57 +0200 |
|---|---|---|
| committer | FrozenCow <frozencow@gmail.com> | 2014-11-07 16:35:38 +0100 |
| commit | 64b86333acd7310369aed07cbaa3ff36dede2c6d (patch) | |
| tree | 9a4fe698707a9f3d4c3fee756daeafc0f34dce51 /drivers/usb | |
| parent | d56a43710ccb878b51a1a1dcc1ff0254f52ca825 (diff) | |
This patch adds a "cdrom" sysfs entry for each mass_storage LUN, just
like "ro" sysfs entry. This allows switching between USB and CD-ROM
emulation without reinserting the module or recompiling the kernel.
Change-Id: Idf83c74815b1ad370428ab9d3e5503d5f7bcd3b6
Diffstat (limited to 'drivers/usb')
| -rw-r--r-- | drivers/usb/gadget/f_mass_storage.c | 5 | ||||
| -rw-r--r-- | drivers/usb/gadget/storage_common.c | 37 |
2 files changed, 42 insertions, 0 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 835619048ac..04c5ec49803 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2881,6 +2881,7 @@ static int fsg_main_thread(void *common_) 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); +static DEVICE_ATTR(cdrom, 0644, fsg_show_cdrom, fsg_store_cdrom); #ifdef CONFIG_USB_MSC_PROFILING static DEVICE_ATTR(perf, 0644, fsg_show_perf, fsg_store_perf); #endif @@ -2999,6 +3000,9 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, rc = device_create_file(&curlun->dev, &dev_attr_nofua); if (rc) goto error_luns; + rc = device_create_file(&curlun->dev, &dev_attr_cdrom); + if (rc) + goto error_luns; #ifdef CONFIG_USB_MSC_PROFILING rc = device_create_file(&curlun->dev, &dev_attr_perf); if (rc) @@ -3136,6 +3140,7 @@ static void fsg_common_release(struct kref *ref) #ifdef CONFIG_USB_MSC_PROFILING device_remove_file(&lun->dev, &dev_attr_perf); #endif + device_remove_file(&lun->dev, &dev_attr_cdrom); device_remove_file(&lun->dev, &dev_attr_nofua); device_remove_file(&lun->dev, &dev_attr_ro); device_remove_file(&lun->dev, &dev_attr_file); diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 3c57df4e18a..6788ce41aef 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -801,6 +801,14 @@ static ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%u\n", curlun->nofua); } +static ssize_t fsg_show_cdrom (struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + + return sprintf(buf, "%d\n", curlun->cdrom); +} + #ifdef CONFIG_USB_MSC_PROFILING static ssize_t fsg_show_perf(struct device *dev, struct device_attribute *attr, char *buf) @@ -956,3 +964,32 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr, up_write(filesem); return (rc < 0 ? rc : count); } + +static ssize_t fsg_store_cdrom(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t rc; + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + struct rw_semaphore *filesem = dev_get_drvdata(dev); + unsigned cdrom; + + rc = kstrtouint(buf, 2, &cdrom); + if (rc) + return rc; + + /* + * Allow the cdrom status to change only while the + * backing file is closed. + */ + down_read(filesem); + if (fsg_lun_is_open(curlun)) { + LDBG(curlun, "cdrom status change prevented\n"); + rc = -EBUSY; + } else { + curlun->cdrom = cdrom; + LDBG(curlun, "cdrom status set to %d\n", curlun->cdrom); + rc = count; + } + up_read(filesem); + return rc; +} |
