ChangeSet 1.893.2.17, 2002/12/26 18:53:28-08:00, spse@secret.org.uk [PATCH] 2.4.20 usbvideo fixes from 2.5 2/5 This patch fixes the use of USBVIDEO_NUMFRAMES. A few places in the code assumed it was 2. diff -Nru a/drivers/usb/usbvideo.c b/drivers/usb/usbvideo.c --- a/drivers/usb/usbvideo.c Mon Jan 6 11:30:34 2003 +++ b/drivers/usb/usbvideo.c Mon Jan 6 11:30:34 2003 @@ -1167,7 +1167,7 @@ if (!CAMERA_IS_OPERATIONAL(uvd)) return -EFAULT; - if (size > (((2 * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) + if (size > (((USBVIDEO_NUMFRAMES * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) return -EINVAL; pos = (unsigned long) uvd->fbuf; @@ -1446,12 +1446,13 @@ case VIDIOCGMBUF: { struct video_mbuf vm; + int i; memset(&vm, 0, sizeof(vm)); - vm.size = uvd->max_frame_size * 2; - vm.frames = 2; - vm.offsets[0] = 0; - vm.offsets[1] = uvd->max_frame_size; + vm.size = uvd->max_frame_size * USBVIDEO_NUMFRAMES; + vm.frames = USBVIDEO_NUMFRAMES; + for(i = 0; i < USBVIDEO_NUMFRAMES; i++) + vm.offsets[i] = i * uvd->max_frame_size; if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm))) return -EFAULT; @@ -1501,8 +1502,8 @@ } return -EINVAL; } - if ((vm.frame != 0) && (vm.frame != 1)) { - err("VIDIOCMCAPTURE: vm.frame=%d. !E [0,1]", vm.frame); + if ((vm.frame < 0) && (vm.frame >= USBVIDEO_NUMFRAMES)) { + err("VIDIOCMCAPTURE: vm.frame=%d. !E [0-%d]", vm.frame, USBVIDEO_NUMFRAMES-1); return -EINVAL; } if (uvd->frame[vm.frame].frameState == FrameState_Grabbing) { @@ -1600,7 +1601,7 @@ long usbvideo_v4l_read(struct video_device *dev, char *buf, unsigned long count, int noblock) { struct uvd *uvd = (struct uvd *) dev; - int frmx = -1; + int frmx = -1, i; struct usbvideo_frame *frame; if (!CAMERA_IS_OPERATIONAL(uvd) || (buf == NULL)) @@ -1612,14 +1613,13 @@ down(&uvd->lock); /* See if a frame is completed, then use it. */ - if ((uvd->frame[0].frameState == FrameState_Done) || - (uvd->frame[0].frameState == FrameState_Done_Hold) || - (uvd->frame[0].frameState == FrameState_Error)) { - frmx = 0; - } else if ((uvd->frame[1].frameState >= FrameState_Done) || - (uvd->frame[1].frameState == FrameState_Done_Hold) || - (uvd->frame[1].frameState >= FrameState_Done)) { - frmx = 1; + for(i = 0; i < USBVIDEO_NUMFRAMES; i++) { + if ((uvd->frame[i].frameState == FrameState_Done) || + (uvd->frame[i].frameState == FrameState_Done_Hold) || + (uvd->frame[i].frameState == FrameState_Error)) { + frmx = i; + break; + } } /* FIXME: If we don't start a frame here then who ever does? */ @@ -1634,10 +1634,12 @@ * We will need to wait until it becomes cooked, of course. */ if (frmx == -1) { - if (uvd->frame[0].frameState == FrameState_Grabbing) - frmx = 0; - else if (uvd->frame[1].frameState == FrameState_Grabbing) - frmx = 1; + for(i = 0; i < USBVIDEO_NUMFRAMES; i++) { + if (uvd->frame[i].frameState == FrameState_Grabbing) { + frmx = i; + break; + } + } } /* @@ -1741,7 +1743,7 @@ /* Mark it as available to be used again. */ uvd->frame[frmx].frameState = FrameState_Unused; - if (usbvideo_NewFrame(uvd, frmx ? 0 : 1)) { + if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES)) { err("%s: usbvideo_NewFrame failed.", __FUNCTION__); } } @@ -1976,7 +1978,7 @@ uvd->settingsAdjusted = 1; } - n = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES; + n = (framenum + 1) % USBVIDEO_NUMFRAMES; if (uvd->frame[n].frameState == FrameState_Ready) framenum = n; @@ -2008,7 +2010,8 @@ */ if (!(uvd->flags & FLAGS_SEPARATE_FRAMES)) { /* This copies previous frame into this one to mask losses */ - memmove(frame->data, uvd->frame[1-framenum].data, uvd->max_frame_size); + int prev = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES; + memmove(frame->data, uvd->frame[prev].data, uvd->max_frame_size); } else { if (uvd->flags & FLAGS_CLEAN_FRAMES) { /* This provides a "clean" frame but slows things down */