diff options
author | Michal Nazarewicz <m.nazarewicz@samsung.com> | 2009-10-28 11:57:17 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 14:55:19 -0500 |
commit | 93f937405bd5280ced9bf845f620d1de19b9bf7d (patch) | |
tree | 3ca72e8b1326087623ed1e2e97a2db45643b0d12 /drivers | |
parent | e909ef5def59236b91fa9ee83446084eb6f48d1a (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.c | 129 | ||||
-rw-r--r-- | drivers/usb/gadget/storage_common.c | 116 |
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]; | |||
278 | static const char fsg_string_config[] = "Self-powered"; | 278 | static const char fsg_string_config[] = "Self-powered"; |
279 | static const char fsg_string_interface[] = "Mass Storage"; | 279 | static const char fsg_string_interface[] = "Mass Storage"; |
280 | 280 | ||
281 | |||
282 | #include "storage_common.c" | ||
283 | |||
284 | |||
281 | MODULE_DESCRIPTION(DRIVER_DESC); | 285 | MODULE_DESCRIPTION(DRIVER_DESC); |
282 | MODULE_AUTHOR("Alan Stern"); | 286 | MODULE_AUTHOR("Alan Stern"); |
283 | MODULE_LICENSE("Dual BSD/GPL"); | 287 | MODULE_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 | |||
307 | static struct { | 301 | static 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 | ||
418 | struct fsg_dev { | 408 | struct 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 | ||
3137 | static 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 | |||
3146 | static 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 | |||
3174 | static 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 | |||
3200 | static 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() */ |
3236 | static DEVICE_ATTR(ro, 0444, show_ro, NULL); | 3129 | static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL); |
3237 | static DEVICE_ATTR(file, 0444, show_file, NULL); | 3130 | static 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 | ||
3250 | static void lun_release(struct device *dev) | 3143 | static 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 | |||
258 | enum fsg_buffer_state { | 272 | enum 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 | |||
616 | static 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 | |||
626 | static 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 | |||
654 | static 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 | |||
680 | static 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 | } | ||