<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.489   -&gt; 1.490  
#	drivers/usb/media/usbvideo.h	1.12    -&gt; 1.13   
#	drivers/usb/media/usbvideo.c	1.21    -&gt; 1.22   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/08/17	spse@secret.org.uk	1.490
# [PATCH] cleanup RingQueue_* functions in usbvideo.c
# 
# This patch against 2.5.31 cleans up the RingQueue_* functions
# 
# - make the buffer length be a power of 2 to speed up index manipulation
# - make RingQueue_Dequeue use memcpy() rather than a byte by byte copy
# - make RingQueue_Enqueue use memcpy() instead of memmove() as the memory
#   regions do not overlap
# - Add RingQueue_Flush() and RingQueue_GetFreeSpace()
# - make RingQueue_GetLength() an inline
# --------------------------------------------
#
diff -Nru a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c
--- a/drivers/usb/media/usbvideo.c	Sun Aug 18 20:48:36 2002
+++ b/drivers/usb/media/usbvideo.c	Sun Aug 18 20:48:36 2002
@@ -135,9 +135,21 @@
 
 static void RingQueue_Allocate(RingQueue_t *rq, int rqLen)
 {
+	/* Make sure the requested size is a power of 2 and
+	   round up if necessary. This allows index wrapping
+	   using masks rather than modulo */
+
+	int i = 1;
 	assert(rq != NULL);
 	assert(rqLen &gt; 0);
+
+	while(rqLen &gt;&gt; i)
+		i++;
+	if(rqLen != 1 &lt;&lt; (i-1))
+		rqLen = 1 &lt;&lt; i;
+
 	rq-&gt;length = rqLen;
+	rq-&gt;ri = rq-&gt;wi = 0;
 	rq-&gt;queue = usbvideo_rvmalloc(rq-&gt;length);
 	assert(rq-&gt;queue != NULL);
 }
@@ -161,12 +173,32 @@
 
 int RingQueue_Dequeue(RingQueue_t *rq, unsigned char *dst, int len)
 {
-	int i;
+	int rql, toread;
+
 	assert(rq != NULL);
 	assert(dst != NULL);
-	for (i=0; i &lt; len; i++) {
-		dst[i] = rq-&gt;queue[rq-&gt;ri];
-		RING_QUEUE_DEQUEUE_BYTES(rq,1);
+
+	rql = RingQueue_GetLength(rq);
+	if(!rql)
+		return 0;
+
+	/* Clip requested length to available data */
+	if(len &gt; rql)
+		len = rql;
+
+	toread = len;
+	if(rq-&gt;ri &gt; rq-&gt;wi) {
+		/* Read data from tail */
+		int read = (toread &lt; (rq-&gt;length - rq-&gt;ri)) ? toread : rq-&gt;length - rq-&gt;ri;
+		memcpy(dst, rq-&gt;queue + rq-&gt;ri, read);
+		toread -= read;
+		dst += read;
+		rq-&gt;ri = (rq-&gt;ri + read) &amp; (rq-&gt;length-1);
+	}
+	if(toread) {
+		/* Read data from head */
+		memcpy(dst, rq-&gt;queue + rq-&gt;ri, toread);
+		rq-&gt;ri = (rq-&gt;ri + toread) &amp; (rq-&gt;length-1);
 	}
 	return len;
 }
@@ -194,7 +226,7 @@
 		if (m &gt; q_avail)
 			m = q_avail;
 
-		memmove(rq-&gt;queue + rq-&gt;wi, cdata, m);
+		memcpy(rq-&gt;queue + rq-&gt;wi, cdata, m);
 		RING_QUEUE_ADVANCE_INDEX(rq, wi, m);
 		cdata += m;
 		enqueued += m;
@@ -205,24 +237,6 @@
 
 EXPORT_SYMBOL(RingQueue_Enqueue);
 
-int RingQueue_GetLength(const RingQueue_t *rq)
-{
-	int ri, wi;
-
-	assert(rq != NULL);
-
-	ri = rq-&gt;ri;
-	wi = rq-&gt;wi;
-	if (ri == wi)
-		return 0;
-	else if (ri &lt; wi)
-		return wi - ri;
-	else
-		return wi + (rq-&gt;length - ri);
-}
-
-EXPORT_SYMBOL(RingQueue_GetLength);
-
 static void RingQueue_InterruptibleSleepOn(RingQueue_t *rq)
 {
 	assert(rq != NULL);
@@ -238,6 +252,16 @@
 
 EXPORT_SYMBOL(RingQueue_WakeUpInterruptible);
 
+void RingQueue_Flush(RingQueue_t *rq)
+{
+	assert(rq != NULL);
+	rq-&gt;ri = 0;
+	rq-&gt;wi = 0;
+}
+
+EXPORT_SYMBOL(RingQueue_Flush);
+
+
 /*
  * usbvideo_VideosizeToString()
  *
@@ -374,7 +398,7 @@
 		q_used = RingQueue_GetLength(&amp;uvd-&gt;dp);
 		if ((uvd-&gt;dp.ri + q_used) &gt;= uvd-&gt;dp.length) {
 			u_hi = uvd-&gt;dp.length;
-			u_lo = (q_used + uvd-&gt;dp.ri) % uvd-&gt;dp.length;
+			u_lo = (q_used + uvd-&gt;dp.ri) &amp; (uvd-&gt;dp.length-1);
 		} else {
 			u_hi = (q_used + uvd-&gt;dp.ri);
 			u_lo = -1;
@@ -1256,7 +1280,7 @@
 		/* Allocate memory for the frame buffers */
 		uvd-&gt;fbuf_size = USBVIDEO_NUMFRAMES * uvd-&gt;max_frame_size;
 		uvd-&gt;fbuf = usbvideo_rvmalloc(uvd-&gt;fbuf_size);
-		RingQueue_Allocate(&amp;uvd-&gt;dp, 128*1024); /* FIXME #define */
+		RingQueue_Allocate(&amp;uvd-&gt;dp, RING_QUEUE_SIZE);
 		if ((uvd-&gt;fbuf == NULL) ||
 		    (!RingQueue_IsAllocated(&amp;uvd-&gt;dp))) {
 			err("%s: Failed to allocate fbuf or dp", proc);
diff -Nru a/drivers/usb/media/usbvideo.h b/drivers/usb/media/usbvideo.h
--- a/drivers/usb/media/usbvideo.h	Sun Aug 18 20:48:36 2002
+++ b/drivers/usb/media/usbvideo.h	Sun Aug 18 20:48:36 2002
@@ -113,9 +113,10 @@
     mr = LIMIT_RGB(mm_r); \
 }
 
-#define	RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)-&gt;ind = ((rq)-&gt;ind + (n)) % (rq)-&gt;length
+#define	RING_QUEUE_SIZE		(128*1024)	/* Must be a power of 2 */
+#define	RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)-&gt;ind = ((rq)-&gt;ind + (n)) &amp; ((rq)-&gt;length-1)
 #define	RING_QUEUE_DEQUEUE_BYTES(rq,n) RING_QUEUE_ADVANCE_INDEX(rq,ri,n)
-#define	RING_QUEUE_PEEK(rq,ofs) ((rq)-&gt;queue[((ofs) + (rq)-&gt;ri) % (rq)-&gt;length])
+#define	RING_QUEUE_PEEK(rq,ofs) ((rq)-&gt;queue[((ofs) + (rq)-&gt;ri) &amp; ((rq)-&gt;length-1)])
 
 typedef struct {
 	unsigned char *queue;	/* Data from the Isoc data pump */
@@ -306,8 +307,18 @@
 
 int  RingQueue_Dequeue(RingQueue_t *rq, unsigned char *dst, int len);
 int  RingQueue_Enqueue(RingQueue_t *rq, const unsigned char *cdata, int n);
-int  RingQueue_GetLength(const RingQueue_t *rq);
 void RingQueue_WakeUpInterruptible(RingQueue_t *rq);
+void RingQueue_Flush(RingQueue_t *rq);
+
+static inline int RingQueue_GetLength(const RingQueue_t *rq)
+{
+	return (rq-&gt;wi - rq-&gt;ri + rq-&gt;length) &amp; (rq-&gt;length-1);
+}
+
+static inline int RingQueue_GetFreeSpace(const RingQueue_t *rq)
+{
+	return rq-&gt;length - RingQueue_GetLength(rq);
+}
 
 void usbvideo_DrawLine(
 	usbvideo_frame_t *frame,
</pre></body></html>