aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc/usbtest.c
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2015-10-13 03:18:21 -0400
committerFelipe Balbi <balbi@ti.com>2015-10-13 14:19:49 -0400
commit145f48c518edb945ea5b689a1d21052597f9d64b (patch)
tree14b445b06831bb1203810a4c68f2e379b126bdba /drivers/usb/misc/usbtest.c
parent44e4a60dacf8a96f28b5e021b54ba9eeb793ca2e (diff)
usb: misc: usbtest: add bulk queue test
The bulk queue tests are used to show 'best performance' for bulk transfer, we are often asked this question by users. The implementation is the same with iso test, that is queue request at interrupt completion, so we reuse the iso structures, and rename them as common one. It's result should be very close to IC simulation, in order to get that, the device side should also need to prepare enough queue. We have got the 'best performance' (IN: 41MB, OUT: 39MB) at i.mx platform (USB2, ARM Cortex A9, stream mode need to enable) with below command: Host side: modprobe usbtest ./testusb -a -t 27 -g 64 -s 16384 ./testusb -a -t 28 -g 64 -s 16384 Gadget side: modprobe g_zero loopdefault=1 qlen=64 buflen=16384 Signed-off-by: Peter Chen <peter.chen@freescale.com> Cc: Greg KH <gregkh@linuxfoundation.org> Cc: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/misc/usbtest.c')
-rw-r--r--drivers/usb/misc/usbtest.c105
1 files changed, 74 insertions, 31 deletions
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index ad6dd4a1de6c..637f3f7cfce8 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -17,6 +17,7 @@
17static int override_alt = -1; 17static int override_alt = -1;
18module_param_named(alt, override_alt, int, 0644); 18module_param_named(alt, override_alt, int, 0644);
19MODULE_PARM_DESC(alt, ">= 0 to override altsetting selection"); 19MODULE_PARM_DESC(alt, ">= 0 to override altsetting selection");
20static void complicated_callback(struct urb *urb);
20 21
21/*-------------------------------------------------------------------------*/ 22/*-------------------------------------------------------------------------*/
22 23
@@ -239,7 +240,8 @@ static struct urb *usbtest_alloc_urb(
239 unsigned long bytes, 240 unsigned long bytes,
240 unsigned transfer_flags, 241 unsigned transfer_flags,
241 unsigned offset, 242 unsigned offset,
242 u8 bInterval) 243 u8 bInterval,
244 usb_complete_t complete_fn)
243{ 245{
244 struct urb *urb; 246 struct urb *urb;
245 247
@@ -248,10 +250,10 @@ static struct urb *usbtest_alloc_urb(
248 return urb; 250 return urb;
249 251
250 if (bInterval) 252 if (bInterval)
251 usb_fill_int_urb(urb, udev, pipe, NULL, bytes, simple_callback, 253 usb_fill_int_urb(urb, udev, pipe, NULL, bytes, complete_fn,
252 NULL, bInterval); 254 NULL, bInterval);
253 else 255 else
254 usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, simple_callback, 256 usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, complete_fn,
255 NULL); 257 NULL);
256 258
257 urb->interval = (udev->speed == USB_SPEED_HIGH) 259 urb->interval = (udev->speed == USB_SPEED_HIGH)
@@ -296,7 +298,17 @@ static struct urb *simple_alloc_urb(
296 u8 bInterval) 298 u8 bInterval)
297{ 299{
298 return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0, 300 return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0,
299 bInterval); 301 bInterval, simple_callback);
302}
303
304static struct urb *complicated_alloc_urb(
305 struct usb_device *udev,
306 int pipe,
307 unsigned long bytes,
308 u8 bInterval)
309{
310 return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0,
311 bInterval, complicated_callback);
300} 312}
301 313
302static unsigned pattern; 314static unsigned pattern;
@@ -1795,12 +1807,12 @@ static int ctrl_out(struct usbtest_dev *dev,
1795 1807
1796/*-------------------------------------------------------------------------*/ 1808/*-------------------------------------------------------------------------*/
1797 1809
1798/* ISO tests ... mimics common usage 1810/* ISO/BULK tests ... mimics common usage
1799 * - buffer length is split into N packets (mostly maxpacket sized) 1811 * - buffer length is split into N packets (mostly maxpacket sized)
1800 * - multi-buffers according to sglen 1812 * - multi-buffers according to sglen
1801 */ 1813 */
1802 1814
1803struct iso_context { 1815struct transfer_context {
1804 unsigned count; 1816 unsigned count;
1805 unsigned pending; 1817 unsigned pending;
1806 spinlock_t lock; 1818 spinlock_t lock;
@@ -1809,11 +1821,12 @@ struct iso_context {
1809 unsigned long errors; 1821 unsigned long errors;
1810 unsigned long packet_count; 1822 unsigned long packet_count;
1811 struct usbtest_dev *dev; 1823 struct usbtest_dev *dev;
1824 bool is_iso;
1812}; 1825};
1813 1826
1814static void iso_callback(struct urb *urb) 1827static void complicated_callback(struct urb *urb)
1815{ 1828{
1816 struct iso_context *ctx = urb->context; 1829 struct transfer_context *ctx = urb->context;
1817 1830
1818 spin_lock(&ctx->lock); 1831 spin_lock(&ctx->lock);
1819 ctx->count--; 1832 ctx->count--;
@@ -1822,7 +1835,7 @@ static void iso_callback(struct urb *urb)
1822 if (urb->error_count > 0) 1835 if (urb->error_count > 0)
1823 ctx->errors += urb->error_count; 1836 ctx->errors += urb->error_count;
1824 else if (urb->status != 0) 1837 else if (urb->status != 0)
1825 ctx->errors += urb->number_of_packets; 1838 ctx->errors += (ctx->is_iso ? urb->number_of_packets : 1);
1826 else if (urb->actual_length != urb->transfer_buffer_length) 1839 else if (urb->actual_length != urb->transfer_buffer_length)
1827 ctx->errors++; 1840 ctx->errors++;
1828 else if (check_guard_bytes(ctx->dev, urb) != 0) 1841 else if (check_guard_bytes(ctx->dev, urb) != 0)
@@ -1909,7 +1922,7 @@ static struct urb *iso_alloc_urb(
1909 urb->iso_frame_desc[i].offset = maxp * i; 1922 urb->iso_frame_desc[i].offset = maxp * i;
1910 } 1923 }
1911 1924
1912 urb->complete = iso_callback; 1925 urb->complete = complicated_callback;
1913 /* urb->context = SET BY CALLER */ 1926 /* urb->context = SET BY CALLER */
1914 urb->interval = 1 << (desc->bInterval - 1); 1927 urb->interval = 1 << (desc->bInterval - 1);
1915 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; 1928 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
@@ -1917,10 +1930,10 @@ static struct urb *iso_alloc_urb(
1917} 1930}
1918 1931
1919static int 1932static int
1920test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, 1933test_queue(struct usbtest_dev *dev, struct usbtest_param *param,
1921 int pipe, struct usb_endpoint_descriptor *desc, unsigned offset) 1934 int pipe, struct usb_endpoint_descriptor *desc, unsigned offset)
1922{ 1935{
1923 struct iso_context context; 1936 struct transfer_context context;
1924 struct usb_device *udev; 1937 struct usb_device *udev;
1925 unsigned i; 1938 unsigned i;
1926 unsigned long packets = 0; 1939 unsigned long packets = 0;
@@ -1930,20 +1943,20 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param,
1930 memset(&context, 0, sizeof(context)); 1943 memset(&context, 0, sizeof(context));
1931 context.count = param->iterations * param->sglen; 1944 context.count = param->iterations * param->sglen;
1932 context.dev = dev; 1945 context.dev = dev;
1946 context.is_iso = !!desc;
1933 init_completion(&context.done); 1947 init_completion(&context.done);
1934 spin_lock_init(&context.lock); 1948 spin_lock_init(&context.lock);
1935 1949
1936 udev = testdev_to_usbdev(dev); 1950 udev = testdev_to_usbdev(dev);
1937 dev_info(&dev->intf->dev,
1938 "iso period %d %sframes, wMaxPacket %d, transactions: %d\n",
1939 1 << (desc->bInterval - 1),
1940 (udev->speed == USB_SPEED_HIGH) ? "micro" : "",
1941 usb_endpoint_maxp(desc) & 0x7ff,
1942 1 + (0x3 & (usb_endpoint_maxp(desc) >> 11)));
1943 1951
1944 for (i = 0; i < param->sglen; i++) { 1952 for (i = 0; i < param->sglen; i++) {
1945 urbs[i] = iso_alloc_urb(udev, pipe, desc, 1953 if (context.is_iso)
1954 urbs[i] = iso_alloc_urb(udev, pipe, desc,
1946 param->length, offset); 1955 param->length, offset);
1956 else
1957 urbs[i] = complicated_alloc_urb(udev, pipe,
1958 param->length, 0);
1959
1947 if (!urbs[i]) { 1960 if (!urbs[i]) {
1948 status = -ENOMEM; 1961 status = -ENOMEM;
1949 goto fail; 1962 goto fail;
@@ -1952,11 +1965,21 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param,
1952 urbs[i]->context = &context; 1965 urbs[i]->context = &context;
1953 } 1966 }
1954 packets *= param->iterations; 1967 packets *= param->iterations;
1955 dev_info(&dev->intf->dev, 1968
1956 "total %lu msec (%lu packets)\n", 1969 if (context.is_iso) {
1957 (packets * (1 << (desc->bInterval - 1))) 1970 dev_info(&dev->intf->dev,
1958 / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), 1971 "iso period %d %sframes, wMaxPacket %d, transactions: %d\n",
1959 packets); 1972 1 << (desc->bInterval - 1),
1973 (udev->speed == USB_SPEED_HIGH) ? "micro" : "",
1974 usb_endpoint_maxp(desc) & 0x7ff,
1975 1 + (0x3 & (usb_endpoint_maxp(desc) >> 11)));
1976
1977 dev_info(&dev->intf->dev,
1978 "total %lu msec (%lu packets)\n",
1979 (packets * (1 << (desc->bInterval - 1)))
1980 / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1),
1981 packets);
1982 }
1960 1983
1961 spin_lock_irq(&context.lock); 1984 spin_lock_irq(&context.lock);
1962 for (i = 0; i < param->sglen; i++) { 1985 for (i = 0; i < param->sglen; i++) {
@@ -1993,7 +2016,8 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param,
1993 ; 2016 ;
1994 else if (context.submit_error) 2017 else if (context.submit_error)
1995 status = -EACCES; 2018 status = -EACCES;
1996 else if (context.errors > context.packet_count / 10) 2019 else if (context.errors >
2020 (context.is_iso ? context.packet_count / 10 : 0))
1997 status = -EIO; 2021 status = -EIO;
1998 return status; 2022 return status;
1999 2023
@@ -2014,8 +2038,8 @@ static int test_unaligned_bulk(
2014 const char *label) 2038 const char *label)
2015{ 2039{
2016 int retval; 2040 int retval;
2017 struct urb *urb = usbtest_alloc_urb( 2041 struct urb *urb = usbtest_alloc_urb(testdev_to_usbdev(tdev),
2018 testdev_to_usbdev(tdev), pipe, length, transfer_flags, 1, 0); 2042 pipe, length, transfer_flags, 1, 0, simple_callback);
2019 2043
2020 if (!urb) 2044 if (!urb)
2021 return -ENOMEM; 2045 return -ENOMEM;
@@ -2342,7 +2366,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2342 param->iterations, 2366 param->iterations,
2343 param->sglen, param->length); 2367 param->sglen, param->length);
2344 /* FIRMWARE: iso sink */ 2368 /* FIRMWARE: iso sink */
2345 retval = test_iso_queue(dev, param, 2369 retval = test_queue(dev, param,
2346 dev->out_iso_pipe, dev->iso_out, 0); 2370 dev->out_iso_pipe, dev->iso_out, 0);
2347 break; 2371 break;
2348 2372
@@ -2355,7 +2379,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2355 param->iterations, 2379 param->iterations,
2356 param->sglen, param->length); 2380 param->sglen, param->length);
2357 /* FIRMWARE: iso source */ 2381 /* FIRMWARE: iso source */
2358 retval = test_iso_queue(dev, param, 2382 retval = test_queue(dev, param,
2359 dev->in_iso_pipe, dev->iso_in, 0); 2383 dev->in_iso_pipe, dev->iso_in, 0);
2360 break; 2384 break;
2361 2385
@@ -2436,7 +2460,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2436 "TEST 22: write %d iso odd, %d entries of %d bytes\n", 2460 "TEST 22: write %d iso odd, %d entries of %d bytes\n",
2437 param->iterations, 2461 param->iterations,
2438 param->sglen, param->length); 2462 param->sglen, param->length);
2439 retval = test_iso_queue(dev, param, 2463 retval = test_queue(dev, param,
2440 dev->out_iso_pipe, dev->iso_out, 1); 2464 dev->out_iso_pipe, dev->iso_out, 1);
2441 break; 2465 break;
2442 2466
@@ -2447,7 +2471,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2447 "TEST 23: read %d iso odd, %d entries of %d bytes\n", 2471 "TEST 23: read %d iso odd, %d entries of %d bytes\n",
2448 param->iterations, 2472 param->iterations,
2449 param->sglen, param->length); 2473 param->sglen, param->length);
2450 retval = test_iso_queue(dev, param, 2474 retval = test_queue(dev, param,
2451 dev->in_iso_pipe, dev->iso_in, 1); 2475 dev->in_iso_pipe, dev->iso_in, 1);
2452 break; 2476 break;
2453 2477
@@ -2504,6 +2528,25 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2504 retval = simple_io(dev, urb, param->iterations, 0, 0, "test26"); 2528 retval = simple_io(dev, urb, param->iterations, 0, 0, "test26");
2505 simple_free_urb(urb); 2529 simple_free_urb(urb);
2506 break; 2530 break;
2531 case 27:
2532 /* We do performance test, so ignore data compare */
2533 if (dev->out_pipe == 0 || param->sglen == 0 || pattern != 0)
2534 break;
2535 dev_info(&intf->dev,
2536 "TEST 27: bulk write %dMbytes\n", (param->iterations *
2537 param->sglen * param->length) / (1024 * 1024));
2538 retval = test_queue(dev, param,
2539 dev->out_pipe, NULL, 0);
2540 break;
2541 case 28:
2542 if (dev->in_pipe == 0 || param->sglen == 0 || pattern != 0)
2543 break;
2544 dev_info(&intf->dev,
2545 "TEST 28: bulk read %dMbytes\n", (param->iterations *
2546 param->sglen * param->length) / (1024 * 1024));
2547 retval = test_queue(dev, param,
2548 dev->in_pipe, NULL, 0);
2549 break;
2507 } 2550 }
2508 do_gettimeofday(&param->duration); 2551 do_gettimeofday(&param->duration);
2509 param->duration.tv_sec -= start.tv_sec; 2552 param->duration.tv_sec -= start.tv_sec;