On Mon, Apr 16, 2012 at 02:19:08PM -0700, Paul Zimmerman wrote: > Enable the usbtest driver to test peripherals with super speed > isoc endpoints. So far this has only been tested with the modified > gadget zero with isoc endpoint support. > > A module parameter 'need_iso' is added to force the driver to look > for an alternate interface containing isoc endpoints, instead of > stopping at the first one with bulk endpoints. > > Signed-off-by: Paul Zimmerman <paulz@xxxxxxxxxxxx> This can be done differently. Ideally we would not need any module parameters. When you want to run the ISO tests, just make sure to set the correct alternate setting. Other than that, it looks ok. > --- > drivers/usb/misc/usbtest.c | 52 ++++++++++++++++++++++++++++++++----------- > 1 files changed, 38 insertions(+), 14 deletions(-) > > diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c > index 8fe901d..e96d9f4 100644 > --- a/drivers/usb/misc/usbtest.c > +++ b/drivers/usb/misc/usbtest.c > @@ -64,6 +64,7 @@ struct usbtest_dev { > int in_iso_pipe; > int out_iso_pipe; > struct usb_endpoint_descriptor *iso_in, *iso_out; > + struct usb_ss_ep_comp_descriptor *iso_in_comp, *iso_out_comp; > struct mutex lock; > > #define TBUF_SIZE 256 > @@ -87,6 +88,10 @@ static struct usb_device *testdev_to_usbdev(struct usbtest_dev *test) > > /*-------------------------------------------------------------------------*/ > > +static unsigned need_iso; > +module_param(need_iso, uint, S_IRUGO|S_IWUSR); > +MODULE_PARM_DESC(need_iso, "require ISO endpoints"); > + > static int > get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf) > { > @@ -137,12 +142,17 @@ try_iso: > iso_out = e; > } > } > - if ((in && out) || iso_in || iso_out) > + if (need_iso && (!iso_in || !iso_out) && > + tmp != intf->num_altsetting - 1) > + continue; > + if ((in && out) || iso_in || iso_out) > goto found; > } > return -EINVAL; > > found: > + if (need_iso) > + dev->info->alt = tmp; > udev = testdev_to_usbdev(dev); > if (alt->desc.bAlternateSetting != 0) { > tmp = usb_set_interface(udev, > @@ -160,6 +170,7 @@ found: > } > if (iso_in) { > dev->iso_in = &iso_in->desc; > + dev->iso_in_comp = &iso_in->ss_ep_comp; > dev->in_iso_pipe = usb_rcvisocpipe(udev, > iso_in->desc.bEndpointAddress > & USB_ENDPOINT_NUMBER_MASK); > @@ -167,6 +178,7 @@ found: > > if (iso_out) { > dev->iso_out = &iso_out->desc; > + dev->iso_out_comp = &iso_out->ss_ep_comp; > dev->out_iso_pipe = usb_sndisocpipe(udev, > iso_out->desc.bEndpointAddress > & USB_ENDPOINT_NUMBER_MASK); > @@ -201,7 +213,8 @@ static struct urb *usbtest_alloc_urb( > if (!urb) > return urb; > usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, simple_callback, NULL); > - urb->interval = (udev->speed == USB_SPEED_HIGH) > + urb->interval = (udev->speed == USB_SPEED_HIGH || > + udev->speed == USB_SPEED_SUPER) > ? (INTERRUPT_RATE << 3) > : INTERRUPT_RATE; > urb->transfer_flags = transfer_flags; > @@ -476,9 +489,9 @@ static int perform_sglist( > > while (retval == 0 && iterations-- > 0) { > retval = usb_sg_init(req, udev, pipe, > - (udev->speed == USB_SPEED_HIGH) > - ? (INTERRUPT_RATE << 3) > - : INTERRUPT_RATE, > + (udev->speed == USB_SPEED_HIGH || > + udev->speed == USB_SPEED_SUPER) > + ? (INTERRUPT_RATE << 3) : INTERRUPT_RATE, > sg, nents, 0, GFP_KERNEL); > > if (retval) > @@ -1583,6 +1596,7 @@ static struct urb *iso_alloc_urb( > struct usb_device *udev, > int pipe, > struct usb_endpoint_descriptor *desc, > + struct usb_ss_ep_comp_descriptor *comp, > long bytes, > unsigned offset > ) > @@ -1594,6 +1608,8 @@ static struct urb *iso_alloc_urb( > return NULL; > maxp = 0x7ff & usb_endpoint_maxp(desc); > maxp *= 1 + (0x3 & (usb_endpoint_maxp(desc) >> 11)); > + maxp *= USB_SS_MULT(comp->bmAttributes); > + maxp *= 1 + comp->bMaxBurst; > packets = DIV_ROUND_UP(bytes, maxp); > > urb = usb_alloc_urb(packets, GFP_KERNEL); > @@ -1639,7 +1655,8 @@ static struct urb *iso_alloc_urb( > > static int > test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, > - int pipe, struct usb_endpoint_descriptor *desc, unsigned offset) > + int pipe, struct usb_endpoint_descriptor *desc, > + struct usb_ss_ep_comp_descriptor *comp, unsigned offset) > { > struct iso_context context; > struct usb_device *udev; > @@ -1662,11 +1679,12 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, > dev_info(&dev->intf->dev, > "... iso period %d %sframes, wMaxPacket %04x\n", > 1 << (desc->bInterval - 1), > - (udev->speed == USB_SPEED_HIGH) ? "micro" : "", > + (udev->speed == USB_SPEED_HIGH || > + udev->speed == USB_SPEED_SUPER) ? "micro" : "", > usb_endpoint_maxp(desc)); > > for (i = 0; i < param->sglen; i++) { > - urbs[i] = iso_alloc_urb(udev, pipe, desc, > + urbs[i] = iso_alloc_urb(udev, pipe, desc, comp, > param->length, offset); > if (!urbs[i]) { > status = -ENOMEM; > @@ -1679,7 +1697,8 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, > dev_info(&dev->intf->dev, > "... total %lu msec (%lu packets)\n", > (packets * (1 << (desc->bInterval - 1))) > - / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), > + / ((udev->speed == USB_SPEED_HIGH || > + udev->speed == USB_SPEED_SUPER) ? 8 : 1), > packets); > > spin_lock_irq(&context.lock); > @@ -2062,7 +2081,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) > param->sglen, param->length); > /* FIRMWARE: iso sink */ > retval = test_iso_queue(dev, param, > - dev->out_iso_pipe, dev->iso_out, 0); > + dev->out_iso_pipe, dev->iso_out, > + dev->iso_out_comp, 0); > break; > > /* iso read tests */ > @@ -2075,7 +2095,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) > param->sglen, param->length); > /* FIRMWARE: iso source */ > retval = test_iso_queue(dev, param, > - dev->in_iso_pipe, dev->iso_in, 0); > + dev->in_iso_pipe, dev->iso_in, > + dev->iso_in_comp, 0); > break; > > /* FIXME scatterlist cancel (needs helper thread) */ > @@ -2156,7 +2177,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) > param->iterations, > param->sglen, param->length); > retval = test_iso_queue(dev, param, > - dev->out_iso_pipe, dev->iso_out, 1); > + dev->out_iso_pipe, dev->iso_out, > + dev->iso_out_comp, 1); > break; > > case 23: > @@ -2167,7 +2189,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) > param->iterations, > param->sglen, param->length); > retval = test_iso_queue(dev, param, > - dev->in_iso_pipe, dev->iso_in, 1); > + dev->in_iso_pipe, dev->iso_in, > + dev->iso_in_comp, 1); > break; > > /* unlink URBs from a bulk-OUT queue */ > @@ -2248,6 +2271,8 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id) > if (!dev) > return -ENOMEM; > info = (struct usbtest_info *) id->driver_info; > + if (need_iso) > + info->iso = 1; > dev->info = info; > mutex_init(&dev->lock); > > @@ -2523,4 +2548,3 @@ module_exit(usbtest_exit); > > MODULE_DESCRIPTION("USB Core/HCD Testing Driver"); > MODULE_LICENSE("GPL"); > - > -- > 1.7.1 > -- balbi
Attachment:
signature.asc
Description: Digital signature