## Automatically generated incremental diff
## From:   linux-2.5.1-pre7
## To:     linux-2.5.1-pre8
## Robot:  $Id: make-incremental-diff,v 1.8 2001/12/04 06:05:04 hpa Exp $

diff -urN linux-2.5.1-pre7/Documentation/usb/error-codes.txt linux/Documentation/usb/error-codes.txt
--- linux-2.5.1-pre7/Documentation/usb/error-codes.txt	Wed Oct 17 14:34:06 2001
+++ linux/Documentation/usb/error-codes.txt	Sat Dec  8 21:05:02 2001
@@ -1,14 +1,9 @@
-Revised: 2000-Dec-05.
+Revised: 2001-Dec-06.
 
 This is the documentation of (hopefully) all possible error codes (and
 their interpretation) that can be returned from the host controller drivers 
 and from usbcore.
 
-NOTE:
-The USB_ST_* codes are deprecated and are only listed for compatibility;
-new software should use only -E* instead!
-
-
 
 **************************************************************************
 *                   Error codes returned by usb_submit_urb               *
@@ -16,7 +11,6 @@
 
 Non-USB-specific:
 
-USB_ST_NOERROR
 0		URB submission went fine
 
 -ENOMEM		no memory for allocation of internal structures	
@@ -25,12 +19,10 @@
 
 -ENODEV		specified USB-device or bus doesn't exist
 
-USB_ST_REQUEST_ERROR
 -ENXIO		a control or interrupt URB is already queued to this endpoint; or
 		  a bulk URB is already queued to this endpoint and
 		  USB_QUEUE_BULK wasn't used (UHCI HCDs only)
 
-USB_ST_URB_INVALID_ERROR
 -EINVAL		a) Invalid transfer type specified (or not supported)
 		b) Invalid interrupt interval (0<=n<256)
 		c) more than one interrupt packet requested
@@ -42,12 +34,10 @@
 
 -EFBIG		too much ISO frames requested (currently uhci>900)
 
-USB_ST_STALL
 -EPIPE		specified pipe-handle is already stalled
 
 -EMSGSIZE	endpoint message size is zero, do interface/alternate setting
 
-USB_ST_BANDWIDTH_ERROR
 -ENOSPC		The host controller's bandwidth is already consumed and
 		this request would push it past its allowed limit.
 
@@ -60,60 +50,43 @@
 *                   or in iso_frame_desc[n].status (for ISO)             *
 **************************************************************************
 
-USB_ST_NOERROR
 0			Transfer completed successfully
 
-USB_ST_URB_KILLED
 -ENOENT			URB was canceled by usb_unlink_urb
 
-USB_ST_URB_PENDING
 -EINPROGRESS		URB still pending, no results yet
 			(actually no error until now;-)
 
-USB_ST_BITSTUFF
-USB_ST_INTERNALERROR
 -EPROTO			a) bitstuff error
 			b) unknown USB error 
 
-USB_ST_CRC
 -EILSEQ			CRC mismatch
 
-USB_ST_STALL
 -EPIPE			endpoint stalled
 
-USB_ST_BUFFEROVERRUN
 -ECOMM			During an IN transfer, the host controller
 			received data from an endpoint faster than it
 			could be written to system memory
 
-USB_ST_BUFFERUNDERRUN
 -ENOSR			During an OUT transfer, the host controller
 			could not retrieve data from system memory fast
 			enough to keep up with the USB data rate
 
-USB_ST_DATAOVERRUN
 -EOVERFLOW		The amount of data returned by the endpoint was
 			greater than either the max packet size of the
 			endpoint or the remaining buffer size.  "Babble".
 
-USB_ST_DATAUNDERRUN
 -EREMOTEIO		The endpoint returned less than max packet size
 			and that amount did not fill the specified buffer
-USB_ST_NORESPONSE
-USB_ST_TIMEOUT
 -ETIMEDOUT		transfer timed out, NAK
 
-USB_ST_REMOVED	
 -ENODEV			device was removed
 
-USB_ST_SHORT_PACKET
 -EREMOTEIO		short packet detected
 
-USB_ST_PARTIAL_ERROR
 -EXDEV			ISO transfer only partially completed
 			look at individual frame status for details
 
-USB_ST_URB_INVALID_ERROR
 -EINVAL			ISO madness, if this happens: Log off and go home
 
 -ECONNRESET		the URB is being unlinked asynchronously
diff -urN linux-2.5.1-pre7/Documentation/usb/scanner.txt linux/Documentation/usb/scanner.txt
--- linux-2.5.1-pre7/Documentation/usb/scanner.txt	Sat Oct 20 19:13:11 2001
+++ linux/Documentation/usb/scanner.txt	Sat Dec  8 21:05:02 2001
@@ -83,7 +83,7 @@
 	`mknod /dev/usbscanner1 c 180 49`
                       . 
                       .
-	`mknod /dev/usbscanner15 180 63`
+	`mknod /dev/usbscanner15 c 180 63`
 
 
 If you foresee using only one scanner it is best to:
diff -urN linux-2.5.1-pre7/Makefile linux/Makefile
--- linux-2.5.1-pre7/Makefile	Sat Dec  8 21:04:22 2001
+++ linux/Makefile	Sat Dec  8 21:05:02 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 1
-EXTRAVERSION =-pre7
+EXTRAVERSION =-pre8
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.5.1-pre7/arch/i386/defconfig linux/arch/i386/defconfig
--- linux-2.5.1-pre7/arch/i386/defconfig	Sat Dec  8 21:04:22 2001
+++ linux/arch/i386/defconfig	Sat Dec  8 21:05:02 2001
@@ -496,9 +496,6 @@
 # IrDA (infrared) support
 #
 # CONFIG_IRDA is not set
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
 
 #
 # ISDN subsystem
diff -urN linux-2.5.1-pre7/drivers/block/DAC960.c linux/drivers/block/DAC960.c
--- linux-2.5.1-pre7/drivers/block/DAC960.c	Sat Dec  8 21:04:22 2001
+++ linux/drivers/block/DAC960.c	Sat Dec  8 21:05:02 2001
@@ -1947,7 +1947,6 @@
   */
   RequestQueue = BLK_DEFAULT_QUEUE(MajorNumber);
   blk_init_queue(RequestQueue, DAC960_RequestFunction);
-  blk_queue_headactive(RequestQueue, 0);
   RequestQueue->queuedata = Controller;
   RequestQueue->max_segments = Controller->DriverScatterGatherLimit;
   RequestQueue->max_sectors = Controller->MaxBlocksPerCommand;
diff -urN linux-2.5.1-pre7/drivers/block/block_ioctl.c linux/drivers/block/block_ioctl.c
--- linux-2.5.1-pre7/drivers/block/block_ioctl.c	Sat Dec  8 21:04:22 2001
+++ linux/drivers/block/block_ioctl.c	Sat Dec  8 21:05:02 2001
@@ -37,7 +37,7 @@
 
 	rq->flags |= REQ_BARRIER;
 	rq->waiting = &wait;
-	elv_add_request(q, rq);
+	elv_add_request(q, rq, 1);
 	generic_unplug_device(q);
 	wait_for_completion(&wait);
 
diff -urN linux-2.5.1-pre7/drivers/block/cciss.c linux/drivers/block/cciss.c
--- linux-2.5.1-pre7/drivers/block/cciss.c	Sat Dec  8 21:04:22 2001
+++ linux/drivers/block/cciss.c	Sat Dec  8 21:05:02 2001
@@ -1867,7 +1867,6 @@
 	q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);
         q->queuedata = hba[i];
         blk_init_queue(q, do_cciss_request);
-        blk_queue_headactive(q, 0);		
 	blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);
 	blk_queue_max_segments(q, MAXSGENTRIES);
 	blk_queue_max_sectors(q, 512);
diff -urN linux-2.5.1-pre7/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- linux-2.5.1-pre7/drivers/block/cpqarray.c	Sat Dec  8 21:04:22 2001
+++ linux/drivers/block/cpqarray.c	Sat Dec  8 21:05:02 2001
@@ -468,7 +468,6 @@
 		q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);
 		q->queuedata = hba[i];
 		blk_init_queue(q, do_ida_request);
-		blk_queue_headactive(q, 0);
 		blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask);
 		blk_queue_max_segments(q, SG_MAX);
 		blksize_size[MAJOR_NR+i] = ida_blocksizes + (i*256);
diff -urN linux-2.5.1-pre7/drivers/block/genhd.c linux/drivers/block/genhd.c
--- linux-2.5.1-pre7/drivers/block/genhd.c	Sat Dec  8 21:04:22 2001
+++ linux/drivers/block/genhd.c	Sat Dec  8 21:05:02 2001
@@ -149,8 +149,7 @@
 	char buf[64];
 	int len, n;
 
-	len = sprintf(page, "major minor   #blocks  start_sect   nr_sects  "
-			"name\n\n");
+	len = sprintf(page, "major minor  #blocks  name\n\n");
 	read_lock(&gendisk_lock);
 	for (gp = gendisk_head; gp; gp = gp->next) {
 		for (n = 0; n < (gp->nr_real << gp->minor_shift); n++) {
@@ -158,10 +157,8 @@
 				continue;
 
 			len += snprintf(page + len, 63,
-					"%4d  %4d %10d  %10lu %10lu  %s\n",
+					"%4d  %4d %10d %s\n",
 					gp->major, n, gp->sizes[n],
-					gp->part[n].start_sect,
-					gp->part[n].nr_sects,
 					disk_name(gp, n, buf));
 			if (len < offset)
 				offset -= len, len = 0;
diff -urN linux-2.5.1-pre7/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- linux-2.5.1-pre7/drivers/block/ll_rw_blk.c	Sat Dec  8 21:04:22 2001
+++ linux/drivers/block/ll_rw_blk.c	Sat Dec  8 21:05:02 2001
@@ -562,6 +562,7 @@
 
 static int blk_init_free_list(request_queue_t *q)
 {
+	struct request_list *rl;
 	struct request *rq;
 	int i;
 
@@ -573,20 +574,22 @@
 	/*
 	 * Divide requests in half between read and write
 	 */
+	rl = &q->rq[READ];
 	for (i = 0; i < queue_nr_requests; i++) {
 		rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL);
 		if (!rq)
 			goto nomem;
 
+		/*
+		 * half way through, switch to WRITE list
+		 */
+		if (i == queue_nr_requests / 2)
+			rl = &q->rq[WRITE];
+
 		memset(rq, 0, sizeof(struct request));
 		rq->rq_status = RQ_INACTIVE;
-		if (i < queue_nr_requests >> 1) {
-			list_add(&rq->queuelist, &q->rq[READ].free);
-			q->rq[READ].count++;
-		} else {
-			list_add(&rq->queuelist, &q->rq[WRITE].free);
-			q->rq[WRITE].count++;
-		}
+		list_add(&rq->queuelist, &rl->free);
+		rl->count++;
 	}
 
 	init_waitqueue_head(&q->rq[READ].wait);
@@ -692,21 +695,22 @@
 static struct request *get_request_wait(request_queue_t *q, int rw)
 {
 	DECLARE_WAITQUEUE(wait, current);
+	struct request_list *rl = &q->rq[rw];
 	struct request *rq;
 
 	spin_lock_prefetch(&q->queue_lock);
 
 	generic_unplug_device(q);
-	add_wait_queue(&q->rq[rw].wait, &wait);
+	add_wait_queue(&rl->wait, &wait);
 	do {
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		if (q->rq[rw].count < batch_requests)
+		if (rl->count < batch_requests)
 			schedule();
 		spin_lock_irq(&q->queue_lock);
 		rq = get_request(q, rw);
 		spin_unlock_irq(&q->queue_lock);
 	} while (rq == NULL);
-	remove_wait_queue(&q->rq[rw].wait, &wait);
+	remove_wait_queue(&rl->wait, &wait);
 	current->state = TASK_RUNNING;
 	return rq;
 }
@@ -1234,7 +1238,6 @@
 	 */
 	BUG_ON(!bio->bi_end_io);
 
-	BIO_BUG_ON(bio_offset(bio) > PAGE_SIZE);
 	BIO_BUG_ON(!bio->bi_size);
 	BIO_BUG_ON(!bio->bi_io_vec);
 
@@ -1397,6 +1400,28 @@
 extern int stram_device_init (void);
 #endif
 
+inline void blk_recalc_request(struct request *rq, int nsect)
+{
+	rq->hard_sector += nsect;
+	rq->hard_nr_sectors -= nsect;
+	rq->sector = rq->hard_sector;
+	rq->nr_sectors = rq->hard_nr_sectors;
+
+	rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
+	rq->hard_cur_sectors = rq->current_nr_sectors;
+
+	/*
+	 * if total number of sectors is less than the first segment
+	 * size, something has gone terribly wrong
+	 */
+	if (rq->nr_sectors < rq->current_nr_sectors) {
+		printk("blk: request botched\n");
+		rq->nr_sectors = rq->current_nr_sectors;
+	}
+
+	rq->buffer = bio_data(rq->bio);
+}
+
 /**
  * end_that_request_first - end I/O on one buffer.
  * @req:      the request being processed
@@ -1414,53 +1439,55 @@
 
 int end_that_request_first(struct request *req, int uptodate, int nr_sectors)
 {
-	struct bio *bio, *nxt;
-	int nsect, total_nsect = 0;
+	int nsect, total_nsect;
+	struct bio *bio;
 
 	req->errors = 0;
 	if (!uptodate)
 		printk("end_request: I/O error, dev %s, sector %lu\n",
 			kdevname(req->rq_dev), req->sector);
 
-	if ((bio = req->bio) != NULL) {
-next_chunk:
+	total_nsect = 0;
+	while ((bio = req->bio)) {
 		nsect = bio_iovec(bio)->bv_len >> 9;
 
+		bio->bi_size -= bio_iovec(bio)->bv_len;
+
+		/*
+		 * not a complete bvec done
+		 */
+		if (unlikely(nsect > nr_sectors)) {
+			int residual = (nsect - nr_sectors) << 9;
+
+			bio_iovec(bio)->bv_offset += residual;
+			bio_iovec(bio)->bv_len -= residual;
+			blk_recalc_request(req, nr_sectors);
+			return 1;
+		}
+
 		nr_sectors -= nsect;
 		total_nsect += nsect;
 
 		if (++bio->bi_idx >= bio->bi_vcnt) {
-			nxt = bio->bi_next;
-			if (!bio_endio(bio, uptodate, total_nsect)) {
-				total_nsect = 0;
-				req->bio = nxt;
-			} else
+			req->bio = bio->bi_next;
+
+			if (unlikely(bio_endio(bio, uptodate, total_nsect)))
 				BUG();
+
+			total_nsect = 0;
 		}
 
-		if ((bio = req->bio) != NULL) {
-			req->hard_sector += nsect;
-			req->hard_nr_sectors -= nsect;
-			req->sector = req->hard_sector;
-			req->nr_sectors = req->hard_nr_sectors;
-
-			req->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
-			req->hard_cur_sectors = req->current_nr_sectors;
-			if (req->nr_sectors < req->current_nr_sectors) {
-				printk("end_request: buffer-list destroyed\n");
-				req->nr_sectors = req->current_nr_sectors;
-			}
+		if ((bio = req->bio)) {
+			blk_recalc_request(req, nsect);
 
-			req->buffer = bio_data(bio);
 			/*
 			 * end more in this run, or just return 'not-done'
 			 */
-			if (nr_sectors > 0)
-				goto next_chunk;
-
-			return 1;
+			if (unlikely(nr_sectors <= 0))
+				return 1;
 		}
 	}
+
 	return 0;
 }
 
@@ -1544,3 +1571,4 @@
 EXPORT_SYMBOL(blk_rq_map_sg);
 EXPORT_SYMBOL(blk_nohighio);
 EXPORT_SYMBOL(blk_dump_rq_flags);
+EXPORT_SYMBOL(submit_bio);
diff -urN linux-2.5.1-pre7/drivers/block/nbd.c linux/drivers/block/nbd.c
--- linux-2.5.1-pre7/drivers/block/nbd.c	Sat Dec  8 21:04:22 2001
+++ linux/drivers/block/nbd.c	Sat Dec  8 21:05:02 2001
@@ -516,7 +516,6 @@
 	blksize_size[MAJOR_NR] = nbd_blksizes;
 	blk_size[MAJOR_NR] = nbd_sizes;
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_nbd_request);
-	blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
 	for (i = 0; i < MAX_NBD; i++) {
 		nbd_dev[i].refcnt = 0;
 		nbd_dev[i].file = NULL;
diff -urN linux-2.5.1-pre7/drivers/block/xd.c linux/drivers/block/xd.c
--- linux-2.5.1-pre7/drivers/block/xd.c	Sat Dec  8 21:04:22 2001
+++ linux/drivers/block/xd.c	Sat Dec  8 21:05:02 2001
@@ -121,7 +121,6 @@
 static struct hd_struct xd_struct[XD_MAXDRIVES << 6];
 static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES];
 static int xd_blocksizes[XD_MAXDRIVES << 6];
-static int xd_maxsect[XD_MAXDRIVES << 6];
 
 extern struct block_device_operations xd_fops;
 
@@ -246,8 +245,7 @@
 	}
 
 	/* xd_maxsectors depends on controller - so set after detection */
-	for(i=0; i<(XD_MAXDRIVES << 6); i++) xd_maxsect[i] = xd_maxsectors;
-	max_sectors[MAJOR_NR] = xd_maxsect;
+	blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), xd_maxsectors);
 
 	for (i = 0; i < xd_drives; i++) {
 		xd_valid[i] = 1;
@@ -294,11 +292,11 @@
 			block = CURRENT->sector;
 			count = CURRENT->nr_sectors;
 
-			switch (CURRENT->cmd) {
+			switch (rq_data_dir(CURRENT)) {
 				case READ:
 				case WRITE:
 					for (retry = 0; (retry < XD_RETRIES) && !code; retry++)
-						code = xd_readwrite(CURRENT->cmd,CURRENT_DEV,CURRENT->buffer,block,count);
+						code = xd_readwrite(rq_data_dir(CURRENT),CURRENT_DEV,CURRENT->buffer,block,count);
 					break;
 				default:
 					printk("do_xd_request: unknown request\n");
diff -urN linux-2.5.1-pre7/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c
--- linux-2.5.1-pre7/drivers/cdrom/sbpcd.c	Sat Dec  8 21:04:22 2001
+++ linux/drivers/cdrom/sbpcd.c	Sat Dec  8 21:05:02 2001
@@ -5870,7 +5870,6 @@
 	(BLK_DEFAULT_QUEUE(MAJOR_NR))->front_merge_fn = dont_bh_merge_fn;
 	(BLK_DEFAULT_QUEUE(MAJOR_NR))->merge_requests_fn = dont_merge_requests_fn;
 #endif
-	blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
 	read_ahead[MAJOR_NR] = buffers * (CD_FRAMESIZE / 512);
 	
 	request_region(CDo_command,4,major_name);
diff -urN linux-2.5.1-pre7/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.1-pre7/drivers/ide/ide-cd.c	Sat Dec  8 21:04:22 2001
+++ linux/drivers/ide/ide-cd.c	Sat Dec  8 21:05:02 2001
@@ -1615,7 +1615,7 @@
 /*
  * just wrap this around cdrom_do_packet_command
  */
-static int cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
+static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
 {
 	struct packet_command pc;
 	ide_startstop_t startstop;
@@ -2145,7 +2145,8 @@
 	pc.timeout = cgc->timeout;
 	pc.sense = cgc->sense;
 	cgc->stat = cdrom_queue_packet_command(drive, &pc);
-	cgc->buflen -= pc.buflen;
+	if (!cgc->stat)
+		cgc->buflen -= pc.buflen;
 	return cgc->stat;
 }
 
diff -urN linux-2.5.1-pre7/drivers/ide/ide-cd.h linux/drivers/ide/ide-cd.h
--- linux-2.5.1-pre7/drivers/ide/ide-cd.h	Sat Dec  8 21:04:22 2001
+++ linux/drivers/ide/ide-cd.h	Sat Dec  8 21:05:02 2001
@@ -435,7 +435,7 @@
 
 	byte     curlba[3];
 	byte     nslots;
-	__u16 short slot_tablelen;
+	__u16 slot_tablelen;
 };
 
 
diff -urN linux-2.5.1-pre7/drivers/isdn/hisax/st5481_b.c linux/drivers/isdn/hisax/st5481_b.c
--- linux-2.5.1-pre7/drivers/isdn/hisax/st5481_b.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/isdn/hisax/st5481_b.c	Sat Dec  8 21:05:03 2001
@@ -168,7 +168,7 @@
 	test_and_clear_bit(buf_nr, &b_out->busy);
 
 	if (urb->status < 0) {
-		if (urb->status != USB_ST_URB_KILLED) {
+		if (urb->status != -ENOENT) {
 			WARN("urb status %d",urb->status);
 			if (b_out->busy == 0) {
 				st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2 | USB_DIR_OUT, NULL, NULL);
diff -urN linux-2.5.1-pre7/drivers/isdn/hisax/st5481_d.c linux/drivers/isdn/hisax/st5481_d.c
--- linux-2.5.1-pre7/drivers/isdn/hisax/st5481_d.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/isdn/hisax/st5481_d.c	Sat Dec  8 21:05:03 2001
@@ -382,7 +382,7 @@
 	test_and_clear_bit(buf_nr, &d_out->busy);
 
 	if (urb->status < 0) {
-		if (urb->status != USB_ST_URB_KILLED) {
+		if (urb->status != -ENOENT) {
 			WARN("urb status %d",urb->status);
 			if (d_out->busy == 0) {
 				st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
diff -urN linux-2.5.1-pre7/drivers/isdn/hisax/st5481_usb.c linux/drivers/isdn/hisax/st5481_usb.c
--- linux-2.5.1-pre7/drivers/isdn/hisax/st5481_usb.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/isdn/hisax/st5481_usb.c	Sat Dec  8 21:05:03 2001
@@ -130,7 +130,7 @@
 	struct ctrl_msg *ctrl_msg;
 	
 	if (urb->status < 0) {
-		if (urb->status != USB_ST_URB_KILLED) {
+		if (urb->status != -ENOENT) {
 			WARN("urb status %d",urb->status);
 		} else {
 			DBG(1,"urb killed");
@@ -184,7 +184,7 @@
 	int j;
 
 	if (urb->status < 0) {
-		if (urb->status != USB_ST_URB_KILLED) {
+		if (urb->status != -ENOENT) {
 			WARN("urb status %d",urb->status);
 			urb->actual_length = 0;
 		} else {
@@ -470,7 +470,7 @@
 	int len, count, status;
 
 	if (urb->status < 0) {
-		if (urb->status != USB_ST_URB_KILLED) {
+		if (urb->status != -ENOENT) {
 			WARN("urb status %d",urb->status);
 		} else {
 			DBG(1,"urb killed");
diff -urN linux-2.5.1-pre7/drivers/message/i2o/i2o_block.c linux/drivers/message/i2o/i2o_block.c
--- linux-2.5.1-pre7/drivers/message/i2o/i2o_block.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/message/i2o/i2o_block.c	Sat Dec  8 21:05:03 2001
@@ -1423,7 +1423,6 @@
 	atomic_set(&i2ob_queues[unit]->queue_depth, 0);
 
 	blk_init_queue(&i2ob_queues[unit]->req_queue, i2ob_request);
-	blk_queue_headactive(&i2ob_queues[unit]->req_queue, 0);
 	i2ob_queues[unit]->req_queue.queuedata = &i2ob_queues[unit];
 
 	return 0;
@@ -1822,7 +1821,6 @@
 	blk_dev[MAJOR_NR].queue = i2ob_get_queue;
 	
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), i2ob_request);
-	blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
 
 	for (i = 0; i < MAX_I2OB << 4; i++) {
 		i2ob_dev[i].refcnt = 0;
diff -urN linux-2.5.1-pre7/drivers/net/irda/irda-usb.c linux/drivers/net/irda/irda-usb.c
--- linux-2.5.1-pre7/drivers/net/irda/irda-usb.c	Fri Nov  9 14:22:17 2001
+++ linux/drivers/net/irda/irda-usb.c	Sat Dec  8 21:05:03 2001
@@ -256,7 +256,7 @@
 
 	/* Grab the speed URB */
 	purb = &self->speed_urb;
-	if (purb->status != USB_ST_NOERROR) {
+	if (purb->status != 0) {
 		WARNING(__FUNCTION__ "(), URB still in use!\n");
 		return;
 	}
@@ -301,7 +301,7 @@
 	}
 
 	/* Check for timeout and other USB nasties */
-	if(purb->status != USB_ST_NOERROR) {
+	if (purb->status != 0) {
 		/* I get a lot of -ECONNABORTED = -103 here - Jean II */
 		IRDA_DEBUG(0, __FUNCTION__ "(), URB complete status %d, transfer_flags 0x%04X\n", purb->status, purb->transfer_flags);
 
@@ -314,7 +314,7 @@
 	}
 
 	/* urb is now available */
-	purb->status = USB_ST_NOERROR;
+	purb->status = 0;
 
 	/* If it was the speed URB, allow the stack to send more packets */
 	if(purb == &self->speed_urb) {
@@ -372,7 +372,7 @@
 		}
 	}
 
-	if (purb->status != USB_ST_NOERROR) {
+	if (purb->status != 0) {
 		WARNING(__FUNCTION__ "(), URB still in use!\n");
 		dev_kfree_skb(skb);
 		return 0;
@@ -490,7 +490,7 @@
 	purb->context = NULL;
 
 	/* Check for timeout and other USB nasties */
-	if(purb->status != USB_ST_NOERROR) {
+	if (purb->status != 0) {
 		/* I get a lot of -ECONNABORTED = -103 here - Jean II */
 		IRDA_DEBUG(0, __FUNCTION__ "(), URB complete status %d, transfer_flags 0x%04X\n", purb->status, purb->transfer_flags);
 
@@ -504,7 +504,7 @@
 	}
 
 	/* urb is now available */
-	purb->status = USB_ST_NOERROR;
+	purb->status = 0;
 
 	/* If the network is closed, stop everything */
 	if ((!self->netopen) || (!self->present)) {
@@ -547,11 +547,11 @@
 
 	/* Check speed URB */
 	purb = &(self->speed_urb);
-	if (purb->status != USB_ST_NOERROR) {
+	if (purb->status != 0) {
 		IRDA_DEBUG(0, "%s: Speed change timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, purb->status, purb->transfer_flags);
 
 		switch (purb->status) {
-		case USB_ST_URB_PENDING:	/* -EINPROGRESS == -115 */
+		case -EINPROGRESS:
 			usb_unlink_urb(purb);
 			/* Note : above will  *NOT* call netif_wake_queue()
 			 * in completion handler, we will come back here.
@@ -563,7 +563,7 @@
 		case -ETIMEDOUT:		/* -110 */
 		case -ENOENT:			/* -2 (urb unlinked by us)  */
 		default:			/* ??? - Play safe */
-			purb->status = USB_ST_NOERROR;
+			purb->status = 0;
 			netif_wake_queue(self->netdev);
 			done = 1;
 			break;
@@ -572,7 +572,7 @@
 
 	/* Check Tx URB */
 	purb = &(self->tx_urb);
-	if (purb->status != USB_ST_NOERROR) {
+	if (purb->status != 0) {
 		struct sk_buff *skb = purb->context;
 
 		IRDA_DEBUG(0, "%s: Tx timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, purb->status, purb->transfer_flags);
@@ -590,7 +590,7 @@
 #endif /* IU_BUG_KICK_TIMEOUT */
 
 		switch (purb->status) {
-		case USB_ST_URB_PENDING:	/* -EINPROGRESS == -115 */
+		case -EINPROGRESS:
 			usb_unlink_urb(purb);
 			/* Note : above will  *NOT* call netif_wake_queue()
 			 * in completion handler, because purb->status will
@@ -610,7 +610,7 @@
 				dev_kfree_skb_any(skb);
 				purb->context = NULL;
 			}
-			purb->status = USB_ST_NOERROR;
+			purb->status = 0;
 			netif_wake_queue(self->netdev);
 			done = 1;
 			break;
@@ -727,7 +727,7 @@
 	purb->transfer_flags = USB_QUEUE_BULK;
 	/* Note : unlink *must* be synchronous because of the code in 
 	 * irda_usb_net_close() -> free the skb - Jean II */
-	purb->status = USB_ST_NOERROR;
+	purb->status = 0;
 	purb->next = NULL;	/* Don't auto resubmit URBs */
 	
 	ret = usb_submit_urb(purb);
@@ -768,9 +768,9 @@
 	}
 	
 	/* Check the status */
-	if(purb->status != USB_ST_NOERROR) {
+	if (purb->status != 0) {
 		switch (purb->status) {
-		case USB_ST_CRC:		/* -EILSEQ */
+		case -EILSEQ:
 			self->stats.rx_errors++;
 			self->stats.rx_crc_errors++;	
 			break;
@@ -1442,9 +1442,9 @@
 	ret = usb_set_interface(dev, ifnum, 0);
 	IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", ifnum, ret);
 	switch (ret) {
-		case USB_ST_NOERROR:		/* 0 */
+		case 0:
 			break;
-		case USB_ST_STALL:		/* -EPIPE = -32 */
+		case -EPIPE:		/* -EPIPE = -32 */
 			usb_clear_halt(dev, usb_sndctrlpipe(dev, 0));
 			IRDA_DEBUG(0, __FUNCTION__ "(), Clearing stall on control interface\n" );
 			break;
diff -urN linux-2.5.1-pre7/drivers/s390/block/dasd.c linux/drivers/s390/block/dasd.c
--- linux-2.5.1-pre7/drivers/s390/block/dasd.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/s390/block/dasd.c	Sat Dec  8 21:05:03 2001
@@ -3343,7 +3343,6 @@
         device->request_queue = kmalloc(sizeof(request_queue_t),GFP_KERNEL);
         device->request_queue->queuedata = device;
         blk_init_queue (device->request_queue, do_dasd_request);
-        blk_queue_headactive (device->request_queue, 0);
         elevator_init (&(device->request_queue->elevator),ELEVATOR_NOOP);
 
         for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
diff -urN linux-2.5.1-pre7/drivers/s390/block/xpram.c linux/drivers/s390/block/xpram.c
--- linux-2.5.1-pre7/drivers/s390/block/xpram.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/s390/block/xpram.c	Sat Dec  8 21:05:03 2001
@@ -1041,7 +1041,6 @@
 #elif (XPRAM_VERSION == 24)
 	q = BLK_DEFAULT_QUEUE (major);
 	blk_init_queue (q, xpram_request);
-	blk_queue_headactive (BLK_DEFAULT_QUEUE (major), 0);
 #endif /* V22/V24 */
 	read_ahead[major] = xpram_rahead;
 
diff -urN linux-2.5.1-pre7/drivers/s390/char/tapeblock.c linux/drivers/s390/char/tapeblock.c
--- linux-2.5.1-pre7/drivers/s390/char/tapeblock.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/s390/char/tapeblock.c	Sat Dec  8 21:05:03 2001
@@ -77,7 +77,6 @@
     blksize_size[tapeblock_major][ti->blk_minor]=2048; // blocks are 2k by default.
     hardsect_size[tapeblock_major][ti->blk_minor]=512;
     blk_init_queue (&ti->request_queue, tape_request_fn); 
-    blk_queue_headactive (&ti->request_queue, 0); 
 #ifdef CONFIG_DEVFS_FS
     tapeblock_mkdevfstree(ti);
 #endif
diff -urN linux-2.5.1-pre7/drivers/sbus/char/jsflash.c linux/drivers/sbus/char/jsflash.c
--- linux-2.5.1-pre7/drivers/sbus/char/jsflash.c	Thu Oct 25 13:58:35 2001
+++ linux/drivers/sbus/char/jsflash.c	Sat Dec  8 21:05:03 2001
@@ -662,7 +662,6 @@
 	blk_size[JSFD_MAJOR] = jsfd_sizes;
 
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
-	/* blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); */
 	for (i = 0; i < JSF_MAX; i++) {
 		if ((i & JSF_PART_MASK) >= JSF_NPART) continue;
 		jsf = &jsf0;	/* actually, &jsfv[i >> JSF_PART_BITS] */
diff -urN linux-2.5.1-pre7/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- linux-2.5.1-pre7/drivers/scsi/ide-scsi.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/scsi/ide-scsi.c	Sat Dec  8 21:05:03 2001
@@ -429,7 +429,7 @@
 	pc->current_position=pc->buffer;
 	bcount = IDE_MIN (pc->request_transfer, 63 * 1024);		/* Request to transfer the entire buffer at once */
 
-	if (drive->using_dma && rq->special)
+	if (drive->using_dma && rq->bio)
 		dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);
 
 	SELECT_DRIVE(HWIF(drive), drive);
diff -urN linux-2.5.1-pre7/drivers/scsi/imm.c linux/drivers/scsi/imm.c
--- linux-2.5.1-pre7/drivers/scsi/imm.c	Sun Sep 30 12:26:07 2001
+++ linux/drivers/scsi/imm.c	Sat Dec  8 21:05:03 2001
@@ -124,11 +124,6 @@
     int i, nhosts, try_again;
     struct parport *pb;
 
-    /*
-     * unlock to allow the lowlevel parport driver to probe
-     * the irqs
-     */
-    spin_unlock_irq(&io_request_lock);
     pb = parport_enumerate();
 
     printk("imm: Version %s\n", IMM_VERSION);
@@ -137,7 +132,6 @@
 
     if (!pb) {
 	printk("imm: parport reports no devices.\n");
-	spin_lock_irq(&io_request_lock);
 	return 0;
     }
   retry_entry:
@@ -163,7 +157,6 @@
 		      "pardevice is owning the port for too longtime!\n",
 			   i);
 		    parport_unregister_device (imm_hosts[i].dev);
-		    spin_lock_irq(&io_request_lock);
 		    return 0;
 		}
 	    }
@@ -219,13 +212,11 @@
     }
     if (nhosts == 0) {
 	if (try_again == 1) {
-	    spin_lock_irq(&io_request_lock);
 	    return 0;
 	}
 	try_again = 1;
 	goto retry_entry;
     } else {
-	spin_lock_irq (&io_request_lock);
 	return 1;		/* return number of hosts detected */
     }
 }
@@ -834,7 +825,7 @@
 	    if (cmd->SCp.buffers_residual--) {
 		cmd->SCp.buffer++;
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
-		cmd->SCp.ptr = cmd->SCp.buffer->address;
+		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
 
 		/*
 		 * Make sure that we transfer even number of bytes
@@ -897,6 +888,7 @@
 {
     imm_struct *tmp = (imm_struct *) data;
     Scsi_Cmnd *cmd = tmp->cur_cmd;
+    struct Scsi_Host *host = cmd->host;
     unsigned long flags;
 
     if (!cmd) {
@@ -948,10 +940,10 @@
     if (cmd->SCp.phase > 0)
 	imm_pb_release(cmd->host->unique_id);
 
-    spin_lock_irqsave(&io_request_lock, flags);
+    spin_lock_irqsave(&host->host_lock, flags);
     tmp->cur_cmd = 0;
     cmd->scsi_done(cmd);
-    spin_unlock_irqrestore(&io_request_lock, flags);
+    spin_unlock_irqrestore(&host->host_lock, flags);
     return;
 }
 
@@ -1008,7 +1000,7 @@
 	    /* if many buffers are available, start filling the first */
 	    cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 	    cmd->SCp.this_residual = cmd->SCp.buffer->length;
-	    cmd->SCp.ptr = cmd->SCp.buffer->address;
+	    cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
 	} else {
 	    /* else fill the only available buffer */
 	    cmd->SCp.buffer = NULL;
diff -urN linux-2.5.1-pre7/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- linux-2.5.1-pre7/drivers/scsi/scsi.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/scsi/scsi.c	Sat Dec  8 21:05:03 2001
@@ -183,7 +183,6 @@
 	request_queue_t *q = &SDpnt->request_queue;
 
 	blk_init_queue(q, scsi_request_fn);
-	blk_queue_headactive(q, 0);
 	q->queuedata = (void *) SDpnt;
 #ifdef DMA_CHUNK_SIZE
 	blk_queue_max_segments(q, 64);
@@ -231,7 +230,8 @@
 	req = &SCpnt->request;
 	req->rq_status = RQ_SCSI_DONE;	/* Busy, but indicate request done */
 
-	complete(req->waiting);
+	if (req->waiting)
+		complete(req->waiting);
 }
 
 /*
diff -urN linux-2.5.1-pre7/drivers/scsi/scsi_lib.c linux/drivers/scsi/scsi_lib.c
--- linux-2.5.1-pre7/drivers/scsi/scsi_lib.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/scsi/scsi_lib.c	Sat Dec  8 21:05:03 2001
@@ -72,7 +72,13 @@
 
 	ASSERT_LOCK(&q->queue_lock, 0);
 
-	rq->flags = REQ_SPECIAL | REQ_NOMERGE | REQ_BARRIER;
+	/*
+	 * tell I/O scheduler that this isn't a regular read/write (ie it
+	 * must not attempt merges on this) and that it acts as a soft
+	 * barrier
+	 */
+	rq->flags = REQ_SPECIAL | REQ_BARRIER;
+
 	rq->special = data;
 	rq->q = NULL;
 	rq->bio = rq->biotail = NULL;
@@ -86,12 +92,7 @@
 	 * device, or a host that is unable to accept a particular command.
 	 */
 	spin_lock_irqsave(&q->queue_lock, flags);
-
-	if (at_head)
-		list_add(&rq->queuelist, &q->queue_head);
-	else
-		list_add_tail(&rq->queuelist, &q->queue_head);
-
+	__elv_add_request(q, rq, !at_head, 0);
 	q->request_fn(q);
 	spin_unlock_irqrestore(&q->queue_lock, flags);
 }
@@ -261,10 +262,7 @@
 		 * the bad sector.
 		 */
 		SCpnt->request.special = (void *) SCpnt;
-#if 0
-		SCpnt->request.flags |= REQ_SPECIAL;
-#endif
-		list_add(&SCpnt->request.queuelist, &q->queue_head);
+		__elv_add_request(q, &SCpnt->request, 0, 0);
 	}
 
 	/*
@@ -360,23 +358,15 @@
 				     int frequeue)
 {
 	request_queue_t *q = &SCpnt->device->request_queue;
-	struct request *req;
+	struct request *req = &SCpnt->request;
 
 	ASSERT_LOCK(&q->queue_lock, 0);
 
-	req = &SCpnt->request;
-	while (end_that_request_first(req, 1, sectors)) {
-		if (!req->bio) {
-			printk("scsi_end_request: missing bio\n");
-			break;
-		}
-	}
-
 	/*
 	 * If there are blocks left over at the end, set up the command
 	 * to queue the remainder of them.
 	 */
-	if (req->bio) {
+	if (end_that_request_first(req, 1, sectors)) {
 		if (!requeue)
 			return SCpnt;
 
@@ -834,13 +824,6 @@
 		 */
 		if (SHpnt->in_recovery || blk_queue_plugged(q))
 			return;
-
-		/*
-		 * if we are at the max queue depth, don't attempt to queue
-		 * more
-		 */
-		if (SHpnt->host_busy == SDpnt->queue_depth)
-			break;
 
 		/*
 		 * If the device cannot accept another request, then quit.
diff -urN linux-2.5.1-pre7/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- linux-2.5.1-pre7/drivers/scsi/sd.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/scsi/sd.c	Sat Dec  8 21:05:03 2001
@@ -286,6 +286,12 @@
 	char nbuff[6];
 #endif
 
+	/*
+	 * don't support specials for nwo
+	 */
+	if (!(SCpnt->request.flags & REQ_CMD))
+		return 0;
+
 	devm = SD_PARTITION(SCpnt->request.rq_dev);
 	dev = DEVICE_NR(SCpnt->request.rq_dev);
 
diff -urN linux-2.5.1-pre7/drivers/usb/CDCEther.c linux/drivers/usb/CDCEther.c
--- linux-2.5.1-pre7/drivers/usb/CDCEther.c	Fri Oct  5 12:06:08 2001
+++ linux/drivers/usb/CDCEther.c	Sat Dec  8 21:05:03 2001
@@ -82,9 +82,9 @@
 	ether_dev->flags |= CDC_ETHER_RX_BUSY;
 
 	switch ( urb->status ) {
-		case USB_ST_NOERROR:
+		case 0:
 			break;
-		case USB_ST_NORESPONSE:
+		case -ETIMEDOUT:
 			dbg( "no repsonse in BULK IN" );
 			ether_dev->flags &= ~CDC_ETHER_RX_BUSY;
 			break;
@@ -179,9 +179,9 @@
 //		return;
 //		
 //	switch ( urb->status ) {
-//		case USB_ST_NOERROR:
+//		case 0:
 //			break;
-//		case USB_ST_URB_KILLED:
+//		case -ENOENT:
 //			return;
 //		default:
 //			info("intr status %d", urb->status);
@@ -337,13 +337,9 @@
 	ether_dev_t *ether_dev = (ether_dev_t *)net->priv;
 	int	res;
 
-	// We are finally getting used!
-	MOD_INC_USE_COUNT;
-
 	// Turn on the USB and let the packets flow!!!
 	if ( (res = enable_net_traffic( ether_dev )) ) {
 		err( __FUNCTION__ "can't enable_net_traffic() - %d", res );
-		MOD_DEC_USE_COUNT;
 		return -EIO;
 	}
 
@@ -391,9 +387,6 @@
 	usb_unlink_urb( &ether_dev->tx_urb );
 	usb_unlink_urb( &ether_dev->intr_urb );
 	
-	// We are not being used now.
-	MOD_DEC_USE_COUNT;
-
 	// That's it.  I'm done.
 	return 0;
 }
@@ -480,6 +473,7 @@
                      i++, mclist = mclist->next) {
 			memcpy(&mclist->dmi_addr, &buff[i * 6], 6);
 		}
+#if 0
 		usb_control_msg(ether_dev->usb,
 				usb_sndctrlpipe(ether_dev->usb, 0),
 				SET_ETHERNET_MULTICAST_FILTER, /* request */
@@ -489,11 +483,13 @@
 				buff,
 				(6* net->mc_count), /* size */
 				HZ); /* timeout */
+#endif
 		kfree(buff);
 	}
- 
+
+#if 0 
 	CDC_SetEthernetPacketFilter(ether_dev);
-	
+#endif	
         // Tell the kernel to start giving frames to us again.
 	netif_wake_queue(net);
 }
@@ -1210,6 +1206,7 @@
 	// Now that we have an ethernet device, let's set it up
 	// (And I don't mean "set [it] up the bomb".)
 	net->priv = ether_dev;
+	SET_MODULE_OWNER(net);
 	net->open = CDCEther_open;
 	net->stop = CDCEther_close;
 	net->watchdog_timeo = CDC_ETHER_TX_TIMEOUT;
diff -urN linux-2.5.1-pre7/drivers/usb/Config.in linux/drivers/usb/Config.in
--- linux-2.5.1-pre7/drivers/usb/Config.in	Fri Nov  2 17:18:58 2001
+++ linux/drivers/usb/Config.in	Sat Dec  8 21:05:03 2001
@@ -9,7 +9,7 @@
    bool '  USB verbose debug messages' CONFIG_USB_DEBUG
 
 comment 'Miscellaneous USB options'
-   bool '  Preliminary USB device filesystem' CONFIG_USB_DEVICEFS
+   bool '  USB device filesystem' CONFIG_USB_DEVICEFS
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
       bool '  Enforce USB bandwidth allocation (EXPERIMENTAL)' CONFIG_USB_BANDWIDTH
    else
diff -urN linux-2.5.1-pre7/drivers/usb/audio.c linux/drivers/usb/audio.c
--- linux-2.5.1-pre7/drivers/usb/audio.c	Fri Oct  5 12:04:50 2001
+++ linux/drivers/usb/audio.c	Sat Dec  8 21:05:03 2001
@@ -899,7 +899,7 @@
 	struct usbin *u = &as->usbin;
 	unsigned long flags;
 	unsigned int mask;
-	int suret = USB_ST_NOERROR;
+	int suret = 0;
 
 #if 0
 	printk(KERN_DEBUG "usbin_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
@@ -917,7 +917,7 @@
 	if (!usbin_retire_desc(u, urb) &&
 	    u->flags & FLG_RUNNING &&
 	    !usbin_prepare_desc(u, urb) && 
-	    (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) {
+	    (suret = usb_submit_urb(urb)) == 0) {
 		u->flags |= mask;
 	} else {
 		u->flags &= ~(mask | FLG_RUNNING);
@@ -964,7 +964,7 @@
 	struct usbin *u = &as->usbin;
 	unsigned long flags;
 	unsigned int mask;
-	int suret = USB_ST_NOERROR;
+	int suret = 0;
 
 #if 0
 	printk(KERN_DEBUG "usbin_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
@@ -982,7 +982,7 @@
 	if (!usbin_sync_retire_desc(u, urb) &&
 	    u->flags & FLG_RUNNING &&
 	    !usbin_sync_prepare_desc(u, urb) && 
-	    (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) {
+	    (suret = usb_submit_urb(urb)) == 0) {
 		u->flags |= mask;
 	} else {
 		u->flags &= ~(mask | FLG_RUNNING);
@@ -1257,7 +1257,7 @@
 	struct usbout *u = &as->usbout;
 	unsigned long flags;
 	unsigned int mask;
-	int suret = USB_ST_NOERROR;
+	int suret = 0;
 
 #if 0
 	printk(KERN_DEBUG "usbout_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
@@ -1275,7 +1275,7 @@
 	if (!usbout_retire_desc(u, urb) &&
 	    u->flags & FLG_RUNNING &&
 	    !usbout_prepare_desc(u, urb) && 
-	    (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) {
+	    (suret = usb_submit_urb(urb)) == 0) {
 		u->flags |= mask;
 	} else {
 		u->flags &= ~(mask | FLG_RUNNING);
@@ -1329,7 +1329,7 @@
 	struct usbout *u = &as->usbout;
 	unsigned long flags;
 	unsigned int mask;
-	int suret = USB_ST_NOERROR;
+	int suret = 0;
 
 #if 0
 	printk(KERN_DEBUG "usbout_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
@@ -1347,7 +1347,7 @@
 	if (!usbout_sync_retire_desc(u, urb) &&
 	    u->flags & FLG_RUNNING &&
 	    !usbout_sync_prepare_desc(u, urb) && 
-	    (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) {
+	    (suret = usb_submit_urb(urb)) == 0) {
 		u->flags |= mask;
 	} else {
 		u->flags &= ~(mask | FLG_RUNNING);
@@ -3362,28 +3362,48 @@
 	struct usb_device *dev = state->s->usbdev;
 	unsigned char data[1];
 #endif
+	unsigned char nr_logical_channels, i;
 
 	usb_audio_recurseunit(state, ftr[4]);
+
+	if (ftr[5] == 0 ) {
+		printk(KERN_ERR "usbaudio: wrong controls size in feature unit %u\n",ftr[3]);
+		return;
+	}
+
 	if (state->nrchannels == 0) {
 		printk(KERN_ERR "usbaudio: feature unit %u source has no channels\n", ftr[3]);
 		return;
 	}
 	if (state->nrchannels > 2)
 		printk(KERN_WARNING "usbaudio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]);
-	if (state->nrchannels == 1 && ftr[0] == 7+ftr[5]) {
-		printk(KERN_DEBUG "usbaudio: workaround for Philips camera microphone descriptor enabled\n");
-		mchftr = ftr[6];
-		chftr = 0;
-	} else {
-		if (ftr[0] < 7+ftr[5]*(1+state->nrchannels)) {
-			printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", ftr[3]);
-			return;
+
+	nr_logical_channels=(ftr[0]-7)/ftr[5]-1;
+
+	if (nr_logical_channels != state->nrchannels) {
+		printk(KERN_WARNING "usbaudio: warning: found %d of %d logical channels.\n", state->nrchannels,nr_logical_channels);
+
+		if (state->nrchannels == 1 && nr_logical_channels==0) {
+			printk(KERN_INFO "usbaudio: assuming the channel found is the master channel (got a Philips camera?). Should be fine.\n");
+		} else if (state->nrchannels == 1 && nr_logical_channels==2) {
+			printk(KERN_INFO "usbaudio: assuming that a stereo channel connected directly to a mixer is missing in search (got Labtec headset?). Should be fine.\n");
+			state->nrchannels=nr_logical_channels;
+		} else {
+			printk(KERN_WARNING "usbaudio: no idea what's going on..., contact linux-usb-devel@lists.sourceforge.net\n");
 		}
-		mchftr = ftr[6];
+	}
+
+	/* There is always a master channel */
+	mchftr = ftr[6];
+	/* Binary AND over logical channels if they exist */
+	if (nr_logical_channels) {
 		chftr = ftr[6+ftr[5]];
-		if (state->nrchannels > 1)
-			chftr &= ftr[6+2*ftr[5]];
+		for (i = 2; i <= nr_logical_channels; i++)
+			chftr &= ftr[6+i*ftr[5]];
+	} else {
+		chftr = 0;
 	}
+
 	/* volume control */
 	if (chftr & 2) {
 		ch = getmixchannel(state, getvolchannel(state));
diff -urN linux-2.5.1-pre7/drivers/usb/bluetooth.c linux/drivers/usb/bluetooth.c
--- linux-2.5.1-pre7/drivers/usb/bluetooth.c	Tue Nov 13 09:19:41 2001
+++ linux/drivers/usb/bluetooth.c	Sat Dec  8 21:05:03 2001
@@ -1,11 +1,15 @@
 /*
- * bluetooth.c   Version 0.12
+ * bluetooth.c   Version 0.13
  *
  * Copyright (c) 2000, 2001 Greg Kroah-Hartman	<greg@kroah.com>
  * Copyright (c) 2000 Mark Douglas Corner	<mcorner@umich.edu>
  *
  * USB Bluetooth driver, based on the Bluetooth Spec version 1.0B
  * 
+ * (2001/11/30) Version 0.13 gkh
+ *	- added locking patch from Masoodur Rahman <rmasoodu@in.ibm.com>
+ *	- removed active variable, as open_count will do.
+ *
  * (2001/07/09) Version 0.12 gkh
  *	- removed in_interrupt() call, as it doesn't make sense to do 
  *	  that anymore.
@@ -118,7 +122,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.12"
+#define DRIVER_VERSION "v0.13"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman, Mark Douglas Corner"
 #define DRIVER_DESC "USB Bluetooth tty driver"
 
@@ -170,8 +174,8 @@
 	struct tty_struct *	tty;		/* the coresponding tty for this port */
 
 	unsigned char		minor;		/* the starting minor number for this device */
-	char			active;		/* someone has this device open */
 	int			throttle;	/* throttled by tty layer */
+	int			open_count;
 	
 	__u8			control_out_bInterfaceNum;
 	struct urb *		control_urb_pool[NUM_CONTROL_URBS];
@@ -200,6 +204,7 @@
 	unsigned char		int_buffer[EVENT_BUFFER_SIZE];
 	unsigned int		bulk_packet_pos;
 	unsigned char		bulk_buffer[ACL_BUFFER_SIZE];	/* 64k preallocated, fix? */
+	struct semaphore	lock;
 };
 
 
@@ -361,43 +366,46 @@
 		return -ENODEV;
 	}
 
-	if (bluetooth->active) {
-		dbg (__FUNCTION__ " - device already open");
-		return -EINVAL;
-	}
-
-	/* set up our structure making the tty driver remember our object, and us it */
-	tty->driver_data = bluetooth;
-	bluetooth->tty = tty;
-
-	/* force low_latency on so that our tty_push actually forces the data through, 
-	 * otherwise it is scheduled, and with high data rates (like with OHCI) data
-	 * can get lost. */
-	bluetooth->tty->low_latency = 1;
+	down (&bluetooth->lock);
+ 
+	++bluetooth->open_count;
+	if (bluetooth->open_count == 1) {
+		/* set up our structure making the tty driver remember our object, and us it */
+		tty->driver_data = bluetooth;
+		bluetooth->tty = tty;
+
+		/* force low_latency on so that our tty_push actually forces the data through, 
+	 	* otherwise it is scheduled, and with high data rates (like with OHCI) data
+	 	* can get lost. */
+		bluetooth->tty->low_latency = 1;
 	
-	bluetooth->active = 1;
-
-	/* Reset the packet position counters */
-	bluetooth->int_packet_pos = 0;
-	bluetooth->bulk_packet_pos = 0;
+		/* Reset the packet position counters */
+		bluetooth->int_packet_pos = 0;
+		bluetooth->bulk_packet_pos = 0;
 
 #ifndef BTBUGGYHARDWARE
-	/* Start reading from the device */
-	FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, 
-		      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
-		      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 
-		      bluetooth_read_bulk_callback, bluetooth);
-	result = usb_submit_urb(bluetooth->read_urb);
-	if (result)
-		dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result);
+		/* Start reading from the device */
+		FILL_BULK_URB (bluetooth->read_urb, bluetooth->dev, 
+			       usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
+			       bluetooth->bulk_in_buffer,
+			       bluetooth->bulk_in_buffer_size,
+			       bluetooth_read_bulk_callback, bluetooth);
+		result = usb_submit_urb(bluetooth->read_urb);
+		if (result)
+			dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result);
 #endif
-	FILL_INT_URB(bluetooth->interrupt_in_urb, bluetooth->dev, 
-		     usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress),
-		     bluetooth->interrupt_in_buffer, bluetooth->interrupt_in_buffer_size, 
-		     bluetooth_int_callback, bluetooth, bluetooth->interrupt_in_interval);
-	result = usb_submit_urb(bluetooth->interrupt_in_urb);
-	if (result)
-		dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result);
+		FILL_INT_URB (bluetooth->interrupt_in_urb, bluetooth->dev,
+			      usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress),
+			      bluetooth->interrupt_in_buffer,
+			      bluetooth->interrupt_in_buffer_size,
+			      bluetooth_int_callback, bluetooth,
+			      bluetooth->interrupt_in_interval);
+		result = usb_submit_urb(bluetooth->interrupt_in_urb);
+		if (result)
+			dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result);
+	}
+	
+	up(&bluetooth->lock);
 
 	return 0;
 }
@@ -414,18 +422,24 @@
 
 	dbg(__FUNCTION__);
 
-	if (!bluetooth->active) {
+	if (!bluetooth->open_count) {
 		dbg (__FUNCTION__ " - device not opened");
 		return;
 	}
 
-	/* shutdown any bulk reads and writes that might be going on */
-	for (i = 0; i < NUM_BULK_URBS; ++i)
-		usb_unlink_urb (bluetooth->write_urb_pool[i]);
-	usb_unlink_urb (bluetooth->read_urb);
-	usb_unlink_urb (bluetooth->interrupt_in_urb);
-
-	bluetooth->active = 0;
+	down (&bluetooth->lock);
+ 
+	--bluetooth->open_count;
+	if (bluetooth->open_count <= 0) {
+		bluetooth->open_count = 0;
+
+		/* shutdown any bulk reads and writes that might be going on */
+		for (i = 0; i < NUM_BULK_URBS; ++i)
+			usb_unlink_urb (bluetooth->write_urb_pool[i]);
+		usb_unlink_urb (bluetooth->read_urb);
+		usb_unlink_urb (bluetooth->interrupt_in_urb);
+	}
+	up(&bluetooth->lock);
 }
 
 
@@ -447,7 +461,7 @@
 
 	dbg(__FUNCTION__ " - %d byte(s)", count);
 
-	if (!bluetooth->active) {
+	if (!bluetooth->open_count) {
 		dbg (__FUNCTION__ " - device not opened");
 		return -EINVAL;
 	}
@@ -572,7 +586,7 @@
 
 	dbg(__FUNCTION__);
 
-	if (!bluetooth->active) {
+	if (!bluetooth->open_count) {
 		dbg (__FUNCTION__ " - device not open");
 		return -EINVAL;
 	}
@@ -598,7 +612,7 @@
 		return -ENODEV;
 	}
 
-	if (!bluetooth->active) {
+	if (!bluetooth->open_count) {
 		dbg (__FUNCTION__ " - device not open");
 		return -EINVAL;
 	}
@@ -624,7 +638,7 @@
 
 	dbg(__FUNCTION__);
 
-	if (!bluetooth->active) {
+	if (!bluetooth->open_count) {
 		dbg (__FUNCTION__ " - device not open");
 		return;
 	}
@@ -645,7 +659,7 @@
 
 	dbg(__FUNCTION__);
 
-	if (!bluetooth->active) {
+	if (!bluetooth->open_count) {
 		dbg (__FUNCTION__ " - device not open");
 		return;
 	}
@@ -664,7 +678,7 @@
 
 	dbg(__FUNCTION__ " - cmd 0x%.4x", cmd);
 
-	if (!bluetooth->active) {
+	if (!bluetooth->open_count) {
 		dbg (__FUNCTION__ " - device not open");
 		return -ENODEV;
 	}
@@ -684,7 +698,7 @@
 
 	dbg(__FUNCTION__);
 
-	if (!bluetooth->active) {
+	if (!bluetooth->open_count) {
 		dbg (__FUNCTION__ " - device not open");
 		return;
 	}
@@ -706,7 +720,7 @@
 
 	dbg(__FUNCTION__);
 
-	if (!bluetooth->active) {
+	if (!bluetooth->open_count) {
 		dbg (__FUNCTION__ " - device not open");
 		return;
 	}
@@ -731,7 +745,7 @@
 
 	dbg(__FUNCTION__);
 
-	if (!bluetooth->active) {
+	if (!bluetooth->open_count) {
 		dbg (__FUNCTION__ " - device not open");
 		return;
 	}
@@ -961,7 +975,7 @@
 	}	
 
 exit:
-	if (!bluetooth || !bluetooth->active)
+	if (!bluetooth || !bluetooth->open_count)
 		return;
 
 	FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, 
@@ -1102,6 +1116,7 @@
 	bluetooth->minor = minor;
 	bluetooth->tqueue.routine = bluetooth_softint;
 	bluetooth->tqueue.data = bluetooth;
+	init_MUTEX(&bluetooth->lock);
 
 	/* record the interface number for the control out */
 	bluetooth->control_out_bInterfaceNum = control_out_endpoint;
@@ -1217,10 +1232,10 @@
 	int i;
 
 	if (bluetooth) {
-		if ((bluetooth->active) && (bluetooth->tty))
+		if ((bluetooth->open_count) && (bluetooth->tty))
 			tty_hangup(bluetooth->tty);
 
-		bluetooth->active = 0;
+		bluetooth->open_count = 0;
 
 		if (bluetooth->read_urb) {
 			usb_unlink_urb (bluetooth->read_urb);
diff -urN linux-2.5.1-pre7/drivers/usb/dc2xx.c linux/drivers/usb/dc2xx.c
--- linux-2.5.1-pre7/drivers/usb/dc2xx.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/dc2xx.c	Sat Dec  8 21:05:03 2001
@@ -199,7 +199,7 @@
 				retval = count;
 			break;
 		}
-		if (retval != USB_ST_TIMEOUT)
+		if (retval != -ETIMEDOUT)
 			break;
 		interruptible_sleep_on_timeout (&camera->wait, RETRY_TIMEOUT);
 
@@ -267,7 +267,7 @@
 			} else if (!result)
 				break;
 				
-			if (result == USB_ST_TIMEOUT) {	/* NAK - delay a bit */
+			if (result == -ETIMEDOUT) {	/* NAK - delay a bit */
 				if (!maxretry--) {
 					if (!bytes_written)
 						bytes_written = -ETIME;
diff -urN linux-2.5.1-pre7/drivers/usb/devices.c linux/drivers/usb/devices.c
--- linux-2.5.1-pre7/drivers/usb/devices.c	Sat Oct 20 19:13:11 2001
+++ linux/drivers/usb/devices.c	Sat Dec  8 21:05:03 2001
@@ -139,9 +139,12 @@
 	{USB_CLASS_PHYSICAL,		"PID"},
 	{USB_CLASS_PRINTER,		"print"},
 	{USB_CLASS_MASS_STORAGE,	"stor."},
-	{USB_CLASS_DATA,		"data"},
+	{USB_CLASS_CDC_DATA,		"data"},
 	{USB_CLASS_APP_SPEC,		"app."},
 	{USB_CLASS_VENDOR_SPEC,		"vend."},
+	{USB_CLASS_STILL_IMAGE,		"still"},
+	{USB_CLASS_CSCID,		"scard"},
+	{USB_CLASS_CONTENT_SEC,		"c-sec"},
 	{-1,				"unk."}		/* leave as last */
 };
 
diff -urN linux-2.5.1-pre7/drivers/usb/devio.c linux/drivers/usb/devio.c
--- linux-2.5.1-pre7/drivers/usb/devio.c	Fri Nov  2 17:18:58 2001
+++ linux/drivers/usb/devio.c	Sat Dec  8 21:05:03 2001
@@ -276,7 +276,7 @@
                 list_del(&as->asynclist);
                 INIT_LIST_HEAD(&as->asynclist);
                 spin_unlock_irqrestore(&ps->lock, flags);
-                /* usb_unlink_urb calls the completion handler with status == USB_ST_URB_KILLED */
+                /* usb_unlink_urb calls the completion handler with status == -ENOENT */
                 usb_unlink_urb(&as->urb);
                 spin_lock_irqsave(&ps->lock, flags);
         }
@@ -299,11 +299,12 @@
 {
 	struct dev_state *ps = (struct dev_state *)context;
 
-	ps->ifclaimed = 0;
+	if (ps)
+		ps->ifclaimed = 0;
 }
 
 struct usb_driver usbdevfs_driver = {
-	name:		"usbdevfs",
+	name:		"usbfs",
 	probe:		driver_probe,
 	disconnect:	driver_disconnect,
 };
diff -urN linux-2.5.1-pre7/drivers/usb/hid-core.c linux/drivers/usb/hid-core.c
--- linux-2.5.1-pre7/drivers/usb/hid-core.c	Sun Sep 16 11:07:43 2001
+++ linux/drivers/usb/hid-core.c	Sat Dec  8 21:05:03 2001
@@ -897,7 +897,7 @@
 	u8 data[len];
 	int read;
 
-	if ((read = usb_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, data, len)) != len) {
+	if ((read = hid_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, data, len)) != len) {
 		dbg("reading report type %d id %d failed len %d read %d", report->type + 1, report->id, len, read);
 		return;
 	}
@@ -1064,7 +1064,7 @@
 			list = report_enum->report_list.next;
 			while (list != &report_enum->report_list) {
 				report = (struct hid_report *) list;
-				usb_set_idle(hid->dev, hid->ifnum, 0, report->id);
+				hid_set_idle(hid->dev, hid->ifnum, 0, report->id);
 				hid_read_report(hid, report);
 				list = list->next;
 			}
@@ -1089,6 +1089,16 @@
 	{ 0, 0 }
 };
 
+static int get_class_descriptor(struct usb_device *dev, int ifnum,
+		unsigned char type, void *buf, int size)
+{
+	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+		USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
+		(type << 8), ifnum, buf, size,
+		HZ * USB_CTRL_GET_TIMEOUT);
+}
+
+
 static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
 {
 	struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0;
@@ -1102,14 +1112,14 @@
 		if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) &&
 			(hid_blacklist[n].idProduct == dev->descriptor.idProduct)) return NULL;
 
-	if (usb_get_extra_descriptor(interface, USB_DT_HID, &hdesc) && ((!interface->bNumEndpoints) ||
-		usb_get_extra_descriptor(&interface->endpoint[0], USB_DT_HID, &hdesc))) {
+	if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->bNumEndpoints) ||
+		usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
 			dbg("class descriptor not present\n");
 			return NULL;
 	}
 
 	for (n = 0; n < hdesc->bNumDescriptors; n++)
-		if (hdesc->desc[n].bDescriptorType == USB_DT_REPORT)
+		if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
 			rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
 
 	if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
@@ -1120,7 +1130,7 @@
 	{
 		__u8 rdesc[rsize];
 
-		if ((n = usb_get_class_descriptor(dev, interface->bInterfaceNumber, USB_DT_REPORT, 0, rdesc, rsize)) < 0) {
+		if ((n = get_class_descriptor(dev, interface->bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
 			dbg("reading report descriptor failed");
 			return NULL;
 		}
@@ -1170,7 +1180,7 @@
 
 	for (n = 0; n < HID_CONTROL_FIFO_SIZE; n++) {
 		hid->out[n].dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
-		hid->out[n].dr.request = USB_REQ_SET_REPORT;
+		hid->out[n].dr.request = HID_REQ_SET_REPORT;
 		hid->out[n].dr.index = cpu_to_le16(hid->ifnum);
 	}
 
@@ -1198,7 +1208,7 @@
 
 #if 0
 	if (interface->bInterfaceSubClass == 1)
-		usb_set_protocol(dev, hid->ifnum, 1);
+		hid_set_protocol(dev, hid->ifnum, 1);
 #endif
 
 	return hid;
@@ -1236,7 +1246,7 @@
 
 	c = "Device";
 	for (i = 0; i < hid->maxapplication; i++)
-		if (IS_INPUT_APPLICATION(hid->application[i])) {
+		if ((hid->application[i] & 0xffff) < ARRAY_SIZE(hid_types)) {
 			c = hid_types[hid->application[i] & 0xffff];
 			break;
 		}
diff -urN linux-2.5.1-pre7/drivers/usb/hid.h linux/drivers/usb/hid.h
--- linux-2.5.1-pre7/drivers/usb/hid.h	Tue Nov 13 17:45:27 2001
+++ linux/drivers/usb/hid.h	Sat Dec  8 21:05:03 2001
@@ -30,6 +30,88 @@
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
+/*
+ * HID class requests
+ */
+#define HID_REQ_GET_REPORT		0x01
+#define HID_REQ_GET_IDLE		0x02
+#define HID_REQ_GET_PROTOCOL		0x03
+#define HID_REQ_SET_REPORT		0x09
+#define HID_REQ_SET_IDLE		0x0A
+#define HID_REQ_SET_PROTOCOL		0x0B
+
+/*
+ * HID class descriptor types
+ */
+#define HID_DT_HID			(USB_TYPE_CLASS | 0x01)
+#define HID_DT_REPORT			(USB_TYPE_CLASS | 0x02)
+#define HID_DT_PHYSICAL			(USB_TYPE_CLASS | 0x03)
+
+/*
+ * Utilities for class control messaging
+ */
+static inline int
+hid_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id)
+{
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+		HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+		(duration << 8) | report_id, ifnum, NULL, 0,
+		HZ * USB_CTRL_SET_TIMEOUT);
+}
+
+static inline int
+hid_get_protocol(struct usb_device *dev, int ifnum)
+{
+	unsigned char type;
+	int ret;
+
+	if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+			HID_REQ_GET_PROTOCOL,
+			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+			0, ifnum, &type, 1, 
+			HZ * USB_CTRL_GET_TIMEOUT)) < 0)
+		return ret;
+
+	return type;
+}
+
+static inline int
+hid_set_protocol(struct usb_device *dev, int ifnum, int protocol)
+{
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+		HID_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+		protocol, ifnum, NULL, 0, 
+		HZ * USB_CTRL_SET_TIMEOUT);
+}
+
+static inline int
+hid_get_report(struct usb_device *dev, int ifnum, unsigned char type,
+	unsigned char id, void *buf, int size)
+{
+	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+		HID_REQ_GET_REPORT,
+		USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+		(type << 8) + id, ifnum, buf, size, 
+		HZ * USB_CTRL_GET_TIMEOUT);
+}
+
+static inline int
+hid_set_report(struct usb_device *dev, int ifnum, unsigned char type,
+	unsigned char id, void *buf, int size)
+{
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+		HID_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+		(type << 8) + id, ifnum, buf, size, HZ);
+		// FIXME USB_CTRL_SET_TIMEOUT
+}
+
+
+/*
+ * "Boot Protocol" keyboard/mouse drivers use don't use all of HID;
+ * they're a lot smaller but can't support all the device features.
+ */
+#ifndef	_HID_BOOT_PROTOCOL
+
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/list.h>
@@ -359,9 +441,7 @@
 #else
 #define hid_dump_input(a,b)	do { } while (0)
 #define hid_dump_device(c)	do { } while (0)
-#endif
-
-#endif
+#endif /* DEBUG */
 
 #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || ( a == 0x000c0001))
 
@@ -372,3 +452,8 @@
 void hid_write_report(struct hid_device *, struct hid_report *);
 void hid_read_report(struct hid_device *, struct hid_report *);
 void hid_init_reports(struct hid_device *hid);
+
+#endif	/* !_HID_BOOT_PROTOCOL */
+
+#endif	/* !__HID_H */
+
diff -urN linux-2.5.1-pre7/drivers/usb/inode.c linux/drivers/usb/inode.c
--- linux-2.5.1-pre7/drivers/usb/inode.c	Sat Oct 20 19:13:11 2001
+++ linux/drivers/usb/inode.c	Sat Dec  8 21:05:03 2001
@@ -654,7 +654,13 @@
         return NULL;
 }
 
+/*
+ * The usbdevfs name is now depreciated (as of 2.5.1).
+ * It will be removed when the 2.7.x development cycle is started.
+ * You have been warned :)
+ */
 static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbdevfs_read_super, FS_SINGLE);
+static DECLARE_FSTYPE(usb_fs_type, "usbfs", usbdevfs_read_super, FS_SINGLE);
 
 /* --------------------------------------------------------------------- */
 
@@ -747,7 +753,12 @@
 	}
 	if ((ret = usb_register(&usbdevfs_driver)))
 		return ret;
+	if ((ret = register_filesystem(&usb_fs_type))) {
+		usb_deregister(&usbdevfs_driver);
+		return ret;
+	}
 	if ((ret = register_filesystem(&usbdevice_fs_type))) {
+		unregister_filesystem(&usb_fs_type);
 		usb_deregister(&usbdevfs_driver);
 		return ret;
 	}
@@ -761,6 +772,7 @@
 void __exit usbdevfs_cleanup(void)
 {
 	usb_deregister(&usbdevfs_driver);
+	unregister_filesystem(&usb_fs_type);
 	unregister_filesystem(&usbdevice_fs_type);
 #ifdef CONFIG_PROC_FS	
         if (usbdir)
@@ -768,7 +780,3 @@
 #endif
 }
 
-#if 0
-module_init(usbdevfs_init);
-module_exit(usbdevfs_cleanup);
-#endif
diff -urN linux-2.5.1-pre7/drivers/usb/kaweth.c linux/drivers/usb/kaweth.c
--- linux-2.5.1-pre7/drivers/usb/kaweth.c	Tue Nov 13 09:19:41 2001
+++ linux/drivers/usb/kaweth.c	Sat Dec  8 21:05:03 2001
@@ -944,6 +944,13 @@
 }
 
 
+// FIXME this completion stuff is a modified clone of
+// an OLD version of some stuff in usb.c ... 
+struct usb_api_data {
+	wait_queue_head_t wqh;
+	int done;
+};
+
 /*-------------------------------------------------------------------*
  * completion handler for compatibility wrappers (sync control/bulk) *
  *-------------------------------------------------------------------*/
diff -urN linux-2.5.1-pre7/drivers/usb/mdc800.c linux/drivers/usb/mdc800.c
--- linux-2.5.1-pre7/drivers/usb/mdc800.c	Tue Oct  9 15:15:02 2001
+++ linux/drivers/usb/mdc800.c	Sat Dec  8 21:05:03 2001
@@ -30,8 +30,14 @@
  *
  * The driver supports only one camera.
  * 
- * (08/04/2001) gb
+ * Fix: mdc800 used sleep_on and slept with io_lock held.
+ * Converted sleep_on to waitqueues with schedule_timeout and made io_lock
+ * a semaphore from a spinlock.
+ * by Oliver Neukum <520047054719-0001@t-online.de>
+ * (02/12/2001)
+ * 
  * Identify version on module load.
+ * (08/04/2001) gb
  *
  * version 0.7.5
  * Fixed potential SMP races with Spinlocks.
@@ -136,6 +142,7 @@
 
 	purb_t			irq_urb;
 	wait_queue_head_t	irq_wait;
+	int			irq_woken;
 	char*			irq_urb_buffer;
 
 	int			camera_busy;          // is camera busy ?
@@ -145,11 +152,13 @@
 	purb_t   		write_urb;
 	char*			write_urb_buffer;
 	wait_queue_head_t	write_wait;
+	int			written;
 
 
 	purb_t	   		download_urb;
 	char*			download_urb_buffer;
 	wait_queue_head_t	download_wait;
+	int			downloaded;
 	int			download_left;		// Bytes left to download ?
 
 
@@ -159,7 +168,7 @@
 	int			out_count;	// Bytes in the buffer
 
 	int			open;		// Camera device open ?
-	spinlock_t		io_lock;	// IO -lock	
+	struct semaphore	io_lock;	// IO -lock
 
 	char 			in [8];		// Command Input Buffer
 	int  			in_count;
@@ -284,6 +293,7 @@
 	if (wake_up)
 	{
 		mdc800->camera_request_ready=0;
+		mdc800->irq_woken=1;
 		wake_up_interruptible (&mdc800->irq_wait);
 	}
 }
@@ -300,9 +310,19 @@
  */
 static int mdc800_usb_waitForIRQ (int mode, int msec)
 {
+        DECLARE_WAITQUEUE(wait, current);
+
 	mdc800->camera_request_ready=1+mode;
 
-	interruptible_sleep_on_timeout (&mdc800->irq_wait, msec*HZ/1000);
+	add_wait_queue(&mdc800->irq_wait, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	if (!mdc800->irq_woken)
+	{
+		schedule_timeout (msec*HZ/1000);
+	}
+        remove_wait_queue(&mdc800->irq_wait, &wait);
+	set_current_state(TASK_RUNNING);
+	mdc800->irq_woken = 0;
 
 	if (mdc800->camera_request_ready>0)
 	{
@@ -337,6 +357,7 @@
 	{	
 		mdc800->state=READY;
 	}
+	mdc800->written = 1;
 	wake_up_interruptible (&mdc800->write_wait);
 }
 
@@ -364,6 +385,7 @@
 	{
 		err ("request bytes fails (status:%i)", urb->status);
 	}
+	mdc800->downloaded = 1;
 	wake_up_interruptible (&mdc800->download_wait);
 }
 
@@ -445,7 +467,7 @@
 
 	info ("Found Mustek MDC800 on USB.");
 
-	spin_lock (&mdc800->io_lock);
+	down (&mdc800->io_lock);
 
 	mdc800->dev=dev;
 	mdc800->open=0;
@@ -484,7 +506,7 @@
 
 	mdc800->state=READY;
 
-	spin_unlock (&mdc800->io_lock);
+	up (&mdc800->io_lock);
 	
 	return mdc800;
 }
@@ -558,7 +580,7 @@
 	int retval=0;
 	int errn=0;
 
-	spin_lock (&mdc800->io_lock);
+	down (&mdc800->io_lock);
 	
 	if (mdc800->state == NOT_CONNECTED)
 	{
@@ -594,7 +616,7 @@
 	dbg ("Mustek MDC800 device opened.");
 
 error_out:
-	spin_unlock (&mdc800->io_lock);
+	up (&mdc800->io_lock);
 	return errn;
 }
 
@@ -607,10 +629,9 @@
 	int retval=0;
 	dbg ("Mustek MDC800 device closed.");
 
-	spin_lock (&mdc800->io_lock);
+	down (&mdc800->io_lock);
 	if (mdc800->open && (mdc800->state != NOT_CONNECTED))
 	{
-		spin_unlock(&mdc800->io_lock);
 		usb_unlink_urb (mdc800->irq_urb);
 		usb_unlink_urb (mdc800->write_urb);
 		usb_unlink_urb (mdc800->download_urb);
@@ -618,11 +639,10 @@
 	}
 	else
 	{
-		spin_unlock (&mdc800->io_lock);
 		retval=-EIO;
 	}
 
-
+	up(&mdc800->io_lock);
 	return retval;
 }
 
@@ -634,22 +654,23 @@
 {
 	int   left=len, sts=len; /* single transfer size */
 	char* ptr=buf;
+	DECLARE_WAITQUEUE(wait, current);
 
-	spin_lock (&mdc800->io_lock);
+	down (&mdc800->io_lock);
 	if (mdc800->state == NOT_CONNECTED)
 	{
-		spin_unlock (&mdc800->io_lock);
+		up (&mdc800->io_lock);
 		return -EBUSY;
 	}
 	if (mdc800->state == WORKING)
 	{
 		warn ("Illegal State \"working\" reached during read ?!");
-		spin_unlock (&mdc800->io_lock);
+		up (&mdc800->io_lock);
 		return -EBUSY;
 	}
 	if (!mdc800->open)
 	{
-		spin_unlock (&mdc800->io_lock);
+		up (&mdc800->io_lock);
 		return -EBUSY;
 	}
 
@@ -657,7 +678,7 @@
 	{
 		if (signal_pending (current)) 
 		{
-			spin_unlock (&mdc800->io_lock);
+			up (&mdc800->io_lock);
 			return -EINTR;
 		}
 
@@ -676,21 +697,29 @@
 				if (usb_submit_urb (mdc800->download_urb))
 				{
 					err ("Can't submit download urb (status=%i)",mdc800->download_urb->status);
-					spin_unlock (&mdc800->io_lock);
+					up (&mdc800->io_lock);
 					return len-left;
 				}
-				interruptible_sleep_on_timeout (&mdc800->download_wait, TO_DOWNLOAD_GET_READY*HZ/1000);
+				add_wait_queue(&mdc800->download_wait, &wait);
+				set_current_state(TASK_INTERRUPTIBLE);
+				if (!mdc800->downloaded)
+				{
+					schedule_timeout (TO_DOWNLOAD_GET_READY*HZ/1000);
+				}
+				set_current_state(TASK_RUNNING);
+				remove_wait_queue(&mdc800->download_wait, &wait);
+				mdc800->downloaded = 0;
 				if (mdc800->download_urb->status != 0)
 				{
 					err ("request download-bytes fails (status=%i)",mdc800->download_urb->status);
-					spin_unlock (&mdc800->io_lock);
+					up (&mdc800->io_lock);
 					return len-left;
 				}
 			}
 			else
 			{
 				/* No more bytes -> that's an error*/
-				spin_unlock (&mdc800->io_lock);
+				up (&mdc800->io_lock);
 				return -EIO;
 			}
 		}
@@ -704,7 +733,7 @@
 		}
 	}
 
-	spin_unlock (&mdc800->io_lock);
+	up (&mdc800->io_lock);
 	return len-left;
 }
 
@@ -718,16 +747,17 @@
 static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t len, loff_t *pos)
 {
 	int i=0;
+	DECLARE_WAITQUEUE(wait, current);
 
-	spin_lock (&mdc800->io_lock);
+	down (&mdc800->io_lock);
 	if (mdc800->state != READY)
 	{
-		spin_unlock (&mdc800->io_lock);
+		up (&mdc800->io_lock);
 		return -EBUSY;
 	}
 	if (!mdc800->open )
 	{
-		spin_unlock (&mdc800->io_lock);
+		up (&mdc800->io_lock);
 		return -EBUSY;
 	}
 
@@ -735,7 +765,7 @@
 	{
 		if (signal_pending (current)) 
 		{
-			spin_unlock (&mdc800->io_lock);
+			up (&mdc800->io_lock);
 			return -EINTR;
 		}
 
@@ -757,7 +787,7 @@
 		else
 		{
 			err ("Command is to long !\n");
-			spin_unlock (&mdc800->io_lock);
+			up (&mdc800->io_lock);
 			return -EIO;
 		}
 
@@ -769,7 +799,7 @@
 			if (mdc800_usb_waitForIRQ (0,TO_GET_READY))
 			{
 				err ("Camera didn't get ready.\n");
-				spin_unlock (&mdc800->io_lock);
+				up (&mdc800->io_lock);
 				return -EIO;
 			}
 
@@ -781,14 +811,22 @@
 			if (usb_submit_urb (mdc800->write_urb))
 			{
 				err ("submitting write urb fails (status=%i)", mdc800->write_urb->status);
-				spin_unlock (&mdc800->io_lock);
+				up (&mdc800->io_lock);
 				return -EIO;
 			}
-			interruptible_sleep_on_timeout (&mdc800->write_wait, TO_WRITE_GET_READY*HZ/1000);
+			add_wait_queue(&mdc800->write_wait, &wait);
+			set_current_state(TASK_INTERRUPTIBLE);
+			if (!mdc800->written)
+			{
+				schedule_timeout (TO_WRITE_GET_READY*HZ/1000);
+			}
+                        set_current_state(TASK_RUNNING);
+			remove_wait_queue(&mdc800->write_wait, &wait);
+			mdc800->written = 0;
 			if (mdc800->state == WORKING)
 			{
 				usb_unlink_urb (mdc800->write_urb);
-				spin_unlock (&mdc800->io_lock);
+				up (&mdc800->io_lock);
 				return -EIO;
 			}
 
@@ -800,7 +838,7 @@
 					{
 						err ("call 0x07 before 0x05,0x3e");
 						mdc800->state=READY;
-						spin_unlock (&mdc800->io_lock);
+						up (&mdc800->io_lock);
 						return -EIO;
 					}
 					mdc800->pic_len=-1;
@@ -819,7 +857,7 @@
 						if (mdc800_usb_waitForIRQ (1,TO_READ_FROM_IRQ))
 						{
 							err ("requesting answer from irq fails");
-							spin_unlock (&mdc800->io_lock);
+							up (&mdc800->io_lock);
 							return -EIO;
 						}
 
@@ -847,7 +885,7 @@
 						if (mdc800_usb_waitForIRQ (0,TO_DEFAULT_COMMAND))
 						{
 							err ("Command Timeout.");
-							spin_unlock (&mdc800->io_lock);
+							up (&mdc800->io_lock);
 							return -EIO;
 						}
 					}
@@ -857,7 +895,7 @@
 		}
 		i++;
 	}
-	spin_unlock (&mdc800->io_lock);
+	up (&mdc800->io_lock);
 	return i;
 }
 
@@ -916,11 +954,15 @@
 	mdc800->dev=0;
 	mdc800->open=0;
 	mdc800->state=NOT_CONNECTED;
-	spin_lock_init (&mdc800->io_lock);
+	init_MUTEX (&mdc800->io_lock);
 
 	init_waitqueue_head (&mdc800->irq_wait);
 	init_waitqueue_head (&mdc800->write_wait);
 	init_waitqueue_head (&mdc800->download_wait);
+
+	mdc800->irq_woken = 0;
+	mdc800->downloaded = 0;
+	mdc800->written = 0;
 
 	try (mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL));
 	try (mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL));
diff -urN linux-2.5.1-pre7/drivers/usb/pegasus.c linux/drivers/usb/pegasus.c
--- linux-2.5.1-pre7/drivers/usb/pegasus.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/usb/pegasus.c	Sat Dec  8 21:05:03 2001
@@ -53,7 +53,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.4.21 (2001/08/27)"
+#define DRIVER_VERSION "v0.4.22 (2001/12/07)"
 #define DRIVER_AUTHOR "Petko Manolov <pmanolov@lnxw.com>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
@@ -102,7 +102,7 @@
 		return;
 
 	switch ( urb->status ) {
-		case USB_ST_NOERROR:
+		case 0:
 			if ( pegasus->flags & ETH_REGS_CHANGE ) {
 				pegasus->flags &= ~ETH_REGS_CHANGE;
 				pegasus->flags |= ETH_REGS_CHANGED;
@@ -110,9 +110,9 @@
 				return;
 			}
 			break;
-		case USB_ST_URB_PENDING:
+		case -EINPROGRESS:
 			return;
-		case USB_ST_URB_KILLED:
+		case -ENOENT:
 			break;
 		default:
 			warn( __FUNCTION__ " status %d", urb->status);
@@ -526,9 +526,9 @@
 	pegasus->flags |= PEGASUS_RX_BUSY;
 
 	switch ( urb->status ) {
-		case USB_ST_NOERROR:
+		case 0:
 			break;
-		case USB_ST_NORESPONSE:
+		case -ETIMEDOUT:
 			dbg( "reset MAC" );
 			pegasus->flags &= ~PEGASUS_RX_BUSY;
 			break;
@@ -607,9 +607,9 @@
 		return;
 		
 	switch ( urb->status ) {
-		case USB_ST_NOERROR:
+		case 0:
 			break;
-		case USB_ST_URB_KILLED:
+		case -ENOENT:
 			return;
 		default:
 			info("intr status %d", urb->status);
@@ -713,10 +713,8 @@
 	pegasus_t *pegasus = (pegasus_t *)net->priv;
 	int	res;
 
-	MOD_INC_USE_COUNT;
 	if ( (res = enable_net_traffic(net, pegasus->usb)) ) {
 		err("can't enable_net_traffic() - %d", res);
-		MOD_DEC_USE_COUNT;
 		return -EIO;
 	}
 	FILL_BULK_URB( &pegasus->rx_urb, pegasus->usb,
@@ -755,7 +753,6 @@
 #ifdef	PEGASUS_USE_INTR
 	usb_unlink_urb( &pegasus->intr_urb );
 #endif
-	MOD_DEC_USE_COUNT;
 
 	return 0;
 }
@@ -867,6 +864,7 @@
 	
 	pegasus->usb = dev;
 	pegasus->net = net;
+	SET_MODULE_OWNER(net);
 	net->priv = pegasus;
 	net->open = pegasus_open;
 	net->stop = pegasus_close;
diff -urN linux-2.5.1-pre7/drivers/usb/pegasus.h linux/drivers/usb/pegasus.h
--- linux-2.5.1-pre7/drivers/usb/pegasus.h	Wed Oct 17 14:34:06 2001
+++ linux/drivers/usb/pegasus.h	Sat Dec  8 21:05:03 2001
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@dce.bg)
+ *  Copyright (c) 1999,2000 Petko Manolov - Petkan (pmanolov@lnxw.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -138,6 +138,7 @@
 #define	VENDOR_DLINK		0x2001
 #define	VENDOR_ELSA		0x05cc
 #define	VENDOR_IODATA		0x04bb
+#define	VENDOR_KINGSTON		0x0951
 #define	VENDOR_LANEED		0x056e
 #define	VENDOR_LINKSYS		0x066b
 #define	VENDOR_MELCO		0x0411
@@ -210,6 +211,8 @@
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
 		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
+		DEFAULT_GPIO_RESET)
 PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b,
diff -urN linux-2.5.1-pre7/drivers/usb/rio500.c linux/drivers/usb/rio500.c
--- linux-2.5.1-pre7/drivers/usb/rio500.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/usb/rio500.c	Sat Dec  8 21:05:03 2001
@@ -324,7 +324,7 @@
 			dbg("write stats: result:%d thistime:%lu partial:%u",
 			     result, thistime, partial);
 
-			if (result == USB_ST_TIMEOUT) {	/* NAK - so hold for a while */
+			if (result == -ETIMEDOUT) {	/* NAK - so hold for a while */
 				if (!maxretry--) {
 					errn = -ETIME;
 					goto error;
@@ -403,7 +403,7 @@
 
 		if (partial) {
 			count = this_read = partial;
-		} else if (result == USB_ST_TIMEOUT || result == 15) {	/* FIXME: 15 ??? */
+		} else if (result == -ETIMEDOUT || result == 15) {	/* FIXME: 15 ??? */
 			if (!maxretry--) {
 				up(&(rio->lock));
 				err("read_rio: maxretry timeout");
@@ -412,7 +412,7 @@
 			interruptible_sleep_on_timeout(&rio->wait_q,
 						       NAK_TIMEOUT);
 			continue;
-		} else if (result != USB_ST_DATAUNDERRUN) {
+		} else if (result != -EREMOTEIO) {
 			up(&(rio->lock));
 			err("Read Whoops - result:%u partial:%u this_read:%u",
 			     result, partial, this_read);
diff -urN linux-2.5.1-pre7/drivers/usb/scanner.c linux/drivers/usb/scanner.c
--- linux-2.5.1-pre7/drivers/usb/scanner.c	Sat Oct 20 19:13:11 2001
+++ linux/drivers/usb/scanner.c	Sat Dec  8 21:05:03 2001
@@ -278,6 +278,28 @@
  *    - Users are now notified to consult the Documentation/usb/scanner.txt
  *      for common error messages rather than the maintainer.
  *
+ * 0.4.7  11/28/2001
+ *    - Fixed typo in Documentation/scanner.txt.  Thanks to
+ *      Karel <karel.vervaeke@pandora.be> for pointing it out.
+ *    - Added ID's for a Memorex 6136u. Thanks to =C1lvaro Gaspar de
+ *      Valenzuela" <agaspard@utsi.edu>.
+ *    - Added ID's for Agfa e25.  Thanks to Heinrich 
+ *      Rust <Heinrich.Rust@gmx.de>.  Also reported to work with
+ *      Linux and SANE (?).
+ *    - Added Canon FB620U, D646U, and 1220U ID's.  Thanks to Paul
+ *      Rensing <Paul_Rensing@StanfordAlumni.org>.  For more info
+ *      on Linux support for these models, contact 
+ *      salvestrini@users.sourceforge.net.
+ *    - Added Plustek OpticPro UT12, OpticPro U24, KYE/Genius
+ *      ColorPage-HR6 V2 ID's in addition to many "Unknown" models
+ *      under those vendors.  Thanks to
+ *      Jaeger, Gerhard" <g.jaeger@earthling.net>.  These scanner are
+ *      apparently based upon the LM983x IC's.
+ *    - Applied Frank's patch that addressed some locking and module
+ *      referencing counts.  Thanks to both
+ *      Frank Zago <fzago@greshamstorage.com> and
+ *      Oliver Neukum <520047054719-0001@t-online.de> for reviewing/testing.
+ *
  * TODO
  *    - Performance
  *    - Select/poll methods
@@ -324,17 +346,16 @@
 	struct scn_usb_data *scn;
 	unsigned char *data;
 	scn = urb->context;
-	down(&(scn->sem));
+
 	data = &scn->button;
 	data += 0;		/* Keep gcc from complaining about unused var */
 
 	if (urb->status) {
-		up(&(scn->sem));
 		return;
 	}
 
 	dbg("irq_scanner(%d): data:%x", scn->scn_minor, *data);
-	up(&(scn->sem));
+
 	return;
 }
 
@@ -358,6 +379,7 @@
 
 	if (!p_scn_table[scn_minor]) {
 		up(&scn_mutex);
+		MOD_DEC_USE_COUNT;
 		err("open_scanner(%d): Unable to access minor data", scn_minor);
 		return -ENODEV;
 	}
@@ -606,7 +628,7 @@
 			}
 			ret = result;
 			break;
-		} else if ((result < 0) && (result != USB_ST_DATAUNDERRUN)) {
+		} else if ((result < 0) && (result != -EREMOTEIO)) {
 			warn("read_scanner(%d): funky result:%d. Consult Documentation/usb/scanner.txt.", scn_minor, (int)result);
 			ret = -EIO;
 			break;
@@ -939,6 +961,7 @@
 /* Check to make sure that the last slot isn't already taken */
 	if (p_scn_table[scn_minor]) {
 		err("probe_scanner: No more minor devices remaining.");
+		up(&scn_mutex);
 		return NULL;
 	}
 
@@ -946,6 +969,7 @@
 
 	if (!(scn = kmalloc (sizeof (struct scn_usb_data), GFP_KERNEL))) {
 		err("probe_scanner: Out of memory.");
+		up(&scn_mutex);
 		return NULL;
 	}
 	memset (scn, 0, sizeof(struct scn_usb_data));
@@ -1028,9 +1052,11 @@
 	if (scn->devfs == NULL)
 		dbg("scanner%d: device node registration failed", scn_minor);
 
+	p_scn_table[scn_minor] = scn;
+
 	up(&scn_mutex);
 
-	return p_scn_table[scn_minor] = scn;
+	return scn;
 }
 
 static void
diff -urN linux-2.5.1-pre7/drivers/usb/scanner.h linux/drivers/usb/scanner.h
--- linux-2.5.1-pre7/drivers/usb/scanner.h	Sat Oct 20 19:13:11 2001
+++ linux/drivers/usb/scanner.h	Sat Dec  8 21:05:03 2001
@@ -86,12 +86,23 @@
 	{ USB_DEVICE(0x06bd, 0x2061) },	/* Another SnapScan 1212U (?)*/
 	{ USB_DEVICE(0x06bd, 0x0100) },	/* SnapScan Touch */
 	{ USB_DEVICE(0x06bd, 0x2091) }, /* SnapScan e20 */
+	{ USB_DEVICE(0x06bd, 0x2095) }, /* SnapScan e25 */
 	{ USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */
 	{ USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */
+	/* Canon */
+	{ USB_DEVICE(0x04a9, 0x2202) }, /* FB620U */
+	{ USB_DEVICE(0x04a9, 0x220b) }, /* D646U */
+	{ USB_DEVICE(0x04a9, 0x2207) }, /* 1220U */
 	/* Colorado -- See Primax/Colorado below */
 	/* Epson -- See Seiko/Epson below */
 	/* Genius */
 	{ USB_DEVICE(0x0458, 0x2001) },	/* ColorPage-Vivid Pro */
+	{ USB_DEVICE(0x0458, 0x2007) },	/* ColorPage HR6 V2 */
+	{ USB_DEVICE(0x0458, 0x2008) },	/* Unknown */
+	{ USB_DEVICE(0x0458, 0x2009) },	/* Unknown */
+	{ USB_DEVICE(0x0458, 0x2013) },	/* Unknown */
+	{ USB_DEVICE(0x0458, 0x2015) },	/* Unknown  */
+	{ USB_DEVICE(0x0458, 0x2016) },	/* Unknown  */
 	/* Hewlett Packard */
 	{ USB_DEVICE(0x03f0, 0x0205) },	/* 3300C */
 	{ USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */
@@ -108,6 +119,8 @@
 	{ USB_DEVICE(0x0638, 0x0268) }, /* 1200U */
 	/* Lifetec */
 	{ USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */
+	/* Memorex */
+	{ USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */
 	/* Microtek -- No longer supported - Enable SCSI and USB Microtek in kernel config */
 	//	{ USB_DEVICE(0x05da, 0x0099) },	/* ScanMaker X6 - X6U */
 	//	{ USB_DEVICE(0x05da, 0x0094) },	/* Phantom 336CX - C3 */
@@ -128,6 +141,19 @@
 	{ USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */
 	{ USB_DEVICE(0x055f, 0x0008) }, /* 1200 CU Plus */
 	{ USB_DEVICE(0x0ff5, 0x0010) }, /* BearPaw 1200F */
+	/* Plustek */
+	{ USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12 */
+	{ USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro UT24 */
+	{ USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0010) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0015) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */
 	/* Primax/Colorado */
 	{ USB_DEVICE(0x0461, 0x0300) },	/* G2-300 #1 */
 	{ USB_DEVICE(0x0461, 0x0380) },	/* G2-600 #1 */
diff -urN linux-2.5.1-pre7/drivers/usb/serial/belkin_sa.c linux/drivers/usb/serial/belkin_sa.c
--- linux-2.5.1-pre7/drivers/usb/serial/belkin_sa.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/belkin_sa.c	Sat Dec  8 21:05:03 2001
@@ -211,9 +211,7 @@
 	++port->open_count;
 	MOD_INC_USE_COUNT;
 	
-	if (!port->active) {
-		port->active = 1;
-
+	if (port->open_count == 1) {
 		/*Start reading from the device*/
 		/* TODO: Look at possibility of submitting mulitple URBs to device to
 		 *       enhance buffering.  Win trace shows 16 initial read URBs.
@@ -262,7 +260,7 @@
 			usb_unlink_urb (port->read_urb);
 			usb_unlink_urb (port->interrupt_in_urb);
 		}
-		port->active = 0;
+		port->open_count = 0;
 	}
 	
 	up (&port->sem);
diff -urN linux-2.5.1-pre7/drivers/usb/serial/cyberjack.c linux/drivers/usb/serial/cyberjack.c
--- linux-2.5.1-pre7/drivers/usb/serial/cyberjack.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/cyberjack.c	Sat Dec  8 21:05:03 2001
@@ -156,8 +156,7 @@
 
 	++port->open_count;
 
-	if (!port->active) {
-		port->active = 1;
+	if (port->open_count == 1) {
 		/* force low_latency on so that our tty_push actually forces
 		 * the data through, otherwise it is scheduled, and with high
 		 * data rates (like with OHCI) data can get lost.
@@ -201,8 +200,6 @@
 			usb_unlink_urb (port->read_urb);
 			usb_unlink_urb (port->interrupt_in_urb);
 		}
-
-		port->active = 0;
 		port->open_count = 0;
 	}
 
diff -urN linux-2.5.1-pre7/drivers/usb/serial/digi_acceleport.c linux/drivers/usb/serial/digi_acceleport.c
--- linux-2.5.1-pre7/drivers/usb/serial/digi_acceleport.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/digi_acceleport.c	Sat Dec  8 21:05:03 2001
@@ -14,6 +14,10 @@
 *  Peter Berger (pberger@brimson.com)
 *  Al Borchers (borchers@steinerpoint.com)
 * 
+* (12/03/2001) gkh
+*	switched to using port->open_count instead of private version.
+*	Removed port->active
+*
 * (04/08/2001) gb
 *	Identify version on module load.
 *
@@ -429,7 +433,6 @@
 	int dp_write_urb_in_use;
 	unsigned int dp_modem_signals;
 	wait_queue_head_t dp_modem_change_wait;
-	int dp_open_count;			/* inc on open, dec on close */
 	int dp_transmit_idle;
 	wait_queue_head_t dp_transmit_idle_wait;
 	int dp_throttled;
@@ -1380,7 +1383,7 @@
 	/* try to send any buffered data on this port, if it is open */
 	spin_lock( &priv->dp_port_lock );
 	priv->dp_write_urb_in_use = 0;
-	if( priv->dp_open_count && port->write_urb->status != -EINPROGRESS
+	if( port->open_count && port->write_urb->status != -EINPROGRESS
 	&& priv->dp_out_buf_len > 0 ) {
 
 		*((unsigned char *)(port->write_urb->transfer_buffer))
@@ -1474,7 +1477,7 @@
 	unsigned long flags = 0;
 
 
-dbg( "digi_open: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, port->active, priv->dp_open_count );
+dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count );
 
 	/* be sure the device is started up */
 	if( digi_startup_device( port->serial ) != 0 )
@@ -1489,7 +1492,7 @@
 	}
 
 	/* inc module use count before sleeping to wait for closes */
-	++priv->dp_open_count;
+	++port->open_count;
 	MOD_INC_USE_COUNT;
 
 	/* wait for a close in progress to finish */
@@ -1498,7 +1501,7 @@
 			&priv->dp_close_wait, DIGI_RETRY_TIMEOUT,
 			&priv->dp_port_lock, flags );
 		if( signal_pending(current) ) {
-			--priv->dp_open_count;
+			--port->open_count;
 			MOD_DEC_USE_COUNT;
 			return( -EINTR );
 		}
@@ -1507,13 +1510,11 @@
 
 	/* if port is already open, just return */
 	/* be sure exactly one open proceeds */
-	if( port->active ) {
+	if( port->open_count != 1)  {
 		spin_unlock_irqrestore( &priv->dp_port_lock, flags );
 		return( 0 );
 	}
 
-	/* first open, mark port as active */
-	port->active = 1;
 	spin_unlock_irqrestore( &priv->dp_port_lock, flags );
  
 	/* read modem signals automatically whenever they change */
@@ -1554,17 +1555,17 @@
 	unsigned long flags = 0;
 
 
-dbg( "digi_close: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, port->active, priv->dp_open_count );
+dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count );
 
 
 	/* do cleanup only after final close on this port */
 	spin_lock_irqsave( &priv->dp_port_lock, flags );
-	if( priv->dp_open_count > 1 ) {
-		--priv->dp_open_count;
+	if( port->open_count > 1 ) {
+		--port->open_count;
 		MOD_DEC_USE_COUNT;
 		spin_unlock_irqrestore( &priv->dp_port_lock, flags );
 		return;
-	} else if( priv->dp_open_count <= 0 ) {
+	} else if( port->open_count <= 0 ) {
 		spin_unlock_irqrestore( &priv->dp_port_lock, flags );
 		return;
 	}
@@ -1638,10 +1639,9 @@
 	tty->closing = 0;
 
 	spin_lock_irqsave( &priv->dp_port_lock, flags );
-	port->active = 0;
 	priv->dp_write_urb_in_use = 0;
 	priv->dp_in_close = 0;
-	--priv->dp_open_count;
+	--port->open_count;
 	MOD_DEC_USE_COUNT;
 	wake_up_interruptible( &priv->dp_close_wait );
 	spin_unlock_irqrestore( &priv->dp_port_lock, flags );
@@ -1710,8 +1710,6 @@
 	/* number of regular ports + 1 for the out-of-band port */
 	for( i=0; i<serial->type->num_ports+1; i++ ) {
 
-		serial->port[i].active = 0;
-
 		/* allocate port private structure */
 		priv = serial->port[i].private =
 			(digi_port_t *)kmalloc( sizeof(digi_port_t),
@@ -1730,7 +1728,6 @@
 		priv->dp_write_urb_in_use = 0;
 		priv->dp_modem_signals = 0;
 		init_waitqueue_head( &priv->dp_modem_change_wait );
-		priv->dp_open_count = 0;
 		priv->dp_transmit_idle = 0;
 		init_waitqueue_head( &priv->dp_transmit_idle_wait );
 		priv->dp_throttled = 0;
@@ -1789,9 +1786,9 @@
 	for( i=0; i<serial->type->num_ports; i++ ) {
 		priv = serial->port[i].private;
 		spin_lock_irqsave( &priv->dp_port_lock, flags );
-		while( priv->dp_open_count > 0 ) {
+		while( serial->port[i].open_count > 0 ) {
 			MOD_DEC_USE_COUNT;
-			--priv->dp_open_count;
+			--serial->port[i].open_count;
 		}
 		spin_unlock_irqrestore( &priv->dp_port_lock, flags );
 	}
@@ -1883,7 +1880,7 @@
 
 	/* do not process callbacks on closed ports */
 	/* but do continue the read chain */
-	if( priv->dp_open_count == 0 )
+	if( port->open_count == 0 )
 		return( 0 );
 
 	/* short/multiple packet check */
@@ -2017,7 +2014,7 @@
 			if( val & DIGI_READ_INPUT_SIGNALS_CTS ) {
 				priv->dp_modem_signals |= TIOCM_CTS;
 				/* port must be open to use tty struct */
-				if( priv->dp_open_count
+				if( port->open_count
 				&& port->tty->termios->c_cflag & CRTSCTS ) {
 					port->tty->hw_stopped = 0;
 					digi_wakeup_write( port );
@@ -2025,7 +2022,7 @@
 			} else {
 				priv->dp_modem_signals &= ~TIOCM_CTS;
 				/* port must be open to use tty struct */
-				if( priv->dp_open_count
+				if( port->open_count
 				&& port->tty->termios->c_cflag & CRTSCTS ) {
 					port->tty->hw_stopped = 1;
 				}
diff -urN linux-2.5.1-pre7/drivers/usb/serial/empeg.c linux/drivers/usb/serial/empeg.c
--- linux-2.5.1-pre7/drivers/usb/serial/empeg.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/empeg.c	Sat Dec  8 21:05:03 2001
@@ -161,12 +161,11 @@
 	++port->open_count;
 	MOD_INC_USE_COUNT;
 
-	if (!port->active) {
+	if (port->open_count == 1) {
 
 		/* Force default termio settings */
 		empeg_set_termios (port, NULL) ;
 
-		port->active = 1;
 		bytes_in = 0;
 		bytes_out = 0;
 
@@ -218,7 +217,6 @@
 			/* shutdown our bulk read */
 			usb_unlink_urb (port->read_urb);
 		}
-		port->active = 0;
 		port->open_count = 0;
 	}
 
diff -urN linux-2.5.1-pre7/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c
--- linux-2.5.1-pre7/drivers/usb/serial/ftdi_sio.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/ftdi_sio.c	Sat Dec  8 21:05:03 2001
@@ -321,9 +321,7 @@
 	MOD_INC_USE_COUNT;
 	++port->open_count;
 
-	if (!port->active){
-		port->active = 1;
-
+	if (port->open_count == 1){
 		/* This will push the characters through immediately rather 
 		   than queue a task to deliver them */
 		port->tty->low_latency = 1;
@@ -404,7 +402,6 @@
 			usb_unlink_urb (port->write_urb);
 			usb_unlink_urb (port->read_urb);
 		}
-		port->active = 0;
 		port->open_count = 0;
 	} else {  
 		/* Send a HUP if necessary */
diff -urN linux-2.5.1-pre7/drivers/usb/serial/io_edgeport.c linux/drivers/usb/serial/io_edgeport.c
--- linux-2.5.1-pre7/drivers/usb/serial/io_edgeport.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/io_edgeport.c	Sat Dec  8 21:05:03 2001
@@ -987,9 +987,7 @@
 	++port->open_count;
 	MOD_INC_USE_COUNT;
 	
-	if (!port->active) {
-		port->active = 1;
-
+	if (port->open_count == 1) {
 		/* force low_latency on so that our tty_push actually forces the data through, 
 		   otherwise it is scheduled, and with high data rates (like with OHCI) data
 		   can get lost. */
@@ -1000,7 +998,6 @@
 		serial = port->serial;
 		edge_serial = (struct edgeport_serial *)serial->private;
 		if (edge_serial == NULL) {
-			port->active = 0;
 			port->open_count = 0;
 			MOD_DEC_USE_COUNT;
 			return -ENODEV;
@@ -1064,7 +1061,6 @@
 		if (response < 0) {
 			err(__FUNCTION__" - error sending open port command");
 			edge_port->openPending = FALSE;
-			port->active = 0;
 			port->open_count = 0;
 			MOD_DEC_USE_COUNT;
 			return -ENODEV;
@@ -1080,7 +1076,6 @@
 			/* open timed out */
 			dbg(__FUNCTION__" - open timedout");
 			edge_port->openPending = FALSE;
-			port->active = 0;
 			port->open_count = 0;
 			MOD_DEC_USE_COUNT;
 			return -ENODEV;
@@ -1285,7 +1280,6 @@
 		if (edge_port->txfifo.fifo) {
 			kfree(edge_port->txfifo.fifo);
 		}
-		port->active = 0;
 		port->open_count = 0;
 	}
 
diff -urN linux-2.5.1-pre7/drivers/usb/serial/ir-usb.c linux/drivers/usb/serial/ir-usb.c
--- linux-2.5.1-pre7/drivers/usb/serial/ir-usb.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/ir-usb.c	Sat Dec  8 21:05:03 2001
@@ -206,9 +206,7 @@
 	++port->open_count;
 	MOD_INC_USE_COUNT;
 	
-	if (!port->active) {
-		port->active = 1;
-
+	if (port->open_count == 1) {
 		if (buffer_size) {
 			/* override the default buffer sizes */
 			buffer = kmalloc (buffer_size, GFP_KERNEL);
@@ -268,7 +266,6 @@
 			/* shutdown our bulk read */
 			usb_unlink_urb (port->read_urb);
 		}
-		port->active = 0;
 		port->open_count = 0;
 
 	}
diff -urN linux-2.5.1-pre7/drivers/usb/serial/keyspan.c linux/drivers/usb/serial/keyspan.c
--- linux-2.5.1-pre7/drivers/usb/serial/keyspan.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/keyspan.c	Sat Dec  8 21:05:03 2001
@@ -468,7 +468,7 @@
 	p_priv = (struct keyspan_port_private *)(port->private);
 	dbg (__FUNCTION__ " urb %d\n", urb == p_priv->out_urbs[1]); 
 
-	if (port->active) {
+	if (port->open_count) {
 		queue_task(&port->tqueue, &tq_immediate);
 		mark_bh(IMMEDIATE_BH);
 	}
@@ -880,9 +880,8 @@
 	MOD_INC_USE_COUNT;
 
 	down (&port->sem);
+	already_active = port->open_count;
 	++port->open_count;
-	already_active = port->active;
-	port->active = 1;
 	up (&port->sem);
 
 	if (already_active)
@@ -948,18 +947,15 @@
 	down (&port->sem);
 
 	if (--port->open_count <= 0) {
-		if (port->active) {
-			if (serial->dev) {
-				/* Stop reading/writing urbs */
-				stop_urb(p_priv->inack_urb);
-				stop_urb(p_priv->outcont_urb);
-				for (i = 0; i < 2; i++) {
-					stop_urb(p_priv->in_urbs[i]);
-					stop_urb(p_priv->out_urbs[i]);
-				}
+		if (serial->dev) {
+			/* Stop reading/writing urbs */
+			stop_urb(p_priv->inack_urb);
+			stop_urb(p_priv->outcont_urb);
+			for (i = 0; i < 2; i++) {
+				stop_urb(p_priv->in_urbs[i]);
+				stop_urb(p_priv->out_urbs[i]);
 			}
 		}
-		port->active = 0;
 		port->open_count = 0;
 		port->tty = 0;
 	}
diff -urN linux-2.5.1-pre7/drivers/usb/serial/keyspan_pda.c linux/drivers/usb/serial/keyspan_pda.c
--- linux-2.5.1-pre7/drivers/usb/serial/keyspan_pda.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/keyspan_pda.c	Sat Dec  8 21:05:03 2001
@@ -675,9 +675,7 @@
 	MOD_INC_USE_COUNT;
 	++port->open_count;
 
-	if (!port->active) {
-		port->active = 1;
- 
+	if (port->open_count == 1) {
 		/* find out how much room is in the Tx ring */
 		rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 				     6, /* write_room */
@@ -723,7 +721,6 @@
 	return rc;
 error:
 	--port->open_count;
-	port->active = 0;
 	MOD_DEC_USE_COUNT;
 	up (&port->sem);
 	return rc;
@@ -748,7 +745,6 @@
 			usb_unlink_urb (port->write_urb);
 			usb_unlink_urb (port->interrupt_in_urb);
 		}
-		port->active = 0;
 		port->open_count = 0;
 	}
 
diff -urN linux-2.5.1-pre7/drivers/usb/serial/mct_u232.c linux/drivers/usb/serial/mct_u232.c
--- linux-2.5.1-pre7/drivers/usb/serial/mct_u232.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/mct_u232.c	Sat Dec  8 21:05:03 2001
@@ -27,6 +27,9 @@
  * 10-Nov-2001 Wolfgang Grandegger
  *   - Fixed an endianess problem with the baudrate selection for PowerPC.
  *
+ * 06-Dec-2001 Martin Hamilton <martinh@gnu.org>
+ *	Added support for the Belkin F5U109 DB9 adaptor
+ *
  * 30-May-2001 Greg Kroah-Hartman
  *	switched from using spinlock to a semaphore, which fixes lots of problems.
  *
@@ -133,6 +136,7 @@
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
+	{ USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
 	{ }		/* Terminating entry */
 };
 
@@ -175,7 +179,8 @@
 #define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
 
 static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) {
-	if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID) {
+	if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID
+	  || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) {
 		switch (value) {
 			case    300: return 0x01;
 			case    600: return 0x02; /* this one not tested */
@@ -340,9 +345,7 @@
 	++port->open_count;
 	MOD_INC_USE_COUNT;
 
-	if (!port->active) {
-		port->active = 1;
-
+	if (port->open_count == 1) {
 		/* Compensate for a hardware bug: although the Sitecom U232-P25
 		 * device reports a maximum output packet size of 32 bytes,
 		 * it seems to be able to accept only 16 bytes (and that's what
@@ -416,7 +419,7 @@
 			usb_unlink_urb (port->read_urb);
 			usb_unlink_urb (port->interrupt_in_urb);
 		}
-		port->active = 0;
+		port->open_count = 0;
 	}
 	
 	up (&port->sem);
diff -urN linux-2.5.1-pre7/drivers/usb/serial/mct_u232.h linux/drivers/usb/serial/mct_u232.h
--- linux-2.5.1-pre7/drivers/usb/serial/mct_u232.h	Thu Feb  8 16:30:40 2001
+++ linux/drivers/usb/serial/mct_u232.h	Sat Dec  8 21:05:03 2001
@@ -30,9 +30,12 @@
 #define MCT_U232_SITECOM_PID		0x0230	/* Sitecom Product Id */
 
 /* DU-H3SP USB BAY hub */
-
 #define MCT_U232_DU_H3SP_PID		0x0200	/* D-Link DU-H3SP USB BAY */
 
+/* Belkin badge the MCT U232-P9 as the F5U109 */
+#define MCT_U232_BELKIN_F5U109_VID	0x050d	/* Vendor Id */
+#define MCT_U232_BELKIN_F5U109_PID	0x0109	/* Product Id */
+
 /*
  * Vendor Request Interface
  */
@@ -363,6 +366,25 @@
  * 	  bmAttributes        =   03 (Interrupt)
  * 	  wMaxPacketSize      = 0002
  * 	  bInterval           =   02
+ *
+ *
+ * Hardware details (added by Martin Hamilton, 2001/12/06)
+ * -----------------------------------------------------------------
+ *
+ * This info was gleaned from opening a Belkin F5U109 DB9 USB serial
+ * adaptor, which turns out to simply be a re-badged U232-P9.  We
+ * know this because there is a sticky label on the circuit board
+ * which says "U232-P9" ;-)
+ * 
+ * The circuit board inside the adaptor contains a Philips PDIUSBD12
+ * USB endpoint chip and a Phillips P87C52UBAA microcontroller with
+ * embedded UART.  Exhaustive documentation for these is available at:
+ *
+ *   http://www.semiconductors.philips.com/pip/p87c52ubaa
+ *   http://www.semiconductors.philips.com/pip/pdiusbd12
+ *
+ * Thanks to Julian Highfield for the pointer to the Philips database.
+ * 
  */
 
 #endif /* __LINUX_USB_SERIAL_MCT_U232_H */
diff -urN linux-2.5.1-pre7/drivers/usb/serial/omninet.c linux/drivers/usb/serial/omninet.c
--- linux-2.5.1-pre7/drivers/usb/serial/omninet.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/omninet.c	Sat Dec  8 21:05:03 2001
@@ -161,14 +161,11 @@
 	MOD_INC_USE_COUNT;
 	++port->open_count;
 
-	if (!port->active) {
-		port->active = 1;
-
+	if (port->open_count == 1) {
 		od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL );
 		if( !od ) {
 			err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct omninet_data));
-			--port->open_count;
-			port->active = 0;
+			port->open_count = 0;
 			up (&port->sem);
 			MOD_DEC_USE_COUNT;
 			return -ENOMEM;
@@ -219,7 +216,6 @@
 			usb_unlink_urb (port->read_urb);
 		}
 
-		port->active = 0;
 		port->open_count = 0;
 		od = (struct omninet_data *)port->private;
 		if (od)
diff -urN linux-2.5.1-pre7/drivers/usb/serial/pl2303.c linux/drivers/usb/serial/pl2303.c
--- linux-2.5.1-pre7/drivers/usb/serial/pl2303.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/pl2303.c	Sat Dec  8 21:05:03 2001
@@ -371,9 +371,7 @@
 	++port->open_count;
 	MOD_INC_USE_COUNT;
 
-	if (!port->active) {
-		port->active = 1;
-
+	if (port->open_count == 1) {
 #define FISH(a,b,c,d)									\
 		result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0),	\
 				       b, a, c, d, buf, 1, 100);			\
@@ -478,8 +476,6 @@
 				     "(interrupt_in_urb) failed with reason: %d",
 				     result);
 		}
-
-		port->active = 0;
 		port->open_count = 0;
 	}
 
@@ -648,7 +644,7 @@
 
 	if (urb->status) {
 		dbg (__FUNCTION__ " - urb->status = %d", urb->status);
-		if (!port->active) {
+		if (!port->open_count) {
 			dbg (__FUNCTION__ " - port is closed, exiting.");
 			return;
 		}
@@ -680,7 +676,7 @@
 	}
 
 	/* Schedule the next read _if_ we are still open */
-	if (port->active) {
+	if (port->open_count) {
 		urb->dev = serial->dev;
 		result = usb_submit_urb(urb);
 		if (result)
diff -urN linux-2.5.1-pre7/drivers/usb/serial/usb-serial.h linux/drivers/usb/serial/usb-serial.h
--- linux-2.5.1-pre7/drivers/usb/serial/usb-serial.h	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/usb-serial.h	Sat Dec  8 21:05:03 2001
@@ -11,6 +11,10 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (12/03/2001) gkh
+ *	removed active from the port structure.
+ *	added documentation to the usb_serial_device_type structure
+ *
  * (10/10/2001) gkh
  *	added vendor and product to serial structure.  Needed to determine device
  *	owner when the device is disconnected.
@@ -65,7 +69,6 @@
 	struct usb_serial	*serial;	/* pointer back to the owner of this port */
 	struct tty_struct *	tty;		/* the coresponding tty for this port */
 	unsigned char		number;
-	char			active;		/* someone has this device open */
 
 	unsigned char *		interrupt_in_buffer;
 	struct urb *		interrupt_in_urb;
@@ -111,21 +114,40 @@
 #define NUM_DONT_CARE	(-1)
 
 
-/* This structure defines the individual serial converter. */
+/**
+ * usb_serial_device_type - a structure that defines a usb serial device
+ * @name: pointer to a string that describes this device.  This string used
+ *	in the syslog messages when a device is inserted or removed.
+ * @id_table: pointer to a list of usb_device_id structures that define all
+ *	of the devices this structure can support.
+ * @num_interrupt_in: the number of interrupt in endpoints this device will
+ *	have.
+ * @num_bulk_in: the number of bulk in endpoints this device will have.
+ * @num_bulk_out: the number of bulk out endpoints this device will have.
+ * @num_ports: the number of different ports this device will have.
+ * @startup: pointer to the driver's startup function.  This will be called
+ *	when the driver is inserted into the system.  Return 0 to continue
+ *	on with the initialization sequence.  Anything else will abort it.
+ * @shutdown: pointer to the driver's shutdown function.  This will be
+ *	called when the device is removed from the system.
+ *
+ * This structure is defines a USB Serial device.  It provides all of
+ * the information that the USB serial core code needs.  If the function
+ * pointers are defined, then the USB serial core code will call them when
+ * the corresponding tty port functions are called.  If they are not
+ * called, the generic serial function will be used instead.
+ */
 struct usb_serial_device_type {
 	char	*name;
 	const struct usb_device_id *id_table;
 	char	num_interrupt_in;
 	char	num_bulk_in;
 	char	num_bulk_out;
-	char	num_ports;		/* number of serial ports this device has */
+	char	num_ports;
 
 	struct list_head	driver_list;
 	
-	/* function call to make before accepting driver */
-	/* return 0 to continue initialization, anything else to abort */
 	int (*startup) (struct usb_serial *serial);
-	
 	void (*shutdown) (struct usb_serial *serial);
 
 	/* serial function calls */
diff -urN linux-2.5.1-pre7/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c
--- linux-2.5.1-pre7/drivers/usb/serial/usbserial.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/usbserial.c	Sat Dec  8 21:05:03 2001
@@ -545,7 +545,7 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 	
-	if (!port->active) {
+	if (!port->open_count) {
 		dbg (__FUNCTION__ " - port not opened");
 		return;
 	}
@@ -570,7 +570,7 @@
 	
 	dbg(__FUNCTION__ " - port %d, %d byte(s)", port->number, count);
 
-	if (!port->active) {
+	if (!port->open_count) {
 		dbg (__FUNCTION__ " - port not opened");
 		return -EINVAL;
 	}
@@ -595,7 +595,7 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 	
-	if (!port->active) {
+	if (!port->open_count) {
 		dbg (__FUNCTION__ " - port not open");
 		return -EINVAL;
 	}
@@ -618,7 +618,7 @@
 		return -ENODEV;
 	}
 
-	if (!port->active) {
+	if (!port->open_count) {
 		dbg (__FUNCTION__ " - port not open");
 		return -EINVAL;
 	}
@@ -643,7 +643,7 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	if (!port->active) {
+	if (!port->open_count) {
 		dbg (__FUNCTION__ " - port not open");
 		return;
 	}
@@ -668,7 +668,7 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	if (!port->active) {
+	if (!port->open_count) {
 		dbg (__FUNCTION__ " - port not open");
 		return;
 	}
@@ -693,7 +693,7 @@
 
 	dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", port->number, cmd);
 
-	if (!port->active) {
+	if (!port->open_count) {
 		dbg (__FUNCTION__ " - port not open");
 		return -ENODEV;
 	}
@@ -718,7 +718,7 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	if (!port->active) {
+	if (!port->open_count) {
 		dbg (__FUNCTION__ " - port not open");
 		return;
 	}
@@ -743,7 +743,7 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	if (!port->active) {
+	if (!port->open_count) {
 		dbg (__FUNCTION__ " - port not open");
 		return;
 	}
@@ -787,9 +787,7 @@
 	
 	++port->open_count;
 	
-	if (!port->active) {
-		port->active = 1;
-
+	if (port->open_count == 1) {
 		/* force low_latency on so that our tty_push actually forces the data through, 
 		   otherwise it is scheduled, and with high data rates (like with OHCI) data
 		   can get lost. */
@@ -798,13 +796,14 @@
 		/* if we have a bulk interrupt, start reading from it */
 		if (serial->num_bulk_in) {
 			/* Start reading from the device */
-			FILL_BULK_URB(port->read_urb, serial->dev, 
-				      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
-				      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
-				      ((serial->type->read_bulk_callback) ?
-				       serial->type->read_bulk_callback :
-				       generic_read_bulk_callback), 
-				      port);
+			usb_fill_bulk_urb (port->read_urb, serial->dev,
+					   usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+					   port->read_urb->transfer_buffer,
+					   port->read_urb->transfer_buffer_length,
+					   ((serial->type->read_bulk_callback) ?
+					     serial->type->read_bulk_callback :
+					     generic_read_bulk_callback),
+					   port);
 			result = usb_submit_urb(port->read_urb);
 			if (result)
 				err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
@@ -835,8 +834,6 @@
 			if (serial->num_bulk_in)
 				usb_unlink_urb (port->read_urb);
 		}
-		
-		port->active = 0;
 		port->open_count = 0;
 	}
 
@@ -879,13 +876,13 @@
 		usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer);
 
 		/* set up our urb */
-		FILL_BULK_URB(port->write_urb, serial->dev, 
-			      usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
-			      port->write_urb->transfer_buffer, count,
-			      ((serial->type->write_bulk_callback) ? 
-			       serial->type->write_bulk_callback : 
-			       generic_write_bulk_callback), 
-			      port);
+		usb_fill_bulk_urb (port->write_urb, serial->dev,
+				   usb_sndbulkpipe (serial->dev,
+					   	    port->bulk_out_endpointAddress),
+				   port->write_urb->transfer_buffer, count,
+				   ((serial->type->write_bulk_callback) ? 
+				     serial->type->write_bulk_callback :
+				     generic_write_bulk_callback), port);
 
 		/* send the data out the bulk port */
 		result = usb_submit_urb(port->write_urb);
@@ -973,13 +970,14 @@
 	}
 
 	/* Continue trying to always read  */
-	FILL_BULK_URB(port->read_urb, serial->dev, 
-		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
-		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
-		      ((serial->type->read_bulk_callback) ?
-		       serial->type->read_bulk_callback :
-		       generic_read_bulk_callback), 
-		      port);
+	usb_fill_bulk_urb (port->read_urb, serial->dev,
+			   usb_rcvbulkpipe (serial->dev,
+				   	    port->bulk_in_endpointAddress),
+			   port->read_urb->transfer_buffer,
+			   port->read_urb->transfer_buffer_length,
+			   ((serial->type->read_bulk_callback) ? 
+			     serial->type->read_bulk_callback : 
+			     generic_read_bulk_callback), port);
 	result = usb_submit_urb(port->read_urb);
 	if (result)
 		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
@@ -1203,13 +1201,14 @@
 			err("Couldn't allocate bulk_in_buffer");
 			goto probe_error;
 		}
-		FILL_BULK_URB(port->read_urb, dev, 
-			      usb_rcvbulkpipe(dev, endpoint->bEndpointAddress),
-			      port->bulk_in_buffer, buffer_size, 
-			      ((serial->type->read_bulk_callback) ?
-			       serial->type->read_bulk_callback :
-			       generic_read_bulk_callback), 
-			      port);
+		usb_fill_bulk_urb (port->read_urb, dev,
+				   usb_rcvbulkpipe (dev,
+					   	    endpoint->bEndpointAddress),
+				   port->bulk_in_buffer, buffer_size,
+				   ((serial->type->read_bulk_callback) ? 
+				     serial->type->read_bulk_callback : 
+				     generic_read_bulk_callback),
+				   port);
 	}
 
 	for (i = 0; i < num_bulk_out; ++i) {
@@ -1228,13 +1227,14 @@
 			err("Couldn't allocate bulk_out_buffer");
 			goto probe_error;
 		}
-		FILL_BULK_URB(port->write_urb, dev, 
-			      usb_sndbulkpipe(dev, endpoint->bEndpointAddress),
-			      port->bulk_out_buffer, buffer_size,
-			      ((serial->type->write_bulk_callback) ? 
-			       serial->type->write_bulk_callback : 
-			       generic_write_bulk_callback), 
-			      port);
+		usb_fill_bulk_urb (port->write_urb, dev,
+				   usb_sndbulkpipe (dev,
+						    endpoint->bEndpointAddress),
+				   port->bulk_out_buffer, buffer_size, 
+				   ((serial->type->write_bulk_callback) ? 
+				     serial->type->write_bulk_callback : 
+				     generic_write_bulk_callback),
+				   port);
 	}
 
 	for (i = 0; i < num_interrupt_in; ++i) {
@@ -1252,12 +1252,12 @@
 			err("Couldn't allocate interrupt_in_buffer");
 			goto probe_error;
 		}
-		FILL_INT_URB(port->interrupt_in_urb, dev, 
-			     usb_rcvintpipe(dev, endpoint->bEndpointAddress),
-			     port->interrupt_in_buffer, buffer_size, 
-			     serial->type->read_int_callback,
-			     port, 
-			     endpoint->bInterval);
+		usb_fill_int_urb (port->interrupt_in_urb, dev, 
+				  usb_rcvintpipe (dev,
+						  endpoint->bEndpointAddress),
+				  port->interrupt_in_buffer, buffer_size, 
+				  serial->type->read_int_callback, port, 
+				  endpoint->bInterval);
 	}
 
 	/* initialize some parts of the port structures */
@@ -1335,7 +1335,7 @@
 		serial_shutdown (serial);
 
 		for (i = 0; i < serial->num_ports; ++i)
-			serial->port[i].active = 0;
+			serial->port[i].open_count = 0;
 
 		for (i = 0; i < serial->num_bulk_in; ++i) {
 			port = &serial->port[i];
diff -urN linux-2.5.1-pre7/drivers/usb/serial/visor.c linux/drivers/usb/serial/visor.c
--- linux-2.5.1-pre7/drivers/usb/serial/visor.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/visor.c	Sat Dec  8 21:05:03 2001
@@ -127,7 +127,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.6"
+#define DRIVER_VERSION "v1.7"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
 #define DRIVER_DESC "USB HandSpring Visor, Palm m50x, Sony Clié driver"
 
@@ -251,8 +251,7 @@
 	++port->open_count;
 	MOD_INC_USE_COUNT;
 	
-	if (!port->active) {
-		port->active = 1;
+	if (port->open_count == 1) {
 		bytes_in = 0;
 		bytes_out = 0;
 
@@ -262,10 +261,12 @@
 		port->tty->low_latency = 1;
 		
 		/* Start reading from the device */
-		FILL_BULK_URB(port->read_urb, serial->dev, 
-			      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
-			      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
-			      visor_read_bulk_callback, port);
+		usb_fill_bulk_urb (port->read_urb, serial->dev,
+				   usb_rcvbulkpipe (serial->dev, 
+						    port->bulk_in_endpointAddress),
+				   port->read_urb->transfer_buffer,
+				   port->read_urb->transfer_buffer_length,
+				   visor_read_bulk_callback, port);
 		result = usb_submit_urb(port->read_urb);
 		if (result)
 			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
@@ -314,7 +315,6 @@
 			/* shutdown our bulk read */
 			usb_unlink_urb (port->read_urb);
 		}
-		port->active = 0;
 		port->open_count = 0;
 	}
 	up (&port->sem);
@@ -375,8 +375,11 @@
 		usb_serial_debug_data (__FILE__, __FUNCTION__, transfer_size, urb->transfer_buffer);
 
 		/* build up our urb */
-		FILL_BULK_URB (urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), 
-				urb->transfer_buffer, transfer_size, visor_write_bulk_callback, port);
+		usb_fill_bulk_urb (urb, serial->dev,
+				   usb_sndbulkpipe (serial->dev,
+						    port->bulk_out_endpointAddress),
+				   urb->transfer_buffer, transfer_size, 
+				   visor_write_bulk_callback, port);
 		urb->transfer_flags |= USB_QUEUE_BULK;
 
 		/* send it down the pipe */
@@ -506,10 +509,12 @@
 	}
 
 	/* Continue trying to always read  */
-	FILL_BULK_URB(port->read_urb, serial->dev, 
-		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
-		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
-		      visor_read_bulk_callback, port);
+	usb_fill_bulk_urb (port->read_urb, serial->dev,
+			   usb_rcvbulkpipe (serial->dev,
+					    port->bulk_in_endpointAddress),
+			   port->read_urb->transfer_buffer,
+			   port->read_urb->transfer_buffer_length,
+			   visor_read_bulk_callback, port);
 	result = usb_submit_urb(port->read_urb);
 	if (result)
 		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
@@ -647,11 +652,8 @@
 	dbg (__FUNCTION__);
 
 	/* stop reads and writes on all ports */
-	for (i=0; i < serial->num_ports; ++i) {
-		while (serial->port[i].open_count > 0) {
-			visor_close (&serial->port[i], NULL);
-		}
-	}
+	for (i=0; i < serial->num_ports; ++i)
+		serial->port[i].open_count = 0;
 }
 
 
diff -urN linux-2.5.1-pre7/drivers/usb/serial/whiteheat.c linux/drivers/usb/serial/whiteheat.c
--- linux-2.5.1-pre7/drivers/usb/serial/whiteheat.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/serial/whiteheat.c	Sat Dec  8 21:05:03 2001
@@ -309,9 +309,7 @@
 	++port->open_count;
 	MOD_INC_USE_COUNT;
 	
-	if (!port->active) {
-		port->active = 1;
-
+	if (port->open_count == 1) {
 		/* set up some stuff for our command port */
 		command_port = &port->serial->port[COMMAND_PORT];
 		if (command_port->private == NULL) {
@@ -391,7 +389,7 @@
 		/* shutdown our bulk reads and writes */
 		usb_unlink_urb (port->write_urb);
 		usb_unlink_urb (port->read_urb);
-		port->active = 0;
+		port->open_count = 0;
 	}
 	MOD_DEC_USE_COUNT;
 	up (&port->sem);
diff -urN linux-2.5.1-pre7/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c
--- linux-2.5.1-pre7/drivers/usb/usb-ohci.c	Fri Nov  9 13:41:42 2001
+++ linux/drivers/usb/usb-ohci.c	Sat Dec  8 21:05:04 2001
@@ -485,7 +485,7 @@
 
 			/* implicitly requeued */
   			urb->actual_length = 0;
-  			urb->status = USB_ST_URB_PENDING;
+  			urb->status = -EINPROGRESS;
   			if (urb_priv->state != URB_DEL)
   				td_submit_urb (urb);
   			break;
@@ -502,7 +502,7 @@
 				urb->complete (urb);
 				spin_lock_irqsave (&usb_ed_lock, flags);
 				urb->actual_length = 0;
-  				urb->status = USB_ST_URB_PENDING;
+  				urb->status = -EINPROGRESS;
   				urb->start_frame = urb_priv->ed->last_iso + 1;
   				if (urb_priv->state != URB_DEL) {
   					for (i = 0; i < urb->number_of_packets; i++) {
@@ -673,7 +673,7 @@
 
 	urb->actual_length = 0;
 	urb->hcpriv = urb_priv;
-	urb->status = USB_ST_URB_PENDING;
+	urb->status = -EINPROGRESS;
 
 	/* link the ed into a chain if is not already */
 	if (ed->state != ED_OPER)
@@ -737,7 +737,7 @@
 	if (usb_pipedevice (urb->pipe) == ohci->rh.devnum)
 		return rh_unlink_urb (urb);
 
-	if (urb->hcpriv && (urb->status == USB_ST_URB_PENDING)) { 
+	if (urb->hcpriv && (urb->status == -EINPROGRESS)) { 
 		if (!ohci->disabled) {
 			urb_priv_t  * urb_priv;
 
@@ -777,11 +777,11 @@
 
 				/* wait until all TDs are deleted */
 				set_current_state(TASK_UNINTERRUPTIBLE);
-				while (timeout && (urb->status == USB_ST_URB_PENDING))
+				while (timeout && (urb->status == -EINPROGRESS))
 					timeout = schedule_timeout (timeout);
 				set_current_state(TASK_RUNNING);
 				remove_wait_queue (&unlink_wakeup, &wait); 
-				if (urb->status == USB_ST_URB_PENDING) {
+				if (urb->status == -EINPROGRESS) {
 					err ("unlink URB timeout");
 					return -ETIMEDOUT;
 				}
diff -urN linux-2.5.1-pre7/drivers/usb/usb-ohci.h linux/drivers/usb/usb-ohci.h
--- linux-2.5.1-pre7/drivers/usb/usb-ohci.h	Wed Oct 24 08:26:12 2001
+++ linux/drivers/usb/usb-ohci.h	Sat Dec  8 21:05:04 2001
@@ -11,22 +11,22 @@
 static int cc_to_error[16] = { 
 
 /* mapping of the OHCI CC status to error codes */ 
-	/* No  Error  */               USB_ST_NOERROR,
-	/* CRC Error  */               USB_ST_CRC,
-	/* Bit Stuff  */               USB_ST_BITSTUFF,
-	/* Data Togg  */               USB_ST_CRC,
-	/* Stall      */               USB_ST_STALL,
-	/* DevNotResp */               USB_ST_NORESPONSE,
-	/* PIDCheck   */               USB_ST_BITSTUFF,
-	/* UnExpPID   */               USB_ST_BITSTUFF,
-	/* DataOver   */               USB_ST_DATAOVERRUN,
-	/* DataUnder  */               USB_ST_DATAUNDERRUN,
-	/* reservd    */               USB_ST_NORESPONSE,
-	/* reservd    */               USB_ST_NORESPONSE,
-	/* BufferOver */               USB_ST_BUFFEROVERRUN,
-	/* BuffUnder  */               USB_ST_BUFFERUNDERRUN,
-	/* Not Access */               USB_ST_NORESPONSE,
-	/* Not Access */               USB_ST_NORESPONSE 
+	/* No  Error  */	0,
+	/* CRC Error  */	-EILSEQ,
+	/* Bit Stuff  */	-EPROTO,
+	/* Data Togg  */	-EILSEQ,
+	/* Stall      */	-EPIPE,
+	/* DevNotResp */	-ETIMEDOUT,
+	/* PIDCheck   */	-EPROTO,
+	/* UnExpPID   */	-EPROTO,
+	/* DataOver   */	-EOVERFLOW,
+	/* DataUnder  */	-EREMOTEIO,
+	/* reservd    */	-ETIMEDOUT,
+	/* reservd    */	-ETIMEDOUT,
+	/* BufferOver */	-ECOMM,
+	/* BuffUnder  */	-ENOSR,
+	/* Not Access */	-ETIMEDOUT,
+	/* Not Access */	-ETIMEDOUT 
 };
 
 #include <linux/config.h>
diff -urN linux-2.5.1-pre7/drivers/usb/usb.c linux/drivers/usb/usb.c
--- linux-2.5.1-pre7/drivers/usb/usb.c	Sat Dec  8 21:04:23 2001
+++ linux/drivers/usb/usb.c	Sat Dec  8 21:05:04 2001
@@ -106,8 +106,8 @@
  *	Goes through all unclaimed USB interfaces, and offers them to all
  *	registered USB drivers through the 'probe' function.
  *	This will automatically be called after usb_register is called.
- *	It is called by some of the USB subsystems after one of their subdrivers
- *	are registered.
+ *	It is called by some of the subsystems layered over USB
+ *	after one of their subdrivers are registered.
  */
 void usb_scan_devices(void)
 {
@@ -292,7 +292,7 @@
  * bustime is from calc_bus_time(), but converted to microseconds.
  *
  * returns <bustime in us> if successful,
- * or USB_ST_BANDWIDTH_ERROR if bandwidth request fails.
+ * or -ENOSPC if bandwidth request fails.
  *
  * FIXME:
  * This initial implementation does not use Endpoint.bInterval
@@ -333,7 +333,7 @@
 
 	if (!usb_bandwidth_option)	/* don't enforce it */
 		return (bustime);
-	return (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ? bustime : USB_ST_BANDWIDTH_ERROR;
+	return (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ? bustime : -ENOSPC;
 }
 
 void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc)
@@ -1121,7 +1121,10 @@
  * any transfer flags.
  *
  * Successful submissions return 0; otherwise this routine returns a
- * negative error number.
+ * negative error number.  If the submission is successful, the complete
+ * fuction of the urb will be called when the USB host driver is
+ * finished with the urb (either a successful transmission, or some
+ * error case.)
  *
  * Unreserved Bandwidth Transfers:
  *
@@ -1198,12 +1201,14 @@
 		return -ENODEV;
 }
 /*-------------------------------------------------------------------*
- *                     COMPLETION HANDLERS                           *
+ *                         SYNCHRONOUS CALLS                         *
  *-------------------------------------------------------------------*/
 
-/*-------------------------------------------------------------------*
- * completion handler for compatibility wrappers (sync control/bulk) *
- *-------------------------------------------------------------------*/
+struct usb_api_data {
+	wait_queue_head_t wqh;
+	int done;
+};
+
 static void usb_api_blocking_completion(urb_t *urb)
 {
 	struct usb_api_data *awd = (struct usb_api_data *)urb->context;
@@ -1213,10 +1218,6 @@
 	wake_up(&awd->wqh);
 }
 
-/*-------------------------------------------------------------------*
- *                         SYNCHRONOUS CALLS                         *
- *-------------------------------------------------------------------*/
-
 // Starts urb and waits for completion or timeout
 static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length)
 { 
@@ -1723,7 +1724,8 @@
 	return size;
 }
 
-// usbcore-internal:  enumeration/hub only!!
+// hub-only!! ... and only exported for reset/reinit path.
+// otherwise used internally on disconnect/destroy path
 void usb_destroy_configuration(struct usb_device *dev)
 {
 	int c, i, j, k;
@@ -1955,18 +1957,14 @@
  * These are the actual routines to send
  * and receive control messages.
  */
-#ifdef CONFIG_USB_LONG_TIMEOUT
-#define GET_TIMEOUT 4
-#else
-#define GET_TIMEOUT 3
-#endif
-#define SET_TIMEOUT 3
 
-// hub driver only!!! for enumeration
+// hub-only!! ... and only exported for reset/reinit path.
+// otherwise used internally, for usb_new_device()
 int usb_set_address(struct usb_device *dev)
 {
 	return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS,
-		0, dev->devnum, 0, NULL, 0, HZ * GET_TIMEOUT);
+		// FIXME USB_CTRL_SET_TIMEOUT
+		0, dev->devnum, 0, NULL, 0, HZ * USB_CTRL_GET_TIMEOUT);
 }
 
 /**
@@ -1984,7 +1982,7 @@
  * Configuration descriptors (USB_DT_CONFIG) are part of the device
  * structure, at least for the current configuration.
  * In addition to a number of USB-standard descriptors, some
- * devices also use vendor-specific descriptors.
+ * devices also use class-specific or vendor-specific descriptors.
  *
  * This call is synchronous, and may not be used in an interrupt context.
  *
@@ -1999,24 +1997,17 @@
 	memset(buf,0,size);	// Make sure we parse really received data
 
 	while (i--) {
+		/* retries if the returned length was 0; flakey device */
 		if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
-			(type << 8) + index, 0, buf, size, HZ * GET_TIMEOUT)) > 0 ||
-		     result == -EPIPE)
-			break;	/* retry if the returned length was 0; flaky device */
+				    USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+				    (type << 8) + index, 0, buf, size,
+				    HZ * USB_CTRL_GET_TIMEOUT)) > 0
+				|| result == -EPIPE)
+			break;
 	}
 	return result;
 }
 
-// FIXME  Doesn't use USB_DT_CLASS ... but hid-core.c expects it this way
-int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
-		unsigned char type, unsigned char id, void *buf, int size)
-{
-	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-		USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
-		(type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT);
-}
-
 /**
  * usb_get_string - gets a string descriptor
  * @dev: the device whose string descriptor is being retrieved
@@ -2042,7 +2033,8 @@
 {
 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 		USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
-		(USB_DT_STRING << 8) + index, langid, buf, size, HZ * GET_TIMEOUT);
+		(USB_DT_STRING << 8) + index, langid, buf, size,
+		HZ * USB_CTRL_GET_TIMEOUT);
 }
 
 /**
@@ -2100,40 +2092,13 @@
 int usb_get_status(struct usb_device *dev, int type, int target, void *data)
 {
 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-		USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, HZ * GET_TIMEOUT);
+		USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2,
+		HZ * USB_CTRL_GET_TIMEOUT);
 }
 
-// FIXME hid-specific !!  DOES NOT BELONG HERE
-int usb_get_protocol(struct usb_device *dev, int ifnum)
-{
-	unsigned char type;
-	int ret;
-
-	if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-	    USB_REQ_GET_PROTOCOL, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-	    0, ifnum, &type, 1, HZ * GET_TIMEOUT)) < 0)
-		return ret;
 
-	return type;
-}
-
-// FIXME hid-specific !!  DOES NOT BELONG HERE
-int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol)
-{
-	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-		USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-		protocol, ifnum, NULL, 0, HZ * SET_TIMEOUT);
-}
-
-// FIXME hid-specific !!  DOES NOT BELONG HERE
-int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id)
-{
-	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-		USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-		(duration << 8) | report_id, ifnum, NULL, 0, HZ * SET_TIMEOUT);
-}
-
-// hub-only!!
+// hub-only!! ... and only exported for reset/reinit path.
+// otherwise used internally, for config/altsetting reconfig.
 void usb_set_maxpacket(struct usb_device *dev)
 {
 	int i, b;
@@ -2197,7 +2162,8 @@
 */
 
 	result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-		USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, HZ * SET_TIMEOUT);
+		USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0,
+		HZ * USB_CTRL_SET_TIMEOUT);
 
 	/* don't clear if failed */
 	if (result < 0)
@@ -2211,7 +2177,8 @@
 
 	result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,
-		buffer, sizeof(status), HZ * SET_TIMEOUT);
+		// FIXME USB_CTRL_GET_TIMEOUT, yes?  why not usb_get_status() ?
+		buffer, sizeof(status), HZ * USB_CTRL_SET_TIMEOUT);
 
 	memcpy(&status, buffer, sizeof(status));
 	kfree(buffer);
@@ -2327,7 +2294,8 @@
 	}
 
 	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-	    USB_REQ_SET_CONFIGURATION, 0, configuration, 0, NULL, 0, HZ * SET_TIMEOUT)) < 0)
+			USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
+			NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0)
 		return ret;
 
 	dev->actconfig = cp;
@@ -2338,23 +2306,8 @@
 	return 0;
 }
 
-// FIXME hid-specific !!  DOES NOT BELONG HERE
-int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size)
-{
-	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-		USB_REQ_GET_REPORT, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-		(type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT);
-}
-
-// FIXME hid-specific !!  DOES NOT BELONG HERE
-int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size)
-{
-	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-		USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-		(type << 8) + id, ifnum, buf, size, HZ);
-}
-
-// hub driver only !!
+// hub-only!! ... and only in reset path, or usb_new_device()
+// (used by real hubs and virtual root hubs)
 int usb_get_configuration(struct usb_device *dev)
 {
 	int result;
@@ -2761,33 +2714,28 @@
 EXPORT_SYMBOL(usb_claim_bandwidth);
 EXPORT_SYMBOL(usb_release_bandwidth);
 
-EXPORT_SYMBOL(usb_set_address);
-EXPORT_SYMBOL(usb_get_descriptor);
-EXPORT_SYMBOL(usb_get_class_descriptor);
 EXPORT_SYMBOL(__usb_get_extra_descriptor);
-EXPORT_SYMBOL(usb_get_device_descriptor);
-EXPORT_SYMBOL(usb_get_string);
-EXPORT_SYMBOL(usb_string);
-EXPORT_SYMBOL(usb_get_protocol);
-EXPORT_SYMBOL(usb_set_protocol);
-EXPORT_SYMBOL(usb_get_report);
-EXPORT_SYMBOL(usb_set_report);
-EXPORT_SYMBOL(usb_set_idle);
-EXPORT_SYMBOL(usb_clear_halt);
-EXPORT_SYMBOL(usb_set_interface);
-EXPORT_SYMBOL(usb_get_configuration);
-EXPORT_SYMBOL(usb_set_configuration);
-EXPORT_SYMBOL(usb_get_status);
 
 EXPORT_SYMBOL(usb_get_current_frame_number);
 
+// asynchronous request completion model
 EXPORT_SYMBOL(usb_alloc_urb);
 EXPORT_SYMBOL(usb_free_urb);
 EXPORT_SYMBOL(usb_submit_urb);
 EXPORT_SYMBOL(usb_unlink_urb);
 
+// synchronous request completion model
 EXPORT_SYMBOL(usb_control_msg);
 EXPORT_SYMBOL(usb_bulk_msg);
+// synchronous control message convenience routines
+EXPORT_SYMBOL(usb_get_descriptor);
+EXPORT_SYMBOL(usb_get_device_descriptor);
+EXPORT_SYMBOL(usb_get_status);
+EXPORT_SYMBOL(usb_get_string);
+EXPORT_SYMBOL(usb_string);
+EXPORT_SYMBOL(usb_clear_halt);
+EXPORT_SYMBOL(usb_set_configuration);
+EXPORT_SYMBOL(usb_set_interface);
 
 EXPORT_SYMBOL(usb_devfs_handle);
 MODULE_LICENSE("GPL");
diff -urN linux-2.5.1-pre7/drivers/usb/usbkbd.c linux/drivers/usb/usbkbd.c
--- linux-2.5.1-pre7/drivers/usb/usbkbd.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/usb/usbkbd.c	Sat Dec  8 21:05:04 2001
@@ -35,6 +35,9 @@
 #include <linux/init.h>
 #include <linux/usb.h>
 
+#define	_HID_BOOT_PROTOCOL
+#include "hid.h"
+
 /*
  * Version Information
  */
@@ -192,8 +195,8 @@
 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
-	usb_set_protocol(dev, interface->bInterfaceNumber, 0);
-	usb_set_idle(dev, interface->bInterfaceNumber, 0, 0);
+	hid_set_protocol(dev, interface->bInterfaceNumber, 0);
+	hid_set_idle(dev, interface->bInterfaceNumber, 0, 0);
 
 	if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL;
 	memset(kbd, 0, sizeof(struct usb_kbd));
@@ -216,7 +219,7 @@
 		usb_kbd_irq, kbd, endpoint->bInterval);
 
 	kbd->dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
-	kbd->dr.request = USB_REQ_SET_REPORT;
+	kbd->dr.request = HID_REQ_SET_REPORT;
 	kbd->dr.value = 0x200;
 	kbd->dr.index = interface->bInterfaceNumber;
 	kbd->dr.length = 1;
diff -urN linux-2.5.1-pre7/drivers/usb/usbmouse.c linux/drivers/usb/usbmouse.c
--- linux-2.5.1-pre7/drivers/usb/usbmouse.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/usb/usbmouse.c	Sat Dec  8 21:05:04 2001
@@ -35,6 +35,9 @@
 #include <linux/init.h>
 #include <linux/usb.h>
 
+#define	_HID_BOOT_PROTOCOL
+#include "hid.h"
+
 /*
  * Version Information
  */
@@ -118,7 +121,7 @@
 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
-	usb_set_idle(dev, interface->bInterfaceNumber, 0, 0);
+	hid_set_idle(dev, interface->bInterfaceNumber, 0, 0);
 
 	if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL;
 	memset(mouse, 0, sizeof(struct usb_mouse));
diff -urN linux-2.5.1-pre7/drivers/usb/usbnet.c linux/drivers/usb/usbnet.c
--- linux-2.5.1-pre7/drivers/usb/usbnet.c	Wed Nov 21 09:51:08 2001
+++ linux/drivers/usb/usbnet.c	Sat Dec  8 21:05:04 2001
@@ -1535,7 +1535,7 @@
 	struct skb_data		*entry = (struct skb_data *) skb->cb;
 	struct usbnet		*dev = entry->dev;
 
-	if (urb->status == USB_ST_STALL) {
+	if (urb->status == -EPIPE) {
 		if (dev->ctrl_task.sync == 0) {
 			dev->ctrl_task.routine = tx_clear_halt;
 			dev->ctrl_task.data = dev;
@@ -1868,6 +1868,11 @@
 #ifdef	CONFIG_USB_AN2720
 {
 	USB_DEVICE (0x0547, 0x2720),	// AnchorChips defaults
+	driver_info:	(unsigned long) &an2720_info,
+},
+
+{
+	USB_DEVICE (0x0547, 0x2727),	// Xircom PGUNET
 	driver_info:	(unsigned long) &an2720_info,
 },
 #endif
diff -urN linux-2.5.1-pre7/drivers/usb/uss720.c linux/drivers/usb/uss720.c
--- linux-2.5.1-pre7/drivers/usb/uss720.c	Sat Oct 20 19:13:11 2001
+++ linux/drivers/usb/uss720.c	Sat Dec  8 21:05:04 2001
@@ -193,7 +193,7 @@
 	struct parport *pp = (struct parport *)dev_id;
 	struct parport_uss720_private *priv = pp->private_data;	
 
-	if (usbstatus != USB_ST_NOERROR || len < 4 || !buffer)
+	if (usbstatus != 0 || len < 4 || !buffer)
 		return 1;
 	memcpy(priv->reg, buffer, 4);
 	/* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
diff -urN linux-2.5.1-pre7/fs/bio.c linux/fs/bio.c
--- linux-2.5.1-pre7/fs/bio.c	Sat Dec  8 21:04:23 2001
+++ linux/fs/bio.c	Sat Dec  8 21:05:04 2001
@@ -47,7 +47,6 @@
 struct biovec_pool {
 	int bp_size;
 	kmem_cache_t *bp_cachep;
-	wait_queue_head_t bp_wait;
 };
 
 static struct biovec_pool bvec_list[BIOVEC_NR_POOLS];
@@ -161,32 +160,22 @@
 	if ((bvl = kmem_cache_alloc(bp->bp_cachep, gfp_mask)))
 		goto out_gotit;
 
-	/*
-	 * we need slab reservations for this to be completely
-	 * deadlock free...
-	 */
-	if (BIO_CAN_WAIT(gfp_mask)) {
-		DECLARE_WAITQUEUE(wait, current);
+	if (!BIO_CAN_WAIT(gfp_mask))
+		return NULL;
 
-		add_wait_queue_exclusive(&bp->bp_wait, &wait);
-		for (;;) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			bvl = kmem_cache_alloc(bp->bp_cachep, gfp_mask);
-			if (bvl)
-				goto out_gotit;
+	do {
+		bvl = kmem_cache_alloc(bp->bp_cachep, gfp_mask);
+		if (bvl)
+			break;
 
-			run_task_queue(&tq_disk);
-			schedule();
-		}
-		remove_wait_queue(&bp->bp_wait, &wait);
+		run_task_queue(&tq_disk);
 		__set_current_state(TASK_RUNNING);
-	}
+		current->policy |= SCHED_YIELD;
+		schedule();
+	} while (1);
 
-	if (bvl) {
 out_gotit:
-		memset(bvl, 0, bp->bp_size);
-	}
-
+	memset(bvl, 0, bp->bp_size);
 	return bvl;
 }
 
@@ -202,10 +191,8 @@
 	/*
 	 * cloned bio doesn't own the veclist
 	 */
-	if (!(bio->bi_flags & (1 << BIO_CLONED))) {
+	if (!(bio->bi_flags & (1 << BIO_CLONED)))
 		kmem_cache_free(bp->bp_cachep, bio->bi_io_vec);
-		wake_up_nr(&bp->bp_wait, 1);
-	}
 
 	bio_pool_put(bio);
 }
@@ -326,31 +313,46 @@
 }
 
 /**
- *	bio_clone	-	duplicate a bio
- *	@bio: bio to clone
- *	@gfp_mask: allocation priority
+ * 	__bio_clone	-	clone a bio
+ * 	@bio: destination bio
+ * 	@bio_src: bio to clone
  *
- *	Duplicate a &bio. Caller will own the returned bio, but not
+ *	Clone a &bio. Caller will own the returned bio, but not
  *	the actual data it points to. Reference count of returned
  * 	bio will be one.
  */
-struct bio *bio_clone(struct bio *bio, int gfp_mask)
+inline void __bio_clone(struct bio *bio, struct bio *bio_src)
 {
-	struct bio *b = bio_alloc(gfp_mask, 0);
+	bio->bi_io_vec = bio_src->bi_io_vec;
 
-	if (b) {
-		b->bi_io_vec = bio->bi_io_vec;
+	bio->bi_sector = bio_src->bi_sector;
+	bio->bi_dev = bio_src->bi_dev;
+	bio->bi_flags |= 1 << BIO_CLONED;
+	bio->bi_rw = bio_src->bi_rw;
 
-		b->bi_sector = bio->bi_sector;
-		b->bi_dev = bio->bi_dev;
-		b->bi_flags |= 1 << BIO_CLONED;
-		b->bi_rw = bio->bi_rw;
+	/*
+	 * notes -- maybe just leave bi_idx alone. bi_max has no used
+	 * on a cloned bio
+	 */
+	bio->bi_vcnt = bio_src->bi_vcnt;
+	bio->bi_idx = bio_src->bi_idx;
+	bio->bi_size = bio_src->bi_size;
+	bio->bi_max = bio_src->bi_max;
+}
 
-		b->bi_vcnt = bio->bi_vcnt;
-		b->bi_idx = bio->bi_idx;
-		b->bi_size = bio->bi_size;
-		b->bi_max = bio->bi_max;
-	}
+/**
+ *	bio_clone	-	clone a bio
+ *	@bio: bio to clone
+ *	@gfp_mask: allocation priority
+ *
+ * 	Like __bio_clone, only also allocates the returned bio
+ */
+struct bio *bio_clone(struct bio *bio, int gfp_mask)
+{
+	struct bio *b = bio_alloc(gfp_mask, 0);
+
+	if (b)
+		__bio_clone(b, bio);
 
 	return b;
 }
@@ -667,7 +669,6 @@
 			panic("biovec: can't init slab pools\n");
 
 		bp->bp_size = size;
-		init_waitqueue_head(&bp->bp_wait);
 	}
 }
 
@@ -696,4 +697,5 @@
 EXPORT_SYMBOL(bio_endio);
 EXPORT_SYMBOL(bio_init);
 EXPORT_SYMBOL(bio_copy);
+EXPORT_SYMBOL(__bio_clone);
 EXPORT_SYMBOL(bio_clone);
diff -urN linux-2.5.1-pre7/include/asm-alpha/page.h linux/include/asm-alpha/page.h
--- linux-2.5.1-pre7/include/asm-alpha/page.h	Sat Dec  8 21:04:23 2001
+++ linux/include/asm-alpha/page.h	Sat Dec  8 21:05:04 2001
@@ -67,18 +67,6 @@
 
 #define PAGE_BUG(page)	BUG()
 
-#define BUG_ON(condition)			\
-	do {					\
-		if (unlikely((long)(condition)))\
-			BUG();			\
-	} while (0)
-
-#define BUG_ON(condition)			\
-	do {					\
-		if (unlikely((int)(condition)))	\
-			BUG();			\
-	} while (0)
-
 /* Pure 2^n version of get_order */
 extern __inline__ int get_order(unsigned long size)
 {
diff -urN linux-2.5.1-pre7/include/asm-i386/page.h linux/include/asm-i386/page.h
--- linux-2.5.1-pre7/include/asm-i386/page.h	Sat Dec  8 21:04:23 2001
+++ linux/include/asm-i386/page.h	Thu Nov 22 11:46:18 2001
@@ -101,12 +101,6 @@
 	BUG(); \
 } while (0)
 
-#define BUG_ON(condition)			\
-	do {					\
-		if (unlikely((int)(condition)))	\
-			BUG();			\
-	} while (0)
-
 /* Pure 2^n version of get_order */
 static __inline__ int get_order(unsigned long size)
 {
diff -urN linux-2.5.1-pre7/include/linux/bio.h linux/include/linux/bio.h
--- linux-2.5.1-pre7/include/linux/bio.h	Sat Dec  8 21:04:23 2001
+++ linux/include/linux/bio.h	Sat Dec  8 21:05:04 2001
@@ -168,6 +168,7 @@
 
 extern int bio_endio(struct bio *, int, int);
 
+extern inline void __bio_clone(struct bio *, struct bio *);
 extern struct bio *bio_clone(struct bio *, int);
 extern struct bio *bio_copy(struct bio *, int, int);
 
diff -urN linux-2.5.1-pre7/include/linux/blk.h linux/include/linux/blk.h
--- linux-2.5.1-pre7/include/linux/blk.h	Sat Dec  8 21:04:23 2001
+++ linux/include/linux/blk.h	Sat Dec  8 21:05:04 2001
@@ -77,12 +77,21 @@
 	return rq;
 }
 
-extern inline void elv_add_request(request_queue_t *q, struct request *rq)
-{
-	blk_plug_device(q);
-	q->elevator.elevator_add_req_fn(q, rq, q->queue_head.prev);
-}
+#define __elv_add_request_core(q, rq, where, plug)			\
+	do {								\
+		if ((plug))						\
+			blk_plug_device((q));				\
+		(q)->elevator.elevator_add_req_fn((q), (rq), (where));	\
+	} while (0)
 
+#define __elv_add_request(q, rq, back, p)				      \
+	if ((back))							      \
+		__elv_add_request_core((q), (rq), (q)->queue_head.prev, (p)); \
+	else								      \
+		__elv_add_request_core((q), (rq), &(q)->queue_head, 0);	      \
+
+#define elv_add_request(q, rq, back) __elv_add_request((q), (rq), (back), 1)
+	
 #if defined(MAJOR_NR) || defined(IDE_DRIVER)
 
 #undef DEVICE_ON
diff -urN linux-2.5.1-pre7/include/linux/kernel.h linux/include/linux/kernel.h
--- linux-2.5.1-pre7/include/linux/kernel.h	Thu Nov 22 11:46:18 2001
+++ linux/include/linux/kernel.h	Sat Dec  8 21:05:04 2001
@@ -11,6 +11,7 @@
 #include <linux/linkage.h>
 #include <linux/stddef.h>
 #include <linux/types.h>
+#include <linux/compiler.h>
 
 /* Optimization barrier */
 /* The "volatile" is due to gcc bugs */
@@ -176,4 +177,5 @@
 	char _f[20-2*sizeof(long)-sizeof(int)];	/* Padding: libc5 uses this.. */
 };
 
+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
 #endif
diff -urN linux-2.5.1-pre7/include/linux/usb.h linux/include/linux/usb.h
--- linux-2.5.1-pre7/include/linux/usb.h	Sat Dec  8 21:04:23 2001
+++ linux/include/linux/usb.h	Sat Dec  8 21:05:04 2001
@@ -11,10 +11,13 @@
 #define USB_CLASS_COMM			2
 #define USB_CLASS_HID			3
 #define USB_CLASS_PHYSICAL		5
+#define USB_CLASS_STILL_IMAGE		6
 #define USB_CLASS_PRINTER		7
 #define USB_CLASS_MASS_STORAGE		8
 #define USB_CLASS_HUB			9
-#define USB_CLASS_DATA			10
+#define USB_CLASS_CDC_DATA		0x0a
+#define USB_CLASS_CSCID		0x0b /* chip+ smart card */
+#define USB_CLASS_CONTENT_SEC		0x0d /* content security */
 #define USB_CLASS_APP_SPEC		0xfe
 #define USB_CLASS_VENDOR_SPEC		0xff
 
@@ -43,31 +46,6 @@
 #define USB_DIR_IN			0x80
 
 /*
- * Descriptor types
- */
-#define USB_DT_DEVICE			0x01
-#define USB_DT_CONFIG			0x02
-#define USB_DT_STRING			0x03
-#define USB_DT_INTERFACE		0x04
-#define USB_DT_ENDPOINT			0x05
-
-#define USB_DT_HID			(USB_TYPE_CLASS | 0x01)
-#define USB_DT_REPORT			(USB_TYPE_CLASS | 0x02)
-#define USB_DT_PHYSICAL			(USB_TYPE_CLASS | 0x03)
-#define USB_DT_HUB			(USB_TYPE_CLASS | 0x09)
-
-/*
- * Descriptor sizes per descriptor type
- */
-#define USB_DT_DEVICE_SIZE		18
-#define USB_DT_CONFIG_SIZE		9
-#define USB_DT_INTERFACE_SIZE		9
-#define USB_DT_ENDPOINT_SIZE		7
-#define USB_DT_ENDPOINT_AUDIO_SIZE	9	/* Audio extension */
-#define USB_DT_HUB_NONVAR_SIZE		7
-#define USB_DT_HID_SIZE			9
-
-/*
  * Endpoints
  */
 #define USB_ENDPOINT_NUMBER_MASK	0x0f	/* in bEndpointAddress */
@@ -115,16 +93,6 @@
 #define USB_REQ_SET_INTERFACE		0x0B
 #define USB_REQ_SYNCH_FRAME		0x0C
 
-/*
- * HID requests
- */
-#define USB_REQ_GET_REPORT		0x01
-#define USB_REQ_GET_IDLE		0x02
-#define USB_REQ_GET_PROTOCOL		0x03
-#define USB_REQ_SET_REPORT		0x09
-#define USB_REQ_SET_IDLE		0x0A
-#define USB_REQ_SET_PROTOCOL		0x0B
-
 
 #ifdef __KERNEL__
 
@@ -158,32 +126,6 @@
 } devrequest __attribute__ ((packed));
 
 /*
- * USB-status codes:
- * USB_ST* maps to -E* and should go away in the future
- */
-
-#define USB_ST_NOERROR		0
-#define USB_ST_CRC		(-EILSEQ)
-#define USB_ST_BITSTUFF		(-EPROTO)
-#define USB_ST_NORESPONSE	(-ETIMEDOUT)			/* device not responding/handshaking */
-#define USB_ST_DATAOVERRUN	(-EOVERFLOW)
-#define USB_ST_DATAUNDERRUN	(-EREMOTEIO)
-#define USB_ST_BUFFEROVERRUN	(-ECOMM)
-#define USB_ST_BUFFERUNDERRUN	(-ENOSR)
-#define USB_ST_INTERNALERROR	(-EPROTO) 			/* unknown error */
-#define USB_ST_SHORT_PACKET    	(-EREMOTEIO)
-#define USB_ST_PARTIAL_ERROR  	(-EXDEV)			/* ISO transfer only partially completed */
-#define USB_ST_URB_KILLED     	(-ENOENT)			/* URB canceled by user */
-#define USB_ST_URB_PENDING       (-EINPROGRESS)
-#define USB_ST_REMOVED		(-ENODEV) 			/* device not existing or removed */
-#define USB_ST_TIMEOUT		(-ETIMEDOUT)			/* communication timed out, also in urb->status**/
-#define USB_ST_NOTSUPPORTED	(-ENOSYS)			
-#define USB_ST_BANDWIDTH_ERROR	(-ENOSPC)			/* too much bandwidth used */
-#define USB_ST_URB_INVALID_ERROR  (-EINVAL)			/* invalid value/transfer type */
-#define USB_ST_URB_REQUEST_ERROR  (-ENXIO)			/* invalid endpoint */
-#define USB_ST_STALL		(-EPIPE) 			/* pipe stalled, also in urb->status*/
-
-/*
  * USB device number allocation bitmap. There's one bitmap
  * per USB tree.
  */
@@ -197,18 +139,46 @@
 	unsigned long busmap[USB_MAXBUS / (8*sizeof(unsigned long))];
 };
 
+struct usb_device;
+
+/*-------------------------------------------------------------------------*/
+
 /*
- * This is a USB device descriptor.
- *
- * USB device information
+ * Standard USB Descriptor support.
+ * Devices may also have class-specific or vendor-specific descriptors.
  */
 
-/* Everything but the endpoint maximums are aribtrary */
+/*
+ * Descriptor types ... USB 2.0 spec table 9.5
+ */
+#define USB_DT_DEVICE			0x01
+#define USB_DT_CONFIG			0x02
+#define USB_DT_STRING			0x03
+#define USB_DT_INTERFACE		0x04
+#define USB_DT_ENDPOINT			0x05
+#define USB_DT_DEVICE_QUALIFIER		0x06
+#define USB_DT_OTHER_SPEED_CONFIG	0x07
+#define USB_DT_INTERFACE_POWER		0x08
+
+// FIXME should be internal to hub driver
+#define USB_DT_HUB			(USB_TYPE_CLASS | 0x09)
+#define USB_DT_HUB_NONVAR_SIZE		7
+
+/*
+ * Descriptor sizes per descriptor type
+ */
+#define USB_DT_DEVICE_SIZE		18
+#define USB_DT_CONFIG_SIZE		9
+#define USB_DT_INTERFACE_SIZE		9
+#define USB_DT_ENDPOINT_SIZE		7
+#define USB_DT_ENDPOINT_AUDIO_SIZE	9	/* Audio extension */
+
+/* most of these maximums are arbitrary */
 #define USB_MAXCONFIG		8
 #define USB_ALTSETTINGALLOC     4
 #define USB_MAXALTSETTING	128  /* Hard limit */
 #define USB_MAXINTERFACES	32
-#define USB_MAXENDPOINTS	32
+#define USB_MAXENDPOINTS	32   /* Hard limit */
 
 /* All standard descriptors have these 2 fields in common */
 struct usb_descriptor_header {
@@ -216,7 +186,7 @@
 	__u8  bDescriptorType;
 } __attribute__ ((packed));
 
-/* Device descriptor */
+/* USB_DT_DEVICE: Device descriptor */
 struct usb_device_descriptor {
 	__u8  bLength;
 	__u8  bDescriptorType;
@@ -234,7 +204,7 @@
 	__u8  bNumConfigurations;
 } __attribute__ ((packed));
 
-/* Endpoint descriptor */
+/* USB_DT_ENDPOINT: Endpoint descriptor */
 struct usb_endpoint_descriptor {
 	__u8  bLength		__attribute__ ((packed));
 	__u8  bDescriptorType	__attribute__ ((packed));
@@ -245,11 +215,12 @@
 	__u8  bRefresh		__attribute__ ((packed));
 	__u8  bSynchAddress	__attribute__ ((packed));
 
+	/* the rest is internal to the Linux implementation */
    	unsigned char *extra;   /* Extra descriptors */
 	int extralen;
 };
 
-/* Interface descriptor */
+/* USB_DT_INTERFACE: Interface descriptor */
 struct usb_interface_descriptor {
 	__u8  bLength		__attribute__ ((packed));
 	__u8  bDescriptorType	__attribute__ ((packed));
@@ -261,6 +232,7 @@
 	__u8  bInterfaceProtocol __attribute__ ((packed));
 	__u8  iInterface	__attribute__ ((packed));
 
+	/* the rest is internal to the Linux implementation */
   	struct usb_endpoint_descriptor *endpoint;
 
    	unsigned char *extra;   /* Extra descriptors */
@@ -278,7 +250,13 @@
 	void *private_data;
 };
 
-/* Configuration descriptor information.. */
+/* USB_DT_CONFIG: Configuration descriptor information.
+ *
+ * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
+ * descriptor type is different.  Highspeed-capable devices can look
+ * different depending on what speed they're currently running.  Only
+ * devices with a USB_DT_DEVICE_QUALIFIER have an OTHER_SPEED_CONFIG.
+ */
 struct usb_config_descriptor {
 	__u8  bLength		__attribute__ ((packed));
 	__u8  bDescriptorType	__attribute__ ((packed));
@@ -289,20 +267,46 @@
 	__u8  bmAttributes	__attribute__ ((packed));
 	__u8  MaxPower		__attribute__ ((packed));
 
+	/* the rest is internal to the Linux implementation */
 	struct usb_interface *interface;
 
    	unsigned char *extra;   /* Extra descriptors */
 	int extralen;
 };
 
-/* String descriptor */
+/* USB_DT_STRING: String descriptor */
 struct usb_string_descriptor {
 	__u8  bLength;
 	__u8  bDescriptorType;
-	__u16 wData[1];
+	__u16 wData[1];		/* UTF-16LE encoded */
 } __attribute__ ((packed));
 
-struct usb_device;
+/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */
+struct usb_qualifier_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u16 bcdUSB;
+	__u8  bDeviceClass;
+	__u8  bDeviceSubClass;
+	__u8  bDeviceProtocol;
+	__u8  bMaxPacketSize0;
+	__u8  bNumConfigurations;
+	__u8  bRESERVED;
+} __attribute__ ((packed));
+
+/* helpers for driver access to descriptors */
+extern struct usb_interface *
+	usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum);
+extern struct usb_endpoint_descriptor *
+	usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum);
+
+int __usb_get_extra_descriptor(char *buffer, unsigned size,
+	unsigned char type, void **ptr);
+#define usb_get_extra_descriptor(ifpoint,type,ptr)\
+	__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\
+		type,(void**)ptr)
+
+/*-------------------------------------------------------------------------*/
 
 /*
  * Device table entry for "new style" table-driven USB drivers.
@@ -316,34 +320,6 @@
  * Terminate the driver's table with an all-zeroes entry.
  * Use the flag values to control which fields are compared.
  */
-#define USB_DEVICE_ID_MATCH_VENDOR		0x0001
-#define USB_DEVICE_ID_MATCH_PRODUCT		0x0002
-#define USB_DEVICE_ID_MATCH_DEV_LO		0x0004
-#define USB_DEVICE_ID_MATCH_DEV_HI		0x0008
-#define USB_DEVICE_ID_MATCH_DEV_CLASS		0x0010
-#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS	0x0020
-#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL	0x0040
-#define USB_DEVICE_ID_MATCH_INT_CLASS		0x0080
-#define USB_DEVICE_ID_MATCH_INT_SUBCLASS	0x0100
-#define USB_DEVICE_ID_MATCH_INT_PROTOCOL	0x0200
-
-#define USB_DEVICE_ID_MATCH_DEVICE		(USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
-#define USB_DEVICE_ID_MATCH_DEV_RANGE		(USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI)
-#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION	(USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE)
-#define USB_DEVICE_ID_MATCH_DEV_INFO \
-	(USB_DEVICE_ID_MATCH_DEV_CLASS | USB_DEVICE_ID_MATCH_DEV_SUBCLASS | USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
-#define USB_DEVICE_ID_MATCH_INT_INFO \
-	(USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL)
-
-/* Some useful macros */
-#define USB_DEVICE(vend,prod) \
-	match_flags: USB_DEVICE_ID_MATCH_DEVICE, idVendor: (vend), idProduct: (prod)
-#define USB_DEVICE_VER(vend,prod,lo,hi) \
-	match_flags: USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, idVendor: (vend), idProduct: (prod), bcdDevice_lo: (lo), bcdDevice_hi: (hi)
-#define USB_DEVICE_INFO(cl,sc,pr) \
-	match_flags: USB_DEVICE_ID_MATCH_DEV_INFO, bDeviceClass: (cl), bDeviceSubClass: (sc), bDeviceProtocol: (pr)
-#define USB_INTERFACE_INFO(cl,sc,pr) \
-	match_flags: USB_DEVICE_ID_MATCH_INT_INFO, bInterfaceClass: (cl), bInterfaceSubClass: (sc), bInterfaceProtocol: (pr)
 
 /**
  * struct usb_device_id - identifies USB devices for probing and hotplugging
@@ -377,7 +353,7 @@
  *	device flags.
  *
  * In most cases, drivers will create a table of device IDs by using
- * the USB_DEVICE() macros designed for that purpose.
+ * USB_DEVICE(), or similar macros designed for that purpose.
  * They will then export it to userspace using MODULE_DEVICE_TABLE(),
  * and provide it to the USB core through their usb_driver structure.
  *
@@ -413,6 +389,75 @@
 	unsigned long	driver_info;
 };
 
+/* Some useful macros to use to create struct usb_device_id */
+#define USB_DEVICE_ID_MATCH_VENDOR		0x0001
+#define USB_DEVICE_ID_MATCH_PRODUCT		0x0002
+#define USB_DEVICE_ID_MATCH_DEV_LO		0x0004
+#define USB_DEVICE_ID_MATCH_DEV_HI		0x0008
+#define USB_DEVICE_ID_MATCH_DEV_CLASS		0x0010
+#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS	0x0020
+#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL	0x0040
+#define USB_DEVICE_ID_MATCH_INT_CLASS		0x0080
+#define USB_DEVICE_ID_MATCH_INT_SUBCLASS	0x0100
+#define USB_DEVICE_ID_MATCH_INT_PROTOCOL	0x0200
+
+#define USB_DEVICE_ID_MATCH_DEVICE		(USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
+#define USB_DEVICE_ID_MATCH_DEV_RANGE		(USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI)
+#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION	(USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE)
+#define USB_DEVICE_ID_MATCH_DEV_INFO \
+	(USB_DEVICE_ID_MATCH_DEV_CLASS | USB_DEVICE_ID_MATCH_DEV_SUBCLASS | USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
+#define USB_DEVICE_ID_MATCH_INT_INFO \
+	(USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL)
+
+/**
+ * USB_DEVICE - macro used to describe a specific usb device
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific device.
+ */
+#define USB_DEVICE(vend,prod) \
+	match_flags: USB_DEVICE_ID_MATCH_DEVICE, idVendor: (vend), idProduct: (prod)
+/**
+ * USB_DEVICE_VER - macro used to describe a specific usb device with a version range
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ * @lo: the bcdDevice_lo value
+ * @hi: the bcdDevice_hi value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific device, with a version range.
+ */
+#define USB_DEVICE_VER(vend,prod,lo,hi) \
+	match_flags: USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, idVendor: (vend), idProduct: (prod), bcdDevice_lo: (lo), bcdDevice_hi: (hi)
+
+/**
+ * USB_DEVICE_INFO - macro used to describe a class of usb devices
+ * @cl: bDeviceClass value
+ * @sc: bDeviceSubClass value
+ * @pr: bDeviceProtocol value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific class of devices.
+ */
+#define USB_DEVICE_INFO(cl,sc,pr) \
+	match_flags: USB_DEVICE_ID_MATCH_DEV_INFO, bDeviceClass: (cl), bDeviceSubClass: (sc), bDeviceProtocol: (pr)
+
+/**
+ * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces 
+ * @cl: bInterfaceClass value
+ * @sc: bInterfaceSubClass value
+ * @pr: bInterfaceProtocol value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific class of interfaces.
+ */
+#define USB_INTERFACE_INFO(cl,sc,pr) \
+	match_flags: USB_DEVICE_ID_MATCH_INT_INFO, bInterfaceClass: (cl), bInterfaceSubClass: (sc), bInterfaceProtocol: (pr)
+
+/* -------------------------------------------------------------------------- */
+
 /**
  * struct usb_driver - identifies USB driver to usbcore
  * @name: The driver name should be unique among USB drivers
@@ -439,6 +484,8 @@
  *	expose information to user space regardless of where they
  *	do (or don't) show up otherwise in the filesystem.
  * @id_table: USB drivers use ID table to support hotplugging.
+ *	Export this with MODULE_DEVICE_TABLE(usb,...), or use NULL to
+ *	say that probe() should be called for any unclaimed interfce.
  *
  * USB drivers should provide a name, probe() and disconnect() methods,
  * and an id_table.  Other driver fields are optional.
@@ -482,13 +529,22 @@
 
 	/* suspend before the bus suspends;
 	 * disconnect or resume when the bus resumes */
-	// void (*suspend)(struct usb_device *dev);
-	// void (*resume)(struct usb_device *dev);
+	/* void (*suspend)(struct usb_device *dev); */
+	/* void (*resume)(struct usb_device *dev); */
 };
-	
-/*----------------------------------------------------------------------------* 
- * New USB Structures                                                         *
- *----------------------------------------------------------------------------*/
+
+/*
+ * use these in module_init()/module_exit()
+ * and don't forget MODULE_DEVICE_TABLE(usb, ...)
+ */
+extern int usb_register(struct usb_driver *);
+extern void usb_deregister(struct usb_driver *);
+
+/* -------------------------------------------------------------------------- */
+
+/*
+ * URB support, for asynchronous request completions
+ */
 
 /*
  * urb->transfer_flags:
@@ -500,18 +556,21 @@
 #define USB_ASYNC_UNLINK        0x0008
 #define USB_QUEUE_BULK          0x0010
 #define USB_NO_FSBR		0x0020
-#define USB_ZERO_PACKET         0x0040  // Finish bulk OUTs always with zero length packet
-#define USB_TIMEOUT_KILLED	0x1000	// only set by HCD!
+#define USB_ZERO_PACKET         0x0040  /* Finish bulk OUTs with short packet */
+#define URB_NO_INTERRUPT	0x0080	/* HINT: no non-error interrupt needed */
+					/* ... less overhead for QUEUE_BULK */
+#define USB_TIMEOUT_KILLED	0x1000	/* only set by HCD! */
 
 typedef struct
 {
 	unsigned int offset;
-	unsigned int length;		// expected length
+	unsigned int length;		/* expected length */
 	unsigned int actual_length;
 	unsigned int status;
 } iso_packet_descriptor_t, *piso_packet_descriptor_t;
 
 struct urb;
+
 typedef void (*usb_complete_t)(struct urb *);
 
 /**
@@ -601,6 +660,8 @@
  * to poll for transfers.  After the URB has been submitted, the interval
  * and start_frame fields reflect how the transfer was actually scheduled.
  * The polling interval may be more frequent than requested.
+ * For example, some controllers have a maximum interval of 32 microseconds,
+ * while others support intervals of up to 1024 microseconds.
  *
  * Isochronous URBs normally use the USB_ISO_ASAP transfer flag, telling
  * the host controller to schedule the transfer as soon as bandwidth
@@ -634,7 +695,7 @@
  * When completion callback is invoked for non-isochronous URBs, the
  * actual_length field tells how many bytes were transferred.
  *
- * For interrupt and isochronous URBs, the URB provided to the calllback
+ * For interrupt and isochronous URBs, the URB provided to the callback
  * function is still "owned" by the USB core subsystem unless the status
  * indicates that the URB has been unlinked.  Completion handlers should
  * not modify such URBs until they have been unlinked.
@@ -681,8 +742,9 @@
  * @COMPLETE: pointer to the usb_complete_t function
  * @CONTEXT: what to set the urb context to.
  *
- * Initializes a control urb with the proper information needed to submit it to
- * a device.
+ * Initializes a control urb with the proper information needed to submit
+ * it to a device.  This macro is depreciated, the usb_fill_control_urb()
+ * function should be used instead.
  */
 #define FILL_CONTROL_URB(URB,DEV,PIPE,SETUP_PACKET,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) \
     do {\
@@ -706,8 +768,9 @@
  * @COMPLETE: pointer to the usb_complete_t function
  * @CONTEXT: what to set the urb context to.
  *
- * Initializes a bulk urb with the proper information needed to submit it to
- * a device.
+ * Initializes a bulk urb with the proper information needed to submit it
+ * to a device.  This macro is depreciated, the usb_fill_bulk_urb()
+ * function should be used instead.
  */
 #define FILL_BULK_URB(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) \
     do {\
@@ -731,8 +794,9 @@
  * @CONTEXT: what to set the urb context to.
  * @INTERVAL: what to set the urb interval to.
  *
- * Initializes a interrupt urb with the proper information needed to submit it to
- * a device.
+ * Initializes a interrupt urb with the proper information needed to submit
+ * it to a device.  This macro is depreciated, the usb_fill_int_urb()
+ * function should be used instead.
  */
 #define FILL_INT_URB(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT,INTERVAL) \
     do {\
@@ -747,51 +811,150 @@
 	(URB)->start_frame=-1;\
     } while (0)
 
-#define FILL_CONTROL_URB_TO(a,aa,b,c,d,e,f,g,h) \
-    do {\
-	spin_lock_init(&(a)->lock);\
-	(a)->dev=aa;\
-	(a)->pipe=b;\
-	(a)->setup_packet=c;\
-	(a)->transfer_buffer=d;\
-	(a)->transfer_buffer_length=e;\
-	(a)->complete=f;\
-	(a)->context=g;\
-	(a)->timeout=h;\
-    } while (0)
+/**
+ * usb_fill_control_urb - initializes a control urb
+ * @urb: pointer to the urb to initialize.
+ * @dev: pointer to the struct usb_device for this urb.
+ * @pipe: the endpoint pipe
+ * @setup_packet: pointer to the setup_packet buffer
+ * @transfer_buffer: pointer to the transfer buffer
+ * @buffer_length: length of the transfer buffer
+ * @complete: pointer to the usb_complete_t function
+ * @context: what to set the urb context to.
+ *
+ * Initializes a control urb with the proper information needed to submit
+ * it to a device.
+ */
+static inline void usb_fill_control_urb (struct urb *urb,
+					 struct usb_device *dev,
+					 unsigned int pipe,
+					 unsigned char *setup_packet,
+					 void *transfer_buffer,
+					 int buffer_length,
+					 usb_complete_t complete,
+					 void *context)
+{
+	spin_lock_init(&urb->lock);
+	urb->dev = dev;
+	urb->pipe = pipe;
+	urb->setup_packet = setup_packet;
+	urb->transfer_buffer = transfer_buffer;
+	urb->transfer_buffer_length = buffer_length;
+	urb->complete = complete;
+	urb->context = context;
+}
 
-#define FILL_BULK_URB_TO(a,aa,b,c,d,e,f,g) \
-    do {\
-	spin_lock_init(&(a)->lock);\
-	(a)->dev=aa;\
-	(a)->pipe=b;\
-	(a)->transfer_buffer=c;\
-	(a)->transfer_buffer_length=d;\
-	(a)->complete=e;\
-	(a)->context=f;\
-	(a)->timeout=g;\
-    } while (0)
+/**
+ * usb_fill_bulk_urb - macro to help initialize a bulk urb
+ * @urb: pointer to the urb to initialize.
+ * @dev: pointer to the struct usb_device for this urb.
+ * @pipe: the endpoint pipe
+ * @transfer_buffer: pointer to the transfer buffer
+ * @buffer_length: length of the transfer buffer
+ * @complete: pointer to the usb_complete_t function
+ * @context: what to set the urb context to.
+ *
+ * Initializes a bulk urb with the proper information needed to submit it
+ * to a device.
+ */
+static inline void usb_fill_bulk_urb (struct urb *urb,
+				      struct usb_device *dev,
+				      unsigned int pipe,
+				      void *transfer_buffer,
+				      int buffer_length,
+				      usb_complete_t complete,
+				      void *context)
+				      
+{
+	spin_lock_init(&urb->lock);
+	urb->dev = dev;
+	urb->pipe = pipe;
+	urb->transfer_buffer = transfer_buffer;
+	urb->transfer_buffer_length = buffer_length;
+	urb->complete = complete;
+	urb->context = context;
+}
     
-purb_t usb_alloc_urb(int iso_packets);
-void usb_free_urb (purb_t purb);
-int usb_submit_urb(purb_t purb);
-int usb_unlink_urb(purb_t purb);
-int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd,  void *data, int len, int timeout);
-int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout);
+/**
+ * usb_fill_int_urb - macro to help initialize a interrupt urb
+ * @urb: pointer to the urb to initialize.
+ * @dev: pointer to the struct usb_device for this urb.
+ * @pipe: the endpoint pipe
+ * @transfer_buffer: pointer to the transfer buffer
+ * @buffer_length: length of the transfer buffer
+ * @complete: pointer to the usb_complete_t function
+ * @context: what to set the urb context to.
+ * @interval: what to set the urb interval to.
+ *
+ * Initializes a interrupt urb with the proper information needed to submit
+ * it to a device.
+ */
+static inline void usb_fill_int_urb (struct urb *urb,
+				     struct usb_device *dev,
+				     unsigned int pipe,
+				     void *transfer_buffer,
+				     int buffer_length,
+				     usb_complete_t complete,
+				     void *context,
+				     int interval)
+{
+	spin_lock_init(&urb->lock);
+	urb->dev = dev;
+	urb->pipe = pipe;
+	urb->transfer_buffer = transfer_buffer;
+	urb->transfer_buffer_length = buffer_length;
+	urb->complete = complete;
+	urb->context = context;
+	urb->interval = interval;
+	urb->start_frame = -1;
+}
+    
+extern struct urb *usb_alloc_urb(int iso_packets);
+extern void usb_free_urb(struct urb *purb);
+extern int usb_submit_urb(struct urb *purb);
+extern int usb_unlink_urb(struct urb *purb);
 
 /*-------------------------------------------------------------------*
  *                         SYNCHRONOUS CALL SUPPORT                  *
  *-------------------------------------------------------------------*/
 
-struct usb_api_data
-{
-	wait_queue_head_t wqh;
-	int done;
-	/* void* stuff;	*/	/* Possible extension later. */
-};
+extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
+	__u8 request, __u8 requesttype, __u16 value, __u16 index,
+	void *data, __u16 size, int timeout);
+extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
+	void *data, int len, int *actual_length,
+	int timeout);
+
+/* wrappers around usb_control_msg() for the most common standard requests */
+extern int usb_clear_halt(struct usb_device *dev, int pipe);
+extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype,
+	unsigned char descindex, void *buf, int size);
+extern int usb_get_device_descriptor(struct usb_device *dev);
+extern int usb_get_status(struct usb_device *dev,
+	int type, int target, void *data);
+extern int usb_get_string(struct usb_device *dev,
+	unsigned short langid, unsigned char index, void *buf, int size);
+extern int usb_string(struct usb_device *dev, int index,
+	char *buf, size_t size);
+extern int usb_set_configuration(struct usb_device *dev, int configuration);
+extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
+
+/*
+ * timeouts, in seconds, used for sending/receiving control messages
+ * they typically complete within a few frames (msec) after they're issued
+ */
+#ifdef CONFIG_USB_LONG_TIMEOUT
+#define USB_CTRL_GET_TIMEOUT 4
+#else
+#define USB_CTRL_GET_TIMEOUT 3
+#endif
+
+#define USB_CTRL_SET_TIMEOUT 3
 
 /* -------------------------------------------------------------------------- */
 
+/* Host Controller Driver (HCD) support */
+
 struct usb_operations {
 	int (*allocate)(struct usb_device *);
 	int (*deallocate)(struct usb_device *);
@@ -832,6 +995,60 @@
 	atomic_t refcnt;
 };
 
+extern struct usb_bus *usb_alloc_bus(struct usb_operations *);
+extern void usb_free_bus(struct usb_bus *);
+extern void usb_register_bus(struct usb_bus *);
+extern void usb_deregister_bus(struct usb_bus *);
+
+extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
+extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb,
+		int bustime, int isoc);
+extern void usb_release_bandwidth(struct usb_device *dev, struct urb *urb,
+		int isoc);
+extern int usb_root_hub_string(int id, int serial,
+		char *type, __u8 *data, int len);
+
+/*
+ * Some USB 1.1 bandwidth allocation constants.
+ */
+#define BW_HOST_DELAY	1000L		/* nanoseconds */
+#define BW_HUB_LS_SETUP	333L		/* nanoseconds */
+                        /* 4 full-speed bit times (est.) */
+
+#define FRAME_TIME_BITS         12000L		/* frame = 1 millisecond */
+#define FRAME_TIME_MAX_BITS_ALLOC	(90L * FRAME_TIME_BITS / 100L)
+#define FRAME_TIME_USECS	1000L
+#define FRAME_TIME_MAX_USECS_ALLOC	(90L * FRAME_TIME_USECS / 100L)
+
+#define BitTime(bytecount)  (7 * 8 * bytecount / 6)  /* with integer truncation */
+		/* Trying not to use worst-case bit-stuffing
+                   of (7/6 * 8 * bytecount) = 9.33 * bytecount */
+		/* bytecount = data payload byte count */
+
+#define NS_TO_US(ns)	((ns + 500L) / 1000L)
+			/* convert & round nanoseconds to microseconds */
+
+
+/* -------------------------------------------------------------------------- */
+
+/* Enumeration is only for the hub driver, or HCD virtual root hubs */
+extern struct usb_device *usb_alloc_dev(struct usb_device *parent,
+	struct usb_bus *);
+extern void usb_free_dev(struct usb_device *);
+extern int usb_new_device(struct usb_device *dev);
+extern void usb_connect(struct usb_device *dev);
+extern void usb_disconnect(struct usb_device **);
+
+#ifndef _LINUX_HUB_H
+/* exported to hub driver ONLY to support usb_reset_device () */
+extern int usb_get_configuration(struct usb_device *dev);
+extern void usb_set_maxpacket(struct usb_device *dev);
+extern void usb_destroy_configuration(struct usb_device *dev);
+extern int usb_set_address(struct usb_device *dev);
+#endif /* _LINUX_HUB_H */
+
+/* -------------------------------------------------------------------------- */
+
 /* This is arbitrary.
  * From USB 2.0 spec Table 11-13, offset 7, a hub can
  * have up to 255 ports. The most yet reported is 10.
@@ -889,44 +1106,30 @@
 	struct usb_device *children[USB_MAXCHILDREN];
 };
 
-extern struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum);
-extern struct usb_endpoint_descriptor *usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum);
-
-extern int usb_register(struct usb_driver *);
-extern void usb_deregister(struct usb_driver *);
+/* for when layers above USB add new non-USB drivers */
 extern void usb_scan_devices(void);
 
-/* used these for multi-interface device registration */
-extern void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv);
-extern int usb_interface_claimed(struct usb_interface *iface);
-extern void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface);
-const struct usb_device_id *usb_match_id(struct usb_device *dev,
-					 struct usb_interface *interface,
-					 const struct usb_device_id *id);
+/* mostly for devices emulating SCSI over USB */
+extern int usb_reset_device(struct usb_device *dev);
 
-extern struct usb_bus *usb_alloc_bus(struct usb_operations *);
-extern void usb_free_bus(struct usb_bus *);
-extern void usb_register_bus(struct usb_bus *);
-extern void usb_deregister_bus(struct usb_bus *);
+/* for drivers using iso endpoints */
+extern int usb_get_current_frame_number (struct usb_device *usb_dev);
 
-extern struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *);
-extern void usb_free_dev(struct usb_device *);
+/* drivers must track when they bind to a device's interfaces */
 extern void usb_inc_dev_use(struct usb_device *);
 #define usb_dec_dev_use usb_free_dev
 
-extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
-extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc);
-extern void usb_release_bandwidth(struct usb_device *dev, struct urb *urb, int isoc);
-
-extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout);
-
-extern int usb_root_hub_string(int id, int serial, char *type, __u8 *data, int len);
-extern void usb_connect(struct usb_device *dev);
-extern void usb_disconnect(struct usb_device **);
-
-extern void usb_destroy_configuration(struct usb_device *dev);
+/* used these for multi-interface device registration */
+extern void usb_driver_claim_interface(struct usb_driver *driver,
+			struct usb_interface *iface, void* priv);
+extern int usb_interface_claimed(struct usb_interface *iface);
+extern void usb_driver_release_interface(struct usb_driver *driver,
+			struct usb_interface *iface);
+const struct usb_device_id *usb_match_id(struct usb_device *dev,
+					 struct usb_interface *interface,
+					 const struct usb_device_id *id);
 
-int usb_get_current_frame_number (struct usb_device *usb_dev);
+/* -------------------------------------------------------------------------- */
 
 /*
  * Calling this entity a "pipe" is glorifying it. A USB pipe
@@ -934,7 +1137,7 @@
  * of the following information:
  *  - device number (7 bits)
  *  - endpoint number (4 bits)
- *  - current Data0/1 state (1 bit)
+ *  - current Data0/1 state (1 bit) [Historical; now gone]
  *  - direction (1 bit)
  *  - speed (1 bit)
  *  - max packet size (2 bits: 8, 16, 32 or 64) [Historical; now gone.]
@@ -951,7 +1154,7 @@
  *  - direction:	bit 7		(0 = Host-to-Device [Out], 1 = Device-to-Host [In])
  *  - device:		bits 8-14
  *  - endpoint:		bits 15-18
- *  - Data0/1:		bit 19
+ *  - Data0/1:		bit 19		[Historical; now gone. ]
  *  - speed:		bit 26		(0 = Full, 1 = Low Speed)
  *  - pipe type:	bits 30-31	(00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk)
  *
@@ -964,6 +1167,8 @@
  * like full speed devices.
  */
 
+// FIXME 2.5 get rid of usb_pipeslow(), just use dev->speed
+
 #define PIPE_ISOCHRONOUS		0
 #define PIPE_INTERRUPT			1
 #define PIPE_CONTROL			2
@@ -979,7 +1184,6 @@
 #define usb_pipedevice(pipe)	(((pipe) >> 8) & 0x7f)
 #define usb_pipe_endpdev(pipe)	(((pipe) >> 8) & 0x7ff)
 #define usb_pipeendpoint(pipe)	(((pipe) >> 15) & 0xf)
-#define usb_pipedata(pipe)	(((pipe) >> 19) & 1)
 #define usb_pipeslow(pipe)	(((pipe) >> 26) & 1)
 #define usb_pipetype(pipe)	(((pipe) >> 30) & 3)
 #define usb_pipeisoc(pipe)	(usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
@@ -1023,58 +1227,10 @@
 #define usb_snddefctrl(dev)		((PIPE_CONTROL << 30) | __default_pipe(dev))
 #define usb_rcvdefctrl(dev)		((PIPE_CONTROL << 30) | __default_pipe(dev) | USB_DIR_IN)
 
-/*
- * Send and receive control messages..
- */
-int usb_new_device(struct usb_device *dev);
-int usb_reset_device(struct usb_device *dev);
-int usb_set_address(struct usb_device *dev);
-int usb_get_descriptor(struct usb_device *dev, unsigned char desctype,
-	unsigned char descindex, void *buf, int size);
-int usb_get_class_descriptor(struct usb_device *dev, int ifnum, unsigned char desctype,
-	unsigned char descindex, void *buf, int size);
-int usb_get_device_descriptor(struct usb_device *dev);
-int __usb_get_extra_descriptor(char *buffer, unsigned size, unsigned char type, void **ptr);
-int usb_get_status(struct usb_device *dev, int type, int target, void *data);
-int usb_get_configuration(struct usb_device *dev);
-int usb_get_protocol(struct usb_device *dev, int ifnum);
-int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol);
-int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
-int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id);
-int usb_set_configuration(struct usb_device *dev, int configuration);
-int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
-	unsigned char id, void *buf, int size);
-int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type,
-	unsigned char id, void *buf, int size);
-int usb_string(struct usb_device *dev, int index, char *buf, size_t size);
-int usb_clear_halt(struct usb_device *dev, int pipe);
-void usb_set_maxpacket(struct usb_device *dev);
-
-#define usb_get_extra_descriptor(ifpoint,type,ptr)\
-	__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,type,(void**)ptr)
-
-/*
- * Some USB bandwidth allocation constants.
- */
-#define BW_HOST_DELAY	1000L		/* nanoseconds */
-#define BW_HUB_LS_SETUP	333L		/* nanoseconds */
-                        /* 4 full-speed bit times (est.) */
-
-#define FRAME_TIME_BITS         12000L		/* frame = 1 millisecond */
-#define FRAME_TIME_MAX_BITS_ALLOC	(90L * FRAME_TIME_BITS / 100L)
-#define FRAME_TIME_USECS	1000L
-#define FRAME_TIME_MAX_USECS_ALLOC	(90L * FRAME_TIME_USECS / 100L)
-
-#define BitTime(bytecount)  (7 * 8 * bytecount / 6)  /* with integer truncation */
-		/* Trying not to use worst-case bit-stuffing
-                   of (7/6 * 8 * bytecount) = 9.33 * bytecount */
-		/* bytecount = data payload byte count */
-
-#define NS_TO_US(ns)	((ns + 500L) / 1000L)
-			/* convert & round nanoseconds to microseconds */
+/* -------------------------------------------------------------------------- */
 
 /*
- * Debugging helpers..
+ * Debugging and troubleshooting/diagnostic helpers.
  */
 void usb_show_device_descriptor(struct usb_device_descriptor *);
 void usb_show_config_descriptor(struct usb_config_descriptor *);
@@ -1088,13 +1244,17 @@
 #else
 #define dbg(format, arg...) do {} while (0)
 #endif
+
 #define err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" , ## arg)
 #define info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ## arg)
 
 
+/* -------------------------------------------------------------------------- */
+
 /*
  * bus and driver list
+ * exported only for usbdevfs (not visible outside usbcore)
  */
 
 extern struct list_head usb_driver_list;
diff -urN linux-2.5.1-pre7/init/do_mounts.c linux/init/do_mounts.c
--- linux-2.5.1-pre7/init/do_mounts.c	Sat Dec  8 21:04:23 2001
+++ linux/init/do_mounts.c	Sat Dec  8 21:05:04 2001
@@ -351,7 +351,8 @@
 		mount("devfs", ".", "devfs", 0, NULL);
 retry:
 	for (p = fs_names; *p; p += strlen(p)+1) {
-		err = mount(name,"/root",p,root_mountflags,root_mount_data);
+		int err;
+		err = sys_mount(name,"/root",p,root_mountflags,root_mount_data);
 		switch (err) {
 			case 0:
 				goto done;
diff -urN linux-2.5.1-pre7/ipc/shm.c linux/ipc/shm.c
--- linux-2.5.1-pre7/ipc/shm.c	Wed Oct 17 14:16:39 2001
+++ linux/ipc/shm.c	Sat Dec  8 21:05:04 2001
@@ -569,6 +569,7 @@
 {
 	struct shmid_kernel *shp;
 	unsigned long addr;
+	unsigned long size;
 	struct file * file;
 	int    err;
 	unsigned long flags;
@@ -588,8 +589,12 @@
 				return -EINVAL;
 		}
 		flags = MAP_SHARED | MAP_FIXED;
-	} else
+	} else {
+		if ((shmflg & SHM_REMAP))
+			return -EINVAL;
+
 		flags = MAP_SHARED;
+	}
 
 	if (shmflg & SHM_RDONLY) {
 		prot = PROT_READ;
@@ -603,7 +608,7 @@
 
 	/*
 	 * We cannot rely on the fs check since SYSV IPC does have an
-	 * aditional creator id...
+	 * additional creator id...
 	 */
 	shp = shm_lock(shmid);
 	if(shp == NULL)
@@ -618,11 +623,27 @@
 		return -EACCES;
 	}
 	file = shp->shm_file;
+	size = file->f_dentry->d_inode->i_size;
 	shp->shm_nattch++;
 	shm_unlock(shmid);
 
 	down_write(&current->mm->mmap_sem);
-	user_addr = (void *) do_mmap (file, addr, file->f_dentry->d_inode->i_size, prot, flags, 0);
+	if (addr && !(shmflg & SHM_REMAP)) {
+		user_addr = ERR_PTR(-EINVAL);
+		if (find_vma_intersection(current->mm, addr, addr + size))
+			goto invalid;
+		/*
+		 * If shm segment goes below stack, make sure there is some
+		 * space left for the stack to grow (at least 4 pages).
+		 */
+		if (addr < current->mm->start_stack &&
+		    addr > current->mm->start_stack - size - PAGE_SIZE * 5)
+			goto invalid;
+	}
+		
+	user_addr = (void*) do_mmap (file, addr, size, prot, flags, 0);
+
+invalid:
 	up_write(&current->mm->mmap_sem);
 
 	down (&shm_ids.sem);
diff -urN linux-2.5.1-pre7/mm/highmem.c linux/mm/highmem.c
--- linux-2.5.1-pre7/mm/highmem.c	Sat Dec  8 21:04:23 2001
+++ linux/mm/highmem.c	Sat Dec  8 21:05:04 2001
@@ -387,9 +387,9 @@
 			char *vto, *vfrom;
 
 			vto = page_address(to->bv_page) + to->bv_offset;
-			vfrom = kmap(from->bv_page);
-			memcpy(vto, vfrom + from->bv_offset, to->bv_len);
-			kunmap(to->bv_page);
+			vfrom = kmap(from->bv_page) + from->bv_offset;
+			memcpy(vto, vfrom, to->bv_len);
+			kunmap(from->bv_page);
 		}
 	}
 
