diff options
Diffstat (limited to 'drivers/usb/gadget/file_storage.c')
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 93 |
1 files changed, 57 insertions, 36 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index ea09aaa3cab6..0cea9782d7d4 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -224,6 +224,7 @@ | |||
224 | #include <linux/fs.h> | 224 | #include <linux/fs.h> |
225 | #include <linux/init.h> | 225 | #include <linux/init.h> |
226 | #include <linux/kernel.h> | 226 | #include <linux/kernel.h> |
227 | #include <linux/kref.h> | ||
227 | #include <linux/kthread.h> | 228 | #include <linux/kthread.h> |
228 | #include <linux/limits.h> | 229 | #include <linux/limits.h> |
229 | #include <linux/list.h> | 230 | #include <linux/list.h> |
@@ -238,7 +239,6 @@ | |||
238 | #include <linux/string.h> | 239 | #include <linux/string.h> |
239 | #include <linux/suspend.h> | 240 | #include <linux/suspend.h> |
240 | #include <linux/utsname.h> | 241 | #include <linux/utsname.h> |
241 | #include <linux/wait.h> | ||
242 | 242 | ||
243 | #include <linux/usb_ch9.h> | 243 | #include <linux/usb_ch9.h> |
244 | #include <linux/usb_gadget.h> | 244 | #include <linux/usb_gadget.h> |
@@ -250,7 +250,7 @@ | |||
250 | 250 | ||
251 | #define DRIVER_DESC "File-backed Storage Gadget" | 251 | #define DRIVER_DESC "File-backed Storage Gadget" |
252 | #define DRIVER_NAME "g_file_storage" | 252 | #define DRIVER_NAME "g_file_storage" |
253 | #define DRIVER_VERSION "20 October 2004" | 253 | #define DRIVER_VERSION "28 November 2005" |
254 | 254 | ||
255 | static const char longname[] = DRIVER_DESC; | 255 | static const char longname[] = DRIVER_DESC; |
256 | static const char shortname[] = DRIVER_NAME; | 256 | static const char shortname[] = DRIVER_NAME; |
@@ -335,8 +335,8 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
335 | #define MAX_LUNS 8 | 335 | #define MAX_LUNS 8 |
336 | 336 | ||
337 | /* Arggh! There should be a module_param_array_named macro! */ | 337 | /* Arggh! There should be a module_param_array_named macro! */ |
338 | static char *file[MAX_LUNS] = {NULL, }; | 338 | static char *file[MAX_LUNS]; |
339 | static int ro[MAX_LUNS] = {0, }; | 339 | static int ro[MAX_LUNS]; |
340 | 340 | ||
341 | static struct { | 341 | static struct { |
342 | int num_filenames; | 342 | int num_filenames; |
@@ -587,7 +587,7 @@ enum fsg_buffer_state { | |||
587 | struct fsg_buffhd { | 587 | struct fsg_buffhd { |
588 | void *buf; | 588 | void *buf; |
589 | dma_addr_t dma; | 589 | dma_addr_t dma; |
590 | volatile enum fsg_buffer_state state; | 590 | enum fsg_buffer_state state; |
591 | struct fsg_buffhd *next; | 591 | struct fsg_buffhd *next; |
592 | 592 | ||
593 | /* The NetChip 2280 is faster, and handles some protocol faults | 593 | /* The NetChip 2280 is faster, and handles some protocol faults |
@@ -596,9 +596,9 @@ struct fsg_buffhd { | |||
596 | unsigned int bulk_out_intended_length; | 596 | unsigned int bulk_out_intended_length; |
597 | 597 | ||
598 | struct usb_request *inreq; | 598 | struct usb_request *inreq; |
599 | volatile int inreq_busy; | 599 | int inreq_busy; |
600 | struct usb_request *outreq; | 600 | struct usb_request *outreq; |
601 | volatile int outreq_busy; | 601 | int outreq_busy; |
602 | }; | 602 | }; |
603 | 603 | ||
604 | enum fsg_state { | 604 | enum fsg_state { |
@@ -631,13 +631,16 @@ struct fsg_dev { | |||
631 | /* filesem protects: backing files in use */ | 631 | /* filesem protects: backing files in use */ |
632 | struct rw_semaphore filesem; | 632 | struct rw_semaphore filesem; |
633 | 633 | ||
634 | /* reference counting: wait until all LUNs are released */ | ||
635 | struct kref ref; | ||
636 | |||
634 | struct usb_ep *ep0; // Handy copy of gadget->ep0 | 637 | struct usb_ep *ep0; // Handy copy of gadget->ep0 |
635 | struct usb_request *ep0req; // For control responses | 638 | struct usb_request *ep0req; // For control responses |
636 | volatile unsigned int ep0_req_tag; | 639 | unsigned int ep0_req_tag; |
637 | const char *ep0req_name; | 640 | const char *ep0req_name; |
638 | 641 | ||
639 | struct usb_request *intreq; // For interrupt responses | 642 | struct usb_request *intreq; // For interrupt responses |
640 | volatile int intreq_busy; | 643 | int intreq_busy; |
641 | struct fsg_buffhd *intr_buffhd; | 644 | struct fsg_buffhd *intr_buffhd; |
642 | 645 | ||
643 | unsigned int bulk_out_maxpacket; | 646 | unsigned int bulk_out_maxpacket; |
@@ -667,7 +670,6 @@ struct fsg_dev { | |||
667 | struct fsg_buffhd *next_buffhd_to_drain; | 670 | struct fsg_buffhd *next_buffhd_to_drain; |
668 | struct fsg_buffhd buffhds[NUM_BUFFERS]; | 671 | struct fsg_buffhd buffhds[NUM_BUFFERS]; |
669 | 672 | ||
670 | wait_queue_head_t thread_wqh; | ||
671 | int thread_wakeup_needed; | 673 | int thread_wakeup_needed; |
672 | struct completion thread_notifier; | 674 | struct completion thread_notifier; |
673 | struct task_struct *thread_task; | 675 | struct task_struct *thread_task; |
@@ -694,7 +696,6 @@ struct fsg_dev { | |||
694 | unsigned int nluns; | 696 | unsigned int nluns; |
695 | struct lun *luns; | 697 | struct lun *luns; |
696 | struct lun *curlun; | 698 | struct lun *curlun; |
697 | struct completion lun_released; | ||
698 | }; | 699 | }; |
699 | 700 | ||
700 | typedef void (*fsg_routine_t)(struct fsg_dev *); | 701 | typedef void (*fsg_routine_t)(struct fsg_dev *); |
@@ -1073,11 +1074,13 @@ static int populate_config_buf(struct usb_gadget *gadget, | |||
1073 | 1074 | ||
1074 | /* These routines may be called in process context or in_irq */ | 1075 | /* These routines may be called in process context or in_irq */ |
1075 | 1076 | ||
1077 | /* Caller must hold fsg->lock */ | ||
1076 | static void wakeup_thread(struct fsg_dev *fsg) | 1078 | static void wakeup_thread(struct fsg_dev *fsg) |
1077 | { | 1079 | { |
1078 | /* Tell the main thread that something has happened */ | 1080 | /* Tell the main thread that something has happened */ |
1079 | fsg->thread_wakeup_needed = 1; | 1081 | fsg->thread_wakeup_needed = 1; |
1080 | wake_up_all(&fsg->thread_wqh); | 1082 | if (fsg->thread_task) |
1083 | wake_up_process(fsg->thread_task); | ||
1081 | } | 1084 | } |
1082 | 1085 | ||
1083 | 1086 | ||
@@ -1164,11 +1167,12 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
1164 | usb_ep_fifo_flush(ep); | 1167 | usb_ep_fifo_flush(ep); |
1165 | 1168 | ||
1166 | /* Hold the lock while we update the request and buffer states */ | 1169 | /* Hold the lock while we update the request and buffer states */ |
1170 | smp_wmb(); | ||
1167 | spin_lock(&fsg->lock); | 1171 | spin_lock(&fsg->lock); |
1168 | bh->inreq_busy = 0; | 1172 | bh->inreq_busy = 0; |
1169 | bh->state = BUF_STATE_EMPTY; | 1173 | bh->state = BUF_STATE_EMPTY; |
1170 | spin_unlock(&fsg->lock); | ||
1171 | wakeup_thread(fsg); | 1174 | wakeup_thread(fsg); |
1175 | spin_unlock(&fsg->lock); | ||
1172 | } | 1176 | } |
1173 | 1177 | ||
1174 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | 1178 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) |
@@ -1185,11 +1189,12 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | |||
1185 | usb_ep_fifo_flush(ep); | 1189 | usb_ep_fifo_flush(ep); |
1186 | 1190 | ||
1187 | /* Hold the lock while we update the request and buffer states */ | 1191 | /* Hold the lock while we update the request and buffer states */ |
1192 | smp_wmb(); | ||
1188 | spin_lock(&fsg->lock); | 1193 | spin_lock(&fsg->lock); |
1189 | bh->outreq_busy = 0; | 1194 | bh->outreq_busy = 0; |
1190 | bh->state = BUF_STATE_FULL; | 1195 | bh->state = BUF_STATE_FULL; |
1191 | spin_unlock(&fsg->lock); | ||
1192 | wakeup_thread(fsg); | 1196 | wakeup_thread(fsg); |
1197 | spin_unlock(&fsg->lock); | ||
1193 | } | 1198 | } |
1194 | 1199 | ||
1195 | 1200 | ||
@@ -1206,11 +1211,12 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
1206 | usb_ep_fifo_flush(ep); | 1211 | usb_ep_fifo_flush(ep); |
1207 | 1212 | ||
1208 | /* Hold the lock while we update the request and buffer states */ | 1213 | /* Hold the lock while we update the request and buffer states */ |
1214 | smp_wmb(); | ||
1209 | spin_lock(&fsg->lock); | 1215 | spin_lock(&fsg->lock); |
1210 | fsg->intreq_busy = 0; | 1216 | fsg->intreq_busy = 0; |
1211 | bh->state = BUF_STATE_EMPTY; | 1217 | bh->state = BUF_STATE_EMPTY; |
1212 | spin_unlock(&fsg->lock); | ||
1213 | wakeup_thread(fsg); | 1218 | wakeup_thread(fsg); |
1219 | spin_unlock(&fsg->lock); | ||
1214 | } | 1220 | } |
1215 | 1221 | ||
1216 | #else | 1222 | #else |
@@ -1261,8 +1267,8 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
1261 | fsg->cbbuf_cmnd_size = req->actual; | 1267 | fsg->cbbuf_cmnd_size = req->actual; |
1262 | memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); | 1268 | memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); |
1263 | 1269 | ||
1264 | spin_unlock(&fsg->lock); | ||
1265 | wakeup_thread(fsg); | 1270 | wakeup_thread(fsg); |
1271 | spin_unlock(&fsg->lock); | ||
1266 | } | 1272 | } |
1267 | 1273 | ||
1268 | #else | 1274 | #else |
@@ -1514,8 +1520,8 @@ static int fsg_setup(struct usb_gadget *gadget, | |||
1514 | 1520 | ||
1515 | /* Use this for bulk or interrupt transfers, not ep0 */ | 1521 | /* Use this for bulk or interrupt transfers, not ep0 */ |
1516 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | 1522 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, |
1517 | struct usb_request *req, volatile int *pbusy, | 1523 | struct usb_request *req, int *pbusy, |
1518 | volatile enum fsg_buffer_state *state) | 1524 | enum fsg_buffer_state *state) |
1519 | { | 1525 | { |
1520 | int rc; | 1526 | int rc; |
1521 | 1527 | ||
@@ -1523,8 +1529,11 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | |||
1523 | dump_msg(fsg, "bulk-in", req->buf, req->length); | 1529 | dump_msg(fsg, "bulk-in", req->buf, req->length); |
1524 | else if (ep == fsg->intr_in) | 1530 | else if (ep == fsg->intr_in) |
1525 | dump_msg(fsg, "intr-in", req->buf, req->length); | 1531 | dump_msg(fsg, "intr-in", req->buf, req->length); |
1532 | |||
1533 | spin_lock_irq(&fsg->lock); | ||
1526 | *pbusy = 1; | 1534 | *pbusy = 1; |
1527 | *state = BUF_STATE_BUSY; | 1535 | *state = BUF_STATE_BUSY; |
1536 | spin_unlock_irq(&fsg->lock); | ||
1528 | rc = usb_ep_queue(ep, req, GFP_KERNEL); | 1537 | rc = usb_ep_queue(ep, req, GFP_KERNEL); |
1529 | if (rc != 0) { | 1538 | if (rc != 0) { |
1530 | *pbusy = 0; | 1539 | *pbusy = 0; |
@@ -1544,14 +1553,23 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | |||
1544 | 1553 | ||
1545 | static int sleep_thread(struct fsg_dev *fsg) | 1554 | static int sleep_thread(struct fsg_dev *fsg) |
1546 | { | 1555 | { |
1547 | int rc; | 1556 | int rc = 0; |
1548 | 1557 | ||
1549 | /* Wait until a signal arrives or we are woken up */ | 1558 | /* Wait until a signal arrives or we are woken up */ |
1550 | rc = wait_event_interruptible(fsg->thread_wqh, | 1559 | for (;;) { |
1551 | fsg->thread_wakeup_needed); | 1560 | try_to_freeze(); |
1561 | set_current_state(TASK_INTERRUPTIBLE); | ||
1562 | if (signal_pending(current)) { | ||
1563 | rc = -EINTR; | ||
1564 | break; | ||
1565 | } | ||
1566 | if (fsg->thread_wakeup_needed) | ||
1567 | break; | ||
1568 | schedule(); | ||
1569 | } | ||
1570 | __set_current_state(TASK_RUNNING); | ||
1552 | fsg->thread_wakeup_needed = 0; | 1571 | fsg->thread_wakeup_needed = 0; |
1553 | try_to_freeze(); | 1572 | return rc; |
1554 | return (rc ? -EINTR : 0); | ||
1555 | } | 1573 | } |
1556 | 1574 | ||
1557 | 1575 | ||
@@ -1788,6 +1806,7 @@ static int do_write(struct fsg_dev *fsg) | |||
1788 | if (bh->state == BUF_STATE_EMPTY && !get_some_more) | 1806 | if (bh->state == BUF_STATE_EMPTY && !get_some_more) |
1789 | break; // We stopped early | 1807 | break; // We stopped early |
1790 | if (bh->state == BUF_STATE_FULL) { | 1808 | if (bh->state == BUF_STATE_FULL) { |
1809 | smp_rmb(); | ||
1791 | fsg->next_buffhd_to_drain = bh->next; | 1810 | fsg->next_buffhd_to_drain = bh->next; |
1792 | bh->state = BUF_STATE_EMPTY; | 1811 | bh->state = BUF_STATE_EMPTY; |
1793 | 1812 | ||
@@ -2356,6 +2375,7 @@ static int throw_away_data(struct fsg_dev *fsg) | |||
2356 | 2375 | ||
2357 | /* Throw away the data in a filled buffer */ | 2376 | /* Throw away the data in a filled buffer */ |
2358 | if (bh->state == BUF_STATE_FULL) { | 2377 | if (bh->state == BUF_STATE_FULL) { |
2378 | smp_rmb(); | ||
2359 | bh->state = BUF_STATE_EMPTY; | 2379 | bh->state = BUF_STATE_EMPTY; |
2360 | fsg->next_buffhd_to_drain = bh->next; | 2380 | fsg->next_buffhd_to_drain = bh->next; |
2361 | 2381 | ||
@@ -3021,6 +3041,7 @@ static int get_next_command(struct fsg_dev *fsg) | |||
3021 | if ((rc = sleep_thread(fsg)) != 0) | 3041 | if ((rc = sleep_thread(fsg)) != 0) |
3022 | return rc; | 3042 | return rc; |
3023 | } | 3043 | } |
3044 | smp_rmb(); | ||
3024 | rc = received_cbw(fsg, bh); | 3045 | rc = received_cbw(fsg, bh); |
3025 | bh->state = BUF_STATE_EMPTY; | 3046 | bh->state = BUF_STATE_EMPTY; |
3026 | 3047 | ||
@@ -3642,11 +3663,19 @@ static DEVICE_ATTR(file, 0444, show_file, NULL); | |||
3642 | 3663 | ||
3643 | /*-------------------------------------------------------------------------*/ | 3664 | /*-------------------------------------------------------------------------*/ |
3644 | 3665 | ||
3666 | static void fsg_release(struct kref *ref) | ||
3667 | { | ||
3668 | struct fsg_dev *fsg = container_of(ref, struct fsg_dev, ref); | ||
3669 | |||
3670 | kfree(fsg->luns); | ||
3671 | kfree(fsg); | ||
3672 | } | ||
3673 | |||
3645 | static void lun_release(struct device *dev) | 3674 | static void lun_release(struct device *dev) |
3646 | { | 3675 | { |
3647 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3676 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); |
3648 | 3677 | ||
3649 | complete(&fsg->lun_released); | 3678 | kref_put(&fsg->ref, fsg_release); |
3650 | } | 3679 | } |
3651 | 3680 | ||
3652 | static void fsg_unbind(struct usb_gadget *gadget) | 3681 | static void fsg_unbind(struct usb_gadget *gadget) |
@@ -3660,14 +3689,12 @@ static void fsg_unbind(struct usb_gadget *gadget) | |||
3660 | clear_bit(REGISTERED, &fsg->atomic_bitflags); | 3689 | clear_bit(REGISTERED, &fsg->atomic_bitflags); |
3661 | 3690 | ||
3662 | /* Unregister the sysfs attribute files and the LUNs */ | 3691 | /* Unregister the sysfs attribute files and the LUNs */ |
3663 | init_completion(&fsg->lun_released); | ||
3664 | for (i = 0; i < fsg->nluns; ++i) { | 3692 | for (i = 0; i < fsg->nluns; ++i) { |
3665 | curlun = &fsg->luns[i]; | 3693 | curlun = &fsg->luns[i]; |
3666 | if (curlun->registered) { | 3694 | if (curlun->registered) { |
3667 | device_remove_file(&curlun->dev, &dev_attr_ro); | 3695 | device_remove_file(&curlun->dev, &dev_attr_ro); |
3668 | device_remove_file(&curlun->dev, &dev_attr_file); | 3696 | device_remove_file(&curlun->dev, &dev_attr_file); |
3669 | device_unregister(&curlun->dev); | 3697 | device_unregister(&curlun->dev); |
3670 | wait_for_completion(&fsg->lun_released); | ||
3671 | curlun->registered = 0; | 3698 | curlun->registered = 0; |
3672 | } | 3699 | } |
3673 | } | 3700 | } |
@@ -3846,6 +3873,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3846 | curlun->dev.release = lun_release; | 3873 | curlun->dev.release = lun_release; |
3847 | device_create_file(&curlun->dev, &dev_attr_ro); | 3874 | device_create_file(&curlun->dev, &dev_attr_ro); |
3848 | device_create_file(&curlun->dev, &dev_attr_file); | 3875 | device_create_file(&curlun->dev, &dev_attr_file); |
3876 | kref_get(&fsg->ref); | ||
3849 | } | 3877 | } |
3850 | 3878 | ||
3851 | if (file[i] && *file[i]) { | 3879 | if (file[i] && *file[i]) { |
@@ -4061,7 +4089,7 @@ static int __init fsg_alloc(void) | |||
4061 | return -ENOMEM; | 4089 | return -ENOMEM; |
4062 | spin_lock_init(&fsg->lock); | 4090 | spin_lock_init(&fsg->lock); |
4063 | init_rwsem(&fsg->filesem); | 4091 | init_rwsem(&fsg->filesem); |
4064 | init_waitqueue_head(&fsg->thread_wqh); | 4092 | kref_init(&fsg->ref); |
4065 | init_completion(&fsg->thread_notifier); | 4093 | init_completion(&fsg->thread_notifier); |
4066 | 4094 | ||
4067 | the_fsg = fsg; | 4095 | the_fsg = fsg; |
@@ -4069,13 +4097,6 @@ static int __init fsg_alloc(void) | |||
4069 | } | 4097 | } |
4070 | 4098 | ||
4071 | 4099 | ||
4072 | static void fsg_free(struct fsg_dev *fsg) | ||
4073 | { | ||
4074 | kfree(fsg->luns); | ||
4075 | kfree(fsg); | ||
4076 | } | ||
4077 | |||
4078 | |||
4079 | static int __init fsg_init(void) | 4100 | static int __init fsg_init(void) |
4080 | { | 4101 | { |
4081 | int rc; | 4102 | int rc; |
@@ -4085,7 +4106,7 @@ static int __init fsg_init(void) | |||
4085 | return rc; | 4106 | return rc; |
4086 | fsg = the_fsg; | 4107 | fsg = the_fsg; |
4087 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) | 4108 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) |
4088 | fsg_free(fsg); | 4109 | kref_put(&fsg->ref, fsg_release); |
4089 | return rc; | 4110 | return rc; |
4090 | } | 4111 | } |
4091 | module_init(fsg_init); | 4112 | module_init(fsg_init); |
@@ -4103,6 +4124,6 @@ static void __exit fsg_cleanup(void) | |||
4103 | wait_for_completion(&fsg->thread_notifier); | 4124 | wait_for_completion(&fsg->thread_notifier); |
4104 | 4125 | ||
4105 | close_all_backing_files(fsg); | 4126 | close_all_backing_files(fsg); |
4106 | fsg_free(fsg); | 4127 | kref_put(&fsg->ref, fsg_release); |
4107 | } | 4128 | } |
4108 | module_exit(fsg_cleanup); | 4129 | module_exit(fsg_cleanup); |