aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/misc/usbtest.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index b42ae6bfb12b..81ba14c73dc7 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -1337,7 +1337,9 @@ struct iso_context {
1337 unsigned pending; 1337 unsigned pending;
1338 spinlock_t lock; 1338 spinlock_t lock;
1339 struct completion done; 1339 struct completion done;
1340 int submit_error;
1340 unsigned long errors; 1341 unsigned long errors;
1342 unsigned long packet_count;
1341 struct usbtest_dev *dev; 1343 struct usbtest_dev *dev;
1342}; 1344};
1343 1345
@@ -1348,10 +1350,14 @@ static void iso_callback (struct urb *urb, struct pt_regs *regs)
1348 spin_lock(&ctx->lock); 1350 spin_lock(&ctx->lock);
1349 ctx->count--; 1351 ctx->count--;
1350 1352
1353 ctx->packet_count += urb->number_of_packets;
1351 if (urb->error_count > 0) 1354 if (urb->error_count > 0)
1352 ctx->errors += urb->error_count; 1355 ctx->errors += urb->error_count;
1356 else if (urb->status != 0)
1357 ctx->errors += urb->number_of_packets;
1353 1358
1354 if (urb->status == 0 && ctx->count > (ctx->pending - 1)) { 1359 if (urb->status == 0 && ctx->count > (ctx->pending - 1)
1360 && !ctx->submit_error) {
1355 int status = usb_submit_urb (urb, GFP_ATOMIC); 1361 int status = usb_submit_urb (urb, GFP_ATOMIC);
1356 switch (status) { 1362 switch (status) {
1357 case 0: 1363 case 0:
@@ -1362,6 +1368,8 @@ static void iso_callback (struct urb *urb, struct pt_regs *regs)
1362 status); 1368 status);
1363 /* FALLTHROUGH */ 1369 /* FALLTHROUGH */
1364 case -ENODEV: /* disconnected */ 1370 case -ENODEV: /* disconnected */
1371 case -ESHUTDOWN: /* endpoint disabled */
1372 ctx->submit_error = 1;
1365 break; 1373 break;
1366 } 1374 }
1367 } 1375 }
@@ -1371,8 +1379,8 @@ static void iso_callback (struct urb *urb, struct pt_regs *regs)
1371 if (ctx->pending == 0) { 1379 if (ctx->pending == 0) {
1372 if (ctx->errors) 1380 if (ctx->errors)
1373 dev_dbg (&ctx->dev->intf->dev, 1381 dev_dbg (&ctx->dev->intf->dev,
1374 "iso test, %lu errors\n", 1382 "iso test, %lu errors out of %lu\n",
1375 ctx->errors); 1383 ctx->errors, ctx->packet_count);
1376 complete (&ctx->done); 1384 complete (&ctx->done);
1377 } 1385 }
1378done: 1386done:
@@ -1433,15 +1441,14 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param,
1433 struct usb_device *udev; 1441 struct usb_device *udev;
1434 unsigned i; 1442 unsigned i;
1435 unsigned long packets = 0; 1443 unsigned long packets = 0;
1436 int status; 1444 int status = 0;
1437 struct urb *urbs[10]; /* FIXME no limit */ 1445 struct urb *urbs[10]; /* FIXME no limit */
1438 1446
1439 if (param->sglen > 10) 1447 if (param->sglen > 10)
1440 return -EDOM; 1448 return -EDOM;
1441 1449
1450 memset(&context, 0, sizeof context);
1442 context.count = param->iterations * param->sglen; 1451 context.count = param->iterations * param->sglen;
1443 context.pending = param->sglen;
1444 context.errors = 0;
1445 context.dev = dev; 1452 context.dev = dev;
1446 init_completion (&context.done); 1453 init_completion (&context.done);
1447 spin_lock_init (&context.lock); 1454 spin_lock_init (&context.lock);
@@ -1473,6 +1480,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param,
1473 1480
1474 spin_lock_irq (&context.lock); 1481 spin_lock_irq (&context.lock);
1475 for (i = 0; i < param->sglen; i++) { 1482 for (i = 0; i < param->sglen; i++) {
1483 ++context.pending;
1476 status = usb_submit_urb (urbs [i], SLAB_ATOMIC); 1484 status = usb_submit_urb (urbs [i], SLAB_ATOMIC);
1477 if (status < 0) { 1485 if (status < 0) {
1478 ERROR (dev, "submit iso[%d], error %d\n", i, status); 1486 ERROR (dev, "submit iso[%d], error %d\n", i, status);
@@ -1483,12 +1491,26 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param,
1483 1491
1484 simple_free_urb (urbs [i]); 1492 simple_free_urb (urbs [i]);
1485 context.pending--; 1493 context.pending--;
1494 context.submit_error = 1;
1495 break;
1486 } 1496 }
1487 } 1497 }
1488 spin_unlock_irq (&context.lock); 1498 spin_unlock_irq (&context.lock);
1489 1499
1490 wait_for_completion (&context.done); 1500 wait_for_completion (&context.done);
1491 return 0; 1501
1502 /*
1503 * Isochronous transfers are expected to fail sometimes. As an
1504 * arbitrary limit, we will report an error if any submissions
1505 * fail or if the transfer failure rate is > 10%.
1506 */
1507 if (status != 0)
1508 ;
1509 else if (context.submit_error)
1510 status = -EACCES;
1511 else if (context.errors > context.packet_count / 10)
1512 status = -EIO;
1513 return status;
1492 1514
1493fail: 1515fail:
1494 for (i = 0; i < param->sglen; i++) { 1516 for (i = 0; i < param->sglen; i++) {