aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2006-05-22 16:47:13 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-21 18:04:13 -0400
commit9da2150f59e885d88b9eabe0a677f0fa4962f7b4 (patch)
tree74913a5f9712fa8e2e37fc9796b54c7971899c3a /drivers/usb
parent0ae4ea8092e1277cfca07cade7eaba5f594076c1 (diff)
[PATCH] usbtest: report errors in iso tests
This patch (as693b) makes the usbtest driver report errors in the isochronous bulk transfer tests instead of always returning 0. As an arbitrary cutoff, an error is returned if more than 10% of the packet transfers fail. It also stops a test immediately upon receiving an URB submission error. For a test harness, it's especially important to report when errors occur! Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-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++) {