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 */
