aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc/usbtest.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/misc/usbtest.c')
-rw-r--r--drivers/usb/misc/usbtest.c131
1 files changed, 126 insertions, 5 deletions
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index ff9a01f8d405..bb10846affc3 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -268,9 +268,9 @@ static inline void simple_fill_buf(struct urb *urb)
268 } 268 }
269} 269}
270 270
271static inline unsigned buffer_offset(void *buf) 271static inline unsigned long buffer_offset(void *buf)
272{ 272{
273 return (unsigned)buf & (ARCH_KMALLOC_MINALIGN - 1); 273 return (unsigned long)buf & (ARCH_KMALLOC_MINALIGN - 1);
274} 274}
275 275
276static int check_guard_bytes(struct usbtest_dev *tdev, struct urb *urb) 276static int check_guard_bytes(struct usbtest_dev *tdev, struct urb *urb)
@@ -329,7 +329,7 @@ static int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb)
329 329
330static void simple_free_urb(struct urb *urb) 330static void simple_free_urb(struct urb *urb)
331{ 331{
332 unsigned offset = buffer_offset(urb->transfer_buffer); 332 unsigned long offset = buffer_offset(urb->transfer_buffer);
333 333
334 if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) 334 if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
335 usb_free_coherent( 335 usb_free_coherent(
@@ -1030,6 +1030,8 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)
1030 req.wValue = cpu_to_le16((USB_DT_DEVICE << 8) | 0); 1030 req.wValue = cpu_to_le16((USB_DT_DEVICE << 8) | 0);
1031 /* device descriptor size == 18 bytes */ 1031 /* device descriptor size == 18 bytes */
1032 len = udev->descriptor.bMaxPacketSize0; 1032 len = udev->descriptor.bMaxPacketSize0;
1033 if (udev->speed == USB_SPEED_SUPER)
1034 len = 512;
1033 switch (len) { 1035 switch (len) {
1034 case 8: 1036 case 8:
1035 len = 24; 1037 len = 24;
@@ -1195,6 +1197,104 @@ static int unlink_simple(struct usbtest_dev *dev, int pipe, int len)
1195 1197
1196/*-------------------------------------------------------------------------*/ 1198/*-------------------------------------------------------------------------*/
1197 1199
1200struct queued_ctx {
1201 struct completion complete;
1202 atomic_t pending;
1203 unsigned num;
1204 int status;
1205 struct urb **urbs;
1206};
1207
1208static void unlink_queued_callback(struct urb *urb)
1209{
1210 int status = urb->status;
1211 struct queued_ctx *ctx = urb->context;
1212
1213 if (ctx->status)
1214 goto done;
1215 if (urb == ctx->urbs[ctx->num - 4] || urb == ctx->urbs[ctx->num - 2]) {
1216 if (status == -ECONNRESET)
1217 goto done;
1218 /* What error should we report if the URB completed normally? */
1219 }
1220 if (status != 0)
1221 ctx->status = status;
1222
1223 done:
1224 if (atomic_dec_and_test(&ctx->pending))
1225 complete(&ctx->complete);
1226}
1227
1228static int unlink_queued(struct usbtest_dev *dev, int pipe, unsigned num,
1229 unsigned size)
1230{
1231 struct queued_ctx ctx;
1232 struct usb_device *udev = testdev_to_usbdev(dev);
1233 void *buf;
1234 dma_addr_t buf_dma;
1235 int i;
1236 int retval = -ENOMEM;
1237
1238 init_completion(&ctx.complete);
1239 atomic_set(&ctx.pending, 1); /* One more than the actual value */
1240 ctx.num = num;
1241 ctx.status = 0;
1242
1243 buf = usb_alloc_coherent(udev, size, GFP_KERNEL, &buf_dma);
1244 if (!buf)
1245 return retval;
1246 memset(buf, 0, size);
1247
1248 /* Allocate and init the urbs we'll queue */
1249 ctx.urbs = kcalloc(num, sizeof(struct urb *), GFP_KERNEL);
1250 if (!ctx.urbs)
1251 goto free_buf;
1252 for (i = 0; i < num; i++) {
1253 ctx.urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
1254 if (!ctx.urbs[i])
1255 goto free_urbs;
1256 usb_fill_bulk_urb(ctx.urbs[i], udev, pipe, buf, size,
1257 unlink_queued_callback, &ctx);
1258 ctx.urbs[i]->transfer_dma = buf_dma;
1259 ctx.urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
1260 }
1261
1262 /* Submit all the URBs and then unlink URBs num - 4 and num - 2. */
1263 for (i = 0; i < num; i++) {
1264 atomic_inc(&ctx.pending);
1265 retval = usb_submit_urb(ctx.urbs[i], GFP_KERNEL);
1266 if (retval != 0) {
1267 dev_err(&dev->intf->dev, "submit urbs[%d] fail %d\n",
1268 i, retval);
1269 atomic_dec(&ctx.pending);
1270 ctx.status = retval;
1271 break;
1272 }
1273 }
1274 if (i == num) {
1275 usb_unlink_urb(ctx.urbs[num - 4]);
1276 usb_unlink_urb(ctx.urbs[num - 2]);
1277 } else {
1278 while (--i >= 0)
1279 usb_unlink_urb(ctx.urbs[i]);
1280 }
1281
1282 if (atomic_dec_and_test(&ctx.pending)) /* The extra count */
1283 complete(&ctx.complete);
1284 wait_for_completion(&ctx.complete);
1285 retval = ctx.status;
1286
1287 free_urbs:
1288 for (i = 0; i < num; i++)
1289 usb_free_urb(ctx.urbs[i]);
1290 kfree(ctx.urbs);
1291 free_buf:
1292 usb_free_coherent(udev, size, buf, buf_dma);
1293 return retval;
1294}
1295
1296/*-------------------------------------------------------------------------*/
1297
1198static int verify_not_halted(struct usbtest_dev *tdev, int ep, struct urb *urb) 1298static int verify_not_halted(struct usbtest_dev *tdev, int ep, struct urb *urb)
1199{ 1299{
1200 int retval; 1300 int retval;
@@ -1970,8 +2070,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
1970 dev->in_iso_pipe, dev->iso_in, 0); 2070 dev->in_iso_pipe, dev->iso_in, 0);
1971 break; 2071 break;
1972 2072
1973 /* FIXME unlink from queue (ring with N urbs) */
1974
1975 /* FIXME scatterlist cancel (needs helper thread) */ 2073 /* FIXME scatterlist cancel (needs helper thread) */
1976 2074
1977 /* Tests for bulk I/O using DMA mapping by core and odd address */ 2075 /* Tests for bulk I/O using DMA mapping by core and odd address */
@@ -2064,6 +2162,26 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
2064 dev->in_iso_pipe, dev->iso_in, 1); 2162 dev->in_iso_pipe, dev->iso_in, 1);
2065 break; 2163 break;
2066 2164
2165 /* unlink URBs from a bulk-OUT queue */
2166 case 24:
2167 if (dev->out_pipe == 0 || !param->length || param->sglen < 4)
2168 break;
2169 retval = 0;
2170 dev_info(&intf->dev, "TEST 17: unlink from %d queues of "
2171 "%d %d-byte writes\n",
2172 param->iterations, param->sglen, param->length);
2173 for (i = param->iterations; retval == 0 && i > 0; --i) {
2174 retval = unlink_queued(dev, dev->out_pipe,
2175 param->sglen, param->length);
2176 if (retval) {
2177 dev_err(&intf->dev,
2178 "unlink queued writes failed %d, "
2179 "iterations left %d\n", retval, i);
2180 break;
2181 }
2182 }
2183 break;
2184
2067 } 2185 }
2068 do_gettimeofday(&param->duration); 2186 do_gettimeofday(&param->duration);
2069 param->duration.tv_sec -= start.tv_sec; 2187 param->duration.tv_sec -= start.tv_sec;
@@ -2192,6 +2310,9 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)
2192 case USB_SPEED_HIGH: 2310 case USB_SPEED_HIGH:
2193 tmp = "high"; 2311 tmp = "high";
2194 break; 2312 break;
2313 case USB_SPEED_SUPER:
2314 tmp = "super";
2315 break;
2195 default: 2316 default:
2196 tmp = "unknown"; 2317 tmp = "unknown";
2197 break; 2318 break;