usbtest.c (caa2a1226741e023a103e091a7f6dce7c42e82ee) | usbtest.c (9da2150f59e885d88b9eabe0a677f0fa4962f7b4) |
---|---|
1#include <linux/config.h> 2#include <linux/kernel.h> 3#include <linux/errno.h> 4#include <linux/init.h> 5#include <linux/slab.h> 6#include <linux/mm.h> 7#include <linux/module.h> 8#include <linux/moduleparam.h> --- 1323 unchanged lines hidden (view full) --- 1332 * - multi-buffers according to sglen 1333 */ 1334 1335struct iso_context { 1336 unsigned count; 1337 unsigned pending; 1338 spinlock_t lock; 1339 struct completion done; | 1#include <linux/config.h> 2#include <linux/kernel.h> 3#include <linux/errno.h> 4#include <linux/init.h> 5#include <linux/slab.h> 6#include <linux/mm.h> 7#include <linux/module.h> 8#include <linux/moduleparam.h> --- 1323 unchanged lines hidden (view full) --- 1332 * - multi-buffers according to sglen 1333 */ 1334 1335struct iso_context { 1336 unsigned count; 1337 unsigned pending; 1338 spinlock_t lock; 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; 1342}; 1343 1344static void iso_callback (struct urb *urb, struct pt_regs *regs) 1345{ 1346 struct iso_context *ctx = urb->context; 1347 1348 spin_lock(&ctx->lock); 1349 ctx->count--; 1350 | 1343 struct usbtest_dev *dev; 1344}; 1345 1346static void iso_callback (struct urb *urb, struct pt_regs *regs) 1347{ 1348 struct iso_context *ctx = urb->context; 1349 1350 spin_lock(&ctx->lock); 1351 ctx->count--; 1352 |
1353 ctx->packet_count += urb->number_of_packets; |
|
1351 if (urb->error_count > 0) 1352 ctx->errors += urb->error_count; | 1354 if (urb->error_count > 0) 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); 1356 switch (status) { 1357 case 0: 1358 goto done; 1359 default: 1360 dev_dbg (&ctx->dev->intf->dev, 1361 "iso resubmit err %d\n", 1362 status); 1363 /* FALLTHROUGH */ 1364 case -ENODEV: /* disconnected */ | 1361 int status = usb_submit_urb (urb, GFP_ATOMIC); 1362 switch (status) { 1363 case 0: 1364 goto done; 1365 default: 1366 dev_dbg (&ctx->dev->intf->dev, 1367 "iso resubmit err %d\n", 1368 status); 1369 /* FALLTHROUGH */ 1370 case -ENODEV: /* disconnected */ |
1371 case -ESHUTDOWN: /* endpoint disabled */ 1372 ctx->submit_error = 1; |
|
1365 break; 1366 } 1367 } 1368 simple_free_urb (urb); 1369 1370 ctx->pending--; 1371 if (ctx->pending == 0) { 1372 if (ctx->errors) 1373 dev_dbg (&ctx->dev->intf->dev, | 1373 break; 1374 } 1375 } 1376 simple_free_urb (urb); 1377 1378 ctx->pending--; 1379 if (ctx->pending == 0) { 1380 if (ctx->errors) 1381 dev_dbg (&ctx->dev->intf->dev, |
1374 "iso test, %lu errors\n", 1375 ctx->errors); | 1382 "iso test, %lu errors out of %lu\n", 1383 ctx->errors, ctx->packet_count); |
1376 complete (&ctx->done); 1377 } 1378done: 1379 spin_unlock(&ctx->lock); 1380} 1381 1382static struct urb *iso_alloc_urb ( 1383 struct usb_device *udev, --- 44 unchanged lines hidden (view full) --- 1428static int 1429test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, 1430 int pipe, struct usb_endpoint_descriptor *desc) 1431{ 1432 struct iso_context context; 1433 struct usb_device *udev; 1434 unsigned i; 1435 unsigned long packets = 0; | 1384 complete (&ctx->done); 1385 } 1386done: 1387 spin_unlock(&ctx->lock); 1388} 1389 1390static struct urb *iso_alloc_urb ( 1391 struct usb_device *udev, --- 44 unchanged lines hidden (view full) --- 1436static int 1437test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, 1438 int pipe, struct usb_endpoint_descriptor *desc) 1439{ 1440 struct iso_context context; 1441 struct usb_device *udev; 1442 unsigned i; 1443 unsigned long packets = 0; |
1436 int status; | 1444 int status = 0; |
1437 struct urb *urbs[10]; /* FIXME no limit */ 1438 1439 if (param->sglen > 10) 1440 return -EDOM; 1441 | 1445 struct urb *urbs[10]; /* FIXME no limit */ 1446 1447 if (param->sglen > 10) 1448 return -EDOM; 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; 1446 init_completion (&context.done); 1447 spin_lock_init (&context.lock); 1448 1449 memset (urbs, 0, sizeof urbs); 1450 udev = testdev_to_usbdev (dev); 1451 dev_dbg (&dev->intf->dev, 1452 "... iso period %d %sframes, wMaxPacket %04x\n", --- 15 unchanged lines hidden (view full) --- 1468 dev_dbg (&dev->intf->dev, 1469 "... total %lu msec (%lu packets)\n", 1470 (packets * (1 << (desc->bInterval - 1))) 1471 / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), 1472 packets); 1473 1474 spin_lock_irq (&context.lock); 1475 for (i = 0; i < param->sglen; i++) { | 1452 context.dev = dev; 1453 init_completion (&context.done); 1454 spin_lock_init (&context.lock); 1455 1456 memset (urbs, 0, sizeof urbs); 1457 udev = testdev_to_usbdev (dev); 1458 dev_dbg (&dev->intf->dev, 1459 "... iso period %d %sframes, wMaxPacket %04x\n", --- 15 unchanged lines hidden (view full) --- 1475 dev_dbg (&dev->intf->dev, 1476 "... total %lu msec (%lu packets)\n", 1477 (packets * (1 << (desc->bInterval - 1))) 1478 / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), 1479 packets); 1480 1481 spin_lock_irq (&context.lock); 1482 for (i = 0; i < param->sglen; i++) { |
1483 ++context.pending; |
|
1476 status = usb_submit_urb (urbs [i], SLAB_ATOMIC); 1477 if (status < 0) { 1478 ERROR (dev, "submit iso[%d], error %d\n", i, status); 1479 if (i == 0) { 1480 spin_unlock_irq (&context.lock); 1481 goto fail; 1482 } 1483 1484 simple_free_urb (urbs [i]); 1485 context.pending--; | 1484 status = usb_submit_urb (urbs [i], SLAB_ATOMIC); 1485 if (status < 0) { 1486 ERROR (dev, "submit iso[%d], error %d\n", i, status); 1487 if (i == 0) { 1488 spin_unlock_irq (&context.lock); 1489 goto fail; 1490 } 1491 1492 simple_free_urb (urbs [i]); 1493 context.pending--; |
1494 context.submit_error = 1; 1495 break; |
|
1486 } 1487 } 1488 spin_unlock_irq (&context.lock); 1489 1490 wait_for_completion (&context.done); | 1496 } 1497 } 1498 spin_unlock_irq (&context.lock); 1499 1500 wait_for_completion (&context.done); |
1491 return 0; | |
1492 | 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; 1514 |
|
1493fail: 1494 for (i = 0; i < param->sglen; i++) { 1495 if (urbs [i]) 1496 simple_free_urb (urbs [i]); 1497 } 1498 return status; 1499} 1500 --- 678 unchanged lines hidden --- | 1515fail: 1516 for (i = 0; i < param->sglen; i++) { 1517 if (urbs [i]) 1518 simple_free_urb (urbs [i]); 1519 } 1520 return status; 1521} 1522 --- 678 unchanged lines hidden --- |