diff options
author | Thierry Merle <thierry.merle@free.fr> | 2007-05-27 22:21:17 +0200 |
---|---|---|
committer | Thierry Merle <thierry.merle@free.fr> | 2007-05-27 22:21:17 +0200 |
commit | 949e12ae9c097e8c69537b64eb4950ddbcd48ac2 (patch) | |
tree | 4d5eb863586de61a120a1d7c986cf224df1d61db /linux/drivers/media/video/usbvision/usbvision-core.c | |
parent | 72df405254aa20ea12fe0c79a1d2eca5c65f70f1 (diff) | |
download | mediapointer-dvb-s2-949e12ae9c097e8c69537b64eb4950ddbcd48ac2.tar.gz mediapointer-dvb-s2-949e12ae9c097e8c69537b64eb4950ddbcd48ac2.tar.bz2 |
usbvision: fix urb allocation and submits
From: Thierry Merle <thierry.merle@free.fr>
- 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>
Diffstat (limited to 'linux/drivers/media/video/usbvision/usbvision-core.c')
-rw-r--r-- | linux/drivers/media/video/usbvision/usbvision-core.c | 93 |
1 files changed, 60 insertions, 33 deletions
diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c index 536c6c767..a6afa78bf 100644 --- a/linux/drivers/media/video/usbvision/usbvision-core.c +++ b/linux/drivers/media/video/usbvision/usbvision-core.c @@ -1459,6 +1459,11 @@ static void usbvision_isocIrq(struct urb *urb, struct pt_regs *regs) if (!USBVISION_IS_OPERATIONAL(usbvision)) return; + /* any urb with wrong status is ignored without acknowledgement */ + if (urb->status == -ENOENT) { + return; + } + f = &usbvision->curFrame; /* Manage streaming interruption */ @@ -1481,18 +1486,21 @@ static void usbvision_isocIrq(struct urb *urb, struct pt_regs *regs) if (usbvision->streaming == Stream_On) { /* If we collected enough data let's parse! */ - if (scratch_len(usbvision) > USBVISION_HEADER_LENGTH) { /* 12 == header_length */ - /*If we don't have a frame we're current working on, complain */ - if(!list_empty(&(usbvision->inqueue))) { - if (!(*f)) { - (*f) = list_entry(usbvision->inqueue.next,struct usbvision_frame, frame); - } - usbvision_parse_data(usbvision); - } - else { - PDEBUG(DBG_IRQ, "received data, but no one needs it"); - scratch_reset(usbvision); + if ((scratch_len(usbvision) > USBVISION_HEADER_LENGTH) && + (!list_empty(&(usbvision->inqueue))) ) { + if (!(*f)) { + (*f) = list_entry(usbvision->inqueue.next, + struct usbvision_frame, + frame); } + usbvision_parse_data(usbvision); + } + else { + /*If we don't have a frame + we're current working on, complain */ + PDEBUG(DBG_IRQ, + "received data, but no one needs it"); + scratch_reset(usbvision); } } else { @@ -1512,10 +1520,10 @@ static void usbvision_isocIrq(struct urb *urb, struct pt_regs *regs) urb->dev = usbvision->dev; errCode = usb_submit_urb (urb, GFP_ATOMIC); - /* Disable this warning. By design of the driver. */ - // if(errCode) { - // err("%s: usb_submit_urb failed: error %d", __FUNCTION__, errCode); - // } + if(errCode) { + err("%s: usb_submit_urb failed: error %d", + __FUNCTION__, errCode); + } #endif return; @@ -2474,7 +2482,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) { struct usb_device *dev = usbvision->dev; int bufIdx, errCode, regValue; - const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE; + int sb_size; if (!USBVISION_IS_OPERATIONAL(usbvision)) return -EFAULT; @@ -2488,11 +2496,14 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) usbvision->last_error = errCode; return -EBUSY; } + sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize; - regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; + regValue = (16 - usbvision_read_reg(usbvision, + USBVISION_ALTER_REG)) & 0x0F; usbvision->usb_bandwidth = regValue >> 1; - PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth); + PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", + usbvision->usb_bandwidth); @@ -2512,7 +2523,11 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) return -ENOMEM; } usbvision->sbuf[bufIdx].urb = urb; - usbvision->sbuf[bufIdx].data = usb_buffer_alloc(usbvision->dev, sb_size, GFP_KERNEL,&urb->transfer_dma); + usbvision->sbuf[bufIdx].data = + usb_buffer_alloc(usbvision->dev, + sb_size, + GFP_KERNEL, + &urb->transfer_dma); urb->dev = dev; urb->context = usbvision; urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp); @@ -2530,7 +2545,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) for (j = k = 0; j < USBVISION_URB_FRAMES; j++, k += usbvision->isocPacketSize) { urb->iso_frame_desc[j].offset = k; - urb->iso_frame_desc[j].length = usbvision->isocPacketSize; + urb->iso_frame_desc[j].length = + usbvision->isocPacketSize; } } @@ -2538,10 +2554,12 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) /* Link URBs into a ring so that they invoke each other infinitely */ for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { if ((bufIdx + 1) < USBVISION_NUMSBUF) { - usbvision->sbuf[bufIdx].urb->next = usbvision->sbuf[bufIdx + 1].urb; + usbvision->sbuf[bufIdx].urb->next = + usbvision->sbuf[bufIdx + 1].urb; } else { - usbvision->sbuf[bufIdx].urb->next = usbvision->sbuf[0].urb; + usbvision->sbuf[bufIdx].urb->next = + usbvision->sbuf[0].urb; } } #endif @@ -2551,15 +2569,19 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb); #else - errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, GFP_KERNEL); + errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, + GFP_KERNEL); #endif if (errCode) { - err("%s: usb_submit_urb(%d) failed: error %d", __FUNCTION__, bufIdx, errCode); + err("%s: usb_submit_urb(%d) failed: error %d", + __FUNCTION__, bufIdx, errCode); } } usbvision->streaming = Stream_Idle; - PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", __FUNCTION__, usbvision->video_endp); + PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", + __FUNCTION__, + usbvision->video_endp); return 0; } @@ -2573,7 +2595,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) void usbvision_stop_isoc(struct usb_usbvision *usbvision) { int bufIdx, errCode, regValue; - const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE; + int sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize; if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL)) return; @@ -2595,12 +2617,13 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { errCode = usb_unlink_urb(usbvision->sbuf[bufIdx].urb); if (errCode < 0) - err("%s: usb_unlink_urb() failed: error %d", __FUNCTION__, errCode); + err("%s: usb_unlink_urb() failed: error %d", + __FUNCTION__, errCode); } if (usbvision->sbuf[bufIdx].data){ usb_buffer_free(usbvision->dev, - (EM28XX_NUM_PACKETS*usbvision->max_pkt_size), + sb_size, usbvision->sbuf[bufIdx].data, usbvision->sbuf[bufIdx].urb->transfer_dma); } @@ -2620,15 +2643,19 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) errCode = usb_set_interface(usbvision->dev, usbvision->iface, usbvision->ifaceAlt); if (errCode < 0) { - err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode); + err("%s: usb_set_interface() failed: error %d", + __FUNCTION__, errCode); usbvision->last_error = errCode; } - regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; - usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1; - PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize); + regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; + usbvision->isocPacketSize = + (regValue == 0) ? 0 : (regValue * 64) - 1; + PDEBUG(DBG_ISOC, "ISO Packet Length:%d", + usbvision->isocPacketSize); usbvision->usb_bandwidth = regValue >> 1; - PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth); + PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", + usbvision->usb_bandwidth); } } |