aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc/usbtest.c
diff options
context:
space:
mode:
authorAmit Virdi <amit.virdi@st.com>2014-08-22 05:06:37 -0400
committerFelipe Balbi <balbi@ti.com>2014-08-29 16:51:11 -0400
commit457a0955e152ac3b0de46ecbe7a8b434856fda67 (patch)
treee0f91f22bd735cb0a921824b42a86f9cd5664abd /drivers/usb/misc/usbtest.c
parentef11982dd7a657512c362242508bb4021e0d67b6 (diff)
usbtest: Add interrupt EP testcases
Two simple test cases for interrupt endpoints are added to the usbtest.c file. These are simple non-queued interrupt IN and interrupt OUT transfers. Currently, only gadget zero is capable of executing the interrupt EP test cases. However, extending the same to other gadgets is extremely simple and can be done on-demand. The two new tests added are - Test 25: To verify Interrupt OUT transfer - Test 26: To verify Interrupt IN transfer Since the default value of wMaxPacketSize is set as 1024, so interrupt IN transfers must be specified with the size parameter = multiple of 1024. Otherwise the default value (512) in the usbtest application fails the transfer. See [RUN 4] for sample logs The application logs (usbtest) and corresponding kernel logs are as following: [Run 1] ./testusb -a -c 10 -s 2048 -t 26 -v 511 usbtest 7-1:3.0: TEST 26: read 2048 bytes 10 times [Run 2] ./testusb -a -c 10 -s 1024 -t 25 -v 511 usbtest 7-1:3.0: TEST 25: write 1024 bytes 10 times [Run 3] ./testusb -a -c 10 -s 1098 -t 25 -v 511 usbtest 7-1:3.0: TEST 25: write 1098 bytes 10 times [Run 4 - Failure case scenario] ./testusb -a -t 26 unknown speed /dev/bus/usb/007/004 0 /dev/bus/usb/007/004 test 26 --> 75 (Value too large for defined data type) usbtest 7-1:3.0: TEST 26: read 512 bytes 1000 times usb 7-1: test26 failed, iterations left 999, status -75 (not 0) Signed-off-by: Amit Virdi <amit.virdi@st.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/misc/usbtest.c')
-rw-r--r--drivers/usb/misc/usbtest.c113
1 files changed, 98 insertions, 15 deletions
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 829f446064ea..90e6644dc886 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -54,6 +54,7 @@ struct usbtest_info {
54 unsigned autoconf:1; 54 unsigned autoconf:1;
55 unsigned ctrl_out:1; 55 unsigned ctrl_out:1;
56 unsigned iso:1; /* try iso in/out */ 56 unsigned iso:1; /* try iso in/out */
57 unsigned intr:1; /* try interrupt in/out */
57 int alt; 58 int alt;
58}; 59};
59 60
@@ -70,7 +71,10 @@ struct usbtest_dev {
70 int out_pipe; 71 int out_pipe;
71 int in_iso_pipe; 72 int in_iso_pipe;
72 int out_iso_pipe; 73 int out_iso_pipe;
74 int in_int_pipe;
75 int out_int_pipe;
73 struct usb_endpoint_descriptor *iso_in, *iso_out; 76 struct usb_endpoint_descriptor *iso_in, *iso_out;
77 struct usb_endpoint_descriptor *int_in, *int_out;
74 struct mutex lock; 78 struct mutex lock;
75 79
76#define TBUF_SIZE 256 80#define TBUF_SIZE 256
@@ -101,6 +105,7 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
101 struct usb_host_interface *alt; 105 struct usb_host_interface *alt;
102 struct usb_host_endpoint *in, *out; 106 struct usb_host_endpoint *in, *out;
103 struct usb_host_endpoint *iso_in, *iso_out; 107 struct usb_host_endpoint *iso_in, *iso_out;
108 struct usb_host_endpoint *int_in, *int_out;
104 struct usb_device *udev; 109 struct usb_device *udev;
105 110
106 for (tmp = 0; tmp < intf->num_altsetting; tmp++) { 111 for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
@@ -108,6 +113,7 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
108 113
109 in = out = NULL; 114 in = out = NULL;
110 iso_in = iso_out = NULL; 115 iso_in = iso_out = NULL;
116 int_in = int_out = NULL;
111 alt = intf->altsetting + tmp; 117 alt = intf->altsetting + tmp;
112 118
113 if (override_alt >= 0 && 119 if (override_alt >= 0 &&
@@ -124,6 +130,9 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
124 switch (usb_endpoint_type(&e->desc)) { 130 switch (usb_endpoint_type(&e->desc)) {
125 case USB_ENDPOINT_XFER_BULK: 131 case USB_ENDPOINT_XFER_BULK:
126 break; 132 break;
133 case USB_ENDPOINT_XFER_INT:
134 if (dev->info->intr)
135 goto try_intr;
127 case USB_ENDPOINT_XFER_ISOC: 136 case USB_ENDPOINT_XFER_ISOC:
128 if (dev->info->iso) 137 if (dev->info->iso)
129 goto try_iso; 138 goto try_iso;
@@ -139,6 +148,15 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
139 out = e; 148 out = e;
140 } 149 }
141 continue; 150 continue;
151try_intr:
152 if (usb_endpoint_dir_in(&e->desc)) {
153 if (!int_in)
154 int_in = e;
155 } else {
156 if (!int_out)
157 int_out = e;
158 }
159 continue;
142try_iso: 160try_iso:
143 if (usb_endpoint_dir_in(&e->desc)) { 161 if (usb_endpoint_dir_in(&e->desc)) {
144 if (!iso_in) 162 if (!iso_in)
@@ -148,7 +166,7 @@ try_iso:
148 iso_out = e; 166 iso_out = e;
149 } 167 }
150 } 168 }
151 if ((in && out) || iso_in || iso_out) 169 if ((in && out) || iso_in || iso_out || int_in || int_out)
152 goto found; 170 goto found;
153 } 171 }
154 return -EINVAL; 172 return -EINVAL;
@@ -183,6 +201,20 @@ found:
183 iso_out->desc.bEndpointAddress 201 iso_out->desc.bEndpointAddress
184 & USB_ENDPOINT_NUMBER_MASK); 202 & USB_ENDPOINT_NUMBER_MASK);
185 } 203 }
204
205 if (int_in) {
206 dev->int_in = &int_in->desc;
207 dev->in_int_pipe = usb_rcvintpipe(udev,
208 int_in->desc.bEndpointAddress
209 & USB_ENDPOINT_NUMBER_MASK);
210 }
211
212 if (int_out) {
213 dev->int_out = &int_out->desc;
214 dev->out_int_pipe = usb_sndintpipe(udev,
215 int_out->desc.bEndpointAddress
216 & USB_ENDPOINT_NUMBER_MASK);
217 }
186 return 0; 218 return 0;
187} 219}
188 220
@@ -205,14 +237,22 @@ static struct urb *usbtest_alloc_urb(
205 int pipe, 237 int pipe,
206 unsigned long bytes, 238 unsigned long bytes,
207 unsigned transfer_flags, 239 unsigned transfer_flags,
208 unsigned offset) 240 unsigned offset,
241 u8 bInterval)
209{ 242{
210 struct urb *urb; 243 struct urb *urb;
211 244
212 urb = usb_alloc_urb(0, GFP_KERNEL); 245 urb = usb_alloc_urb(0, GFP_KERNEL);
213 if (!urb) 246 if (!urb)
214 return urb; 247 return urb;
215 usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, simple_callback, NULL); 248
249 if (bInterval)
250 usb_fill_int_urb(urb, udev, pipe, NULL, bytes, simple_callback,
251 NULL, bInterval);
252 else
253 usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, simple_callback,
254 NULL);
255
216 urb->interval = (udev->speed == USB_SPEED_HIGH) 256 urb->interval = (udev->speed == USB_SPEED_HIGH)
217 ? (INTERRUPT_RATE << 3) 257 ? (INTERRUPT_RATE << 3)
218 : INTERRUPT_RATE; 258 : INTERRUPT_RATE;
@@ -251,9 +291,11 @@ static struct urb *usbtest_alloc_urb(
251static struct urb *simple_alloc_urb( 291static struct urb *simple_alloc_urb(
252 struct usb_device *udev, 292 struct usb_device *udev,
253 int pipe, 293 int pipe,
254 unsigned long bytes) 294 unsigned long bytes,
295 u8 bInterval)
255{ 296{
256 return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0); 297 return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0,
298 bInterval);
257} 299}
258 300
259static unsigned pattern; 301static unsigned pattern;
@@ -1255,7 +1297,7 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)
1255 goto cleanup; 1297 goto cleanup;
1256 } 1298 }
1257 req.wLength = cpu_to_le16(len); 1299 req.wLength = cpu_to_le16(len);
1258 urb[i] = u = simple_alloc_urb(udev, pipe, len); 1300 urb[i] = u = simple_alloc_urb(udev, pipe, len, 0);
1259 if (!u) 1301 if (!u)
1260 goto cleanup; 1302 goto cleanup;
1261 1303
@@ -1328,7 +1370,7 @@ static int unlink1(struct usbtest_dev *dev, int pipe, int size, int async)
1328 int retval = 0; 1370 int retval = 0;
1329 1371
1330 init_completion(&completion); 1372 init_completion(&completion);
1331 urb = simple_alloc_urb(testdev_to_usbdev(dev), pipe, size); 1373 urb = simple_alloc_urb(testdev_to_usbdev(dev), pipe, size, 0);
1332 if (!urb) 1374 if (!urb)
1333 return -ENOMEM; 1375 return -ENOMEM;
1334 urb->context = &completion; 1376 urb->context = &completion;
@@ -1616,9 +1658,9 @@ static int halt_simple(struct usbtest_dev *dev)
1616 struct usb_device *udev = testdev_to_usbdev(dev); 1658 struct usb_device *udev = testdev_to_usbdev(dev);
1617 1659
1618 if (udev->speed == USB_SPEED_SUPER) 1660 if (udev->speed == USB_SPEED_SUPER)
1619 urb = simple_alloc_urb(udev, 0, 1024); 1661 urb = simple_alloc_urb(udev, 0, 1024, 0);
1620 else 1662 else
1621 urb = simple_alloc_urb(udev, 0, 512); 1663 urb = simple_alloc_urb(udev, 0, 512, 0);
1622 if (urb == NULL) 1664 if (urb == NULL)
1623 return -ENOMEM; 1665 return -ENOMEM;
1624 1666
@@ -1962,7 +2004,7 @@ static int test_unaligned_bulk(
1962{ 2004{
1963 int retval; 2005 int retval;
1964 struct urb *urb = usbtest_alloc_urb( 2006 struct urb *urb = usbtest_alloc_urb(
1965 testdev_to_usbdev(tdev), pipe, length, transfer_flags, 1); 2007 testdev_to_usbdev(tdev), pipe, length, transfer_flags, 1, 0);
1966 2008
1967 if (!urb) 2009 if (!urb)
1968 return -ENOMEM; 2010 return -ENOMEM;
@@ -2068,7 +2110,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2068 dev_info(&intf->dev, 2110 dev_info(&intf->dev,
2069 "TEST 1: write %d bytes %u times\n", 2111 "TEST 1: write %d bytes %u times\n",
2070 param->length, param->iterations); 2112 param->length, param->iterations);
2071 urb = simple_alloc_urb(udev, dev->out_pipe, param->length); 2113 urb = simple_alloc_urb(udev, dev->out_pipe, param->length, 0);
2072 if (!urb) { 2114 if (!urb) {
2073 retval = -ENOMEM; 2115 retval = -ENOMEM;
2074 break; 2116 break;
@@ -2083,7 +2125,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2083 dev_info(&intf->dev, 2125 dev_info(&intf->dev,
2084 "TEST 2: read %d bytes %u times\n", 2126 "TEST 2: read %d bytes %u times\n",
2085 param->length, param->iterations); 2127 param->length, param->iterations);
2086 urb = simple_alloc_urb(udev, dev->in_pipe, param->length); 2128 urb = simple_alloc_urb(udev, dev->in_pipe, param->length, 0);
2087 if (!urb) { 2129 if (!urb) {
2088 retval = -ENOMEM; 2130 retval = -ENOMEM;
2089 break; 2131 break;
@@ -2098,7 +2140,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2098 dev_info(&intf->dev, 2140 dev_info(&intf->dev,
2099 "TEST 3: write/%d 0..%d bytes %u times\n", 2141 "TEST 3: write/%d 0..%d bytes %u times\n",
2100 param->vary, param->length, param->iterations); 2142 param->vary, param->length, param->iterations);
2101 urb = simple_alloc_urb(udev, dev->out_pipe, param->length); 2143 urb = simple_alloc_urb(udev, dev->out_pipe, param->length, 0);
2102 if (!urb) { 2144 if (!urb) {
2103 retval = -ENOMEM; 2145 retval = -ENOMEM;
2104 break; 2146 break;
@@ -2114,7 +2156,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2114 dev_info(&intf->dev, 2156 dev_info(&intf->dev,
2115 "TEST 4: read/%d 0..%d bytes %u times\n", 2157 "TEST 4: read/%d 0..%d bytes %u times\n",
2116 param->vary, param->length, param->iterations); 2158 param->vary, param->length, param->iterations);
2117 urb = simple_alloc_urb(udev, dev->in_pipe, param->length); 2159 urb = simple_alloc_urb(udev, dev->in_pipe, param->length, 0);
2118 if (!urb) { 2160 if (!urb) {
2119 retval = -ENOMEM; 2161 retval = -ENOMEM;
2120 break; 2162 break;
@@ -2411,6 +2453,39 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2411 } 2453 }
2412 break; 2454 break;
2413 2455
2456 /* Simple non-queued interrupt I/O tests */
2457 case 25:
2458 if (dev->out_int_pipe == 0)
2459 break;
2460 dev_info(&intf->dev,
2461 "TEST 25: write %d bytes %u times\n",
2462 param->length, param->iterations);
2463 urb = simple_alloc_urb(udev, dev->out_int_pipe, param->length,
2464 dev->int_out->bInterval);
2465 if (!urb) {
2466 retval = -ENOMEM;
2467 break;
2468 }
2469 /* FIRMWARE: interrupt sink (maybe accepts short writes) */
2470 retval = simple_io(dev, urb, param->iterations, 0, 0, "test25");
2471 simple_free_urb(urb);
2472 break;
2473 case 26:
2474 if (dev->in_int_pipe == 0)
2475 break;
2476 dev_info(&intf->dev,
2477 "TEST 26: read %d bytes %u times\n",
2478 param->length, param->iterations);
2479 urb = simple_alloc_urb(udev, dev->in_int_pipe, param->length,
2480 dev->int_in->bInterval);
2481 if (!urb) {
2482 retval = -ENOMEM;
2483 break;
2484 }
2485 /* FIRMWARE: interrupt source (maybe generates short writes) */
2486 retval = simple_io(dev, urb, param->iterations, 0, 0, "test26");
2487 simple_free_urb(urb);
2488 break;
2414 } 2489 }
2415 do_gettimeofday(&param->duration); 2490 do_gettimeofday(&param->duration);
2416 param->duration.tv_sec -= start.tv_sec; 2491 param->duration.tv_sec -= start.tv_sec;
@@ -2447,6 +2522,7 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)
2447 struct usbtest_info *info; 2522 struct usbtest_info *info;
2448 char *rtest, *wtest; 2523 char *rtest, *wtest;
2449 char *irtest, *iwtest; 2524 char *irtest, *iwtest;
2525 char *intrtest, *intwtest;
2450 2526
2451 udev = interface_to_usbdev(intf); 2527 udev = interface_to_usbdev(intf);
2452 2528
@@ -2487,6 +2563,7 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)
2487 */ 2563 */
2488 rtest = wtest = ""; 2564 rtest = wtest = "";
2489 irtest = iwtest = ""; 2565 irtest = iwtest = "";
2566 intrtest = intwtest = "";
2490 if (force_interrupt || udev->speed == USB_SPEED_LOW) { 2567 if (force_interrupt || udev->speed == USB_SPEED_LOW) {
2491 if (info->ep_in) { 2568 if (info->ep_in) {
2492 dev->in_pipe = usb_rcvintpipe(udev, info->ep_in); 2569 dev->in_pipe = usb_rcvintpipe(udev, info->ep_in);
@@ -2525,15 +2602,20 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)
2525 irtest = " iso-in"; 2602 irtest = " iso-in";
2526 if (dev->out_iso_pipe) 2603 if (dev->out_iso_pipe)
2527 iwtest = " iso-out"; 2604 iwtest = " iso-out";
2605 if (dev->in_int_pipe)
2606 intrtest = " int-in";
2607 if (dev->out_int_pipe)
2608 intwtest = " int-out";
2528 } 2609 }
2529 2610
2530 usb_set_intfdata(intf, dev); 2611 usb_set_intfdata(intf, dev);
2531 dev_info(&intf->dev, "%s\n", info->name); 2612 dev_info(&intf->dev, "%s\n", info->name);
2532 dev_info(&intf->dev, "%s {control%s%s%s%s%s} tests%s\n", 2613 dev_info(&intf->dev, "%s {control%s%s%s%s%s%s%s} tests%s\n",
2533 usb_speed_string(udev->speed), 2614 usb_speed_string(udev->speed),
2534 info->ctrl_out ? " in/out" : "", 2615 info->ctrl_out ? " in/out" : "",
2535 rtest, wtest, 2616 rtest, wtest,
2536 irtest, iwtest, 2617 irtest, iwtest,
2618 intrtest, intwtest,
2537 info->alt >= 0 ? " (+alt)" : ""); 2619 info->alt >= 0 ? " (+alt)" : "");
2538 return 0; 2620 return 0;
2539} 2621}
@@ -2607,6 +2689,7 @@ static struct usbtest_info gz_info = {
2607 .autoconf = 1, 2689 .autoconf = 1,
2608 .ctrl_out = 1, 2690 .ctrl_out = 1,
2609 .iso = 1, 2691 .iso = 1,
2692 .intr = 1,
2610 .alt = 0, 2693 .alt = 0,
2611}; 2694};
2612 2695