aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorFrozenCow <frozencow@gmail.com>2013-07-04 12:36:57 +0200
committerFrozenCow <frozencow@gmail.com>2014-11-07 16:35:38 +0100
commit64b86333acd7310369aed07cbaa3ff36dede2c6d (patch)
tree9a4fe698707a9f3d4c3fee756daeafc0f34dce51 /drivers/usb/gadget
parentd56a43710ccb878b51a1a1dcc1ff0254f52ca825 (diff)
usb: gadget: mass_storage: added sysfs entry for cdrom to LUNsHEADkitkat
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/gadget')
-rw-r--r--drivers/usb/gadget/f_mass_storage.c5
-rw-r--r--drivers/usb/gadget/storage_common.c37
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;
+}