aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichal Nazarewicz <m.nazarewicz@samsung.com>2009-10-28 11:57:17 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:55:19 -0500
commit93f937405bd5280ced9bf845f620d1de19b9bf7d (patch)
tree3ca72e8b1326087623ed1e2e97a2db45643b0d12 /drivers
parente909ef5def59236b91fa9ee83446084eb6f48d1a (diff)
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')
-rw-r--r--drivers/usb/gadget/file_storage.c129
-rw-r--r--drivers/usb/gadget/storage_common.c116
2 files changed, 128 insertions, 117 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index ee712a5715e7..7998402b1840 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -278,18 +278,14 @@ static char fsg_string_serial[13];
278static const char fsg_string_config[] = "Self-powered"; 278static const char fsg_string_config[] = "Self-powered";
279static const char fsg_string_interface[] = "Mass Storage"; 279static const char fsg_string_interface[] = "Mass Storage";
280 280
281
282#include "storage_common.c"
283
284
281MODULE_DESCRIPTION(DRIVER_DESC); 285MODULE_DESCRIPTION(DRIVER_DESC);
282MODULE_AUTHOR("Alan Stern"); 286MODULE_AUTHOR("Alan Stern");
283MODULE_LICENSE("Dual BSD/GPL"); 287MODULE_LICENSE("Dual BSD/GPL");
284 288
285/* Thanks to NetChip Technologies for donating this product ID.
286 *
287 * DO NOT REUSE THESE IDs with any other driver!! Ever!!
288 * Instead: allocate your own, using normal USB-IF procedures. */
289#define FSG_VENDOR_ID 0x0525 // NetChip
290#define FSG_PRODUCT_ID 0xa4a5 // Linux-USB File-backed Storage Gadget
291
292
293/* 289/*
294 * This driver assumes self-powered hardware and has no way for users to 290 * This driver assumes self-powered hardware and has no way for users to
295 * trigger remote wakeup. It uses autoconfiguration to select endpoints 291 * trigger remote wakeup. It uses autoconfiguration to select endpoints
@@ -302,8 +298,6 @@ MODULE_LICENSE("Dual BSD/GPL");
302 298
303/* Encapsulate the module parameter settings */ 299/* Encapsulate the module parameter settings */
304 300
305#define FSG_MAX_LUNS 8
306
307static struct { 301static struct {
308 char *file[FSG_MAX_LUNS]; 302 char *file[FSG_MAX_LUNS];
309 int ro[FSG_MAX_LUNS]; 303 int ro[FSG_MAX_LUNS];
@@ -410,10 +404,6 @@ MODULE_PARM_DESC(buflen, "I/O buffer size");
410 404
411/*-------------------------------------------------------------------------*/ 405/*-------------------------------------------------------------------------*/
412 406
413#include "storage_common.c"
414
415/*-------------------------------------------------------------------------*/
416
417 407
418struct fsg_dev { 408struct fsg_dev {
419 /* lock protects: state, all the req_busy's, and cbbuf_cmnd */ 409 /* lock protects: state, all the req_busy's, and cbbuf_cmnd */
@@ -3134,107 +3124,10 @@ static int fsg_main_thread(void *fsg_)
3134 3124
3135/*-------------------------------------------------------------------------*/ 3125/*-------------------------------------------------------------------------*/
3136 3126
3137static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
3138{
3139 struct fsg_lun *curlun = fsg_lun_from_dev(dev);
3140
3141 return sprintf(buf, "%d\n", fsg_lun_is_open(curlun)
3142 ? curlun->ro
3143 : curlun->initially_ro);
3144}
3145
3146static ssize_t show_file(struct device *dev, struct device_attribute *attr,
3147 char *buf)
3148{
3149 struct fsg_lun *curlun = fsg_lun_from_dev(dev);
3150 struct fsg_dev *fsg = dev_get_drvdata(dev);
3151 char *p;
3152 ssize_t rc;
3153
3154 down_read(&fsg->filesem);
3155 if (fsg_lun_is_open(curlun)) { // Get the complete pathname
3156 p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1);
3157 if (IS_ERR(p))
3158 rc = PTR_ERR(p);
3159 else {
3160 rc = strlen(p);
3161 memmove(buf, p, rc);
3162 buf[rc] = '\n'; // Add a newline
3163 buf[++rc] = 0;
3164 }
3165 } else { // No file, return 0 bytes
3166 *buf = 0;
3167 rc = 0;
3168 }
3169 up_read(&fsg->filesem);
3170 return rc;
3171}
3172
3173
3174static ssize_t store_ro(struct device *dev, struct device_attribute *attr,
3175 const char *buf, size_t count)
3176{
3177 ssize_t rc = count;
3178 struct fsg_lun *curlun = fsg_lun_from_dev(dev);
3179 struct fsg_dev *fsg = dev_get_drvdata(dev);
3180 int i;
3181
3182 if (sscanf(buf, "%d", &i) != 1)
3183 return -EINVAL;
3184
3185 /* Allow the write-enable status to change only while the backing file
3186 * is closed. */
3187 down_read(&fsg->filesem);
3188 if (fsg_lun_is_open(curlun)) {
3189 LDBG(curlun, "read-only status change prevented\n");
3190 rc = -EBUSY;
3191 } else {
3192 curlun->ro = !!i;
3193 curlun->initially_ro = !!i;
3194 LDBG(curlun, "read-only status set to %d\n", curlun->ro);
3195 }
3196 up_read(&fsg->filesem);
3197 return rc;
3198}
3199
3200static ssize_t store_file(struct device *dev, struct device_attribute *attr,
3201 const char *buf, size_t count)
3202{
3203 struct fsg_lun *curlun = fsg_lun_from_dev(dev);
3204 struct fsg_dev *fsg = dev_get_drvdata(dev);
3205 int rc = 0;
3206
3207 if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) {
3208 LDBG(curlun, "eject attempt prevented\n");
3209 return -EBUSY; // "Door is locked"
3210 }
3211
3212 /* Remove a trailing newline */
3213 if (count > 0 && buf[count-1] == '\n')
3214 ((char *) buf)[count-1] = 0; // Ugh!
3215
3216 /* Eject current medium */
3217 down_write(&fsg->filesem);
3218 if (fsg_lun_is_open(curlun)) {
3219 fsg_lun_close(curlun);
3220 curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
3221 }
3222
3223 /* Load new medium */
3224 if (count > 0 && buf[0]) {
3225 rc = fsg_lun_open(curlun, buf);
3226 if (rc == 0)
3227 curlun->unit_attention_data =
3228 SS_NOT_READY_TO_READY_TRANSITION;
3229 }
3230 up_write(&fsg->filesem);
3231 return (rc < 0 ? rc : count);
3232}
3233
3234 3127
3235/* The write permissions and store_xxx pointers are set in fsg_bind() */ 3128/* The write permissions and store_xxx pointers are set in fsg_bind() */
3236static DEVICE_ATTR(ro, 0444, show_ro, NULL); 3129static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL);
3237static DEVICE_ATTR(file, 0444, show_file, NULL); 3130static DEVICE_ATTR(file, 0444, fsg_show_file, NULL);
3238 3131
3239 3132
3240/*-------------------------------------------------------------------------*/ 3133/*-------------------------------------------------------------------------*/
@@ -3249,7 +3142,9 @@ static void fsg_release(struct kref *ref)
3249 3142
3250static void lun_release(struct device *dev) 3143static void lun_release(struct device *dev)
3251{ 3144{
3252 struct fsg_dev *fsg = dev_get_drvdata(dev); 3145 struct rw_semaphore *filesem = dev_get_drvdata(dev);
3146 struct fsg_dev *fsg =
3147 container_of(filesem, struct fsg_dev, filesem);
3253 3148
3254 kref_put(&fsg->ref, fsg_release); 3149 kref_put(&fsg->ref, fsg_release);
3255} 3150}
@@ -3408,10 +3303,10 @@ static int __init fsg_bind(struct usb_gadget *gadget)
3408 3303
3409 if (mod_data.removable) { // Enable the store_xxx attributes 3304 if (mod_data.removable) { // Enable the store_xxx attributes
3410 dev_attr_file.attr.mode = 0644; 3305 dev_attr_file.attr.mode = 0644;
3411 dev_attr_file.store = store_file; 3306 dev_attr_file.store = fsg_store_file;
3412 if (!mod_data.cdrom) { 3307 if (!mod_data.cdrom) {
3413 dev_attr_ro.attr.mode = 0644; 3308 dev_attr_ro.attr.mode = 0644;
3414 dev_attr_ro.store = store_ro; 3309 dev_attr_ro.store = fsg_store_ro;
3415 } 3310 }
3416 } 3311 }
3417 3312
@@ -3443,7 +3338,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
3443 curlun->dev.release = lun_release; 3338 curlun->dev.release = lun_release;
3444 curlun->dev.parent = &gadget->dev; 3339 curlun->dev.parent = &gadget->dev;
3445 curlun->dev.driver = &fsg_driver.driver; 3340 curlun->dev.driver = &fsg_driver.driver;
3446 dev_set_drvdata(&curlun->dev, fsg); 3341 dev_set_drvdata(&curlun->dev, &fsg->filesem);
3447 dev_set_name(&curlun->dev,"%s-lun%d", 3342 dev_set_name(&curlun->dev,"%s-lun%d",
3448 dev_name(&gadget->dev), i); 3343 dev_name(&gadget->dev), i);
3449 3344
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index affd23b5436f..6523cb6f4c4d 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -37,6 +37,14 @@
37#include <asm/unaligned.h> 37#include <asm/unaligned.h>
38 38
39 39
40/* Thanks to NetChip Technologies for donating this product ID.
41 *
42 * DO NOT REUSE THESE IDs with any other driver!! Ever!!
43 * Instead: allocate your own, using normal USB-IF procedures. */
44#define FSG_VENDOR_ID 0x0525 // NetChip
45#define FSG_PRODUCT_ID 0xa4a5 // Linux-USB File-backed Storage Gadget
46
47
40/*-------------------------------------------------------------------------*/ 48/*-------------------------------------------------------------------------*/
41 49
42 50
@@ -255,6 +263,12 @@ static struct fsg_lun *fsg_lun_from_dev(struct device *dev)
255/* Number of buffers we will use. 2 is enough for double-buffering */ 263/* Number of buffers we will use. 2 is enough for double-buffering */
256#define FSG_NUM_BUFFERS 2 264#define FSG_NUM_BUFFERS 2
257 265
266/* Default size of buffer length. */
267#define FSG_BUFLEN ((u32)16384)
268
269/* Maximal number of LUNs supported in mass storage function */
270#define FSG_MAX_LUNS 8
271
258enum fsg_buffer_state { 272enum fsg_buffer_state {
259 BUF_STATE_EMPTY = 0, 273 BUF_STATE_EMPTY = 0,
260 BUF_STATE_FULL, 274 BUF_STATE_FULL,
@@ -594,3 +608,105 @@ static void store_cdrom_address(u8 *dest, int msf, u32 addr)
594 put_unaligned_be32(addr, dest); 608 put_unaligned_be32(addr, dest);
595 } 609 }
596} 610}
611
612
613/*-------------------------------------------------------------------------*/
614
615
616static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
617 char *buf)
618{
619 struct fsg_lun *curlun = fsg_lun_from_dev(dev);
620
621 return sprintf(buf, "%d\n", fsg_lun_is_open(curlun)
622 ? curlun->ro
623 : curlun->initially_ro);
624}
625
626static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
627 char *buf)
628{
629 struct fsg_lun *curlun = fsg_lun_from_dev(dev);
630 struct rw_semaphore *filesem = dev_get_drvdata(dev);
631 char *p;
632 ssize_t rc;
633
634 down_read(filesem);
635 if (fsg_lun_is_open(curlun)) { // Get the complete pathname
636 p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1);
637 if (IS_ERR(p))
638 rc = PTR_ERR(p);
639 else {
640 rc = strlen(p);
641 memmove(buf, p, rc);
642 buf[rc] = '\n'; // Add a newline
643 buf[++rc] = 0;
644 }
645 } else { // No file, return 0 bytes
646 *buf = 0;
647 rc = 0;
648 }
649 up_read(filesem);
650 return rc;
651}
652
653
654static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
655 const char *buf, size_t count)
656{
657 ssize_t rc = count;
658 struct fsg_lun *curlun = fsg_lun_from_dev(dev);
659 struct rw_semaphore *filesem = dev_get_drvdata(dev);
660 int i;
661
662 if (sscanf(buf, "%d", &i) != 1)
663 return -EINVAL;
664
665 /* Allow the write-enable status to change only while the backing file
666 * is closed. */
667 down_read(filesem);
668 if (fsg_lun_is_open(curlun)) {
669 LDBG(curlun, "read-only status change prevented\n");
670 rc = -EBUSY;
671 } else {
672 curlun->ro = !!i;
673 curlun->initially_ro = !!i;
674 LDBG(curlun, "read-only status set to %d\n", curlun->ro);
675 }
676 up_read(filesem);
677 return rc;
678}
679
680static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
681 const char *buf, size_t count)
682{
683 struct fsg_lun *curlun = fsg_lun_from_dev(dev);
684 struct rw_semaphore *filesem = dev_get_drvdata(dev);
685 int rc = 0;
686
687 if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) {
688 LDBG(curlun, "eject attempt prevented\n");
689 return -EBUSY; // "Door is locked"
690 }
691
692 /* Remove a trailing newline */
693 if (count > 0 && buf[count-1] == '\n')
694 ((char *) buf)[count-1] = 0; // Ugh!
695
696 /* Eject current medium */
697 down_write(filesem);
698 if (fsg_lun_is_open(curlun)) {
699 fsg_lun_close(curlun);
700 curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
701 }
702
703 /* Load new medium */
704 if (count > 0 && buf[0]) {
705 rc = fsg_lun_open(curlun, buf);
706 if (rc == 0)
707 curlun->unit_attention_data =
708 SS_NOT_READY_TO_READY_TRANSITION;
709 }
710 up_write(filesem);
711 return (rc < 0 ? rc : count);
712}