aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorPer Forlin <per.forlin@linaro.org>2011-08-19 15:21:27 -0400
committerFelipe Balbi <balbi@ti.com>2011-09-09 06:06:04 -0400
commit6532c7fdb2c3a2ec1b949ecd2ff5375069c1639a (patch)
tree26afd8fdff7923f818f49aa405bb4208d1da914e /drivers/usb/gadget
parent04eee25b1d754a837360504b7af426d1f86ffeb7 (diff)
usb: gadget: storage: make FSG_NUM_BUFFERS variable size
FSG_NUM_BUFFERS is set to 2 as default. Usually 2 buffers are enough to establish a good buffering pipeline. The number may be increased in order to compensate a for bursty VFS behaviour. Here follows a description of system that may require more than 2 buffers. * CPU ondemand governor active * latency cost for wake up and/or frequency change * DMA for IO Use case description. * Data transfer from MMC via VFS to USB. * DMA shuffles data from MMC and to USB. * The CPU wakes up every now and then to pass data in and out from VFS, which cause the bursty VFS behaviour. Test set up * Running dd on the host reading from the mass storage device * cmdline: dd if=/dev/sdb of=/dev/null bs=4k count=$((256*100)) * Caches are dropped on the host and on the device before each run Measurements on a Snowball board with ondemand_governor active. FSG_NUM_BUFFERS 2 104857600 bytes (105 MB) copied, 5.62173 s, 18.7 MB/s 104857600 bytes (105 MB) copied, 5.61811 s, 18.7 MB/s 104857600 bytes (105 MB) copied, 5.57817 s, 18.8 MB/s FSG_NUM_BUFFERS 4 104857600 bytes (105 MB) copied, 5.26839 s, 19.9 MB/s 104857600 bytes (105 MB) copied, 5.2691 s, 19.9 MB/s 104857600 bytes (105 MB) copied, 5.2711 s, 19.9 MB/s There may not be one optimal number for all boards. This is why the number is added to Kconfig. If selecting USB_GADGET_DEBUG_FILES this value may be set by a module parameter as well. Signed-off-by: Per Forlin <per.forlin@linaro.org> Acked-by: Michal Nazarewicz <mina86@mina86.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/Kconfig16
-rw-r--r--drivers/usb/gadget/f_mass_storage.c29
-rw-r--r--drivers/usb/gadget/file_storage.c27
-rw-r--r--drivers/usb/gadget/storage_common.c33
4 files changed, 85 insertions, 20 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index fe5637983892..a60b472a0b39 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -96,6 +96,22 @@ config USB_GADGET_VBUS_DRAW
96 This value will be used except for system-specific gadget 96 This value will be used except for system-specific gadget
97 drivers that have more specific information. 97 drivers that have more specific information.
98 98
99config USB_GADGET_STORAGE_NUM_BUFFERS
100 int "Number of storage pipeline buffers"
101 range 2 4
102 default 2
103 help
104 Usually 2 buffers are enough to establish a good buffering
105 pipeline. The number may be increased in order to compensate
106 for a bursty VFS behaviour. For instance there may be CPU wake up
107 latencies that makes the VFS to appear bursty in a system with
108 an CPU on-demand governor. Especially if DMA is doing IO to
109 offload the CPU. In this case the CPU will go into power
110 save often and spin up occasionally to move data within VFS.
111 If selecting USB_GADGET_DEBUG_FILES this value may be set by
112 a module parameter as well.
113 If unsure, say 2.
114
99# 115#
100# USB Peripheral Controller Support 116# USB Peripheral Controller Support
101# 117#
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 4306a8339487..756941473148 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -362,7 +362,7 @@ struct fsg_common {
362 362
363 struct fsg_buffhd *next_buffhd_to_fill; 363 struct fsg_buffhd *next_buffhd_to_fill;
364 struct fsg_buffhd *next_buffhd_to_drain; 364 struct fsg_buffhd *next_buffhd_to_drain;
365 struct fsg_buffhd buffhds[FSG_NUM_BUFFERS]; 365 struct fsg_buffhd *buffhds;
366 366
367 int cmnd_size; 367 int cmnd_size;
368 u8 cmnd[MAX_COMMAND_SIZE]; 368 u8 cmnd[MAX_COMMAND_SIZE];
@@ -2340,7 +2340,7 @@ reset:
2340 if (common->fsg) { 2340 if (common->fsg) {
2341 fsg = common->fsg; 2341 fsg = common->fsg;
2342 2342
2343 for (i = 0; i < FSG_NUM_BUFFERS; ++i) { 2343 for (i = 0; i < fsg_num_buffers; ++i) {
2344 struct fsg_buffhd *bh = &common->buffhds[i]; 2344 struct fsg_buffhd *bh = &common->buffhds[i];
2345 2345
2346 if (bh->inreq) { 2346 if (bh->inreq) {
@@ -2397,7 +2397,7 @@ reset:
2397 clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); 2397 clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
2398 2398
2399 /* Allocate the requests */ 2399 /* Allocate the requests */
2400 for (i = 0; i < FSG_NUM_BUFFERS; ++i) { 2400 for (i = 0; i < fsg_num_buffers; ++i) {
2401 struct fsg_buffhd *bh = &common->buffhds[i]; 2401 struct fsg_buffhd *bh = &common->buffhds[i];
2402 2402
2403 rc = alloc_request(common, fsg->bulk_in, &bh->inreq); 2403 rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
@@ -2466,7 +2466,7 @@ static void handle_exception(struct fsg_common *common)
2466 2466
2467 /* Cancel all the pending transfers */ 2467 /* Cancel all the pending transfers */
2468 if (likely(common->fsg)) { 2468 if (likely(common->fsg)) {
2469 for (i = 0; i < FSG_NUM_BUFFERS; ++i) { 2469 for (i = 0; i < fsg_num_buffers; ++i) {
2470 bh = &common->buffhds[i]; 2470 bh = &common->buffhds[i];
2471 if (bh->inreq_busy) 2471 if (bh->inreq_busy)
2472 usb_ep_dequeue(common->fsg->bulk_in, bh->inreq); 2472 usb_ep_dequeue(common->fsg->bulk_in, bh->inreq);
@@ -2478,7 +2478,7 @@ static void handle_exception(struct fsg_common *common)
2478 /* Wait until everything is idle */ 2478 /* Wait until everything is idle */
2479 for (;;) { 2479 for (;;) {
2480 int num_active = 0; 2480 int num_active = 0;
2481 for (i = 0; i < FSG_NUM_BUFFERS; ++i) { 2481 for (i = 0; i < fsg_num_buffers; ++i) {
2482 bh = &common->buffhds[i]; 2482 bh = &common->buffhds[i];
2483 num_active += bh->inreq_busy + bh->outreq_busy; 2483 num_active += bh->inreq_busy + bh->outreq_busy;
2484 } 2484 }
@@ -2501,7 +2501,7 @@ static void handle_exception(struct fsg_common *common)
2501 */ 2501 */
2502 spin_lock_irq(&common->lock); 2502 spin_lock_irq(&common->lock);
2503 2503
2504 for (i = 0; i < FSG_NUM_BUFFERS; ++i) { 2504 for (i = 0; i < fsg_num_buffers; ++i) {
2505 bh = &common->buffhds[i]; 2505 bh = &common->buffhds[i];
2506 bh->state = BUF_STATE_EMPTY; 2506 bh->state = BUF_STATE_EMPTY;
2507 } 2507 }
@@ -2710,6 +2710,10 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
2710 int nluns, i, rc; 2710 int nluns, i, rc;
2711 char *pathbuf; 2711 char *pathbuf;
2712 2712
2713 rc = fsg_num_buffers_validate();
2714 if (rc != 0)
2715 return ERR_PTR(rc);
2716
2713 /* Find out how many LUNs there should be */ 2717 /* Find out how many LUNs there should be */
2714 nluns = cfg->nluns; 2718 nluns = cfg->nluns;
2715 if (nluns < 1 || nluns > FSG_MAX_LUNS) { 2719 if (nluns < 1 || nluns > FSG_MAX_LUNS) {
@@ -2728,6 +2732,14 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
2728 common->free_storage_on_release = 0; 2732 common->free_storage_on_release = 0;
2729 } 2733 }
2730 2734
2735 common->buffhds = kcalloc(fsg_num_buffers,
2736 sizeof *(common->buffhds), GFP_KERNEL);
2737 if (!common->buffhds) {
2738 if (common->free_storage_on_release)
2739 kfree(common);
2740 return ERR_PTR(-ENOMEM);
2741 }
2742
2731 common->ops = cfg->ops; 2743 common->ops = cfg->ops;
2732 common->private_data = cfg->private_data; 2744 common->private_data = cfg->private_data;
2733 2745
@@ -2805,7 +2817,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
2805 2817
2806 /* Data buffers cyclic list */ 2818 /* Data buffers cyclic list */
2807 bh = common->buffhds; 2819 bh = common->buffhds;
2808 i = FSG_NUM_BUFFERS; 2820 i = fsg_num_buffers;
2809 goto buffhds_first_it; 2821 goto buffhds_first_it;
2810 do { 2822 do {
2811 bh->next = bh + 1; 2823 bh->next = bh + 1;
@@ -2931,12 +2943,13 @@ static void fsg_common_release(struct kref *ref)
2931 2943
2932 { 2944 {
2933 struct fsg_buffhd *bh = common->buffhds; 2945 struct fsg_buffhd *bh = common->buffhds;
2934 unsigned i = FSG_NUM_BUFFERS; 2946 unsigned i = fsg_num_buffers;
2935 do { 2947 do {
2936 kfree(bh->buf); 2948 kfree(bh->buf);
2937 } while (++bh, --i); 2949 } while (++bh, --i);
2938 } 2950 }
2939 2951
2952 kfree(common->buffhds);
2940 if (common->free_storage_on_release) 2953 if (common->free_storage_on_release)
2941 kfree(common); 2954 kfree(common);
2942} 2955}
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index c6f96a2b3110..4b9797d07a67 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -460,7 +460,6 @@ struct fsg_dev {
460 460
461 struct fsg_buffhd *next_buffhd_to_fill; 461 struct fsg_buffhd *next_buffhd_to_fill;
462 struct fsg_buffhd *next_buffhd_to_drain; 462 struct fsg_buffhd *next_buffhd_to_drain;
463 struct fsg_buffhd buffhds[FSG_NUM_BUFFERS];
464 463
465 int thread_wakeup_needed; 464 int thread_wakeup_needed;
466 struct completion thread_notifier; 465 struct completion thread_notifier;
@@ -487,6 +486,8 @@ struct fsg_dev {
487 unsigned int nluns; 486 unsigned int nluns;
488 struct fsg_lun *luns; 487 struct fsg_lun *luns;
489 struct fsg_lun *curlun; 488 struct fsg_lun *curlun;
489 /* Must be the last entry */
490 struct fsg_buffhd buffhds[];
490}; 491};
491 492
492typedef void (*fsg_routine_t)(struct fsg_dev *); 493typedef void (*fsg_routine_t)(struct fsg_dev *);
@@ -2737,7 +2738,7 @@ static int do_set_interface(struct fsg_dev *fsg, int altsetting)
2737 2738
2738reset: 2739reset:
2739 /* Deallocate the requests */ 2740 /* Deallocate the requests */
2740 for (i = 0; i < FSG_NUM_BUFFERS; ++i) { 2741 for (i = 0; i < fsg_num_buffers; ++i) {
2741 struct fsg_buffhd *bh = &fsg->buffhds[i]; 2742 struct fsg_buffhd *bh = &fsg->buffhds[i];
2742 2743
2743 if (bh->inreq) { 2744 if (bh->inreq) {
@@ -2798,7 +2799,7 @@ reset:
2798 } 2799 }
2799 2800
2800 /* Allocate the requests */ 2801 /* Allocate the requests */
2801 for (i = 0; i < FSG_NUM_BUFFERS; ++i) { 2802 for (i = 0; i < fsg_num_buffers; ++i) {
2802 struct fsg_buffhd *bh = &fsg->buffhds[i]; 2803 struct fsg_buffhd *bh = &fsg->buffhds[i];
2803 2804
2804 if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0) 2805 if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0)
@@ -2894,7 +2895,7 @@ static void handle_exception(struct fsg_dev *fsg)
2894 /* Cancel all the pending transfers */ 2895 /* Cancel all the pending transfers */
2895 if (fsg->intreq_busy) 2896 if (fsg->intreq_busy)
2896 usb_ep_dequeue(fsg->intr_in, fsg->intreq); 2897 usb_ep_dequeue(fsg->intr_in, fsg->intreq);
2897 for (i = 0; i < FSG_NUM_BUFFERS; ++i) { 2898 for (i = 0; i < fsg_num_buffers; ++i) {
2898 bh = &fsg->buffhds[i]; 2899 bh = &fsg->buffhds[i];
2899 if (bh->inreq_busy) 2900 if (bh->inreq_busy)
2900 usb_ep_dequeue(fsg->bulk_in, bh->inreq); 2901 usb_ep_dequeue(fsg->bulk_in, bh->inreq);
@@ -2905,7 +2906,7 @@ static void handle_exception(struct fsg_dev *fsg)
2905 /* Wait until everything is idle */ 2906 /* Wait until everything is idle */
2906 for (;;) { 2907 for (;;) {
2907 num_active = fsg->intreq_busy; 2908 num_active = fsg->intreq_busy;
2908 for (i = 0; i < FSG_NUM_BUFFERS; ++i) { 2909 for (i = 0; i < fsg_num_buffers; ++i) {
2909 bh = &fsg->buffhds[i]; 2910 bh = &fsg->buffhds[i];
2910 num_active += bh->inreq_busy + bh->outreq_busy; 2911 num_active += bh->inreq_busy + bh->outreq_busy;
2911 } 2912 }
@@ -2927,7 +2928,7 @@ static void handle_exception(struct fsg_dev *fsg)
2927 * state, and the exception. Then invoke the handler. */ 2928 * state, and the exception. Then invoke the handler. */
2928 spin_lock_irq(&fsg->lock); 2929 spin_lock_irq(&fsg->lock);
2929 2930
2930 for (i = 0; i < FSG_NUM_BUFFERS; ++i) { 2931 for (i = 0; i < fsg_num_buffers; ++i) {
2931 bh = &fsg->buffhds[i]; 2932 bh = &fsg->buffhds[i];
2932 bh->state = BUF_STATE_EMPTY; 2933 bh->state = BUF_STATE_EMPTY;
2933 } 2934 }
@@ -3157,7 +3158,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
3157 } 3158 }
3158 3159
3159 /* Free the data buffers */ 3160 /* Free the data buffers */
3160 for (i = 0; i < FSG_NUM_BUFFERS; ++i) 3161 for (i = 0; i < fsg_num_buffers; ++i)
3161 kfree(fsg->buffhds[i].buf); 3162 kfree(fsg->buffhds[i].buf);
3162 3163
3163 /* Free the request and buffer for endpoint 0 */ 3164 /* Free the request and buffer for endpoint 0 */
@@ -3445,7 +3446,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
3445 req->complete = ep0_complete; 3446 req->complete = ep0_complete;
3446 3447
3447 /* Allocate the data buffers */ 3448 /* Allocate the data buffers */
3448 for (i = 0; i < FSG_NUM_BUFFERS; ++i) { 3449 for (i = 0; i < fsg_num_buffers; ++i) {
3449 struct fsg_buffhd *bh = &fsg->buffhds[i]; 3450 struct fsg_buffhd *bh = &fsg->buffhds[i];
3450 3451
3451 /* Allocate for the bulk-in endpoint. We assume that 3452 /* Allocate for the bulk-in endpoint. We assume that
@@ -3456,7 +3457,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
3456 goto out; 3457 goto out;
3457 bh->next = bh + 1; 3458 bh->next = bh + 1;
3458 } 3459 }
3459 fsg->buffhds[FSG_NUM_BUFFERS - 1].next = &fsg->buffhds[0]; 3460 fsg->buffhds[fsg_num_buffers - 1].next = &fsg->buffhds[0];
3460 3461
3461 /* This should reflect the actual gadget power source */ 3462 /* This should reflect the actual gadget power source */
3462 usb_gadget_set_selfpowered(gadget); 3463 usb_gadget_set_selfpowered(gadget);
@@ -3572,7 +3573,9 @@ static int __init fsg_alloc(void)
3572{ 3573{
3573 struct fsg_dev *fsg; 3574 struct fsg_dev *fsg;
3574 3575
3575 fsg = kzalloc(sizeof *fsg, GFP_KERNEL); 3576 fsg = kzalloc(sizeof *fsg +
3577 fsg_num_buffers * sizeof *(fsg->buffhds), GFP_KERNEL);
3578
3576 if (!fsg) 3579 if (!fsg)
3577 return -ENOMEM; 3580 return -ENOMEM;
3578 spin_lock_init(&fsg->lock); 3581 spin_lock_init(&fsg->lock);
@@ -3590,6 +3593,10 @@ static int __init fsg_init(void)
3590 int rc; 3593 int rc;
3591 struct fsg_dev *fsg; 3594 struct fsg_dev *fsg;
3592 3595
3596 rc = fsg_num_buffers_validate();
3597 if (rc != 0)
3598 return rc;
3599
3593 if ((rc = fsg_alloc()) != 0) 3600 if ((rc = fsg_alloc()) != 0)
3594 return rc; 3601 return rc;
3595 fsg = the_fsg; 3602 fsg = the_fsg;
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 3ea70d8549ef..9fd379998608 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -52,6 +52,12 @@
52 * characters rather then a pointer to void. 52 * characters rather then a pointer to void.
53 */ 53 */
54 54
55/*
56 * When USB_GADGET_DEBUG_FILES is defined the module param num_buffers
57 * sets the number of pipeline buffers (length of the fsg_buffhd array).
58 * The valid range of num_buffers is: num >= 2 && num <= 4.
59 */
60
55 61
56#include <linux/usb/storage.h> 62#include <linux/usb/storage.h>
57#include <scsi/scsi.h> 63#include <scsi/scsi.h>
@@ -264,8 +270,31 @@ static struct fsg_lun *fsg_lun_from_dev(struct device *dev)
264#define EP0_BUFSIZE 256 270#define EP0_BUFSIZE 256
265#define DELAYED_STATUS (EP0_BUFSIZE + 999) /* An impossibly large value */ 271#define DELAYED_STATUS (EP0_BUFSIZE + 999) /* An impossibly large value */
266 272
267/* Number of buffers we will use. 2 is enough for double-buffering */ 273#ifdef CONFIG_USB_GADGET_DEBUG_FILES
268#define FSG_NUM_BUFFERS 2 274
275static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
276module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);
277MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers");
278
279#else
280
281/*
282 * Number of buffers we will use.
283 * 2 is usually enough for good buffering pipeline
284 */
285#define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
286
287#endif /* CONFIG_USB_DEBUG */
288
289/* check if fsg_num_buffers is within a valid range */
290static inline int fsg_num_buffers_validate(void)
291{
292 if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
293 return 0;
294 pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
295 fsg_num_buffers, 2 ,4);
296 return -EINVAL;
297}
269 298
270/* Default size of buffer length. */ 299/* Default size of buffer length. */
271#define FSG_BUFLEN ((u32)16384) 300#define FSG_BUFLEN ((u32)16384)