unsigned                autoconf:1;
        unsigned                ctrl_out:1;
        unsigned                iso:1;          /* try iso in/out */
+       unsigned                intr:1;         /* try interrupt in/out */
        int                     alt;
 };
 
        int                     out_pipe;
        int                     in_iso_pipe;
        int                     out_iso_pipe;
+       int                     in_int_pipe;
+       int                     out_int_pipe;
        struct usb_endpoint_descriptor  *iso_in, *iso_out;
+       struct usb_endpoint_descriptor  *int_in, *int_out;
        struct mutex            lock;
 
 #define TBUF_SIZE      256
        struct usb_host_interface       *alt;
        struct usb_host_endpoint        *in, *out;
        struct usb_host_endpoint        *iso_in, *iso_out;
+       struct usb_host_endpoint        *int_in, *int_out;
        struct usb_device               *udev;
 
        for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
 
                in = out = NULL;
                iso_in = iso_out = NULL;
+               int_in = int_out = NULL;
                alt = intf->altsetting + tmp;
 
                if (override_alt >= 0 &&
                        switch (usb_endpoint_type(&e->desc)) {
                        case USB_ENDPOINT_XFER_BULK:
                                break;
+                       case USB_ENDPOINT_XFER_INT:
+                               if (dev->info->intr)
+                                       goto try_intr;
                        case USB_ENDPOINT_XFER_ISOC:
                                if (dev->info->iso)
                                        goto try_iso;
                                        out = e;
                        }
                        continue;
+try_intr:
+                       if (usb_endpoint_dir_in(&e->desc)) {
+                               if (!int_in)
+                                       int_in = e;
+                       } else {
+                               if (!int_out)
+                                       int_out = e;
+                       }
+                       continue;
 try_iso:
                        if (usb_endpoint_dir_in(&e->desc)) {
                                if (!iso_in)
                                        iso_out = e;
                        }
                }
-               if ((in && out)  ||  iso_in || iso_out)
+               if ((in && out)  ||  iso_in || iso_out || int_in || int_out)
                        goto found;
        }
        return -EINVAL;
                                iso_out->desc.bEndpointAddress
                                        & USB_ENDPOINT_NUMBER_MASK);
        }
+
+       if (int_in) {
+               dev->int_in = &int_in->desc;
+               dev->in_int_pipe = usb_rcvintpipe(udev,
+                               int_in->desc.bEndpointAddress
+                                       & USB_ENDPOINT_NUMBER_MASK);
+       }
+
+       if (int_out) {
+               dev->int_out = &int_out->desc;
+               dev->out_int_pipe = usb_sndintpipe(udev,
+                               int_out->desc.bEndpointAddress
+                                       & USB_ENDPOINT_NUMBER_MASK);
+       }
        return 0;
 }
 
        int                     pipe,
        unsigned long           bytes,
        unsigned                transfer_flags,
-       unsigned                offset)
+       unsigned                offset,
+       u8                      bInterval)
 {
        struct urb              *urb;
 
        urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!urb)
                return urb;
-       usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, simple_callback, NULL);
+
+       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,
+                               NULL);
+
        urb->interval = (udev->speed == USB_SPEED_HIGH)
                        ? (INTERRUPT_RATE << 3)
                        : INTERRUPT_RATE;
 static struct urb *simple_alloc_urb(
        struct usb_device       *udev,
        int                     pipe,
-       unsigned long           bytes)
+       unsigned long           bytes,
+       u8                      bInterval)
 {
-       return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0);
+       return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0,
+                       bInterval);
 }
 
 static unsigned pattern;
                        goto cleanup;
                }
                req.wLength = cpu_to_le16(len);
-               urb[i] = u = simple_alloc_urb(udev, pipe, len);
+               urb[i] = u = simple_alloc_urb(udev, pipe, len, 0);
                if (!u)
                        goto cleanup;
 
        int                     retval = 0;
 
        init_completion(&completion);
-       urb = simple_alloc_urb(testdev_to_usbdev(dev), pipe, size);
+       urb = simple_alloc_urb(testdev_to_usbdev(dev), pipe, size, 0);
        if (!urb)
                return -ENOMEM;
        urb->context = &completion;
        struct usb_device       *udev = testdev_to_usbdev(dev);
 
        if (udev->speed == USB_SPEED_SUPER)
-               urb = simple_alloc_urb(udev, 0, 1024);
+               urb = simple_alloc_urb(udev, 0, 1024, 0);
        else
-               urb = simple_alloc_urb(udev, 0, 512);
+               urb = simple_alloc_urb(udev, 0, 512, 0);
        if (urb == NULL)
                return -ENOMEM;
 
 {
        int retval;
        struct urb *urb = usbtest_alloc_urb(
-               testdev_to_usbdev(tdev), pipe, length, transfer_flags, 1);
+               testdev_to_usbdev(tdev), pipe, length, transfer_flags, 1, 0);
 
        if (!urb)
                return -ENOMEM;
                dev_info(&intf->dev,
                                "TEST 1:  write %d bytes %u times\n",
                                param->length, param->iterations);
-               urb = simple_alloc_urb(udev, dev->out_pipe, param->length);
+               urb = simple_alloc_urb(udev, dev->out_pipe, param->length, 0);
                if (!urb) {
                        retval = -ENOMEM;
                        break;
                dev_info(&intf->dev,
                                "TEST 2:  read %d bytes %u times\n",
                                param->length, param->iterations);
-               urb = simple_alloc_urb(udev, dev->in_pipe, param->length);
+               urb = simple_alloc_urb(udev, dev->in_pipe, param->length, 0);
                if (!urb) {
                        retval = -ENOMEM;
                        break;
                dev_info(&intf->dev,
                                "TEST 3:  write/%d 0..%d bytes %u times\n",
                                param->vary, param->length, param->iterations);
-               urb = simple_alloc_urb(udev, dev->out_pipe, param->length);
+               urb = simple_alloc_urb(udev, dev->out_pipe, param->length, 0);
                if (!urb) {
                        retval = -ENOMEM;
                        break;
                dev_info(&intf->dev,
                                "TEST 4:  read/%d 0..%d bytes %u times\n",
                                param->vary, param->length, param->iterations);
-               urb = simple_alloc_urb(udev, dev->in_pipe, param->length);
+               urb = simple_alloc_urb(udev, dev->in_pipe, param->length, 0);
                if (!urb) {
                        retval = -ENOMEM;
                        break;
                }
                break;
 
+       /* Simple non-queued interrupt I/O tests */
+       case 25:
+               if (dev->out_int_pipe == 0)
+                       break;
+               dev_info(&intf->dev,
+                               "TEST 25: write %d bytes %u times\n",
+                               param->length, param->iterations);
+               urb = simple_alloc_urb(udev, dev->out_int_pipe, param->length,
+                               dev->int_out->bInterval);
+               if (!urb) {
+                       retval = -ENOMEM;
+                       break;
+               }
+               /* FIRMWARE: interrupt sink (maybe accepts short writes) */
+               retval = simple_io(dev, urb, param->iterations, 0, 0, "test25");
+               simple_free_urb(urb);
+               break;
+       case 26:
+               if (dev->in_int_pipe == 0)
+                       break;
+               dev_info(&intf->dev,
+                               "TEST 26: read %d bytes %u times\n",
+                               param->length, param->iterations);
+               urb = simple_alloc_urb(udev, dev->in_int_pipe, param->length,
+                               dev->int_in->bInterval);
+               if (!urb) {
+                       retval = -ENOMEM;
+                       break;
+               }
+               /* FIRMWARE: interrupt source (maybe generates short writes) */
+               retval = simple_io(dev, urb, param->iterations, 0, 0, "test26");
+               simple_free_urb(urb);
+               break;
        }
        do_gettimeofday(¶m->duration);
        param->duration.tv_sec -= start.tv_sec;
        struct usbtest_info     *info;
        char                    *rtest, *wtest;
        char                    *irtest, *iwtest;
+       char                    *intrtest, *intwtest;
 
        udev = interface_to_usbdev(intf);
 
         */
        rtest = wtest = "";
        irtest = iwtest = "";
+       intrtest = intwtest = "";
        if (force_interrupt || udev->speed == USB_SPEED_LOW) {
                if (info->ep_in) {
                        dev->in_pipe = usb_rcvintpipe(udev, info->ep_in);
                        irtest = " iso-in";
                if (dev->out_iso_pipe)
                        iwtest = " iso-out";
+               if (dev->in_int_pipe)
+                       intrtest = " int-in";
+               if (dev->out_int_pipe)
+                       intwtest = " int-out";
        }
 
        usb_set_intfdata(intf, dev);
        dev_info(&intf->dev, "%s\n", info->name);
-       dev_info(&intf->dev, "%s {control%s%s%s%s%s} tests%s\n",
+       dev_info(&intf->dev, "%s {control%s%s%s%s%s%s%s} tests%s\n",
                        usb_speed_string(udev->speed),
                        info->ctrl_out ? " in/out" : "",
                        rtest, wtest,
                        irtest, iwtest,
+                       intrtest, intwtest,
                        info->alt >= 0 ? " (+alt)" : "");
        return 0;
 }
        .autoconf       = 1,
        .ctrl_out       = 1,
        .iso            = 1,
+       .intr           = 1,
        .alt            = 0,
 };