diff options
author | Thierry Merle <thierry.merle@free.fr> | 2007-05-27 16:21:17 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-06-08 07:21:14 -0400 |
commit | fe818d1d9a50930aa7e1ce7169fb42e1e0c45882 (patch) | |
tree | 2ef3db4ce37192940d9f35d82f1b654dd21f3ea6 /drivers | |
parent | c6604150ab04aaaf98baf1ddca2e9e4f7d3da4d3 (diff) |
V4L/DVB (5720): Usbvision: fix urb allocation and submits
- fixed the urb allocation part that was not taking into account the current alternate setting
this fixes usb_submit_urb returning -90 errno in isocIrq.
- fixed usb_submit_urb returning -1 errno in isocIrq (need to ignore usb urb with status==-ENOENT)
Acked-by: Dwaine P. Garden <dwainegarden@rogers.com>
Signed-off-by: Thierry Merle <thierry.merle@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/usbvision/usbvision-core.c | 82 | ||||
-rw-r--r-- | drivers/media/video/usbvision/usbvision.h | 1 |
2 files changed, 53 insertions, 30 deletions
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index 9118a6227ea6..7df071eb0a3b 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c | |||
@@ -1414,6 +1414,11 @@ static void usbvision_isocIrq(struct urb *urb) | |||
1414 | if (!USBVISION_IS_OPERATIONAL(usbvision)) | 1414 | if (!USBVISION_IS_OPERATIONAL(usbvision)) |
1415 | return; | 1415 | return; |
1416 | 1416 | ||
1417 | /* any urb with wrong status is ignored without acknowledgement */ | ||
1418 | if (urb->status == -ENOENT) { | ||
1419 | return; | ||
1420 | } | ||
1421 | |||
1417 | f = &usbvision->curFrame; | 1422 | f = &usbvision->curFrame; |
1418 | 1423 | ||
1419 | /* Manage streaming interruption */ | 1424 | /* Manage streaming interruption */ |
@@ -1436,18 +1441,21 @@ static void usbvision_isocIrq(struct urb *urb) | |||
1436 | if (usbvision->streaming == Stream_On) { | 1441 | if (usbvision->streaming == Stream_On) { |
1437 | 1442 | ||
1438 | /* If we collected enough data let's parse! */ | 1443 | /* If we collected enough data let's parse! */ |
1439 | if (scratch_len(usbvision) > USBVISION_HEADER_LENGTH) { /* 12 == header_length */ | 1444 | if ((scratch_len(usbvision) > USBVISION_HEADER_LENGTH) && |
1440 | /*If we don't have a frame we're current working on, complain */ | 1445 | (!list_empty(&(usbvision->inqueue))) ) { |
1441 | if(!list_empty(&(usbvision->inqueue))) { | 1446 | if (!(*f)) { |
1442 | if (!(*f)) { | 1447 | (*f) = list_entry(usbvision->inqueue.next, |
1443 | (*f) = list_entry(usbvision->inqueue.next,struct usbvision_frame, frame); | 1448 | struct usbvision_frame, |
1444 | } | 1449 | frame); |
1445 | usbvision_parse_data(usbvision); | ||
1446 | } | ||
1447 | else { | ||
1448 | PDEBUG(DBG_IRQ, "received data, but no one needs it"); | ||
1449 | scratch_reset(usbvision); | ||
1450 | } | 1450 | } |
1451 | usbvision_parse_data(usbvision); | ||
1452 | } | ||
1453 | else { | ||
1454 | /*If we don't have a frame | ||
1455 | we're current working on, complain */ | ||
1456 | PDEBUG(DBG_IRQ, | ||
1457 | "received data, but no one needs it"); | ||
1458 | scratch_reset(usbvision); | ||
1451 | } | 1459 | } |
1452 | } | 1460 | } |
1453 | else { | 1461 | else { |
@@ -1466,10 +1474,10 @@ static void usbvision_isocIrq(struct urb *urb) | |||
1466 | urb->dev = usbvision->dev; | 1474 | urb->dev = usbvision->dev; |
1467 | errCode = usb_submit_urb (urb, GFP_ATOMIC); | 1475 | errCode = usb_submit_urb (urb, GFP_ATOMIC); |
1468 | 1476 | ||
1469 | /* Disable this warning. By design of the driver. */ | 1477 | if(errCode) { |
1470 | // if(errCode) { | 1478 | err("%s: usb_submit_urb failed: error %d", |
1471 | // err("%s: usb_submit_urb failed: error %d", __FUNCTION__, errCode); | 1479 | __FUNCTION__, errCode); |
1472 | // } | 1480 | } |
1473 | 1481 | ||
1474 | return; | 1482 | return; |
1475 | } | 1483 | } |
@@ -2394,7 +2402,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2394 | { | 2402 | { |
2395 | struct usb_device *dev = usbvision->dev; | 2403 | struct usb_device *dev = usbvision->dev; |
2396 | int bufIdx, errCode, regValue; | 2404 | int bufIdx, errCode, regValue; |
2397 | const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE; | 2405 | int sb_size; |
2398 | 2406 | ||
2399 | if (!USBVISION_IS_OPERATIONAL(usbvision)) | 2407 | if (!USBVISION_IS_OPERATIONAL(usbvision)) |
2400 | return -EFAULT; | 2408 | return -EFAULT; |
@@ -2408,11 +2416,14 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2408 | usbvision->last_error = errCode; | 2416 | usbvision->last_error = errCode; |
2409 | return -EBUSY; | 2417 | return -EBUSY; |
2410 | } | 2418 | } |
2419 | sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize; | ||
2411 | 2420 | ||
2412 | regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; | 2421 | regValue = (16 - usbvision_read_reg(usbvision, |
2422 | USBVISION_ALTER_REG)) & 0x0F; | ||
2413 | 2423 | ||
2414 | usbvision->usb_bandwidth = regValue >> 1; | 2424 | usbvision->usb_bandwidth = regValue >> 1; |
2415 | PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth); | 2425 | PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", |
2426 | usbvision->usb_bandwidth); | ||
2416 | 2427 | ||
2417 | 2428 | ||
2418 | 2429 | ||
@@ -2428,7 +2439,11 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2428 | return -ENOMEM; | 2439 | return -ENOMEM; |
2429 | } | 2440 | } |
2430 | usbvision->sbuf[bufIdx].urb = urb; | 2441 | usbvision->sbuf[bufIdx].urb = urb; |
2431 | usbvision->sbuf[bufIdx].data = usb_buffer_alloc(usbvision->dev, sb_size, GFP_KERNEL,&urb->transfer_dma); | 2442 | usbvision->sbuf[bufIdx].data = |
2443 | usb_buffer_alloc(usbvision->dev, | ||
2444 | sb_size, | ||
2445 | GFP_KERNEL, | ||
2446 | &urb->transfer_dma); | ||
2432 | urb->dev = dev; | 2447 | urb->dev = dev; |
2433 | urb->context = usbvision; | 2448 | urb->context = usbvision; |
2434 | urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp); | 2449 | urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp); |
@@ -2442,21 +2457,26 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2442 | for (j = k = 0; j < USBVISION_URB_FRAMES; j++, | 2457 | for (j = k = 0; j < USBVISION_URB_FRAMES; j++, |
2443 | k += usbvision->isocPacketSize) { | 2458 | k += usbvision->isocPacketSize) { |
2444 | urb->iso_frame_desc[j].offset = k; | 2459 | urb->iso_frame_desc[j].offset = k; |
2445 | urb->iso_frame_desc[j].length = usbvision->isocPacketSize; | 2460 | urb->iso_frame_desc[j].length = |
2461 | usbvision->isocPacketSize; | ||
2446 | } | 2462 | } |
2447 | } | 2463 | } |
2448 | 2464 | ||
2449 | 2465 | ||
2450 | /* Submit all URBs */ | 2466 | /* Submit all URBs */ |
2451 | for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { | 2467 | for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { |
2452 | errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, GFP_KERNEL); | 2468 | errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, |
2469 | GFP_KERNEL); | ||
2453 | if (errCode) { | 2470 | if (errCode) { |
2454 | err("%s: usb_submit_urb(%d) failed: error %d", __FUNCTION__, bufIdx, errCode); | 2471 | err("%s: usb_submit_urb(%d) failed: error %d", |
2472 | __FUNCTION__, bufIdx, errCode); | ||
2455 | } | 2473 | } |
2456 | } | 2474 | } |
2457 | 2475 | ||
2458 | usbvision->streaming = Stream_Idle; | 2476 | usbvision->streaming = Stream_Idle; |
2459 | PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", __FUNCTION__, usbvision->video_endp); | 2477 | PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", |
2478 | __FUNCTION__, | ||
2479 | usbvision->video_endp); | ||
2460 | return 0; | 2480 | return 0; |
2461 | } | 2481 | } |
2462 | 2482 | ||
@@ -2470,7 +2490,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2470 | void usbvision_stop_isoc(struct usb_usbvision *usbvision) | 2490 | void usbvision_stop_isoc(struct usb_usbvision *usbvision) |
2471 | { | 2491 | { |
2472 | int bufIdx, errCode, regValue; | 2492 | int bufIdx, errCode, regValue; |
2473 | const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE; | 2493 | int sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize; |
2474 | 2494 | ||
2475 | if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL)) | 2495 | if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL)) |
2476 | return; | 2496 | return; |
@@ -2499,15 +2519,19 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) | |||
2499 | errCode = usb_set_interface(usbvision->dev, usbvision->iface, | 2519 | errCode = usb_set_interface(usbvision->dev, usbvision->iface, |
2500 | usbvision->ifaceAlt); | 2520 | usbvision->ifaceAlt); |
2501 | if (errCode < 0) { | 2521 | if (errCode < 0) { |
2502 | err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode); | 2522 | err("%s: usb_set_interface() failed: error %d", |
2523 | __FUNCTION__, errCode); | ||
2503 | usbvision->last_error = errCode; | 2524 | usbvision->last_error = errCode; |
2504 | } | 2525 | } |
2505 | regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; | 2526 | regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; |
2506 | usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1; | 2527 | usbvision->isocPacketSize = |
2507 | PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize); | 2528 | (regValue == 0) ? 0 : (regValue * 64) - 1; |
2529 | PDEBUG(DBG_ISOC, "ISO Packet Length:%d", | ||
2530 | usbvision->isocPacketSize); | ||
2508 | 2531 | ||
2509 | usbvision->usb_bandwidth = regValue >> 1; | 2532 | usbvision->usb_bandwidth = regValue >> 1; |
2510 | PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth); | 2533 | PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", |
2534 | usbvision->usb_bandwidth); | ||
2511 | } | 2535 | } |
2512 | } | 2536 | } |
2513 | 2537 | ||
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h index bd6f6422ed54..c759d00d7014 100644 --- a/drivers/media/video/usbvision/usbvision.h +++ b/drivers/media/video/usbvision/usbvision.h | |||
@@ -146,7 +146,6 @@ | |||
146 | #define USBVISION_CLIPMASK_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) //bytesize of clipmask | 146 | #define USBVISION_CLIPMASK_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) //bytesize of clipmask |
147 | 147 | ||
148 | #define USBVISION_URB_FRAMES 32 | 148 | #define USBVISION_URB_FRAMES 32 |
149 | #define USBVISION_MAX_ISOC_PACKET_SIZE 959 // NT1003 Specs Document says 1023 | ||
150 | 149 | ||
151 | #define USBVISION_NUM_HEADERMARKER 20 | 150 | #define USBVISION_NUM_HEADERMARKER 20 |
152 | #define USBVISION_NUMFRAMES 3 /* Maximum number of frames an application can get */ | 151 | #define USBVISION_NUMFRAMES 3 /* Maximum number of frames an application can get */ |