The bulk queue tests are used to show 'best performance' for bulk transfer, we are often asked this question by users. 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) 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@xxxxxxxxxxxxx> --- I am not sure if it is good to reuse iso structure, so I take it as RFC. If reuse is accepted, I will rename the iso structures to common one. drivers/usb/misc/usbtest.c | 88 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 19 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index ad6dd4a..f1faeb9 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -17,6 +17,7 @@ static int override_alt = -1; module_param_named(alt, override_alt, int, 0644); MODULE_PARM_DESC(alt, ">= 0 to override altsetting selection"); +static void iso_callback(struct urb *urb); /*-------------------------------------------------------------------------*/ @@ -239,7 +240,8 @@ static struct urb *usbtest_alloc_urb( unsigned long bytes, unsigned transfer_flags, unsigned offset, - u8 bInterval) + u8 bInterval, + bool queue_callback) { struct urb *urb; @@ -250,9 +252,14 @@ static struct urb *usbtest_alloc_urb( if (bInterval) usb_fill_int_urb(urb, udev, pipe, NULL, bytes, simple_callback, NULL, bInterval); - else - usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, simple_callback, + else { + if (queue_callback) + usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, iso_callback, NULL); + else + usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, simple_callback, + NULL); + } urb->interval = (udev->speed == USB_SPEED_HIGH) ? (INTERRUPT_RATE << 3) @@ -296,7 +303,17 @@ static struct urb *simple_alloc_urb( u8 bInterval) { return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0, - bInterval); + bInterval, false); +} + +static struct urb *test_queue_alloc_urb( + struct usb_device *udev, + int pipe, + unsigned long bytes, + u8 bInterval) +{ + return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0, + bInterval, true); } static unsigned pattern; @@ -1809,6 +1826,7 @@ struct iso_context { unsigned long errors; unsigned long packet_count; struct usbtest_dev *dev; + bool is_iso; }; static void iso_callback(struct urb *urb) @@ -1822,7 +1840,7 @@ static void iso_callback(struct urb *urb) if (urb->error_count > 0) ctx->errors += urb->error_count; else if (urb->status != 0) - ctx->errors += urb->number_of_packets; + ctx->errors += (ctx->is_iso ? urb->number_of_packets : 1); else if (urb->actual_length != urb->transfer_buffer_length) ctx->errors++; else if (check_guard_bytes(ctx->dev, urb) != 0) @@ -1930,20 +1948,20 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, memset(&context, 0, sizeof(context)); context.count = param->iterations * param->sglen; context.dev = dev; + context.is_iso = !!desc; init_completion(&context.done); spin_lock_init(&context.lock); udev = testdev_to_usbdev(dev); - dev_info(&dev->intf->dev, - "iso period %d %sframes, wMaxPacket %d, transactions: %d\n", - 1 << (desc->bInterval - 1), - (udev->speed == USB_SPEED_HIGH) ? "micro" : "", - usb_endpoint_maxp(desc) & 0x7ff, - 1 + (0x3 & (usb_endpoint_maxp(desc) >> 11))); for (i = 0; i < param->sglen; i++) { - urbs[i] = iso_alloc_urb(udev, pipe, desc, + if (context.is_iso) + urbs[i] = iso_alloc_urb(udev, pipe, desc, param->length, offset); + else + urbs[i] = test_queue_alloc_urb(udev, pipe, + param->length, 0); + if (!urbs[i]) { status = -ENOMEM; goto fail; @@ -1952,11 +1970,21 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, urbs[i]->context = &context; } packets *= param->iterations; - dev_info(&dev->intf->dev, - "total %lu msec (%lu packets)\n", - (packets * (1 << (desc->bInterval - 1))) - / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), - packets); + + if (context.is_iso) { + dev_info(&dev->intf->dev, + "iso period %d %sframes, wMaxPacket %d, transactions: %d\n", + 1 << (desc->bInterval - 1), + (udev->speed == USB_SPEED_HIGH) ? "micro" : "", + usb_endpoint_maxp(desc) & 0x7ff, + 1 + (0x3 & (usb_endpoint_maxp(desc) >> 11))); + + dev_info(&dev->intf->dev, + "total %lu msec (%lu packets)\n", + (packets * (1 << (desc->bInterval - 1))) + / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), + packets); + } spin_lock_irq(&context.lock); for (i = 0; i < param->sglen; i++) { @@ -1993,7 +2021,7 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, ; else if (context.submit_error) status = -EACCES; - else if (context.errors > context.packet_count / 10) + else if (context.errors > (context.is_iso ? context.packet_count / 10 : 0)) status = -EIO; return status; @@ -2015,7 +2043,7 @@ static int test_unaligned_bulk( { int retval; struct urb *urb = usbtest_alloc_urb( - testdev_to_usbdev(tdev), pipe, length, transfer_flags, 1, 0); + testdev_to_usbdev(tdev), pipe, length, transfer_flags, 1, 0, false); if (!urb) return -ENOMEM; @@ -2504,6 +2532,28 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) retval = simple_io(dev, urb, param->iterations, 0, 0, "test26"); simple_free_urb(urb); break; + case 27: + if (dev->out_pipe == 0 || param->sglen == 0) + break; + dev_info(&intf->dev, + "TEST 27: write %d bulk, %d entries of %d bytes\n", + param->iterations, + param->sglen, param->length); + retval = test_iso_queue(dev, param, + dev->out_pipe, NULL, 0); + break; + + /* iso read tests */ + case 28: + if (dev->in_pipe == 0 || param->sglen == 0) + break; + dev_info(&intf->dev, + "TEST 28: read %d bulk, %d entries of %d bytes\n", + param->iterations, + param->sglen, param->length); + retval = test_iso_queue(dev, param, + dev->in_pipe, NULL, 0); + break; } do_gettimeofday(¶m->duration); param->duration.tv_sec -= start.tv_sec; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html