[patch] CPiA and Isochronous fixes for 2.3.11 (now with patch!)

Johannes Erdfelt jerdfelt@sventech.com
Fri, 30 Jul 1999 12:23:26 -0400


--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii

And I guess the actual patch would help as well. God I feel stupid.

On Fri, Jul 30, 1999, Johannes Erdfelt <jerdfelt@sventech.com> wrote:
> With these fixes I can view video again without it crashing. It contains
> Randy's fixes as discussed on the list.
> 
> It also removes the horrible maxpower kludge, now that interfaces/alt
> configs work correctly.
> 
> This is against 2.3.11 with Randy's /proc patch.
> 
> The patch contains no new functionality (ala the previous patches a
> couple of people have produced) that is next in the merge chain.
> 
> JE
> 

--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="cpia.patch"

diff -u drivers/usb.orig/cpia.c drivers/usb/cpia.c
--- drivers/usb.orig/cpia.c	Thu Jul 29 22:32:27 1999
+++ drivers/usb/cpia.c	Thu Jul 29 22:35:29 1999
@@ -25,6 +25,8 @@
 #include "usb.h"
 #include "cpia.h"
 
+#define CPIA_DEBUG	/* Gobs of debugging info */
+
 #define MAX_FRAME_SIZE (384 * 288 * 3)
 
 /*******************************/
@@ -319,11 +321,13 @@
 	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
 }
 
+/* How much data is left in the scratch buf? */
 #define scratch_left(x)	(cpia->scratchlen - (int)((char *)x - (char *)cpia->scratch))
 
 static void cpia_parse_data(struct usb_cpia *cpia)
 {
 	unsigned char *data = cpia->scratch;
+	unsigned long l;
 	int done;
 
 	done = 0;
@@ -339,6 +343,7 @@
 				break;
 			}
 
+			/* 0x1968 is magic */
 			printk("header: %X\n", (*data << 8) + *(data + 1));
 			if ((*data == 0x19) && (*(data + 1) == 0x68)) {
 				cpia->state = STATE_HEADER;
@@ -346,6 +351,7 @@
 				break;
 			}
 
+			/* Woops, lost the header, find the end of the frame */
 			if (scratch_left(data) < 4) {
 				done = 1;
 				break;
@@ -362,7 +368,9 @@
 				}
 				data++;
 			}
-printk("scan: scanned %d bytes\n", data-begin);
+#ifdef CPIA_DEBUG
+			printk("scan: scanned %d bytes\n", data-begin);
+#endif
 			break;
 		}
 		case STATE_HEADER:
@@ -372,7 +380,9 @@
 				break;
 			}
 
-printk("header: framerate %d\n", data[41]);
+#ifdef CPIA_DEBUG
+			printk("header: framerate %d\n", data[41]);
+#endif
 
 			data += 64;
 
@@ -390,11 +400,11 @@
 					found = 1;
 					break;
 				} else if ((*data == 0xFF) &&
-					(scratch_left(data) >= 3) &&
-					(*(data + 1) == 0xFF) &&
-					(*(data + 2) == 0xFF) &&
-					(*(data + 3) == 0xFF)) {
-					data+=4;
+						(scratch_left(data) >= 3) &&
+						(*(data + 1) == 0xFF) &&
+						(*(data + 2) == 0xFF) &&
+						(*(data + 3) == 0xFF)) {
+					data += 4;
 					cpia->curline = 144;
 					found = 1;
 					break;
@@ -402,25 +412,21 @@
 
 				data++;
 			}
-#if 0
-printk("line %d: scanned %d bytes\n", cpia->curline, data-begin);
-#endif
-if (data-begin == 355 && cpia->frame[cpia->curframe].width != 64) {
-	int i;
-	char *f = cpia->frame[cpia->curframe].data, *b = begin;
 
-#if 0
-printk("copying\n");
-#endif
+			if (data-begin == 355 && cpia->frame[cpia->curframe].width != 64) {
+				int i;
+				char *f = cpia->frame[cpia->curframe].data, *b = begin;
+
+				b += 2;
+				f += (cpia->frame[cpia->curframe].width * 3) * cpia->curline;
+
+				for (i = 0; i < 176; i++)
+					f[(i * 3) + 0] =
+					f[(i * 3) + 1] =
+					f[(i * 3) + 2] =
+						b[(i * 2)];
+			}
 
-	b+=2;
-	f+=(cpia->frame[cpia->curframe].width*3)*cpia->curline;
-	for (i = 0; i < 176; i++)
-		f[(i * 3) + 0] =
-		f[(i * 3) + 1] =
-		f[(i * 3) + 2] =
-			b[(i * 2)];
-}
 			if (found) {
 				cpia->curline++;
 				if (cpia->curline >= 144) {
@@ -440,13 +446,11 @@
 		}
 	}
 
-	{
-	int l;
-
+	/* Grab the remaining */
 	l = scratch_left(data);
 	memmove(cpia->scratch, data, l);
+
 	cpia->scratchlen = l;
-	}
 }
 
 static int cpia_isoc_irq(int status, void *__buffer, int len, void *dev_id)
@@ -466,13 +470,21 @@
 		if (cpia->frame[0].state == FRAME_READY) {
 			cpia->curframe = 0;
 			cpia->frame[0].state = FRAME_GRABBING;
-printk("capturing to frame 0\n");
+#ifdef CPIA_DEBUG
+			printk("capturing to frame 0\n");
+#endif
 		} else if (cpia->frame[1].state == FRAME_READY) {
 			cpia->curframe = 1;
 			cpia->frame[1].state = FRAME_GRABBING;
-printk("capturing to frame 1\n");
+#ifdef CPIA_DEBUG
+			printk("capturing to frame 1\n");
+#endif
+#ifdef CPIA_DEBUG
 		} else
-printk("no frame available\n");
+			printk("no frame available\n");
+#else
+		}
+#endif
 	}
 
 	sbuf = &cpia->sbuf[cpia->receivesbuf];
@@ -482,8 +494,10 @@
 	/* Do something to it now */
 	sbuf->len = usb_compress_isochronous(dev, sbuf->isodesc);
 
+#ifdef CPIA_DEBUG
 	if (sbuf->len)
-	printk("%d bytes received\n", sbuf->len);
+		printk("%d bytes received\n", sbuf->len);
+#endif
 
 	if (sbuf->len && cpia->curframe >= 0) {
 		if (sbuf->len > (SCRATCH_BUF_SIZE - cpia->scratchlen)) {
@@ -511,10 +525,6 @@
 
 	cpia->receivesbuf = 0;
 
-#if 0
-	cpia->parsesbuf = 0;
-	cpia->parsepos = 0;
-#endif
 	cpia->scratchlen = 0;
 	cpia->curline = 0;
 	cpia->state = STATE_SCANNING;
@@ -524,15 +534,20 @@
 	cpia->sbuf[1].isodesc = usb_allocate_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->sbuf[1].data, STREAM_BUF_SIZE, 960, cpia_isoc_irq, cpia);
 	cpia->sbuf[2].isodesc = usb_allocate_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->sbuf[2].data, STREAM_BUF_SIZE, 960, cpia_isoc_irq, cpia);
 
+#ifdef CPIA_DEBUG
 	printk("isodesc[0] @ %p\n", cpia->sbuf[0].isodesc);
 	printk("isodesc[1] @ %p\n", cpia->sbuf[1].isodesc);
 	printk("isodesc[2] @ %p\n", cpia->sbuf[2].isodesc);
+#endif
 
 	/* Schedule the queues */
 	usb_schedule_isochronous(dev, cpia->sbuf[0].isodesc, NULL);
 	usb_schedule_isochronous(dev, cpia->sbuf[1].isodesc, cpia->sbuf[0].isodesc);
 	usb_schedule_isochronous(dev, cpia->sbuf[2].isodesc, cpia->sbuf[1].isodesc);
 
+#ifdef CPIA_DEBUG
+	printk("done scheduling\n");
+#endif
 	if (usb_set_interface(cpia->dev, 1, 3)) {
 		printk("cpia_set_interface error\n");
 		return -EINVAL;
@@ -541,6 +556,9 @@
 	usb_cpia_startstreamcap(cpia->dev);
 
 	cpia->streaming = 1;
+#ifdef CPIA_DEBUG
+	printk("now streaming\n");
+#endif
 
 	return 0;
 }
@@ -579,7 +597,9 @@
 {
 	struct usb_cpia *cpia = (struct usb_cpia *)dev;
 
-printk("cpia_open\n");
+#ifdef CPIA_DEBUG
+	printk("cpia_open\n");
+#endif
 
 	cpia->fbuf = rvmalloc(2 * MAX_FRAME_SIZE);
 	if (!cpia->fbuf)
@@ -590,8 +610,10 @@
 
 	cpia->frame[0].data = cpia->fbuf;
 	cpia->frame[1].data = cpia->fbuf + MAX_FRAME_SIZE;
+#ifdef CPIA_DEBUG
 	printk("frame [0] @ %p\n", cpia->frame[0].data);
 	printk("frame [1] @ %p\n", cpia->frame[1].data);
+#endif
 
 	cpia->sbuf[0].data = kmalloc(STREAM_BUF_SIZE, GFP_KERNEL);
 	if (!cpia->sbuf[0].data)
@@ -605,9 +627,11 @@
 	if (!cpia->sbuf[2].data)
 		return -ENOMEM;
 
+#ifdef CPIA_DEBUG
 	printk("sbuf[0] @ %p\n", cpia->sbuf[0].data);
 	printk("sbuf[1] @ %p\n", cpia->sbuf[1].data);
 	printk("sbuf[2] @ %p\n", cpia->sbuf[2].data);
+#endif
 
 	cpia->curframe = -1;
 	cpia->receivesbuf = 0;
@@ -623,7 +647,9 @@
 {
 	struct usb_cpia *cpia = (struct usb_cpia *)dev;
 
-printk("cpia_close\n");
+#ifdef CPIA_DEBUG
+	printk("cpia_close\n");
+#endif
 
 	cpia_stop_isoc(cpia);
 
@@ -646,90 +672,6 @@
 	return -EINVAL;
 }
 
-#if 0
-	if (usb_set_interface(dev, 1, 3)) {
-		printk("cpia_set_interface error\n");
-		return -EINVAL;
-	}
-
-	if (usb_cpia_grab_frame(dev, 0)) {
-		printk("cpia_grab_frame error\n");
-		return -EINVAL;
-	}
-
-	if (usb_cpia_upload_frame(dev, 0)) {
-		printk("cpia_upload_frame error\n");
-		return -EINVAL;
-	}
-
-	buf = cpia->ibuf;
-	uhci_receive_isochronous(dev, usb_rcvisocpipe(dev,1), buf, 176*144*4);
-
-	{
-	printk("header magic: %X\n", (buf[0] << 8) + buf[1]);
-
-	while ((buf[0] != 0x19) || (buf[1] != 0x68)) {
-		int i;
-
-		printk("resync'ing\n");
-		for (i=0;i<(176*144*4)-4;i++, buf++)
-			if (
-				(buf[0] == 0xFF) &&
-				(buf[1] == 0xFF) &&
-				(buf[2] == 0xFF) &&
-				(buf[3] == 0xFF)) {
-				buf+=4;
-				i+=4;
-				break;
-			}
-
-		memmove(cpia->ibuf, buf, (176*144*4) - i);
-		uhci_receive_isochronous(dev, usb_rcvisocpipe(dev,1), cpia->ibuf + (176*144*4) - i, i);
-		buf = cpia->ibuf;
-
-#if 0
-		printk("header magic: %X\n", (buf[0] << 8) + buf[1]);
-#endif
-	}
-
-	printk("size: %d, sample: %d, order: %d\n", buf[16], buf[17], buf[18]);
-	printk("comp: %d, decimation: %d\n", buf[28], buf[29]);
-	printk("roi: top left: %d, %d bottom right: %d, %d\n",
-		buf[26] * 4, buf[24] * 8,
-		buf[27] * 4, buf[25] * 8);
-
-	printk("vm->frame: %d\n", vm->frame);
-
-	{
-	int i, i1;
-	char *b = buf + 64, *fbuf = &cpia->fbuffer[MAX_FRAME_SIZE * (vm->frame & 1)];
-	for (i=0;i<144;i++) {
-#if 0
-		printk("line len: %d\n", (b[1] << 8) + b[0]);
-#endif
-		b += 2;
-		for (i1=0;i1<176;i1++) {
-			fbuf[(i * vm->width * 3) + (i1 * 3)] = 
-			fbuf[(i * vm->width * 3) + (i1 * 3) + 1] = 
-			fbuf[(i * vm->width * 3) + (i1 * 3) + 2] = 
-				b[i1 * 2];
-#if 0
-			*((short *)&fbuf[(i * vm->width * 2) + (i1 * 2)]) =
-				((b[i1 * 2] >> 3) << 11) + ((b[i1 * 2] >> 2) << 6) + (b[i1 * 2] >> 3);
-#endif
-		}
-		b += (176 * 2) + 1;
-	}
-	}
-
-	}
-
-	if (usb_set_interface(dev, 1, 0)) {
-		printk("cpia_set_interface error\n");
-		return -EINVAL;
-	}
-#endif
-
 static int cpia_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
 {
 	struct usb_cpia *cpia = (struct usb_cpia *)dev;
@@ -743,10 +685,10 @@
 			b.type = VID_TYPE_CAPTURE /* | VID_TYPE_SUBCAPTURE */;
 			b.channels = 1;
 			b.audios = 0;
-			b.maxwidth = 176 /* 352 */;
-			b.maxheight = 144 /* 240 */;
-			b.minwidth = 176 /* (Something small?) */;
-			b.minheight = 144 /* "         " */;
+			b.maxwidth = 176	/* 352 */;
+			b.maxheight = 144	/* 240 */;
+			b.minwidth = 176	/* (Something small?) */;
+			b.minheight = 144	/* "         " */;
 
 			if (copy_to_user(arg, &b, sizeof(b)))
 				return -EFAULT;
@@ -846,13 +788,9 @@
 			if (copy_from_user(&p, arg, sizeof(p)))
 				return -EFAULT;
 
-printk("Attempting to set palette %d, depth %d\n", p.palette, p.depth);
-
-#if 0
-			if (p.palette != VIDEO_PALETTE_YUYV)
-				return -EINVAL;
-			if (p.depth != 16)
-				return -EINVAL;
+#ifdef CPIA_DEBUG
+			printk("Attempting to set palette %d, depth %d\n",
+				p.palette, p.depth);
 #endif
 
 			return 0;
@@ -861,7 +799,10 @@
 		{
 			struct video_window vw;
 
-printk("VIDIOCSWIN\n");
+#ifdef CPIA_DEBUG
+			printk("VIDIOCSWIN\n");
+#endif
+
 			if (copy_from_user(&vw, arg, sizeof(vw)))
 				return -EFAULT;
 			if (vw.flags)
@@ -879,7 +820,10 @@
 		{
 			struct video_window vw;
 
-printk("VIDIOCGWIN\n");
+#ifdef CPIA_DEBUG
+			printk("VIDIOCGWIN\n");
+#endif
+
 			vw.x = 0;
 			vw.y = 0;
 			vw.width = 176;
@@ -914,8 +858,11 @@
 			if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm)))
 				return -EFAULT;
 
-printk("MCAPTURE\n");
-printk("frame: %d, size: %dx%d, format: %d\n", vm.frame, vm.width, vm.height, vm.format);
+#ifdef CPIA_DEBUG
+			printk("MCAPTURE\n");
+			printk("frame: %d, size: %dx%d, format: %d\n",
+				vm.frame, vm.width, vm.height, vm.format);
+#endif
 
 			if (vm.format != VIDEO_PALETTE_RGB24)
 				return -EINVAL;
@@ -938,7 +885,9 @@
 			if (copy_from_user((void *)&frame, arg, sizeof(int)))
 				return -EFAULT;
 
+#ifdef CPIA_DEBUG
 			printk("syncing to frame %d\n", frame);
+#endif
 			switch (cpia->frame[frame].state) {
 				case FRAME_UNUSED:
 					return -EINVAL;
@@ -949,7 +898,9 @@
 					cpia->frame[frame].state = FRAME_UNUSED;
 					break;
 			}
+#ifdef CPIA_DEBUG
 			printk("synced to frame %d\n", frame);
+#endif
 			return 0;
 		}
 		case VIDIOCCAPTURE:
@@ -979,7 +930,9 @@
 	struct usb_cpia *cpia = (struct usb_cpia *)dev;
 	int len;
 
+#ifdef CPIA_DEBUG
 	printk("cpia_read: %ld bytes\n", count);
+#endif
 #if 0
 	len = cpia_capture(cpia, buf, count);
 
@@ -994,17 +947,12 @@
 	unsigned long start = (unsigned long)adr;
 	unsigned long page, pos;
 
+#ifdef CPIA_DEBUG
 	printk("mmap: %ld (%lX) bytes\n", size, size);
+#endif
 	if (size > (((2 * MAX_FRAME_SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
 		return -EINVAL;
 
-#if 0
-	if (!cpia->fbuffer) {
-		if ((cpia->fbuffer = rvmalloc(2 * MAX_FRAME_SIZE)) == NULL)
-			return -EINVAL;
-	}
-#endif
-
 	pos = (unsigned long)cpia->fbuf;
 	while (size > 0)
 	{
@@ -1114,39 +1062,6 @@
 		printk("cpia_set_compression error\n");
 		return;
 	}
-
-#if 0
-	if (usb_cpia_grab_frame(dev, 0)) {
-		printk("cpia_grab_frame error\n");
-		return;
-	}
-
-	if (usb_cpia_upload_frame(dev, 1)) {
-		printk("cpia_upload_frame error\n");
-		return;
-	}
-
-	buf = (void *)__get_free_page(GFP_KERNEL);
-
-	{
-	int i;
-	for (i=0;i<448;i++)
-		buf[i]=0;
-	}
-	uhci_receive_isochronous(dev, usb_rcvisocpipe(dev,1), buf, 448);
-
-	{
-	int i;
-	for (i=0;i<448;i++) {
-		printk("%02X ", buf[i]);
-		if ((i % 16) == 15)
-			printk("\n");
-	}
-	printk("\n");
-	}
-
-	free_page((unsigned long)buf);
-#endif
 }
 
 static int cpia_probe(struct usb_device *dev)
@@ -1159,29 +1074,9 @@
 	if (dev->descriptor.bNumConfigurations != 1)
 		return -1;
 
-#if 0
-	/* We don't handle multi-interface hubs */
-	if (dev->config[0].bNumInterfaces != 1)
-		return -1;
-#endif
-
 	interface = &dev->config[0].altsetting[0].interface[0];
 
 	/* Is it a CPiA? */
-/*
-Apr 24 17:49:04 bjorn kernel:   Vendor:  0545 
-Apr 24 17:49:04 bjorn kernel:   Product: 8080 
-*/
-/*
-	if (dev->descriptor.idVendor != 0x0545)
-		return -1;
-	if (dev->descriptor.idProduct != 0x8080)
-		return -1;
-	if (interface->bInterfaceClass != 0xFF)
-		return -1;
-	if (interface->bInterfaceSubClass != 0xFF)
-		return -1;
-*/
 	if (dev->descriptor.idVendor != 0x0553)
 		return -1;
 	if (dev->descriptor.idProduct != 0x0002)
@@ -1191,22 +1086,6 @@
 	if (interface->bInterfaceSubClass != 0x00)
 		return -1;
 
-#if 0
-	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
-	if (interface->bNumEndpoints != 1)
-		return -1;
-
-	endpoint = &interface->endpoint[0];
-
-	/* Output endpoint? Curiousier and curiousier.. */
-	if (!(endpoint->bEndpointAddress & 0x80))
-		return -1;
-
-	/* If it's not an interrupt endpoint, we'd better punt! */
-	if ((endpoint->bmAttributes & 3) != 3)
-		return -1;
-#endif
-
 	/* We found a CPiA */
 	printk("USB CPiA camera found\n");
 
@@ -1222,10 +1101,6 @@
 
 	usb_cpia_configure(cpia);
 
-#if 0
-	usb_request_irq(dev, usb_rcvctrlpipe(dev, endpoint->bEndpointAddress), pport_irq, endpoint->bInterval, pport);
-#endif
-
 	return 0;
 }
 
@@ -1261,6 +1136,7 @@
 {
 	return usb_cpia_init();
 }
+
 void cleanup_module(void)
 {
 }
diff -u drivers/usb.orig/uhci.c drivers/usb/uhci.c
--- drivers/usb.orig/uhci.c	Thu Jul 29 22:32:27 1999
+++ drivers/usb/uhci.c	Thu Jul 29 22:37:19 1999
@@ -468,9 +468,12 @@
 		return USB_ST_INTERNALERROR;
 
 	/* Remove it from the internal irq_list */
+	uhci_remove_irq_list(td);
+#if 0
 	spin_lock_irqsave(&irqlist_lock, flags);
 	list_del(&td->irq_list);
 	spin_unlock_irqrestore(&irqlist_lock, flags);
+#endif
 
 	/* Remove the interrupt TD and QH */
 	uhci_remove_td(td);
@@ -505,12 +508,10 @@
 		if ((cdata != data) && (n))
 			memmove(data, cdata, n);
 
-#if 0
-if (n && n != 960)
-	printk("underrun: %d %d\n", i, n);
-#endif
-if ((isodesc->td[i].status >> 16) & 0xFF)
-	printk("error: %d %X\n", i, (isodesc->td[i].status >> 16));
+		/* Debugging */
+		if ((isodesc->td[i].status >> 16) & 0xFF)
+			printk("error: %d %X\n", i,
+				(isodesc->td[i].status >> 16));
 
 		data += n;
 		totlen += n;
@@ -557,16 +558,13 @@
 
 	/* Insert TD into list */
 	if (!pisodesc) {
+		/* It's not guaranteed to be 1-1024 */
 		frame = inw(uhci->io_addr + USBFRNUM) % 1024;
 		/* HACK: Start 2 frames from now */
 		frame = (frame + 2) % 1024;
 	} else
 		frame = (pisodesc->endframe + 1) % 1024;
 
-#if 0
-printk("scheduling first at frame %d\n", frame);
-#endif
-
 	for (i = 0; i < isodesc->num; i++) {
 		/* Active */
 		isodesc->td[i].status |= (1 << 23);
@@ -575,19 +573,12 @@
 		uhci->fl->frame[(frame + i) % 1024] = virt_to_bus(&isodesc->td[i]);
 	}
 
-#if 0
-printk("last at frame %d\n", (frame + i - 1) % 1024);
-#endif
-
-	/* Interrupt */
+	/* IOC on the last TD */
 	isodesc->td[i - 1].status |= (1 << 24);
 
 	isodesc->frame = frame;
 	isodesc->endframe = (frame + isodesc->num - 1) % 1024;
 
-#if 0
-	return uhci_td_result(dev, td[num - 1]);
-#endif
 	return 0;
 }
 
@@ -610,7 +601,7 @@
 	memset(isodesc, 0, sizeof(*isodesc));
 
 	/* Carefully work around the non contiguous pages */
-	isodesc->num = (len / PAGE_SIZE) * (PAGE_SIZE / maxsze);
+	isodesc->num = len / maxsze;
 	isodesc->td = kmalloc(sizeof(struct uhci_td) * isodesc->num, GFP_KERNEL);
 	isodesc->frame = isodesc->endframe = -1;
 	isodesc->data = data;
@@ -655,15 +646,14 @@
 		i++;
 
 		data += maxsze;
-
-		if (((int)data % PAGE_SIZE) + maxsze >= PAGE_SIZE)
-			data = (char *)(((int)data + maxsze) & ~(PAGE_SIZE - 1));
-		
 		len -= maxsze;
 	} while (i < isodesc->num);
 
+#if 0
 	/* IOC on the last TD */
 	td->status |= (1 << 24);
+#endif
+
 	uhci_add_irq_list(dev->uhci, td, completed, dev_id);
 
 	return isodesc;
@@ -865,7 +855,6 @@
 	td->first = first;
 	td->link = 1;					/* Terminate */
 
-
 	/* Start it up.. */
 	ret = uhci_run_control(dev, first, td);
 
@@ -921,7 +910,7 @@
 	DECLARE_WAITQUEUE(wait, current);
 	struct uhci_qh *bulk_qh = uhci_qh_allocate(dev);
 	struct uhci_td *curtd;
-	struct uhci_device *root_hub=usb_to_uhci(dev->uhci->bus->root_hub);
+	struct uhci_device *root_hub = usb_to_uhci(dev->uhci->bus->root_hub);
 
 	current->state = TASK_UNINTERRUPTIBLE;
 	add_wait_queue(&bulk_wakeup, &wait);
@@ -1094,15 +1083,16 @@
 	struct uhci_device *dev;
 	int i;
 
+	/* Allocate the USB device */
 	usb_dev = kmalloc(sizeof(*usb_dev), GFP_KERNEL);
 	if (!usb_dev)
 		return NULL;
 
 	memset(usb_dev, 0, sizeof(*usb_dev));
 
+	/* Allocate the UHCI device private data */
 	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
-		usb_destroy_configuration(usb_dev);
 		kfree(usb_dev);
 		return NULL;
 	}
@@ -1312,9 +1302,10 @@
 		next = tmp->next;
 
 		if (!((status = td->status) & (1 << 23)) ||  /* No longer active? */
+		    (td->qh &&
 		    ((td->qh->element & ~15) && 
 		      !((status = uhci_link_to_td(td->qh->element)->status) & (1 <<23)) &&
-		      (status & 0x760000) /* is in error state (Stall, db, babble, timeout, bitstuff) */)) {	
+		      (status & 0x760000) /* is in error state (Stall, db, babble, timeout, bitstuff) */))) {	
 			/* remove from IRQ list */
 			__list_del(tmp->prev, next);
 			INIT_LIST_HEAD(tmp);
diff -u drivers/usb.orig/usb.c drivers/usb/usb.c
--- drivers/usb.orig/usb.c	Thu Jul 29 22:32:58 1999
+++ drivers/usb/usb.c	Thu Jul 29 22:30:17 1999
@@ -344,11 +344,6 @@
 	parsed += *ptr;
 	le16_to_cpus(&config->wTotalLength);
 
-	if (config->MaxPower == 200) {
-		printk("bNumInterfaces kludge\n");
-		config->bNumInterfaces += 3;
-	}
-
 	if (config->bNumInterfaces > USB_MAXINTERFACES)
 	{
 		printk(KERN_WARNING "usb: too many interfaces.\n");
@@ -359,8 +354,8 @@
 	config->altsetting = (struct usb_alternate_setting *)
 	        kmalloc(USB_MAXALTSETTING * sizeof(struct usb_alternate_setting), GFP_KERNEL);
 	if (config->altsetting == NULL) {
-	  printk(KERN_WARNING "usb: out of memory.\n");
-	  return -1;
+		printk(KERN_WARNING "usb: out of memory.\n");
+		return -1;
 	}
 	config->act_altsetting = 0;
 	config->num_altsetting = 1;

--UlVJffcvxoiEqYs2--
-----------------------------------------------------------------------------
To unsubscribe from this mailinglist, send the line "unsubscribe vision-webcam" in the
body of a message to "majordomo@errors.no".