X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fmisc%2Fusbtest.c;fp=drivers%2Fusb%2Fmisc%2Fusbtest.c;h=ccc5e8238bd889581b2b445cdb4b26108b5c6644;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=3104f28f6aa8d130206cacdaf7999cbf63e48f1f;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 3104f28f6..ccc5e8238 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1,7 +1,4 @@ #include -#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG) -# define DEBUG -#endif #include #include #include @@ -9,7 +6,7 @@ #include #include #include -#include +#include #include @@ -381,22 +378,29 @@ alloc_sglist (int nents, int max, int vary) sg = kmalloc (nents * sizeof *sg, SLAB_KERNEL); if (!sg) return NULL; - memset (sg, 0, nents * sizeof *sg); for (i = 0; i < nents; i++) { char *buf; + unsigned j; - buf = kmalloc (size, SLAB_KERNEL); + buf = kzalloc (size, SLAB_KERNEL); if (!buf) { free_sglist (sg, i); return NULL; } - memset (buf, 0, size); /* kmalloc pages are always physically contiguous! */ - sg [i].page = virt_to_page (buf); - sg [i].offset = offset_in_page (buf); - sg [i].length = size; + sg_init_one(&sg[i], buf, size); + + switch (pattern) { + case 0: + /* already zeroed */ + break; + case 1: + for (j = 0; j < size; j++) + *buf++ = (u8) (j % 63); + break; + } if (vary) { size += vary; @@ -432,6 +436,8 @@ static int perform_sglist ( usb_sg_wait (req); retval = req->status; + /* FIXME check resulting data pattern */ + /* FIXME if endpoint halted, clear halt (and log) */ } @@ -461,7 +467,7 @@ static int perform_sglist ( static unsigned realworld = 1; module_param (realworld, uint, 0); -MODULE_PARM_DESC (realworld, "clear to demand stricter ch9 compliance"); +MODULE_PARM_DESC (realworld, "clear to demand stricter spec compliance"); static int get_altsetting (struct usbtest_dev *dev) { @@ -604,9 +610,8 @@ static int ch9_postconfig (struct usbtest_dev *dev) USB_DIR_IN | USB_RECIP_DEVICE, 0, 0, dev->buf, 1, USB_CTRL_GET_TIMEOUT); if (retval != 1 || dev->buf [0] != expected) { - dev_dbg (&iface->dev, - "get config --> %d (%d)\n", retval, - expected); + dev_dbg (&iface->dev, "get config --> %d %d (1 %d)\n", + retval, dev->buf[0], expected); return (retval < 0) ? retval : -EDOM; } } @@ -849,10 +854,9 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) * as with bulk/intr sglists, sglen is the queue depth; it also * controls which subtests run (more tests than sglen) or rerun. */ - urb = kmalloc (param->sglen * sizeof (struct urb *), SLAB_KERNEL); + urb = kcalloc(param->sglen, sizeof(struct urb *), SLAB_KERNEL); if (!urb) return -ENOMEM; - memset (urb, 0, param->sglen * sizeof (struct urb *)); for (i = 0; i < param->sglen; i++) { int pipe = usb_rcvctrlpipe (udev, 0); unsigned len; @@ -984,10 +988,10 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) reqp->number = i % NUM_SUBCASES; reqp->expected = expected; u->setup_packet = (char *) &reqp->setup; + u->transfer_flags |= URB_NO_SETUP_DMA_MAP; u->context = &context; u->complete = ctrl_complete; - u->transfer_flags |= URB_ASYNC_UNLINK; } /* queue the urbs */ @@ -1053,7 +1057,6 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async) urb = simple_alloc_urb (testdev_to_usbdev (dev), pipe, size); if (!urb) return -ENOMEM; - urb->transfer_flags |= URB_ASYNC_UNLINK; urb->context = &completion; urb->complete = unlink1_callback; @@ -1243,7 +1246,7 @@ static int ctrl_out (struct usbtest_dev *dev, char *what = "?"; struct usb_device *udev; - if (length > 0xffff || vary >= length) + if (length < 1 || length > 0xffff || vary >= length) return -EINVAL; buf = kmalloc(length, SLAB_KERNEL); @@ -1266,6 +1269,11 @@ static int ctrl_out (struct usbtest_dev *dev, 0, 0, buf, len, USB_CTRL_SET_TIMEOUT); if (retval != len) { what = "write"; + if (retval >= 0) { + INFO(dev, "ctrl_out, wlen %d (expected %d)\n", + retval, len); + retval = -EBADMSG; + } break; } @@ -1275,6 +1283,11 @@ static int ctrl_out (struct usbtest_dev *dev, 0, 0, buf, len, USB_CTRL_GET_TIMEOUT); if (retval != len) { what = "read"; + if (retval >= 0) { + INFO(dev, "ctrl_out, rlen %d (expected %d)\n", + retval, len); + retval = -EBADMSG; + } break; } @@ -1293,8 +1306,13 @@ static int ctrl_out (struct usbtest_dev *dev, } len += vary; + + /* [real world] the "zero bytes IN" case isn't really used. + * hardware can easily trip up in this wierd case, since its + * status stage is IN, not OUT like other ep0in transfers. + */ if (len > length) - len = 0; + len = realworld ? 1 : 0; } if (retval < 0) @@ -1519,6 +1537,11 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) if (down_interruptible (&dev->sem)) return -ERESTARTSYS; + if (intf->dev.power.power_state.event != PM_EVENT_ON) { + up (&dev->sem); + return -EHOSTUNREACH; + } + /* some devices, like ez-usb default devices, need a non-default * altsetting to have any active endpoints. some tests change * altsettings; force a default so most tests don't need to check. @@ -1762,8 +1785,10 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) case 14: if (!dev->info->ctrl_out) break; - dev_dbg (&intf->dev, "TEST 14: %d ep0out, 0..%d vary %d\n", - param->iterations, param->length, param->vary); + dev_dbg (&intf->dev, "TEST 14: %d ep0out, %d..%d vary %d\n", + param->iterations, + realworld ? 1 : 0, param->length, + param->vary); retval = ctrl_out (dev, param->iterations, param->length, param->vary); break; @@ -1851,10 +1876,9 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) } #endif - dev = kmalloc (sizeof *dev, SLAB_KERNEL); + dev = kzalloc(sizeof(*dev), SLAB_KERNEL); if (!dev) return -ENOMEM; - memset (dev, 0, sizeof *dev); info = (struct usbtest_info *) id->driver_info; dev->info = info; init_MUTEX (&dev->sem); @@ -1927,6 +1951,17 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) return 0; } +static int usbtest_suspend (struct usb_interface *intf, pm_message_t message) +{ + return 0; +} + +static int usbtest_resume (struct usb_interface *intf) +{ + return 0; +} + + static void usbtest_disconnect (struct usb_interface *intf) { struct usbtest_dev *dev = usb_get_intfdata (intf); @@ -2109,12 +2144,13 @@ static struct usb_device_id id_table [] = { MODULE_DEVICE_TABLE (usb, id_table); static struct usb_driver usbtest_driver = { - .owner = THIS_MODULE, .name = "usbtest", .id_table = id_table, .probe = usbtest_probe, .ioctl = usbtest_ioctl, .disconnect = usbtest_disconnect, + .suspend = usbtest_suspend, + .resume = usbtest_resume, }; /*-------------------------------------------------------------------------*/