summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/storage_common.c
diff options
context:
space:
mode:
authorMichal Nazarewicz <m.nazarewicz@samsung.com>2009-10-28 16:57:17 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 11:55:19 -0800
commit93f937405bd5280ced9bf845f620d1de19b9bf7d (patch)
tree3ca72e8b1326087623ed1e2e97a2db45643b0d12 /drivers/usb/gadget/storage_common.c
parente909ef5def59236b91fa9ee83446084eb6f48d1a (diff)
downloadop-kernel-dev-93f937405bd5280ced9bf845f620d1de19b9bf7d.zip
op-kernel-dev-93f937405bd5280ced9bf845f620d1de19b9bf7d.tar.gz
USB: g_file_storage: more code from file_storage.c moved to storage_common.c
Since storage_common.c no longer references mod_data object it is now possible to include it before mod_data object is defined. This makes it possible to move some defines that are used as default values of mod_data fields to be defined in storage_common.c file (where they should be set from the beginning). Also, show_ro(), show_file(), store_ro() and store_file() have been moved to storage_common.c with LUN's device's drvdata changed from pointing to fsg_dev to pointing to rw_semaphore (&fsg->filesem). Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com> Cc: David Brownell <dbrownell@users.sourceforge.net> Cc: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/storage_common.c')
-rw-r--r--drivers/usb/gadget/storage_common.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index affd23b..6523cb6 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -37,6 +37,14 @@
#include <asm/unaligned.h>
+/* Thanks to NetChip Technologies for donating this product ID.
+ *
+ * DO NOT REUSE THESE IDs with any other driver!! Ever!!
+ * Instead: allocate your own, using normal USB-IF procedures. */
+#define FSG_VENDOR_ID 0x0525 // NetChip
+#define FSG_PRODUCT_ID 0xa4a5 // Linux-USB File-backed Storage Gadget
+
+
/*-------------------------------------------------------------------------*/
@@ -255,6 +263,12 @@ static struct fsg_lun *fsg_lun_from_dev(struct device *dev)
/* Number of buffers we will use. 2 is enough for double-buffering */
#define FSG_NUM_BUFFERS 2
+/* Default size of buffer length. */
+#define FSG_BUFLEN ((u32)16384)
+
+/* Maximal number of LUNs supported in mass storage function */
+#define FSG_MAX_LUNS 8
+
enum fsg_buffer_state {
BUF_STATE_EMPTY = 0,
BUF_STATE_FULL,
@@ -594,3 +608,105 @@ 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", fsg_lun_is_open(curlun)
+ ? curlun->ro
+ : curlun->initially_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 (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;
+ curlun->initially_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->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);
+}
OpenPOWER on IntegriCloud