## Automatically generated incremental diff
## From:   linux-2.5.70-bk4
## To:     linux-2.5.70-bk5
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.5.70-bk4/Documentation/filesystems/jfs.txt linux-2.5.70-bk5/Documentation/filesystems/jfs.txt
--- linux-2.5.70-bk4/Documentation/filesystems/jfs.txt	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk5/Documentation/filesystems/jfs.txt	2003-05-31 04:35:54.000000000 -0700
@@ -4,10 +4,10 @@
 
 Team members
 ------------
-Steve Best         sbest@us.ibm.com
 Dave Kleikamp      shaggy@austin.ibm.com  
+Dave Blaschke      blaschke@us.ibm.com
+Steve Best         sbest@us.ibm.com
 Barry Arndt        barndt@us.ibm.com
-Christoph Hellwig  hch@infradead.org
 
 The following mount options are supported:
 
diff -urN linux-2.5.70-bk4/Documentation/usb/proc_usb_info.txt linux-2.5.70-bk5/Documentation/usb/proc_usb_info.txt
--- linux-2.5.70-bk4/Documentation/usb/proc_usb_info.txt	2003-05-26 18:00:22.000000000 -0700
+++ linux-2.5.70-bk5/Documentation/usb/proc_usb_info.txt	2003-05-31 04:35:54.000000000 -0700
@@ -1,10 +1,11 @@
 /proc/bus/usb filesystem output
 ===============================
-(version 2002.03.19)
+(version 2003.05.30)
 
 
-The /proc filesystem for USB devices provides /proc/bus/usb/drivers
-and /proc/bus/usb/devices, as well as /proc/bus/usb/BBB/DDD files.
+The usbfs filesystem for USB devices is traditionally mounted at
+/proc/bus/usb.  It provides the /proc/bus/usb/devices file, as well as
+the /proc/bus/usb/BBB/DDD files.
 
 
 **NOTE**: If /proc/bus/usb appears empty, and a host controller
@@ -68,30 +69,6 @@
 
 
 
-THE /proc/bus/usb/drivers FILE:
--------------------------------
-Each of the USB device drivers linked into your kernel (statically,
-or dynamically using "modprobe") is listed in the "drivers" file.
-Here's an example from one system:
-
-         usbdevfs
-         hub
-  0- 15: usblp
-         usbnet
-         serial
-         usb-storage
-         pegasus
-
-If you see this file, "usbdevfs" and "hub" will always be listed,
-since those are part of the "usbcore" framework.
-
-Drivers that use the USB major number (180) to provide character devices
-will include a range of minor numbers, as shown above for the "usblp"
-(actually "printer.o") module.  USB device drivers can of course use any
-major number, but it's easy to use the USB range since there's explicit
-support for subdividing it in the USB device driver framework.
-
-
 THE /proc/bus/usb/devices FILE:
 -------------------------------
 In /proc/bus/usb/devices, each device's output has multiple
diff -urN linux-2.5.70-bk4/Makefile linux-2.5.70-bk5/Makefile
--- linux-2.5.70-bk4/Makefile	2003-05-31 04:35:46.000000000 -0700
+++ linux-2.5.70-bk5/Makefile	2003-05-31 04:35:54.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 70
-EXTRAVERSION = -bk4
+EXTRAVERSION = -bk5
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -urN linux-2.5.70-bk4/drivers/block/ioctl.c linux-2.5.70-bk5/drivers/block/ioctl.c
--- linux-2.5.70-bk4/drivers/block/ioctl.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk5/drivers/block/ioctl.c	2003-05-31 04:35:54.000000000 -0700
@@ -207,11 +207,8 @@
 		set_device_ro(bdev, n);
 		return 0;
 	default:
-		if (disk->fops->ioctl) {
-			ret = disk->fops->ioctl(inode, file, cmd, arg);
-			if (ret != -EINVAL)
-				return ret;
-		}
+		if (disk->fops->ioctl)
+			return disk->fops->ioctl(inode, file, cmd, arg);
 	}
 	return -ENOTTY;
 }
diff -urN linux-2.5.70-bk4/drivers/block/ll_rw_blk.c linux-2.5.70-bk5/drivers/block/ll_rw_blk.c
--- linux-2.5.70-bk4/drivers/block/ll_rw_blk.c	2003-05-31 04:35:46.000000000 -0700
+++ linux-2.5.70-bk5/drivers/block/ll_rw_blk.c	2003-05-31 04:35:54.000000000 -0700
@@ -553,7 +553,7 @@
 
 	memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *));
 	bits = max_depth / BLK_TAGS_PER_LONG;
-	memcpy(bqt->tag_map, bqt->tag_map, bits * sizeof(unsigned long));
+	memcpy(bqt->tag_map, tag_map, bits * sizeof(unsigned long));
 
 	kfree(tag_index);
 	kfree(tag_map);
diff -urN linux-2.5.70-bk4/drivers/block/scsi_ioctl.c linux-2.5.70-bk5/drivers/block/scsi_ioctl.c
--- linux-2.5.70-bk4/drivers/block/scsi_ioctl.c	2003-05-26 18:01:01.000000000 -0700
+++ linux-2.5.70-bk5/drivers/block/scsi_ioctl.c	2003-05-31 04:35:54.000000000 -0700
@@ -68,7 +68,6 @@
 
 	rq->flags |= REQ_NOMERGE;
 	rq->waiting = &wait;
-        drive_stat_acct(rq, rq->nr_sectors, 1);
 	elv_add_request(q, rq, 1, 1);
 	generic_unplug_device(q);
 	wait_for_completion(&wait);
@@ -99,7 +98,7 @@
 
 static int sg_get_timeout(request_queue_t *q)
 {
-	return q->sg_timeout;
+	return q->sg_timeout / (HZ / USER_HZ);
 }
 
 static int sg_set_timeout(request_queue_t *q, int *p)
@@ -107,7 +106,7 @@
 	int timeout, err = get_user(timeout, p);
 
 	if (!err)
-		q->sg_timeout = timeout;
+		q->sg_timeout = timeout * (HZ / USER_HZ);
 
 	return err;
 }
@@ -121,10 +120,14 @@
 {
 	int size, err = get_user(size, p);
 
-	if (!err)
-		q->sg_reserved_size = size;
+	if (err)
+		return err;
 
-	return err;
+	if (size > (q->max_sectors << 9))
+		return -EINVAL;
+
+	q->sg_reserved_size = size;
+	return 0;
 }
 
 /*
@@ -139,16 +142,14 @@
 static int sg_io(request_queue_t *q, struct block_device *bdev,
 		 struct sg_io_hdr *uptr)
 {
-	unsigned long uaddr, start_time;
-	int reading, writing, nr_sectors;
+	unsigned long start_time;
+	int reading, writing;
 	struct sg_io_hdr hdr;
 	struct request *rq;
 	struct bio *bio;
 	char sense[SCSI_SENSE_BUFFERSIZE];
 	void *buffer;
 
-	if (!access_ok(VERIFY_WRITE, uptr, sizeof(*uptr)))
-		return -EFAULT;
 	if (copy_from_user(&hdr, uptr, sizeof(*uptr)))
 		return -EFAULT;
 
@@ -156,11 +157,6 @@
 		return -EINVAL;
 	if (hdr.cmd_len > sizeof(rq->cmd))
 		return -EINVAL;
-	if (!access_ok(VERIFY_READ, hdr.cmdp, hdr.cmd_len))
-		return -EFAULT;
-
-	if (hdr.dxfer_len > 65536)
-		return -EINVAL;
 
 	/*
 	 * we'll do that later
@@ -168,7 +164,9 @@
 	if (hdr.iovec_count)
 		return -EOPNOTSUPP;
 
-	nr_sectors = 0;
+	if (hdr.dxfer_len > (q->max_sectors << 9))
+		return -EIO;
+
 	reading = writing = 0;
 	buffer = NULL;
 	bio = NULL;
@@ -189,19 +187,12 @@
 			break;
 		}
 
-		uaddr = (unsigned long) hdr.dxferp;
-		/* writing to device -> reading from vm */
-		if (writing && !access_ok(VERIFY_READ, uaddr, bytes))
-			return -EFAULT;
-		/* reading from device -> writing to vm */
-		else if (reading && !access_ok(VERIFY_WRITE, uaddr, bytes))
-			return -EFAULT;
-
 		/*
 		 * first try to map it into a bio. reading from device will
 		 * be a write to vm.
 		 */
-		bio = bio_map_user(bdev, uaddr, hdr.dxfer_len, reading);
+		bio = bio_map_user(bdev, (unsigned long) hdr.dxferp,
+				   hdr.dxfer_len, reading);
 
 		/*
 		 * if bio setup failed, fall back to slow approach
@@ -211,10 +202,11 @@
 			if (!buffer)
 				return -ENOMEM;
 
-			nr_sectors = bytes >> 9;
-			if (writing)
-				copy_from_user(buffer,hdr.dxferp,hdr.dxfer_len);
-			else
+			if (writing) {
+				if (copy_from_user(buffer, hdr.dxferp,
+						   hdr.dxfer_len))
+					goto out_buffer;
+			} else
 				memset(buffer, 0, hdr.dxfer_len);
 		}
 	}
@@ -225,7 +217,8 @@
 	 * fill in request structure
 	 */
 	rq->cmd_len = hdr.cmd_len;
-	copy_from_user(rq->cmd, hdr.cmdp, hdr.cmd_len);
+	if (copy_from_user(rq->cmd, hdr.cmdp, hdr.cmd_len))
+		goto out_request;
 	if (sizeof(rq->cmd) != hdr.cmd_len)
 		memset(rq->cmd + hdr.cmd_len, 0, sizeof(rq->cmd) - hdr.cmd_len);
 
@@ -235,18 +228,15 @@
 
 	rq->flags |= REQ_BLOCK_PC;
 
-	rq->hard_nr_sectors = rq->nr_sectors = nr_sectors;
-	rq->hard_cur_sectors = rq->current_nr_sectors = nr_sectors;
-
-	rq->bio = rq->biotail = bio;
+	rq->bio = rq->biotail = NULL;
 
 	if (bio)
 		blk_rq_bio_prep(q, rq, bio);
 
-	rq->data_len = hdr.dxfer_len;
 	rq->data = buffer;
+	rq->data_len = hdr.dxfer_len;
 
-	rq->timeout = hdr.timeout;
+	rq->timeout = (hdr.timeout * HZ) / 1000;
 	if (!rq->timeout)
 		rq->timeout = q->sg_timeout;
 	if (!rq->timeout)
@@ -273,12 +263,11 @@
 	if (hdr.masked_status || hdr.host_status || hdr.driver_status)
 		hdr.info |= SG_INFO_CHECK;
 	hdr.resid = rq->data_len;
-	hdr.duration = (jiffies - start_time) * (1000 / HZ);
+	hdr.duration = ((jiffies - start_time) * 1000) / HZ;
 	hdr.sb_len_wr = 0;
 
 	if (rq->sense_len && hdr.sbp) {
-		int len = (hdr.mx_sb_len < rq->sense_len) ? 
-				hdr.mx_sb_len : rq->sense_len;
+		int len = min((unsigned int) hdr.mx_sb_len, rq->sense_len);
 
 		if (!copy_to_user(hdr.sbp, rq->sense, len))
 			hdr.sb_len_wr = len;
@@ -286,17 +275,25 @@
 
 	blk_put_request(rq);
 
-	copy_to_user(uptr, &hdr, sizeof(*uptr));
+	if (copy_to_user(uptr, &hdr, sizeof(*uptr)))
+		goto out_buffer;
 
 	if (buffer) {
 		if (reading)
-			copy_to_user(hdr.dxferp, buffer, hdr.dxfer_len);
+			if (copy_to_user(hdr.dxferp, buffer, hdr.dxfer_len))
+				goto out_buffer;
 
 		kfree(buffer);
 	}
+
 	/* may not have succeeded, but output values written to control
 	 * structure (struct sg_io_hdr).  */
 	return 0;
+out_request:
+	blk_put_request(rq);
+out_buffer:
+	kfree(buffer);
+	return -EFAULT;
 }
 
 #define FORMAT_UNIT_TIMEOUT		(2 * 60 * 60 * HZ)
diff -urN linux-2.5.70-bk4/drivers/bluetooth/hci_usb.c linux-2.5.70-bk5/drivers/bluetooth/hci_usb.c
--- linux-2.5.70-bk4/drivers/bluetooth/hci_usb.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk5/drivers/bluetooth/hci_usb.c	2003-05-31 04:35:54.000000000 -0700
@@ -943,6 +943,7 @@
 }
 
 static struct usb_driver hci_usb_driver = {
+	.owner      =  THIS_MODULE,
 	.name       =  "hci_usb",
 	.probe      =  hci_usb_probe,
 	.disconnect =  hci_usb_disconnect,
diff -urN linux-2.5.70-bk4/drivers/char/tty_io.c linux-2.5.70-bk5/drivers/char/tty_io.c
--- linux-2.5.70-bk4/drivers/char/tty_io.c	2003-05-31 04:35:46.000000000 -0700
+++ linux-2.5.70-bk5/drivers/char/tty_io.c	2003-05-31 04:35:54.000000000 -0700
@@ -2241,7 +2241,7 @@
 		return 0;
 
 	if (!driver->major) {
-		error = alloc_chrdev_region(&dev, driver->num,
+		error = alloc_chrdev_region(&dev, driver->minor_start, driver->num,
 						(char*)driver->name);
 		if (!error) {
 			driver->major = MAJOR(dev);
diff -urN linux-2.5.70-bk4/drivers/ide/ide-cd.c linux-2.5.70-bk5/drivers/ide/ide-cd.c
--- linux-2.5.70-bk4/drivers/ide/ide-cd.c	2003-05-31 04:35:46.000000000 -0700
+++ linux-2.5.70-bk5/drivers/ide/ide-cd.c	2003-05-31 04:35:54.000000000 -0700
@@ -666,8 +666,10 @@
 		struct cdrom_info *info = drive->driver_data;
 		void *sense = &info->sense_data;
 		
-		if (failed && failed->sense)
+		if (failed && failed->sense) {
 			sense = failed->sense;
+			failed->sense_len = rq->sense_len;
+		}
 
 		cdrom_analyze_sense_data(drive, failed, sense);
 	}
@@ -723,7 +725,7 @@
 		 * scsi status byte
 		 */
 		if ((rq->flags & REQ_BLOCK_PC) && !rq->errors)
-			rq->errors = CHECK_CONDITION;
+			rq->errors = SAM_STAT_CHECK_CONDITION;
 
 		/* Check for tray open. */
 		if (sense_key == NOT_READY) {
@@ -1471,8 +1473,9 @@
 		/* Keep count of how much data we've moved. */
 		rq->data += thislen;
 		rq->data_len -= thislen;
-		if (rq->cmd[0] == GPCMD_REQUEST_SENSE)
-			rq->sense_len++;
+
+		if (rq->flags & REQ_SENSE)
+			rq->sense_len += thislen;
 	} else {
 confused:
 		printk ("%s: cdrom_pc_intr: The drive "
@@ -1609,12 +1612,20 @@
 
 static void post_transform_command(struct request *req)
 {
-	char *ibuf = req->buffer;
 	u8 *c = req->cmd;
+	char *ibuf;
 
 	if (!blk_pc_request(req))
 		return;
 
+	if (req->bio)
+		ibuf = bio_data(req->bio);
+	else
+		ibuf = req->data;
+
+	if (!ibuf)
+		return;
+
 	/*
 	 * set ansi-revision and response data as atapi
 	 */
diff -urN linux-2.5.70-bk4/drivers/ide/ide.c linux-2.5.70-bk5/drivers/ide/ide.c
--- linux-2.5.70-bk4/drivers/ide/ide.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk5/drivers/ide/ide.c	2003-05-31 04:35:55.000000000 -0700
@@ -462,7 +462,6 @@
 	return -ENXIO;
 }
 
-static LIST_HEAD(ata_unused);
 static spinlock_t drives_lock = SPIN_LOCK_UNLOCKED;
 static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED;
 static LIST_HEAD(drivers);
@@ -1437,9 +1436,6 @@
 	spin_unlock(&drivers_lock);
 	if(idedefault_driver.attach(drive) != 0)
 		panic("ide: default attach failed");
-	spin_lock(&drives_lock);
-	list_add_tail(&drive->list, &ata_unused);
-	spin_unlock(&drives_lock);
 	return 1;
 }
 
@@ -1737,7 +1733,6 @@
  * "hdx=cyl,head,sect"	: disk drive is present, with specified geometry
  * "hdx=remap63"	: add 63 to all sector numbers (for OnTrack DM)
  * "hdx=remap"		: remap 0->1 (for EZDrive)
- * "hdx=noremap"	: do not remap 0->1 even though EZD was detected
  * "hdx=autotune"	: driver will attempt to tune interface speed
  *				to the fastest PIO mode supported,
  *				if possible for this drive only.
@@ -1859,8 +1854,8 @@
 		const char *hd_words[] = {
 			"none", "noprobe", "nowerr", "cdrom", "serialize",
 			"autotune", "noautotune", "slow", "swapdata", "bswap",
-			"flash", "remap", "noremap", "scsi", "biostimings",
-			"remap63", NULL };
+			"flash", "remap", "remap63", "scsi", "biostimings",
+			NULL };
 		unit = s[2] - 'a';
 		hw   = unit / MAX_DRIVES;
 		unit = unit % MAX_DRIVES;
@@ -1920,23 +1915,15 @@
 			case -12: /* "remap" */
 				drive->remap_0_to_1 = 1;
 				goto done;
-			case -13: /* "noremap" */
-				drive->remap_0_to_1 = 2;
+			case -13: /* "remap63" */
+				drive->sect0 = 63;
 				goto done;
 			case -14: /* "scsi" */
-#if defined(CONFIG_BLK_DEV_IDESCSI) && defined(CONFIG_SCSI)
 				drive->scsi = 1;
 				goto done;
-#else
-				drive->scsi = 0;
-				goto bad_option;
-#endif /* defined(CONFIG_BLK_DEV_IDESCSI) && defined(CONFIG_SCSI) */
 			case -15: /* "biostimings" */
 				drive->autotune = IDE_TUNE_BIOS;
 				goto done;
-			case -16: /* "remap63" */
-				drive->sect0 = 63;
-				goto done;
 			case 3: /* cyl,head,sect */
 				drive->media	= ide_disk;
 				drive->cyl	= drive->bios_cyl  = vals[0];
@@ -2392,8 +2379,8 @@
 	spin_unlock_irqrestore(&ide_lock, flags);
 	spin_lock(&drives_lock);
 	list_del_init(&drive->list);
-	list_add(&drive->list, &drive->driver->drives);
 	spin_unlock(&drives_lock);
+	/* drive will be added to &idedefault_driver->drives in ata_attach() */
 	return 0;
 }
 
@@ -2416,9 +2403,9 @@
 	list_add(&driver->drivers, &drivers);
 	spin_unlock(&drivers_lock);
 
-	spin_lock(&drives_lock);
 	INIT_LIST_HEAD(&list);
-	list_splice_init(&ata_unused, &list);
+	spin_lock(&drives_lock);
+	list_splice_init(&idedefault_driver.drives, &list);
 	spin_unlock(&drives_lock);
 
 	list_for_each_safe(list_loop, tmp_storage, &list) {
diff -urN linux-2.5.70-bk4/drivers/isdn/hisax/st5481_init.c linux-2.5.70-bk5/drivers/isdn/hisax/st5481_init.c
--- linux-2.5.70-bk4/drivers/isdn/hisax/st5481_init.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk5/drivers/isdn/hisax/st5481_init.c	2003-05-31 04:35:55.000000000 -0700
@@ -181,6 +181,7 @@
 MODULE_DEVICE_TABLE (usb, st5481_ids);
 
 static struct usb_driver st5481_usb_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"st5481_usb",
 	.probe =	probe_st5481,
 	.disconnect =	disconnect_st5481,
diff -urN linux-2.5.70-bk4/drivers/media/video/cpia_usb.c linux-2.5.70-bk5/drivers/media/video/cpia_usb.c
--- linux-2.5.70-bk4/drivers/media/video/cpia_usb.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk5/drivers/media/video/cpia_usb.c	2003-05-31 04:35:55.000000000 -0700
@@ -586,6 +586,7 @@
 
 
 static struct usb_driver cpia_driver = {
+	.owner		= THIS_MODULE,
 	.name		= "cpia",
 	.probe		= cpia_probe,
 	.disconnect	= cpia_disconnect,
diff -urN linux-2.5.70-bk4/drivers/net/irda/irda-usb.c linux-2.5.70-bk5/drivers/net/irda/irda-usb.c
--- linux-2.5.70-bk4/drivers/net/irda/irda-usb.c	2003-05-31 04:35:48.000000000 -0700
+++ linux-2.5.70-bk5/drivers/net/irda/irda-usb.c	2003-05-31 04:35:56.000000000 -0700
@@ -1607,6 +1607,7 @@
  * USB device callbacks
  */
 static struct usb_driver irda_driver = {
+	.owner		= THIS_MODULE,
 	.name		= "irda-usb",
 	.probe		= irda_usb_probe,
 	.disconnect	= irda_usb_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/Makefile linux-2.5.70-bk5/drivers/usb/Makefile
--- linux-2.5.70-bk4/drivers/usb/Makefile	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/Makefile	2003-05-31 04:35:57.000000000 -0700
@@ -59,3 +59,6 @@
 obj-$(CONFIG_USB_TIGL)		+= misc/
 obj-$(CONFIG_USB_USS720)	+= misc/
 
+obj-$(CONFIG_USB_NET2280)	+= gadget/
+obj-$(CONFIG_USB_ZERO)		+= gadget/
+obj-$(CONFIG_USB_ETH)		+= gadget/
diff -urN linux-2.5.70-bk4/drivers/usb/class/audio.c linux-2.5.70-bk5/drivers/usb/class/audio.c
--- linux-2.5.70-bk4/drivers/usb/class/audio.c	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/class/audio.c	2003-05-31 04:35:57.000000000 -0700
@@ -2753,6 +2753,7 @@
 MODULE_DEVICE_TABLE (usb, usb_audio_ids);
 
 static struct usb_driver usb_audio_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"audio",
 	.probe =	usb_audio_probe,
 	.disconnect =	usb_audio_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/class/bluetty.c linux-2.5.70-bk5/drivers/usb/class/bluetty.c
--- linux-2.5.70-bk4/drivers/usb/class/bluetty.c	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/class/bluetty.c	2003-05-31 04:35:57.000000000 -0700
@@ -234,6 +234,7 @@
 MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
 
 static struct usb_driver usb_bluetooth_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"bluetty",
 	.probe =	usb_bluetooth_probe,
 	.disconnect =	usb_bluetooth_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/class/cdc-acm.c linux-2.5.70-bk5/drivers/usb/class/cdc-acm.c
--- linux-2.5.70-bk4/drivers/usb/class/cdc-acm.c	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/class/cdc-acm.c	2003-05-31 04:35:57.000000000 -0700
@@ -725,6 +725,7 @@
 MODULE_DEVICE_TABLE (usb, acm_ids);
 
 static struct usb_driver acm_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"acm",
 	.probe =	acm_probe,
 	.disconnect =	acm_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/class/usb-midi.c linux-2.5.70-bk5/drivers/usb/class/usb-midi.c
--- linux-2.5.70-bk4/drivers/usb/class/usb-midi.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/class/usb-midi.c	2003-05-31 04:35:57.000000000 -0700
@@ -55,8 +55,6 @@
 
 #undef HAVE_SUPPORT_ALSA
 
-#undef MOD_INC_EACH_PROBE
-
 /* ------------------------------------------------------------------------- */
 
 static int singlebyte = 0;
@@ -925,11 +923,6 @@
 	printk(KERN_INFO "usb-midi: Open Succeeded. minor= %d.\n", minor);
 #endif
 
-	/** Side-effect: module cannot be removed until USE_COUNT is 0. **/
-#ifndef MOD_INC_EACH_PROBE
-	MOD_INC_USE_COUNT;
-#endif
-
 	return 0; /** Success. **/
 }
 
@@ -978,15 +971,11 @@
 	wake_up(&open_wait);
 
 	file->private_data = 0;
-	/** Sideeffect: Module cannot be removed until usecount is 0. */
-#ifndef MOD_INC_EACH_PROBE
-	MOD_DEC_USE_COUNT;
-#endif
-
 	return 0;
 }
 
 static struct file_operations usb_midi_fops = {
+	.owner =	THIS_MODULE,
 	.llseek =	usb_midi_llseek,
 	.read =		usb_midi_read,
 	.write =	usb_midi_write,
@@ -2040,10 +2029,6 @@
 	list_add_tail(&s->mididev, &mididevs);
 	up(&open_sem);
 
-#ifdef MOD_INC_EACH_PROBE
-	MOD_INC_USE_COUNT;
-#endif
-
 	usb_set_intfdata (intf, s);
 	return 0;
 }
@@ -2081,11 +2066,6 @@
 	}
 	release_midi_device(s);
 	wake_up(&open_wait);
-#ifdef MOD_INC_EACH_PROBE
-	MOD_DEC_USE_COUNT;
-#endif
-
-	return;
 }
 
 /* we want to look at all devices by hand */
@@ -2095,6 +2075,7 @@
 };
 
 static struct usb_driver usb_midi_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"midi",
 	.probe =	usb_midi_probe,
 	.disconnect =	usb_midi_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/core/Kconfig linux-2.5.70-bk5/drivers/usb/core/Kconfig
--- linux-2.5.70-bk4/drivers/usb/core/Kconfig	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/core/Kconfig	2003-05-31 04:35:57.000000000 -0700
@@ -19,13 +19,11 @@
 	  If you say Y here (and to "/proc file system support" in the "File
 	  systems" section, above), you will get a file /proc/bus/usb/devices
 	  which lists the devices currently connected to your USB bus or
-	  busses, a file /proc/bus/usb/drivers which lists the USB kernel
-	  client drivers currently loaded, and for every connected device a
-	  file named  "/proc/bus/usb/xxx/yyy", where xxx is the bus number and
-	  yyy the device number; the latter files can be used by user space
-	  programs to talk directly to the device. These files are "virtual",
-	  meaning they are generated on the fly and not stored on the hard
-	  drive.
+	  busses, and for every connected device a file named
+	  "/proc/bus/usb/xxx/yyy", where xxx is the bus number and yyy the
+	  device number; the latter files can be used by user space programs
+	  to talk directly to the device. These files are "virtual", meaning
+	  they are generated on the fly and not stored on the hard drive.
 
 	  You may need to mount the usbfs file system to see the files, use
 	  mount -t usbfs none /proc/bus/usb
diff -urN linux-2.5.70-bk4/drivers/usb/core/devio.c linux-2.5.70-bk5/drivers/usb/core/devio.c
--- linux-2.5.70-bk4/drivers/usb/core/devio.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/core/devio.c	2003-05-31 04:35:57.000000000 -0700
@@ -342,6 +342,7 @@
 }
 
 struct usb_driver usbdevfs_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"usbfs",
 	.probe =	driver_probe,
 	.disconnect =	driver_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/core/hcd.c linux-2.5.70-bk5/drivers/usb/core/hcd.c
--- linux-2.5.70-bk4/drivers/usb/core/hcd.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/core/hcd.c	2003-05-31 04:35:57.000000000 -0700
@@ -720,6 +720,7 @@
 	int retval;
 
 	sprintf (&usb_dev->dev.bus_id[0], "usb%d", usb_dev->bus->busnum);
+	usb_dev->state = USB_STATE_DEFAULT;
 	retval = usb_new_device (usb_dev, parent_dev);
 	if (retval)
 		dev_err (parent_dev, "can't register root hub for %s, %d\n",
diff -urN linux-2.5.70-bk4/drivers/usb/core/hub.c linux-2.5.70-bk5/drivers/usb/core/hub.c
--- linux-2.5.70-bk4/drivers/usb/core/hub.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/core/hub.c	2003-05-31 04:35:57.000000000 -0700
@@ -737,6 +737,9 @@
 		if (status != -1) {
 			usb_clear_port_feature(hub,
 				port + 1, USB_PORT_FEAT_C_RESET);
+			dev->state = status
+					? USB_STATE_NOTATTACHED
+					: USB_STATE_DEFAULT;
 			return status;
 		}
 
@@ -1114,6 +1117,7 @@
 MODULE_DEVICE_TABLE (usb, hub_id_table);
 
 static struct usb_driver hub_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"hub",
 	.probe =	hub_probe,
 	.disconnect =	hub_disconnect,
@@ -1198,12 +1202,18 @@
 	if (port < 0)
 		return -ENOENT;
 
+	descriptor = kmalloc(sizeof *descriptor, GFP_NOIO);
+	if (!descriptor) {
+		return -ENOMEM;
+	}
+
 	down(&usb_address0_sem);
 
 	/* Send a reset to the device */
 	if (usb_hub_port_reset(parent, port, dev, HUB_SHORT_RESET_TIME)) {
 		usb_hub_port_disable(parent, port);
 		up(&usb_address0_sem);
+		kfree(descriptor);
 		return(-ENODEV);
 	}
 
@@ -1213,6 +1223,7 @@
 		err("USB device not accepting new address (error=%d)", ret);
 		usb_hub_port_disable(parent, port);
 		up(&usb_address0_sem);
+		kfree(descriptor);
 		return ret;
 	}
 
@@ -1230,10 +1241,7 @@
 	 * If nothing changed, we reprogram the configuration and then
 	 * the alternate settings.
 	 */
-	descriptor = kmalloc(sizeof *descriptor, GFP_NOIO);
-	if (!descriptor) {
-		return -ENOMEM;
-	}
+
 	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, descriptor,
 			sizeof(*descriptor));
 	if (ret < 0) {
@@ -1260,7 +1268,7 @@
 					"(expected %Zi, got %i)",
 					dev->devpath,
 					sizeof(dev->descriptor), ret);
-        
+
 			clear_bit(dev->devnum, dev->bus->devmap.devicemap);
 			dev->devnum = -1;
 			return -EIO;
diff -urN linux-2.5.70-bk4/drivers/usb/core/usb.c linux-2.5.70-bk5/drivers/usb/core/usb.c
--- linux-2.5.70-bk4/drivers/usb/core/usb.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/core/usb.c	2003-05-31 04:35:57.000000000 -0700
@@ -1017,9 +1017,6 @@
 	/* dma masks come from the controller; readonly, except to hcd */
 	dev->dev.dma_mask = parent->dma_mask;
 
-	/* it's not usable yet */
-	dev->state = USB_STATE_DEFAULT;
-
 	/* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
 	 * it's fixed size except for full speed devices.
 	 */
diff -urN linux-2.5.70-bk4/drivers/usb/gadget/ether.c linux-2.5.70-bk5/drivers/usb/gadget/ether.c
--- linux-2.5.70-bk4/drivers/usb/gadget/ether.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/gadget/ether.c	2003-05-31 04:35:57.000000000 -0700
@@ -76,6 +76,7 @@
 
 #define MIN_PACKET	sizeof(struct ethhdr)
 #define	MAX_PACKET	ETH_DATA_LEN	/* biggest packet we'll rx/tx */
+#define RX_EXTRA	20		/* guard against rx overflows */
 
 /* FIXME allow high speed jumbograms */
 
@@ -1226,7 +1227,7 @@
 	int			retval = 0;
 	size_t			size;
 
-	size = (sizeof (struct ethhdr) + dev->net.mtu);
+	size = (sizeof (struct ethhdr) + dev->net.mtu + RX_EXTRA);
 
 	if ((skb = alloc_skb (size, gfp_flags)) == 0) {
 		DEBUG (dev, "no rx skb\n");
diff -urN linux-2.5.70-bk4/drivers/usb/image/hpusbscsi.c linux-2.5.70-bk5/drivers/usb/image/hpusbscsi.c
--- linux-2.5.70-bk4/drivers/usb/image/hpusbscsi.c	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/image/hpusbscsi.c	2003-05-31 04:35:57.000000000 -0700
@@ -22,65 +22,56 @@
 
 #define TRACE_STATE printk(KERN_DEBUG"hpusbscsi->state = %s at line %d\n", states[hpusbscsi->state], __LINE__)
 
-/* global variables */
-
-struct list_head hpusbscsi_devices;
-//LIST_HEAD(hpusbscsi_devices);
-
-/* USB related parts */
+static Scsi_Host_Template hpusbscsi_scsi_host_template = {
+	.module			= THIS_MODULE,
+	.name			= "hpusbscsi",
+	.proc_name		= "hpusbscsi",
+	.queuecommand		= hpusbscsi_scsi_queuecommand,
+	.eh_abort_handler	= hpusbscsi_scsi_abort,
+	.eh_host_reset_handler	= hpusbscsi_scsi_host_reset,
+	.sg_tablesize		= SG_ALL,
+	.can_queue		= 1,
+	.this_id		= -1,
+	.cmd_per_lun		= 1,
+	.use_clustering		= 1,
+	.emulated		= 1,
+};
 
 static int
-hpusbscsi_usb_probe (struct usb_interface *intf,
-		     const struct usb_device_id *id)
+hpusbscsi_usb_probe(struct usb_interface *intf,
+		    const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
+	struct usb_host_interface *altsetting =	intf->altsetting;
 	struct hpusbscsi *new;
-	struct usb_device *dev = interface_to_usbdev (intf);
-	struct usb_host_interface *altsetting =
-		&(intf->altsetting[0]);
-
+	int error = -ENOMEM;
 	int i, result;
 
-	/* basic check */
-
 	if (altsetting->desc.bNumEndpoints != 3) {
 		printk (KERN_ERR "Wrong number of endpoints\n");
 		return -ENODEV;
 	}
 
-	/* descriptor allocation */
-
-	new =
-		(struct hpusbscsi *) kmalloc (sizeof (struct hpusbscsi),
-					      GFP_KERNEL);
-	if (new == NULL)
+	new = kmalloc(sizeof(struct hpusbscsi), GFP_KERNEL);
+	if (!new)
 		return -ENOMEM;
-	DEBUG ("Allocated memory\n");
-	memset (new, 0, sizeof (struct hpusbscsi));
+	memset(new, 0, sizeof(struct hpusbscsi));
 	new->dataurb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!new->dataurb) {
-		kfree (new);
-		return -ENOMEM;
-	}
+	if (!new->dataurb)
+		goto out_kfree;
 	new->controlurb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!new->controlurb) {
-		usb_free_urb (new->dataurb);
-		kfree (new);
-		return -ENOMEM;
-	}
-	new->dev = dev;
-	init_waitqueue_head (&new->pending);
-	init_waitqueue_head (&new->deathrow);
-	INIT_LIST_HEAD (&new->lh);
-
-
+	if (!new->controlurb)
+		goto out_free_dataurb;
 
-	/* finding endpoints */
+	new->dev = dev;
+	init_waitqueue_head(&new->pending);
+	init_waitqueue_head(&new->deathrow);
 
+	error = -ENODEV;
 	for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
-		if (
-		    (altsetting->endpoint[i].desc.
+		if ((altsetting->endpoint[i].desc.
 		     bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-		    USB_ENDPOINT_XFER_BULK) {
+				USB_ENDPOINT_XFER_BULK) {
 			if (altsetting->endpoint[i].desc.
 			    bEndpointAddress & USB_DIR_IN) {
 				new->ep_in =
@@ -97,57 +88,71 @@
 			new->ep_int =
 				altsetting->endpoint[i].desc.
 				bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
-			new->interrupt_interval= altsetting->endpoint[i].desc.bInterval;
+			new->interrupt_interval= altsetting->endpoint[i].desc.
+				bInterval;
 		}
 	}
 
 	/* USB initialisation magic for the simple case */
-
-	result = usb_set_interface (dev, altsetting->desc.bInterfaceNumber, 0);
-
+	result = usb_set_interface(dev, altsetting->desc.bInterfaceNumber, 0);
 	switch (result) {
 	case 0:		/* no error */
 		break;
 	default:
-		printk (KERN_ERR "unknown error %d from usb_set_interface\n",
+		printk(KERN_ERR "unknown error %d from usb_set_interface\n",
 			 result);
-		goto err_out;
+		goto out_free_controlurb;
 	}
 
-	/* making a template for the scsi layer to fake detection of a scsi device */
+	/* build and submit an interrupt URB for status byte handling */
+ 	usb_fill_int_urb(new->controlurb, new->dev,
+			usb_rcvintpipe(new->dev, new->ep_int),
+			&new->scsi_state_byte, 1,
+			control_interrupt_callback,new,
+			new->interrupt_interval);
+
+	if (usb_submit_urb(new->controlurb, GFP_KERNEL) < 0)
+		goto out_free_controlurb;
 
-	memcpy (&(new->ctempl), &hpusbscsi_scsi_host_template,
-		sizeof (hpusbscsi_scsi_host_template));
-	(struct hpusbscsi *) new->ctempl.proc_dir = new;
-	new->ctempl.module = THIS_MODULE;
+	/* In host->hostdata we store a pointer to desc */
+	new->host = scsi_register(&hpusbscsi_scsi_host_template, sizeof(new));
+	if (!new->host)
+		goto out_unlink_controlurb;
 
-	if (scsi_register_host(&new->ctempl))
-		goto err_out;
+	new->host->hostdata[0] = (unsigned long)new;
+	scsi_add_host(new->host, &intf->dev);
 
 	new->sense_command[0] = REQUEST_SENSE;
 	new->sense_command[4] = HPUSBSCSI_SENSE_LENGTH;
 
-	/* adding to list for module unload */
-	list_add (&hpusbscsi_devices, &new->lh);
-
 	usb_set_intfdata(intf, new);
 	return 0;
 
-      err_out:
-	usb_free_urb (new->controlurb);
-	usb_free_urb (new->dataurb);
-	kfree (new);
-	return -ENODEV;
+ out_unlink_controlurb:
+	usb_unlink_urb(new->controlurb);
+ out_free_controlurb:
+	usb_free_urb(new->controlurb);
+ out_free_dataurb:
+	usb_free_urb(new->dataurb);
+ out_kfree:
+	kfree(new);
+	return error;
 }
 
 static void
-hpusbscsi_usb_disconnect (struct usb_interface *intf)
+hpusbscsi_usb_disconnect(struct usb_interface *intf)
 {
 	struct hpusbscsi *desc = usb_get_intfdata(intf);
 
 	usb_set_intfdata(intf, NULL);
-	if (desc)
-		usb_unlink_urb(desc->controlurb);
+
+	scsi_remove_host(desc->host);
+	usb_unlink_urb(desc->controlurb);
+	scsi_unregister(desc->host);
+
+	usb_free_urb(desc->controlurb);
+	usb_free_urb(desc->dataurb);
+	kfree(desc);
 }
 
 static struct usb_device_id hpusbscsi_usb_ids[] = {
@@ -169,6 +174,7 @@
 
 
 static struct usb_driver hpusbscsi_usb_driver = {
+	.owner = THIS_MODULE,
 	.name ="hpusbscsi",
 	.probe =hpusbscsi_usb_probe,
 	.disconnect =hpusbscsi_usb_disconnect,
@@ -177,101 +183,21 @@
 
 /* module initialisation */
 
-int __init
+static int __init
 hpusbscsi_init (void)
 {
-	int result;
-
-	INIT_LIST_HEAD (&hpusbscsi_devices);
-	DEBUG ("Driver loaded\n");
-
-	if ((result = usb_register (&hpusbscsi_usb_driver)) < 0) {
-		printk (KERN_ERR "hpusbscsi: driver registration failed\n");
-		return -1;
-	} else {
-		return 0;
-	}
+	return usb_register(&hpusbscsi_usb_driver);
 }
 
-void __exit
+static void __exit
 hpusbscsi_exit (void)
 {
-	struct list_head *tmp;
-	struct list_head *old;
-	struct hpusbscsi * o;
-
-	for (tmp = hpusbscsi_devices.next; tmp != &hpusbscsi_devices;/*nothing */) {
-		old = tmp;
-		tmp = tmp->next;
-		o = (struct hpusbscsi *)old;
-		usb_unlink_urb(o->controlurb);
-		scsi_unregister_host(&o->ctempl);
-		usb_free_urb(o->controlurb);
-		usb_free_urb(o->dataurb);
-		kfree(old);
-	}
-
-	usb_deregister (&hpusbscsi_usb_driver);
+	usb_deregister(&hpusbscsi_usb_driver);
 }
 
 module_init (hpusbscsi_init);
 module_exit (hpusbscsi_exit);
 
-/* interface to the scsi layer */
-
-static int
-hpusbscsi_scsi_detect (struct SHT *sht)
-{
-	/* Whole function stolen from usb-storage */
-
-	struct hpusbscsi *desc = (struct hpusbscsi *) sht->proc_dir;
-	/* What a hideous hack! */
-
-	char local_name[48];
-
-
-	/* set up the name of our subdirectory under /proc/scsi/ */
-	sprintf (local_name, "hpusbscsi-%d", desc->number);
-	sht->proc_name = kmalloc (strlen (local_name) + 1, GFP_KERNEL);
-	/* FIXME: where is this freed ? */
-
-	if (!sht->proc_name) {
-		return 0;
-	}
-
-	strcpy (sht->proc_name, local_name);
-
-	sht->proc_dir = NULL;
-
-	/* build and submit an interrupt URB for status byte handling */
- 	usb_fill_int_urb(desc->controlurb,
-			desc->dev,
-			usb_rcvintpipe(desc->dev,desc->ep_int),
-			&desc->scsi_state_byte,
-			1,
-			control_interrupt_callback,
-			desc,
-			desc->interrupt_interval
-	);
-
-	if ( 0  >  usb_submit_urb(desc->controlurb, GFP_KERNEL)) {
-		kfree(sht->proc_name);
-		return 0;
-	}
-
-	/* In host->hostdata we store a pointer to desc */
-	desc->host = scsi_register (sht, sizeof (desc));
-	if (desc->host == NULL) {
-		kfree (sht->proc_name);
-		usb_unlink_urb(desc->controlurb);
-		return 0;
-	}
-	desc->host->hostdata[0] = (unsigned long) desc;
-
-
-	return 1;
-}
-
 static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback)
 {
 	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]);
diff -urN linux-2.5.70-bk4/drivers/usb/image/hpusbscsi.h linux-2.5.70-bk5/drivers/usb/image/hpusbscsi.h
--- linux-2.5.70-bk4/drivers/usb/image/hpusbscsi.h	2003-05-26 18:00:23.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/image/hpusbscsi.h	2003-05-31 04:35:57.000000000 -0700
@@ -13,7 +13,6 @@
 
 struct hpusbscsi
 {
-        struct list_head lh;
         struct usb_device *dev; /* NULL indicates unplugged device */
         int ep_out;
         int ep_in;
@@ -36,7 +35,6 @@
 
         int state;
         int current_data_pipe;
-	Scsi_Host_Template ctempl;
 	u8 sense_command[SENSE_COMMAND_SIZE];
         u8 scsi_state_byte;
 };
@@ -52,7 +50,6 @@
 
 #define DIRECTION_IS_IN(x) ((scsi_command_direction[x>>3] >> (x & 7)) & 1)
 
-static int hpusbscsi_scsi_detect (struct SHT * sht);
 static void simple_command_callback(struct urb *u, struct pt_regs *regs);
 static void scatter_gather_callback(struct urb *u, struct pt_regs *regs);
 static void simple_payload_callback (struct urb *u, struct pt_regs *regs);
@@ -64,25 +61,6 @@
 static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb);
 static void issue_request_sense (struct hpusbscsi *hpusbscsi);
 
-static Scsi_Host_Template hpusbscsi_scsi_host_template = {
-	.name			= "hpusbscsi",
-	.detect			= hpusbscsi_scsi_detect,
-//	.release		= hpusbscsi_scsi_release,
-	.queuecommand		= hpusbscsi_scsi_queuecommand,
-
-	.eh_abort_handler	= hpusbscsi_scsi_abort,
-	.eh_host_reset_handler	= hpusbscsi_scsi_host_reset,
-
-	.sg_tablesize		= SG_ALL,
-	.can_queue		= 1,
-	.this_id		= -1,
-	.cmd_per_lun		= 1,
-	.present		= 0,
-	.unchecked_isa_dma	= FALSE,
-	.use_clustering		= TRUE,
-	.emulated		= TRUE
-};
-
 /* defines for internal driver state */
 #define HP_STATE_FREE                 0  /*ready for next request */
 #define HP_STATE_BEGINNING      1  /*command being transferred */
diff -urN linux-2.5.70-bk4/drivers/usb/image/microtek.c linux-2.5.70-bk5/drivers/usb/image/microtek.c
--- linux-2.5.70-bk4/drivers/usb/image/microtek.c	2003-05-26 18:01:03.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/image/microtek.c	2003-05-31 04:35:57.000000000 -0700
@@ -160,6 +160,7 @@
 static struct usb_device_id mts_usb_ids [];
 
 static struct usb_driver mts_usb_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"microtekX6",
 	.probe =	mts_usb_probe,
 	.disconnect =	mts_usb_disconnect,
@@ -326,76 +327,6 @@
 	usb_unlink_urb( desc->urb );
 }
 
-static struct mts_desc * mts_list; /* list of active scanners */
-struct semaphore mts_list_semaphore;
-
-/* Internal list operations */
-
-static
-void mts_remove_nolock( struct mts_desc* to_remove )
-{
-	MTS_DEBUG( "removing 0x%x from list\n",
-		   (int)to_remove );
-
-	lock_kernel();
-	mts_urb_abort(to_remove);
-
-	MTS_DEBUG_GOT_HERE();
-
-	if ( to_remove != mts_list ) {
-		MTS_DEBUG_GOT_HERE();
-		if (to_remove->prev && to_remove->next)
-			to_remove->prev->next = to_remove->next;
-	} else {
-		MTS_DEBUG_GOT_HERE();
-		mts_list = to_remove->next;
-		if (mts_list) {
-			MTS_DEBUG_GOT_HERE();
-			mts_list->prev = 0;
-		}
-	}
-
-	if ( to_remove->next ) {
-		MTS_DEBUG_GOT_HERE();
-		to_remove->next->prev = to_remove->prev;
-	}
-
-	MTS_DEBUG_GOT_HERE();
-	scsi_unregister_host(&to_remove->ctempl);
-	unlock_kernel();
-
-	usb_free_urb(to_remove->urb);
-	kfree( to_remove );
-}
-
-static
-void mts_add_nolock( struct mts_desc* to_add )
-{
-	MTS_DEBUG( "adding 0x%x to list\n", (int)to_add );
-
-	to_add->prev = 0;
-	to_add->next = mts_list;
-	if ( mts_list ) {
-		mts_list->prev = to_add;
-	}
-
-	mts_list = to_add;
-}
-
-
-
-
-/* SCSI driver interface */
-
-/* scsi related functions - dummies for now mostly */
-
-static int mts_scsi_release(struct Scsi_Host *psh)
-{
-	MTS_DEBUG_GOT_HERE();
-
-	return 0;
-}
-
 static int mts_scsi_abort (Scsi_Cmnd *srb)
 {
 	struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
@@ -418,54 +349,6 @@
 	return 0;  /* RANT why here 0 and not SUCCESS */
 }
 
-/* the core of the scsi part */
-
-/* faking a detection - which can't fail :-) */
-
-static int mts_scsi_detect (struct SHT * sht)
-{
-	/* Whole function stolen from usb-storage */
-
-	struct mts_desc * desc = (struct mts_desc *)sht->proc_dir;
-	/* What a hideous hack! */
-
-	char local_name[48];
-
-	MTS_DEBUG_GOT_HERE();
-
-	/* set up the name of our subdirectory under /proc/scsi/ */
-	sprintf(local_name, "microtek-%d", desc->host_number);
-	sht->proc_name = kmalloc (strlen(local_name) + 1, GFP_KERNEL);
-	/* FIXME: where is this freed ? */
-
-	if (!sht->proc_name) {
-		MTS_ERROR( "unable to allocate memory for proc interface!!\n" );
-		return 0;
-	}
-
-	strcpy(sht->proc_name, local_name);
-
- 	sht->proc_dir = NULL;
-
-	/* In host->hostdata we store a pointer to desc */
-	desc->host = scsi_register(sht, sizeof(desc));
-	if (desc->host == NULL) {
-		MTS_ERROR("Cannot register due to low memory");
-		kfree(sht->proc_name);
-		return 0;
-	}
-	desc->host->hostdata[0] = (unsigned long)desc;
-/* FIXME: what if sizeof(void*) != sizeof(unsigned long)? */
-
-	return 1;
-}
-
-
-
-/* Main entrypoint: SCSI commands are dispatched to here */
-
-
-
 static
 int mts_scsi_queuecommand (Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback );
 
@@ -743,52 +626,22 @@
 out:
 	return err;
 }
-/*
- * this defines our 'host'
- */
-
-/* NOTE: This is taken from usb-storage, should be right. */
-
 
 static Scsi_Host_Template mts_scsi_host_template = {
-	.name =         "microtekX6",
-	.detect =	mts_scsi_detect,
-	.release =	mts_scsi_release,
-	.queuecommand =	mts_scsi_queuecommand,
-
-	.eh_abort_handler =	mts_scsi_abort,
-	.eh_host_reset_handler =mts_scsi_host_reset,
-
+	.module			= THIS_MODULE,
+	.name			= "microtekX6",
+	.proc_name		= "microtekX6",
+	.queuecommand		= mts_scsi_queuecommand,
+	.eh_abort_handler	= mts_scsi_abort,
+	.eh_host_reset_handler	= mts_scsi_host_reset,
 	.sg_tablesize =		SG_ALL,
 	.can_queue =		1,
 	.this_id =		-1,
 	.cmd_per_lun =		1,
-	.present =		0,
-	.unchecked_isa_dma =	FALSE,
-	.use_clustering =	TRUE,
-	.emulated =		TRUE
+	.use_clustering =	1,
+	.emulated =		1,
 };
 
-
-/* USB layer driver interface implementation */
-
-static void mts_usb_disconnect (struct usb_interface *intf)
-{
-	struct mts_desc* to_remove = usb_get_intfdata(intf);
-
-	MTS_DEBUG_GOT_HERE();
-
-	usb_set_intfdata(intf, NULL);
-	if (to_remove) {
-		/* leave the list - lock it */
-		down(&mts_list_semaphore);
-
-		mts_remove_nolock(to_remove);
-
-		up(&mts_list_semaphore);
-	}
-}
-
 struct vendor_product
 {
 	char* name;
@@ -836,8 +689,8 @@
 MODULE_DEVICE_TABLE (usb, mts_usb_ids);
 
 
-static int mts_usb_probe (struct usb_interface *intf,
-			  const struct usb_device_id *id)
+static int mts_usb_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id)
 {
 	int i;
 	int result;
@@ -929,39 +782,23 @@
 	}
 	
 	
-	/* allocating a new descriptor */
-	new_desc = (struct mts_desc *)kmalloc(sizeof(struct mts_desc), GFP_KERNEL);
-	if (new_desc == NULL)
-	{
-		MTS_ERROR("couldn't allocate scanner desc, bailing out!\n");
-		return -ENOMEM;
-	}
+	new_desc = kmalloc(sizeof(struct mts_desc), GFP_KERNEL);
+	if (!new_desc)
+		goto out;
 
-	memset( new_desc, 0, sizeof(*new_desc) );
+	memset(new_desc, 0, sizeof(*new_desc));
 	new_desc->urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!new_desc->urb) {
-		kfree(new_desc);
-		return -ENOMEM;
-	}
-		
-	/* initialising that descriptor */
-	new_desc->usb_dev = dev;
+	if (!new_desc->urb)
+		goto out_kfree;
 
+	new_desc->usb_dev = dev;
 	init_MUTEX(&new_desc->lock);
 
-	if(mts_list){
-		new_desc->host_number = mts_list->host_number+1;
-	} else {
-		new_desc->host_number = 0;
-	}
-	
 	/* endpoints */
-	
 	new_desc->ep_out = ep_out;
 	new_desc->ep_response = ep_in_set[0];
 	new_desc->ep_image = ep_in_set[1];
 
-
 	if ( new_desc->ep_out != MTS_EP_OUT )
 		MTS_WARNING( "will this work? Command EP is not usually %d\n",
 			     (int)new_desc->ep_out );
@@ -974,87 +811,48 @@
 		MTS_WARNING( "will this work? Image data EP is not usually %d\n",
 			     (int)new_desc->ep_image );
 
+	new_desc->host = scsi_register(&mts_scsi_host_template,
+			sizeof(new_desc));
+	if (!new_desc->host)
+		goto out_free_urb;
 
-	/* Initialize the host template based on the default one */
-	memcpy(&(new_desc->ctempl), &mts_scsi_host_template, sizeof(mts_scsi_host_template));
-	/* HACK from usb-storage - this is needed for scsi detection */
-	(struct mts_desc *)new_desc->ctempl.proc_dir = new_desc; /* FIXME */
-
-	MTS_DEBUG("registering SCSI module\n");
-
-	new_desc->ctempl.module = THIS_MODULE;
-	result = scsi_register_host(&new_desc->ctempl);
-	/* Will get hit back in microtek_detect by this func */
-	if ( result )
-	{
-		MTS_ERROR( "error %d from scsi_register_host! Help!\n",
-			   (int)result );
-
-		/* FIXME: need more cleanup? */
-		kfree( new_desc );
-		return -ENOMEM;
-	}
-	MTS_DEBUG_GOT_HERE();
-
-	/* FIXME: the bomb is armed, must the host be registered under lock ? */
-	/* join the list - lock it */
-	down(&mts_list_semaphore);
-
-	mts_add_nolock( new_desc );
-
-	up(&mts_list_semaphore);
-
-
-	MTS_DEBUG("completed probe and exiting happily\n");
+	new_desc->host->hostdata[0] = (unsigned long)new_desc;
+	scsi_add_host(new_desc->host, NULL);
 
 	usb_set_intfdata(intf, new_desc);
 	return 0;
-}
-
 
+ out_free_urb:
+	usb_free_urb(new_desc->urb);
+ out_kfree:
+	kfree(new_desc);
+ out:
+	return -ENOMEM;
+}
 
-/* get us noticed by the rest of the kernel */
-
-int __init microtek_drv_init(void)
+static void mts_usb_disconnect (struct usb_interface *intf)
 {
-	int result;
-
-	MTS_DEBUG_GOT_HERE();
-	init_MUTEX(&mts_list_semaphore);
+	struct mts_desc *desc = usb_get_intfdata(intf);
 
-	if ((result = usb_register(&mts_usb_driver)) < 0) {
-		MTS_DEBUG("usb_register returned %d\n", result );
-		return -1;
-	} else {
-		MTS_DEBUG("driver registered.\n");
-	}
+	usb_set_intfdata(intf, NULL);
 
-	info(DRIVER_VERSION ":" DRIVER_DESC);
+	scsi_remove_host(desc->host);
+	usb_unlink_urb(desc->urb);
+	scsi_unregister(desc->host);
 
-	return 0;
+	usb_free_urb(desc->urb);
+	kfree(desc);
 }
 
-void __exit microtek_drv_exit(void)
-{
-	struct mts_desc* next;
 
-	MTS_DEBUG_GOT_HERE();
+static int __init microtek_drv_init(void)
+{
+	return usb_register(&mts_usb_driver);
+}
 
+static void __exit microtek_drv_exit(void)
+{
 	usb_deregister(&mts_usb_driver);
-
-	down(&mts_list_semaphore);
-
-	while (mts_list) {
-		/* keep track of where the next one is */
-		next = mts_list->next;
-
-		mts_remove_nolock( mts_list );
-
-		/* advance the list pointer */
-		mts_list = next;
-	}
-
-	up(&mts_list_semaphore);
 }
 
 module_init(microtek_drv_init);
diff -urN linux-2.5.70-bk4/drivers/usb/image/microtek.h linux-2.5.70-bk5/drivers/usb/image/microtek.h
--- linux-2.5.70-bk4/drivers/usb/image/microtek.h	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/image/microtek.h	2003-05-31 04:35:57.000000000 -0700
@@ -38,9 +38,6 @@
 	u8 ep_image;
 
 	struct Scsi_Host * host;
-	Scsi_Host_Template ctempl;
-	int host_number;
-
 	struct semaphore lock;
 
 	struct urb *urb;
diff -urN linux-2.5.70-bk4/drivers/usb/image/scanner.c linux-2.5.70-bk5/drivers/usb/image/scanner.c
--- linux-2.5.70-bk4/drivers/usb/image/scanner.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/image/scanner.c	2003-05-31 04:35:57.000000000 -0700
@@ -359,6 +359,11 @@
  *    - Fixed endpoint detection. The endpoints were numbered from 1 to n but
  *      that assumption is not correct in all cases.
  *
+ * 0.4.13  2003-05-30
+ *    - Added vendor/product ids for Genius, Hewlett-Packard, Microtek, 
+ *      Mustek, Pacific Image Electronics, Plustek, and Visioneer scanners.
+ *      Fixed names of some other scanners.
+ *
  * TODO
  *    - Performance
  *    - Select/poll methods
@@ -1106,6 +1111,9 @@
 	scn->scn_minor = intf->minor;
 	scn->isopen = 0;
 
+	snprintf(name, sizeof(name), scanner_class.name,
+		 intf->minor - scanner_class.minor_base);
+
 	info ("USB scanner device (0x%04x/0x%04x) now attached to %s",
 	      dev->descriptor.idVendor, dev->descriptor.idProduct, name);
 
@@ -1144,6 +1152,7 @@
 
 static struct
 usb_driver scanner_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"usbscanner",
 	.probe =	probe_scanner,
 	.disconnect =	disconnect_scanner,
diff -urN linux-2.5.70-bk4/drivers/usb/image/scanner.h linux-2.5.70-bk5/drivers/usb/image/scanner.h
--- linux-2.5.70-bk4/drivers/usb/image/scanner.h	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/image/scanner.h	2003-05-31 04:35:57.000000000 -0700
@@ -43,7 +43,7 @@
 
 // #define DEBUG
 
-#define DRIVER_VERSION "0.4.11"
+#define DRIVER_VERSION "0.4.13"
 #define DRIVER_DESC "USB Scanner Driver"
 
 #include <linux/usb.h>
@@ -70,7 +70,7 @@
 
 static struct usb_device_id scanner_device_ids [] = {
 	/* Acer (now Benq) */
-	{ USB_DEVICE(0x04a5, 0x1a20) },	/* Unknown - Oliver Schwartz */
+	{ USB_DEVICE(0x04a5, 0x1a20) },	/* Prisa 310U */
 	{ USB_DEVICE(0x04a5, 0x1a2a) },	/* Another 620U */
 	{ USB_DEVICE(0x04a5, 0x2022) },	/* 340U */
 	{ USB_DEVICE(0x04a5, 0x2040) },	/* 620U (!) */
@@ -101,6 +101,7 @@
 	{ USB_DEVICE(0x05d8, 0x4003) }, /* E+ 48U */
 	{ USB_DEVICE(0x05d8, 0x4004) }, /* E+ Pro */
 	/* Avision */
+	{ USB_DEVICE(0x0638, 0x0268) }, /* iVina 1200U */
 	{ USB_DEVICE(0x0638, 0x0a10) },	/* iVina FB1600 (=Umax Astra 4500) */
 	/* Benq: see Acer */
 	/* Brother */
@@ -138,6 +139,7 @@
 	{ USB_DEVICE(0x0458, 0x2013) }, /* ColorPage HR7 */
 	{ USB_DEVICE(0x0458, 0x2015) }, /* ColorPage HR7LE */
 	{ USB_DEVICE(0x0458, 0x2016) }, /* ColorPage HR6X */
+	{ USB_DEVICE(0x0458, 0x2018) },	/* ColorPage HR7X */
 	/* Hewlett Packard */
 	{ USB_DEVICE(0x03f0, 0x0101) },	/* ScanJet 4100C */
 	{ USB_DEVICE(0x03f0, 0x0102) },	/* PhotoSmart S20 */
@@ -157,10 +159,10 @@
 	{ USB_DEVICE(0x03F0, 0x1005) },	/* ScanJet 5400C */
 	{ USB_DEVICE(0x03F0, 0x1105) },	/* ScanJet 5470C */
 	{ USB_DEVICE(0x03f0, 0x1305) },	/* Scanjet 4570c */
+	{ USB_DEVICE(0x03f0, 0x1411) }, /* PSC 750 */
 	{ USB_DEVICE(0x03f0, 0x2005) },	/* ScanJet 3570c */
 	{ USB_DEVICE(0x03f0, 0x2205) },	/* ScanJet 3500c */
-	/* iVina */
-	{ USB_DEVICE(0x0638, 0x0268) }, /* 1200U */
+	{ USB_DEVICE(0x03f0, 0x2f11) }, /* PSC 1210 */
 	/* Lexmark */
 	{ USB_DEVICE(0x043d, 0x002d) }, /* X70/X73 */
 	{ USB_DEVICE(0x043d, 0x003d) }, /* X83 */
@@ -173,6 +175,7 @@
 	/* Microtek */
 	{ USB_DEVICE(0x05da, 0x30ce) },	/* ScanMaker 3800 */
 	{ USB_DEVICE(0x05da, 0x30cf) },	/* ScanMaker 4800 */
+	{ USB_DEVICE(0x04a7, 0x0224) },	/* Scanport 3000 (actually Visioneer?)*/
 	/* The following SCSI-over-USB Microtek devices are supported by the
 	   microtek driver: Enable SCSI and USB Microtek in kernel config */
 	//	{ USB_DEVICE(0x05da, 0x0099) },	/* ScanMaker X6 - X6U */
@@ -205,25 +208,30 @@
 	{ USB_DEVICE(0x055f, 0x021d) }, /* Bearpaw 2400 CU Plus */
 	{ USB_DEVICE(0x055f, 0x021e) }, /* BearPaw 1200 TA/CS */
 	{ USB_DEVICE(0x055f, 0x0400) }, /* BearPaw 2400 TA PRO */
+	{ USB_DEVICE(0x055f, 0x0401) },	/* P 3600 A3 Pro */
 	{ USB_DEVICE(0x055f, 0x0873) }, /* ScanExpress 600 USB */
 	{ USB_DEVICE(0x055f, 0x1000) }, /* BearPaw 4800 TA PRO */
 	//	{ USB_DEVICE(0x05d8, 0x4002) }, /* BearPaw 1200 CU and ScanExpress 1200 UB Plus (see Artec) */
 	/* Nikon */
 	{ USB_DEVICE(0x04b0, 0x4000) }, /* Coolscan LS 40 ED */
+	/* Pacific Image Electronics */
+	{ USB_DEVICE(0x05e3, 0x0120) },	/* PrimeFilm 1800u */
 	/* Plustek */
+	{ USB_DEVICE(0x07b3, 0x0001) },	/* 1212U */
 	{ USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x0010) }, /* OpticPro U12 */
 	{ USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro U24 */
 	{ USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */
-	{ USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0013) }, /* UT12 */
 	{ USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x0015) }, /* OpticPro U24 */
 	{ USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/UT24 */
 	{ USB_DEVICE(0x07b3, 0x0400) }, /* OpticPro 1248U */
 	{ USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U (another one) */
+	{ USB_DEVICE(0x07b3, 0x0403) },	/* U16B */
 	/* Primax/Colorado */
 	{ USB_DEVICE(0x0461, 0x0300) },	/* G2-300 #1 */
 	{ USB_DEVICE(0x0461, 0x0301) },	/* G2E-300 #1 */
@@ -281,6 +289,8 @@
 	/* Visioneer */
 	{ USB_DEVICE(0x04a7, 0x0211) },	/* OneTouch 7600 USB */
 	{ USB_DEVICE(0x04a7, 0x0221) },	/* OneTouch 5300 USB */
+	{ USB_DEVICE(0x04a7, 0x0224) },	/* OneTouch 4800 USB */
+	{ USB_DEVICE(0x04a7, 0x0226) },	/* OneTouch 5300 USB */
 	{ USB_DEVICE(0x04a7, 0x0231) },	/* 6100 USB */
 	{ USB_DEVICE(0x04a7, 0x0311) },	/* 6200 EPP/USB */
 	{ USB_DEVICE(0x04a7, 0x0321) },	/* OneTouch 8100 EPP/USB */
diff -urN linux-2.5.70-bk4/drivers/usb/input/aiptek.c linux-2.5.70-bk5/drivers/usb/input/aiptek.c
--- linux-2.5.70-bk4/drivers/usb/input/aiptek.c	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/aiptek.c	2003-05-31 04:35:57.000000000 -0700
@@ -357,6 +357,7 @@
 }
 
 static struct usb_driver aiptek_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"aiptek",
 	.probe =	aiptek_probe,
 	.disconnect =	aiptek_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/input/hid-core.c linux-2.5.70-bk5/drivers/usb/input/hid-core.c
--- linux-2.5.70-bk4/drivers/usb/input/hid-core.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/hid-core.c	2003-05-31 04:35:57.000000000 -0700
@@ -1387,9 +1387,9 @@
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_HIDDEV },
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_HIDDEV },
 	{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
-	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD },
-	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD },
-	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD },
+	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD|HID_QUIRK_MULTI_INPUT },
+	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD|HID_QUIRK_MULTI_INPUT },
+	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD|HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE },
@@ -1629,8 +1629,6 @@
 	hid_init_reports(hid);
 	hid_dump_device(hid);
 
-	hid_ff_init(hid);
-
 	if (!hidinput_connect(hid))
 		hid->claimed |= HID_CLAIMED_INPUT;
 	if (!hiddev_connect(hid))
@@ -1680,6 +1678,7 @@
 MODULE_DEVICE_TABLE (usb, hid_usb_ids);
 
 static struct usb_driver hid_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"hid",
 	.probe =	hid_probe,
 	.disconnect =	hid_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/input/hid-input.c linux-2.5.70-bk5/drivers/usb/input/hid-input.c
--- linux-2.5.70-bk4/drivers/usb/input/hid-input.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/hid-input.c	2003-05-31 04:35:57.000000000 -0700
@@ -60,9 +60,36 @@
 	__s32 y;
 }  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
 
-static void hidinput_configure_usage(struct hid_device *device, struct hid_field *field, struct hid_usage *usage)
+static struct input_dev *find_input(struct hid_device *hid, struct hid_field *field)
 {
-	struct input_dev *input = &device->input;
+	struct list_head *lh;
+	struct hid_input *hidinput;
+
+	list_for_each (lh, &hid->inputs) {
+		int i;
+
+		hidinput = list_entry(lh, struct hid_input, list);
+
+		for (i = 0; i < hidinput->maxfield; i++)
+			if (hidinput->fields[i] == field)
+				return &hidinput->input;
+	}
+
+	/* Assume we only have one input and use it */
+	if (!list_empty(&hid->inputs)) {
+		hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+		return &hidinput->input;
+	}
+
+	/* This is really a bug */
+	return NULL;
+}
+
+static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
+				     struct hid_usage *usage)
+{
+	struct input_dev *input = &hidinput->input;
+	struct hid_device *device = hidinput->input.private;
 	int max;
 	int is_abs = 0;
 	unsigned long *bit;
@@ -388,9 +415,12 @@
 
 void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
 {
-	struct input_dev *input = &hid->input;
+	struct input_dev *input = find_input(hid, field);
 	int *quirks = &hid->quirks;
 
+	if (!input)
+		return;
+
 	input_regs(input, regs);
 
 	if (usage->hat_min != usage->hat_max) {
@@ -443,7 +473,13 @@
 
 void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
 {
-	input_sync(&hid->input);
+	struct list_head *lh;
+	struct hid_input *hidinput;
+
+	list_for_each (lh, &hid->inputs) {
+		hidinput = list_entry(lh, struct hid_input, list);
+		input_sync(&hidinput->input);
+	}
 }
 
 static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@@ -490,7 +526,10 @@
 	struct hid_report_enum *report_enum;
 	struct hid_report *report;
 	struct list_head *list;
-	int i, j, k;
+	struct hid_input *hidinput = NULL;
+	int i, j;
+
+	INIT_LIST_HEAD(&hid->inputs);
 
 	for (i = 0; i < hid->maxcollection; i++)
 		if (hid->collection[i].type == HID_COLLECTION_APPLICATION &&
@@ -500,37 +539,79 @@
 	if (i == hid->maxcollection)
 		return -1;
 
-	hid->input.private = hid;
-	hid->input.event = hidinput_input_event;
-	hid->input.open = hidinput_open;
-	hid->input.close = hidinput_close;
-
-	hid->input.name = hid->name;
-	hid->input.phys = hid->phys;
-	hid->input.uniq = hid->uniq;
-	hid->input.id.bustype = BUS_USB;
-	hid->input.id.vendor = dev->descriptor.idVendor;
-	hid->input.id.product = dev->descriptor.idProduct;
-	hid->input.id.version = dev->descriptor.bcdDevice;
-
-	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
-		report_enum = hid->report_enum + k;
-		list = report_enum->report_list.next;
-		while (list != &report_enum->report_list) {
-			report = (struct hid_report *) list;
-			for (i = 0; i < report->maxfield; i++)
-				for (j = 0; j < report->field[i]->maxusage; j++)
-					hidinput_configure_usage(hid, report->field[i], report->field[i]->usage + j);
-			list = list->next;
+	report_enum = hid->report_enum + HID_INPUT_REPORT;
+	list = report_enum->report_list.next;
+	while (list != &report_enum->report_list) {
+		report = (struct hid_report *) list;
+
+		if (!report->maxfield)
+			continue;
+
+		if (!hidinput) {
+			hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL);
+			if (!hidinput) {
+				err("Out of memory during hid input probe");
+				return -1;
+			}
+			memset(hidinput, 0, sizeof(*hidinput));
+
+			list_add_tail(&hidinput->list, &hid->inputs);
+
+			hidinput->input.private = hid;
+			hidinput->input.event = hidinput_input_event;
+			hidinput->input.open = hidinput_open;
+			hidinput->input.close = hidinput_close;
+
+			hidinput->input.name = hid->name;
+			hidinput->input.phys = hid->phys;
+			hidinput->input.uniq = hid->uniq;
+			hidinput->input.id.bustype = BUS_USB;
+			hidinput->input.id.vendor = dev->descriptor.idVendor;
+			hidinput->input.id.product = dev->descriptor.idProduct;
+			hidinput->input.id.version = dev->descriptor.bcdDevice;
 		}
+
+		for (i = 0; i < report->maxfield; i++)
+			for (j = 0; j < report->field[i]->maxusage; j++)
+				hidinput_configure_usage(hidinput, report->field[i],
+							 report->field[i]->usage + j);
+
+		if (hid->quirks & HID_QUIRK_MULTI_INPUT) {
+			/* This will leave hidinput NULL, so that it
+			 * allocates another one if we have more inputs on
+			 * the same interface. Some devices (e.g. Happ's
+			 * UGCI) cram a lot of unrelated inputs into the
+			 * same interface. */
+			hidinput->fields = report->field;
+			hidinput->maxfield = report->maxfield;
+
+			input_register_device(&hidinput->input);
+			hidinput = NULL;
+		}
+
+		list = list->next;
 	}
 
-	input_register_device(&hid->input);
+	/* This only gets called when we are a single-input (most of the
+	 * time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is
+	 * only useful in this case, and not for multi-input quirks. */
+	if (hidinput) {
+		hid_ff_init(hid);
+		input_register_device(&hidinput->input);
+	}
 
 	return 0;
 }
 
 void hidinput_disconnect(struct hid_device *hid)
 {
-	input_unregister_device(&hid->input);
+	struct list_head *lh, *next;
+	struct hid_input *hidinput;
+
+	list_for_each_safe (lh, next, &hid->inputs) {
+		hidinput = list_entry(lh, struct hid_input, list);
+		input_unregister_device(&hidinput->input);
+		list_del(&hidinput->list);
+		kfree(hidinput);
+	}
 }
diff -urN linux-2.5.70-bk4/drivers/usb/input/hid-lgff.c linux-2.5.70-bk5/drivers/usb/input/hid-lgff.c
--- linux-2.5.70-bk4/drivers/usb/input/hid-lgff.c	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/hid-lgff.c	2003-05-31 04:35:57.000000000 -0700
@@ -254,6 +254,7 @@
 	signed short* ff;
 	u16 idVendor = hid->dev->descriptor.idVendor;
 	u16 idProduct = hid->dev->descriptor.idProduct;
+	struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list);
 
 	while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
 		dev++;
@@ -261,15 +262,15 @@
 	ff = dev->ff;
 
 	while (*ff >= 0) {
-		set_bit(*ff, hid->input.ffbit);
+		set_bit(*ff, hidinput->input.ffbit);
 		++ff;
 	}
 
-	hid->input.upload_effect = hid_lgff_upload_effect;
-	hid->input.flush = hid_lgff_flush;
+	hidinput->input.upload_effect = hid_lgff_upload_effect;
+	hidinput->input.flush = hid_lgff_flush;
 
-	set_bit(EV_FF, hid->input.evbit);
-	hid->input.ff_effects_max = LGFF_EFFECTS;
+	set_bit(EV_FF, hidinput->input.evbit);
+	hidinput->input.ff_effects_max = LGFF_EFFECTS;
 }
 
 static void hid_lgff_exit(struct hid_device* hid)
diff -urN linux-2.5.70-bk4/drivers/usb/input/hid-tmff.c linux-2.5.70-bk5/drivers/usb/input/hid-tmff.c
--- linux-2.5.70-bk4/drivers/usb/input/hid-tmff.c	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/hid-tmff.c	2003-05-31 04:35:57.000000000 -0700
@@ -110,6 +110,7 @@
 {
 	struct tmff_device *private;
 	struct list_head *pos;
+	struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list);
 
 	private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL);
 	if (!private)
@@ -154,7 +155,7 @@
 					private->report = report;
 					private->rumble = field;
 
-					set_bit(FF_RUMBLE, hid->input.ffbit);
+					set_bit(FF_RUMBLE, hidinput->input.ffbit);
 					break;
 
 				default:
@@ -163,11 +164,11 @@
 			}
 
 			/* Fallthrough to here only when a valid usage is found */
-			hid->input.upload_effect = hid_tmff_upload_effect;
-			hid->input.flush = hid_tmff_flush;
+			hidinput->input.upload_effect = hid_tmff_upload_effect;
+			hidinput->input.flush = hid_tmff_flush;
 
-			set_bit(EV_FF, hid->input.evbit);
-			hid->input.ff_effects_max = TMFF_EFFECTS;
+			set_bit(EV_FF, hidinput->input.evbit);
+			hidinput->input.ff_effects_max = TMFF_EFFECTS;
 		}
 	}
 
diff -urN linux-2.5.70-bk4/drivers/usb/input/hid.h linux-2.5.70-bk5/drivers/usb/input/hid.h
--- linux-2.5.70-bk4/drivers/usb/input/hid.h	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/hid.h	2003-05-31 04:35:57.000000000 -0700
@@ -207,6 +207,7 @@
 #define HID_QUIRK_NOGET		0x08
 #define HID_QUIRK_HIDDEV	0x10
 #define HID_QUIRK_BADPAD        0x20
+#define HID_QUIRK_MULTI_INPUT	0x40
 
 /*
  * This is the global environment of the parser. This information is
@@ -321,6 +322,13 @@
 #define HID_CTRL_RUNNING	1
 #define HID_OUT_RUNNING		2
 
+struct hid_input {
+	struct list_head list;
+	struct hid_field **fields;
+	int maxfield;
+	struct input_dev input;
+};
+
 struct hid_device {							/* device report descriptor */
 	 __u8 *rdesc;
 	unsigned rsize;
@@ -360,7 +368,7 @@
 	unsigned claimed;						/* Claimed by hidinput, hiddev? */	
 	unsigned quirks;						/* Various quirks the device can pull on us */
 
-	struct input_dev input;						/* The input structure */
+	struct list_head inputs;					/* The list of inputs */
 	void *hiddev;							/* The hiddev structure */
 	int minor;							/* Hiddev minor number */
 
diff -urN linux-2.5.70-bk4/drivers/usb/input/hiddev.c linux-2.5.70-bk5/drivers/usb/input/hiddev.c
--- linux-2.5.70-bk4/drivers/usb/input/hiddev.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/hiddev.c	2003-05-31 04:35:57.000000000 -0700
@@ -777,6 +777,7 @@
 
 
 static /* const */ struct usb_driver hiddev_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"hiddev",
 	.probe =	hiddev_usbd_probe,
 };
diff -urN linux-2.5.70-bk4/drivers/usb/input/kbtab.c linux-2.5.70-bk5/drivers/usb/input/kbtab.c
--- linux-2.5.70-bk4/drivers/usb/input/kbtab.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/kbtab.c	2003-05-31 04:35:57.000000000 -0700
@@ -207,6 +207,7 @@
 }
 
 static struct usb_driver kbtab_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"kbtab",
 	.probe =	kbtab_probe,
 	.disconnect =	kbtab_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/input/pid.c linux-2.5.70-bk5/drivers/usb/input/pid.c
--- linux-2.5.70-bk4/drivers/usb/input/pid.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/pid.c	2003-05-31 04:35:57.000000000 -0700
@@ -269,7 +269,8 @@
 int hid_pid_init(struct hid_device *hid)
 {
     struct hid_ff_pid *private;
-    
+    struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list);
+
     private = hid->ff_private = kmalloc(sizeof(struct hid_ff_pid), GFP_KERNEL);
     if (!private) return -1;
     
@@ -289,11 +290,11 @@
     }
 
     usb_fill_control_urb(private->urbffout, hid->dev,0,(void *) &private->ffcr,private->ctrl_buffer,8,hid_pid_ctrl_out,hid);
-    hid->input.upload_effect = hid_pid_upload_effect;
-    hid->input.flush = hid_pid_flush;
-    hid->input.ff_effects_max = 8;  // A random default
-    set_bit(EV_FF, hid->input.evbit);
-    set_bit(EV_FF_STATUS, hid->input.evbit);
+    hidinput->input.upload_effect = hid_pid_upload_effect;
+    hidinput->input.flush = hid_pid_flush;
+    hidinput->input.ff_effects_max = 8;  // A random default
+    set_bit(EV_FF, hidinput->input.evbit);
+    set_bit(EV_FF_STATUS, hidinput->input.evbit);
 
     spin_lock_init(&private->lock);
 
diff -urN linux-2.5.70-bk4/drivers/usb/input/powermate.c linux-2.5.70-bk5/drivers/usb/input/powermate.c
--- linux-2.5.70-bk4/drivers/usb/input/powermate.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/powermate.c	2003-05-31 04:35:57.000000000 -0700
@@ -426,6 +426,7 @@
 MODULE_DEVICE_TABLE (usb, powermate_devices);
 
 static struct usb_driver powermate_driver = {
+	.owner =	THIS_MODULE,
         .name =         "powermate",
         .probe =        powermate_probe,
         .disconnect =   powermate_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/input/usbkbd.c linux-2.5.70-bk5/drivers/usb/input/usbkbd.c
--- linux-2.5.70-bk4/drivers/usb/input/usbkbd.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/usbkbd.c	2003-05-31 04:35:57.000000000 -0700
@@ -356,6 +356,7 @@
 MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
 
 static struct usb_driver usb_kbd_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"usbkbd",
 	.probe =	usb_kbd_probe,
 	.disconnect =	usb_kbd_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/input/usbmouse.c linux-2.5.70-bk5/drivers/usb/input/usbmouse.c
--- linux-2.5.70-bk4/drivers/usb/input/usbmouse.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/usbmouse.c	2003-05-31 04:35:57.000000000 -0700
@@ -238,6 +238,7 @@
 MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
 
 static struct usb_driver usb_mouse_driver = {
+	.owner		= THIS_MODULE,
 	.name		= "usbmouse",
 	.probe		= usb_mouse_probe,
 	.disconnect	= usb_mouse_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/input/wacom.c linux-2.5.70-bk5/drivers/usb/input/wacom.c
--- linux-2.5.70-bk4/drivers/usb/input/wacom.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/wacom.c	2003-05-31 04:35:57.000000000 -0700
@@ -620,6 +620,7 @@
 }
 
 static struct usb_driver wacom_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"wacom",
 	.probe =	wacom_probe,
 	.disconnect =	wacom_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/input/xpad.c linux-2.5.70-bk5/drivers/usb/input/xpad.c
--- linux-2.5.70-bk4/drivers/usb/input/xpad.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/input/xpad.c	2003-05-31 04:35:57.000000000 -0700
@@ -333,6 +333,7 @@
 }
 
 static struct usb_driver xpad_driver = {
+	.owner		= THIS_MODULE,
 	.name		= "xpad",
 	.probe		= xpad_probe,
 	.disconnect	= xpad_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/media/dabusb.c linux-2.5.70-bk5/drivers/usb/media/dabusb.c
--- linux-2.5.70-bk4/drivers/usb/media/dabusb.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/media/dabusb.c	2003-05-31 04:35:57.000000000 -0700
@@ -767,7 +767,6 @@
 	}
 	dbg("bound to interface: %d", ifnum);
 	up (&s->mutex);
-	MOD_INC_USE_COUNT;
 	usb_set_intfdata (intf, s);
 	return 0;
 
@@ -792,7 +791,6 @@
 			sleep_on (&s->remove_ok);
 		s->usbdev = NULL;
 		s->overruns = 0;
-		MOD_DEC_USE_COUNT;
 	}
 }
 
@@ -804,8 +802,8 @@
 
 MODULE_DEVICE_TABLE (usb, dabusb_ids);
 
-static struct usb_driver dabusb_driver =
-{
+static struct usb_driver dabusb_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"dabusb",
 	.probe =	dabusb_probe,
 	.disconnect =	dabusb_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/media/dsbr100.c linux-2.5.70-bk5/drivers/usb/media/dsbr100.c
--- linux-2.5.70-bk4/drivers/usb/media/dsbr100.c	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/media/dsbr100.c	2003-05-31 04:35:57.000000000 -0700
@@ -137,6 +137,7 @@
 MODULE_DEVICE_TABLE (usb, usb_dsbr100_table);
 
 static struct usb_driver usb_dsbr100_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"dsbr100",
 	.probe =	usb_dsbr100_probe,
 	.disconnect =	usb_dsbr100_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/media/ibmcam.c linux-2.5.70-bk5/drivers/usb/media/ibmcam.c
--- linux-2.5.70-bk4/drivers/usb/media/ibmcam.c	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/media/ibmcam.c	2003-05-31 04:35:57.000000000 -0700
@@ -12,18 +12,6 @@
  * 5/24/00 Removed optional (and unnecessary) locking of the driver while
  * the device remains plugged in. Corrected race conditions in ibmcam_open
  * and ibmcam_probe() routines using this as a guideline:
- *
- * (2) The big kernel lock is automatically released when a process sleeps
- *   in the kernel and is automatically reacquired on reschedule if the
- *   process had the lock originally.  Any code that can be compiled as
- *   a module and is entered with the big kernel lock held *MUST*
- *   increment the use count to activate the indirect module protection
- *   before doing anything that might sleep.
- *
- *   In practice, this means that all routines that live in modules and
- *   are invoked under the big kernel lock should do MOD_INC_USE_COUNT
- *   as their very first action.  And all failure paths from that
- *   routine must do MOD_DEC_USE_COUNT before returning.
  */
 
 #include <linux/kernel.h>
@@ -3865,8 +3853,6 @@
 		return -ENODEV;
 	}
 
-	/* Code below may sleep, need to lock module while we are here */
-	MOD_INC_USE_COUNT;
 	uvd = usbvideo_AllocateDevice(cams);
 	if (uvd != NULL) {
 		/* Here uvd is a fully allocated uvd object */
@@ -3896,7 +3882,6 @@
 			uvd = NULL;
 		}
 	}
-	MOD_DEC_USE_COUNT;
 	usb_set_intfdata (intf, uvd);
 	return 0;
 }
diff -urN linux-2.5.70-bk4/drivers/usb/media/konicawc.c linux-2.5.70-bk5/drivers/usb/media/konicawc.c
--- linux-2.5.70-bk4/drivers/usb/media/konicawc.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/media/konicawc.c	2003-05-31 04:35:57.000000000 -0700
@@ -794,8 +794,6 @@
 
 	DEBUG(1, "Selecting requested active setting=%d. maxPS=%d.", actInterface, maxPS);
 
-	/* Code below may sleep, need to lock module while we are here */
-	MOD_INC_USE_COUNT;
 	uvd = usbvideo_AllocateDevice(cams);
 	if (uvd != NULL) {
 		struct konicawc *cam = (struct konicawc *)(uvd->user_data);
@@ -857,7 +855,6 @@
 		info("konicawc: %s on %s\n", cam->input.name, cam->input.phys);
 #endif
 	}
-	MOD_DEC_USE_COUNT;
 
 	if (uvd) {
 		usb_set_intfdata (intf, uvd);
diff -urN linux-2.5.70-bk4/drivers/usb/media/ov511.c linux-2.5.70-bk5/drivers/usb/media/ov511.c
--- linux-2.5.70-bk4/drivers/usb/media/ov511.c	2003-05-26 18:00:28.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/media/ov511.c	2003-05-31 04:35:57.000000000 -0700
@@ -400,6 +400,7 @@
 			       unsigned long);
 
 static struct file_operations ov511_control_fops = {
+	.owner =	THIS_MODULE,
 	.ioctl =	ov51x_control_ioctl,
 };
 
@@ -6455,8 +6456,6 @@
 		}
 	}
 
-	MOD_INC_USE_COUNT;
-
 	unlock_kernel();
 	return 0;
 
@@ -6482,8 +6481,6 @@
 			ov511_decomp_ops = NULL;
 	}
 
-	MOD_DEC_USE_COUNT;
-
 	unlock_kernel();
 }
 
diff -urN linux-2.5.70-bk4/drivers/usb/media/pwc-if.c linux-2.5.70-bk5/drivers/usb/media/pwc-if.c
--- linux-2.5.70-bk4/drivers/usb/media/pwc-if.c	2003-05-31 04:35:50.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/media/pwc-if.c	2003-05-31 04:35:57.000000000 -0700
@@ -92,8 +92,8 @@
 static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id);
 static void usb_pwc_disconnect(struct usb_interface *intf);
 
-static struct usb_driver pwc_driver =
-{
+static struct usb_driver pwc_driver = {
+	.owner =		THIS_MODULE,
 	.name =			"Philips webcam",	/* name */
 	.id_table =		pwc_device_table,
 	.probe =		usb_pwc_probe,		/* probe() */
diff -urN linux-2.5.70-bk4/drivers/usb/media/se401.c linux-2.5.70-bk5/drivers/usb/media/se401.c
--- linux-2.5.70-bk4/drivers/usb/media/se401.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/media/se401.c	2003-05-31 04:35:57.000000000 -0700
@@ -1548,6 +1548,7 @@
 }
 
 static struct usb_driver se401_driver = {
+	.owner		= THIS_MODULE,
         .name		= "se401",
         .id_table	= device_table,
 	.probe		= se401_probe,
diff -urN linux-2.5.70-bk4/drivers/usb/media/stv680.c linux-2.5.70-bk5/drivers/usb/media/stv680.c
--- linux-2.5.70-bk4/drivers/usb/media/stv680.c	2003-05-26 18:00:43.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/media/stv680.c	2003-05-31 04:35:57.000000000 -0700
@@ -1549,6 +1549,7 @@
 }
 
 static struct usb_driver stv680_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"stv680",
 	.probe =	stv680_probe,
 	.disconnect =	stv680_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/media/ultracam.c linux-2.5.70-bk5/drivers/usb/media/ultracam.c
--- linux-2.5.70-bk4/drivers/usb/media/ultracam.c	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/media/ultracam.c	2003-05-31 04:35:57.000000000 -0700
@@ -600,8 +600,6 @@
 		return -ENODEV;
 	}
 
-	/* Code below may sleep, need to lock module while we are here */
-	MOD_INC_USE_COUNT;
 	uvd = usbvideo_AllocateDevice(cams);
 	if (uvd != NULL) {
 		/* Here uvd is a fully allocated uvd object */
@@ -631,7 +629,6 @@
 			uvd = NULL;
 		}
 	}
-	MOD_DEC_USE_COUNT;
 
 	if (uvd) {
 		usb_set_intfdata (intf, uvd);
diff -urN linux-2.5.70-bk4/drivers/usb/media/vicam.c linux-2.5.70-bk5/drivers/usb/media/vicam.c
--- linux-2.5.70-bk4/drivers/usb/media/vicam.c	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/media/vicam.c	2003-05-31 04:35:57.000000000 -0700
@@ -1210,6 +1210,7 @@
 MODULE_DEVICE_TABLE(usb, vicam_table);
 
 static struct usb_driver vicam_driver = {
+	.owner		= THIS_MODULE,
 	.name		= "vicam",
 	.probe		= vicam_probe,
 	.disconnect	= vicam_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/misc/auerswald.c linux-2.5.70-bk5/drivers/usb/misc/auerswald.c
--- linux-2.5.70-bk4/drivers/usb/misc/auerswald.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/misc/auerswald.c	2003-05-31 04:35:58.000000000 -0700
@@ -2129,6 +2129,7 @@
 
 /* Standard usb driver struct */
 static struct usb_driver auerswald_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"auerswald",
 	.probe =	auerswald_probe,
 	.disconnect =	auerswald_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/misc/emi26.c linux-2.5.70-bk5/drivers/usb/misc/emi26.c
--- linux-2.5.70-bk4/drivers/usb/misc/emi26.c	2003-05-26 18:00:28.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/misc/emi26.c	2003-05-31 04:35:58.000000000 -0700
@@ -227,10 +227,11 @@
 }
 
 struct usb_driver emi26_driver = {
-.name			= "emi26 - firmware loader",
-.probe			= emi26_probe,
-.disconnect		= emi26_disconnect,
-.id_table		= NULL,
+	.owner		= THIS_MODULE,
+	.name		= "emi26 - firmware loader",
+	.probe		= emi26_probe,
+	.disconnect	= emi26_disconnect,
+	.id_table	= NULL,
 };
 
 static int __init emi26_init (void)
diff -urN linux-2.5.70-bk4/drivers/usb/misc/rio500.c linux-2.5.70-bk5/drivers/usb/misc/rio500.c
--- linux-2.5.70-bk4/drivers/usb/misc/rio500.c	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/misc/rio500.c	2003-05-31 04:35:58.000000000 -0700
@@ -518,6 +518,7 @@
 MODULE_DEVICE_TABLE (usb, rio_table);
 
 static struct usb_driver rio_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"rio500",
 	.probe =	probe_rio,
 	.disconnect =	disconnect_rio,
diff -urN linux-2.5.70-bk4/drivers/usb/misc/usblcd.c linux-2.5.70-bk5/drivers/usb/misc/usblcd.c
--- linux-2.5.70-bk4/drivers/usb/misc/usblcd.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/misc/usblcd.c	2003-05-31 04:35:58.000000000 -0700
@@ -332,8 +332,8 @@
 
 MODULE_DEVICE_TABLE (usb, id_table);
 
-static struct
-usb_driver lcd_driver = {
+static struct usb_driver lcd_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"usblcd",
 	.probe =	(void *)probe_lcd,
 	.disconnect =	disconnect_lcd,
diff -urN linux-2.5.70-bk4/drivers/usb/net/catc.c linux-2.5.70-bk5/drivers/usb/net/catc.c
--- linux-2.5.70-bk4/drivers/usb/net/catc.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/net/catc.c	2003-05-31 04:35:58.000000000 -0700
@@ -966,6 +966,7 @@
 MODULE_DEVICE_TABLE(usb, catc_id_table);
 
 static struct usb_driver catc_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"catc",
 	.probe =	catc_probe,
 	.disconnect =	catc_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/net/cdc-ether.c linux-2.5.70-bk5/drivers/usb/net/cdc-ether.c
--- linux-2.5.70-bk4/drivers/usb/net/cdc-ether.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/net/cdc-ether.c	2003-05-31 04:35:58.000000000 -0700
@@ -1342,6 +1342,7 @@
 //////////////////////////////////////////////////////////////////////////////
 
 static struct usb_driver CDCEther_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"CDCEther",
 	.probe =	CDCEther_probe,
 	.disconnect =	CDCEther_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/net/pegasus.c linux-2.5.70-bk5/drivers/usb/net/pegasus.c
--- linux-2.5.70-bk4/drivers/usb/net/pegasus.c	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/net/pegasus.c	2003-05-31 04:35:58.000000000 -0700
@@ -1273,6 +1273,7 @@
 }
 
 static struct usb_driver pegasus_driver = {
+	.owner = THIS_MODULE,
 	.name = driver_name,
 	.probe = pegasus_probe,
 	.disconnect = pegasus_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/net/rtl8150.c linux-2.5.70-bk5/drivers/usb/net/rtl8150.c
--- linux-2.5.70-bk4/drivers/usb/net/rtl8150.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/net/rtl8150.c	2003-05-31 04:35:58.000000000 -0700
@@ -115,6 +115,7 @@
 			   const struct usb_device_id *id);
 
 static struct usb_driver rtl8150_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"rtl8150",
 	.probe =	rtl8150_probe,
 	.disconnect =	rtl8150_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/net/usbnet.c linux-2.5.70-bk5/drivers/usb/net/usbnet.c
--- linux-2.5.70-bk4/drivers/usb/net/usbnet.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/net/usbnet.c	2003-05-31 04:35:58.000000000 -0700
@@ -2780,6 +2780,7 @@
 MODULE_DEVICE_TABLE (usb, products);
 
 static struct usb_driver usbnet_driver = {
+	.owner =	THIS_MODULE,
 	.name =		driver_name,
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/belkin_sa.c linux-2.5.70-bk5/drivers/usb/serial/belkin_sa.c
--- linux-2.5.70-bk4/drivers/usb/serial/belkin_sa.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/belkin_sa.c	2003-05-31 04:35:58.000000000 -0700
@@ -118,6 +118,7 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver belkin_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"belkin",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/cyberjack.c linux-2.5.70-bk5/drivers/usb/serial/cyberjack.c
--- linux-2.5.70-bk4/drivers/usb/serial/cyberjack.c	2003-05-26 18:00:57.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/cyberjack.c	2003-05-31 04:35:58.000000000 -0700
@@ -74,6 +74,7 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver cyberjack_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"cyberjack",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/digi_acceleport.c linux-2.5.70-bk5/drivers/usb/serial/digi_acceleport.c
--- linux-2.5.70-bk4/drivers/usb/serial/digi_acceleport.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/digi_acceleport.c	2003-05-31 04:35:58.000000000 -0700
@@ -499,6 +499,7 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver digi_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"digi_acceleport",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/empeg.c linux-2.5.70-bk5/drivers/usb/serial/empeg.c
--- linux-2.5.70-bk4/drivers/usb/serial/empeg.c	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/empeg.c	2003-05-31 04:35:58.000000000 -0700
@@ -111,6 +111,7 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver empeg_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"empeg",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/ftdi_sio.c linux-2.5.70-bk5/drivers/usb/serial/ftdi_sio.c
--- linux-2.5.70-bk4/drivers/usb/serial/ftdi_sio.c	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/ftdi_sio.c	2003-05-31 04:35:58.000000000 -0700
@@ -152,6 +152,7 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver ftdi_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"ftdi_sio",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/io_edgeport.c linux-2.5.70-bk5/drivers/usb/serial/io_edgeport.c
--- linux-2.5.70-bk4/drivers/usb/serial/io_edgeport.c	2003-05-26 18:00:22.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/io_edgeport.c	2003-05-31 04:35:58.000000000 -0700
@@ -464,6 +464,7 @@
 #include "io_tables.h"	/* all of the devices that this driver supports */
 
 static struct usb_driver io_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"io_edgeport",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/io_ti.c linux-2.5.70-bk5/drivers/usb/serial/io_ti.c
--- linux-2.5.70-bk4/drivers/usb/serial/io_ti.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/io_ti.c	2003-05-31 04:35:58.000000000 -0700
@@ -162,6 +162,7 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver io_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"io_ti",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/ipaq.c linux-2.5.70-bk5/drivers/usb/serial/ipaq.c
--- linux-2.5.70-bk4/drivers/usb/serial/ipaq.c	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/ipaq.c	2003-05-31 04:35:58.000000000 -0700
@@ -138,6 +138,7 @@
 MODULE_DEVICE_TABLE (usb, ipaq_id_table);
 
 static struct usb_driver ipaq_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"ipaq",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/ir-usb.c linux-2.5.70-bk5/drivers/usb/serial/ir-usb.c
--- linux-2.5.70-bk4/drivers/usb/serial/ir-usb.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/ir-usb.c	2003-05-31 04:35:58.000000000 -0700
@@ -130,6 +130,7 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver ir_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"ir-usb",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/keyspan.h linux-2.5.70-bk5/drivers/usb/serial/keyspan.h
--- linux-2.5.70-bk4/drivers/usb/serial/keyspan.h	2003-05-26 18:00:43.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/keyspan.h	2003-05-31 04:35:58.000000000 -0700
@@ -477,6 +477,7 @@
 MODULE_DEVICE_TABLE(usb, keyspan_ids_combined);
 
 static struct usb_driver keyspan_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"keyspan",                
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/keyspan_pda.c linux-2.5.70-bk5/drivers/usb/serial/keyspan_pda.c
--- linux-2.5.70-bk4/drivers/usb/serial/keyspan_pda.c	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/keyspan_pda.c	2003-05-31 04:35:58.000000000 -0700
@@ -155,6 +155,7 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver keyspan_pda_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"keyspan_pda",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/kl5kusb105.c linux-2.5.70-bk5/drivers/usb/serial/kl5kusb105.c
--- linux-2.5.70-bk4/drivers/usb/serial/kl5kusb105.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/kl5kusb105.c	2003-05-31 04:35:58.000000000 -0700
@@ -123,6 +123,7 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver kl5kusb105d_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"kl5kusb105d",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/mct_u232.c linux-2.5.70-bk5/drivers/usb/serial/mct_u232.c
--- linux-2.5.70-bk4/drivers/usb/serial/mct_u232.c	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/mct_u232.c	2003-05-31 04:35:58.000000000 -0700
@@ -144,6 +144,7 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver mct_u232_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"mct_u232",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/omninet.c linux-2.5.70-bk5/drivers/usb/serial/omninet.c
--- linux-2.5.70-bk4/drivers/usb/serial/omninet.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/omninet.c	2003-05-31 04:35:58.000000000 -0700
@@ -84,6 +84,7 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver omninet_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"omninet",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/pl2303.c linux-2.5.70-bk5/drivers/usb/serial/pl2303.c
--- linux-2.5.70-bk4/drivers/usb/serial/pl2303.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/pl2303.c	2003-05-31 04:35:58.000000000 -0700
@@ -84,6 +84,7 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver pl2303_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"pl2303",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/safe_serial.c linux-2.5.70-bk5/drivers/usb/serial/safe_serial.c
--- linux-2.5.70-bk4/drivers/usb/serial/safe_serial.c	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/safe_serial.c	2003-05-31 04:35:58.000000000 -0700
@@ -162,6 +162,7 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver safe_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"safe_serial",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/usb-serial.c linux-2.5.70-bk5/drivers/usb/serial/usb-serial.c
--- linux-2.5.70-bk4/drivers/usb/serial/usb-serial.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/usb-serial.c	2003-05-31 04:35:58.000000000 -0700
@@ -366,6 +366,7 @@
 
 /* Driver structure we register with the USB core */
 static struct usb_driver usb_serial_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"usbserial",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/visor.c linux-2.5.70-bk5/drivers/usb/serial/visor.c
--- linux-2.5.70-bk4/drivers/usb/serial/visor.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/visor.c	2003-05-31 04:35:58.000000000 -0700
@@ -256,6 +256,7 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver visor_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"visor",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/serial/whiteheat.c linux-2.5.70-bk5/drivers/usb/serial/whiteheat.c
--- linux-2.5.70-bk4/drivers/usb/serial/whiteheat.c	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/serial/whiteheat.c	2003-05-31 04:35:58.000000000 -0700
@@ -127,6 +127,7 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver whiteheat_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"whiteheat",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
diff -urN linux-2.5.70-bk4/drivers/usb/storage/scsiglue.c linux-2.5.70-bk5/drivers/usb/storage/scsiglue.c
--- linux-2.5.70-bk4/drivers/usb/storage/scsiglue.c	2003-05-31 04:35:50.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/storage/scsiglue.c	2003-05-31 04:35:58.000000000 -0700
@@ -171,9 +171,11 @@
 /* This is always called with scsi_lock(srb->host) held */
 static int usb_storage_command_abort( Scsi_Cmnd *srb )
 {
-	struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
+	struct Scsi_Host *host = srb->device->host;
+	struct us_data *us = (struct us_data *) host->hostdata[0];
+	int state = atomic_read(&us->sm_state);
 
-	US_DEBUGP("command_abort() called\n");
+	US_DEBUGP("%s called\n", __FUNCTION__);
 
 	/* Is this command still active? */
 	if (us->srb != srb) {
@@ -181,7 +183,31 @@
 		return FAILED;
 	}
 
-	return usb_stor_abort_transport(us);
+	/* Normally the current state is RUNNING.  If the control thread
+	 * hasn't even started processing this command, the state will be
+	 * IDLE.  Anything else is a bug. */
+	if (state != US_STATE_RUNNING && state != US_STATE_IDLE) {
+		printk(KERN_ERR USB_STORAGE "Error in %s: "
+			"invalid state %d\n", __FUNCTION__, state);
+		return FAILED;
+	}
+
+	/* Set state to ABORTING, set the ABORTING bit, and release the lock */
+	atomic_set(&us->sm_state, US_STATE_ABORTING);
+	set_bit(US_FLIDX_ABORTING, &us->flags);
+	scsi_unlock(host);
+
+	/* If the state was RUNNING, stop an ongoing USB transfer */
+	if (state == US_STATE_RUNNING)
+		usb_stor_stop_transport(us);
+
+	/* Wait for the aborted command to finish */
+	wait_for_completion(&us->notify);
+
+	/* Reacquire the lock and allow USB transfers to resume */
+	scsi_lock(host);
+	clear_bit(US_FLIDX_ABORTING, &us->flags);
+	return SUCCESS;
 }
 
 /* This invokes the transport reset mechanism to reset the state of the
diff -urN linux-2.5.70-bk4/drivers/usb/storage/transport.c linux-2.5.70-bk5/drivers/usb/storage/transport.c
--- linux-2.5.70-bk4/drivers/usb/storage/transport.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/storage/transport.c	2003-05-31 04:35:58.000000000 -0700
@@ -69,32 +69,35 @@
  * as those occurring during device-specific initialization, must be handled
  * by a separate code path.)
  *
- * The abort function first sets the machine state, then atomically
- * tests-and-clears the CAN_CANCEL bit in us->flags to see if the current_urb
- * needs to be aborted.
- *
- * The submit function first verifies that the submission completed without
- * errors, and only then sets the CAN_CANCEL bit.  This prevents the abort
- * function from trying to cancel the URB while the submit call is underway.
- * Next, the submit function must test the state to see if we got aborted
- * before the submission or before setting the CAN_CANCEL bit.  If so, it's
- * essential to abort the URB if it hasn't been cancelled already (i.e.,
- * if the CAN_CANCEL bit is still set).  Either way, the function must then
- * wait for the URB to finish.  Note that because the URB_ASYNC_UNLINK flag
- * is set, the URB can still be in progress even after a call to
- * usb_unlink_urb() returns.
- *
- * (It's also permissible, but not necessary, to test the state -before-
- * submitting the URB.  Doing so would prevent an unnecessary submission if
- * the transaction had already been aborted, but this is very unlikely to
- * happen, because the abort would have to have been requested during actual
- * kernel processing rather than during an I/O delay.)
- *
- * The idea is that (1) once the state is changed to ABORTING, either the
- * aborting function or the submitting function is guaranteed to call
- * usb_unlink_urb() for an active URB, and (2) test_and_clear_bit() prevents
- * usb_unlink_urb() from being called more than once or from being called
- * during usb_submit_urb().
+ * The abort function (usb_storage_command_abort() in scsiglue.c) first
+ * sets the machine state and the ABORTING bit in us->flags to prevent
+ * new URBs from being submitted.  It then calls usb_stor_stop_transport()
+ * below, which atomically tests-and-clears the URB_ACTIVE bit in us->flags
+ * to see if the current_urb needs to be stopped.  Likewise, the SG_ACTIVE
+ * bit is tested to see if the current_sg scatter-gather request needs to be
+ * stopped.
+ *
+ * When a disconnect occurs, the DISCONNECTING bit in us->flags is set to
+ * prevent new URBs from being submitted, and usb_stor_stop_transport() is
+ * called to stop any ongoing requests.
+ *
+ * The submit function first verifies that the submitting is allowed
+ * (neither ABORTING nor DISCONNECTING bits are set) and that the submit
+ * completes without errors, and only then sets the URB_ACTIVE bit.  This
+ * prevents the stop_transport() function from trying to cancel the URB
+ * while the submit call is underway.  Next, the submit function must test
+ * the flags to see if an abort or disconnect occurred during the submission
+ * or before the URB_ACTIVE bit was set.  If so, it's essential to cancel
+ * the URB if it hasn't been cancelled already (i.e., if the URB_ACTIVE bit
+ * is still set).  Either way, the function must then wait for the URB to
+ * finish.  Note that because the URB_ASYNC_UNLINK flag is set, the URB can
+ * still be in progress even after a call to usb_unlink_urb() returns.
+ *
+ * The idea is that (1) once the ABORTING or DISCONNECTING bit is set,
+ * either the stop_transport() function or the submitting function
+ * is guaranteed to call usb_unlink_urb() for an active URB,
+ * and (2) test_and_clear_bit() prevents usb_unlink_urb() from being
+ * called more than once or from being called during usb_submit_urb().
  */
 
 /* This is the completion handler which will wake us up when an URB
@@ -118,6 +121,10 @@
 	struct completion urb_done;
 	int status;
 
+	/* don't submit URBS during abort/disconnect processing */
+	if (us->flags & DONT_SUBMIT)
+		return -ECONNRESET;
+
 	/* set up data structures for the wakeup system */
 	init_completion(&urb_done);
 
@@ -137,13 +144,13 @@
 
 	/* since the URB has been submitted successfully, it's now okay
 	 * to cancel it */
-	set_bit(US_FLIDX_CAN_CANCEL, &us->flags);
+	set_bit(US_FLIDX_URB_ACTIVE, &us->flags);
 
-	/* has the current command been aborted? */
-	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
+	/* did an abort/disconnect occur during the submission? */
+	if (us->flags & DONT_SUBMIT) {
 
 		/* cancel the URB, if it hasn't been cancelled already */
-		if (test_and_clear_bit(US_FLIDX_CAN_CANCEL, &us->flags)) {
+		if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) {
 			US_DEBUGP("-- cancelling URB\n");
 			usb_unlink_urb(us->current_urb);
 		}
@@ -151,7 +158,7 @@
 
 	/* wait for the completion of the URB */
 	wait_for_completion(&urb_done);
-	clear_bit(US_FLIDX_CAN_CANCEL, &us->flags);
+	clear_bit(US_FLIDX_URB_ACTIVE, &us->flags);
 
 	/* return the URB status */
 	return us->current_urb->status;
@@ -185,53 +192,6 @@
 	return status;
 }
 
-/* This is our function to emulate usb_bulk_msg() with enough control
- * to make aborts/resets/timeouts work
- */
-int usb_stor_bulk_msg(struct us_data *us, void *data, unsigned int pipe,
-		      unsigned int len, unsigned int *act_len)
-{
-	int status;
-
-	/* fill and submit the URB */
-	usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, data, len,
-		      usb_stor_blocking_completion, NULL);
-	status = usb_stor_msg_common(us);
-
-	/* store the actual length of the data transferred */
-	*act_len = us->current_urb->actual_length;
-	return status;
-}
-
-/* This is our function to submit interrupt URBs with enough control
- * to make aborts/resets/timeouts work
- *
- * This routine always uses us->recv_intr_pipe as the pipe and
- * us->ep_bInterval as the interrupt interval.
- */
-int usb_stor_interrupt_msg(struct us_data *us, void *data,
-			unsigned int len, unsigned int *act_len)
-{
-	unsigned int pipe = us->recv_intr_pipe;
-	unsigned int maxp;
-	int status;
-
-	/* calculate the max packet size */
-	maxp = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe));
-	if (maxp > len)
-		maxp = len;
-
-	/* fill and submit the URB */
-	usb_fill_int_urb(us->current_urb, us->pusb_dev, pipe, data,
-			maxp, usb_stor_blocking_completion, NULL,
-			us->ep_bInterval);
-	status = usb_stor_msg_common(us);
-
-	/* store the actual length of the data transferred */
-	*act_len = us->current_urb->actual_length;
-	return status;
-}
-
 /* This is a version of usb_clear_halt() that doesn't read the status from
  * the device -- this is because some devices crash their internal firmware
  * when the status is requested after a halt.
@@ -275,12 +235,12 @@
  * Interpret the results of a URB transfer
  *
  * This function prints appropriate debugging messages, clears halts on
- * bulk endpoints, and translates the status to the corresponding
+ * non-control endpoints, and translates the status to the corresponding
  * USB_STOR_XFER_xxx return code.
  */
 static int interpret_urb_result(struct us_data *us, unsigned int pipe,
-		unsigned int length, int result, unsigned int partial) {
-
+		unsigned int length, int result, unsigned int partial)
+{
 	US_DEBUGP("Status code %d; transferred %u/%u\n",
 			result, partial, length);
 	switch (result) {
@@ -333,95 +293,109 @@
 }
 
 /*
- * Transfer one control message
- *
- * This function does basically the same thing as usb_stor_control_msg()
- * above, except that return codes are USB_STOR_XFER_xxx rather than the
- * urb status or transfer length.
+ * Transfer one control message, without timeouts, but allowing early
+ * termination.  Return codes are USB_STOR_XFER_xxx.
  */
 int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
 		u8 request, u8 requesttype, u16 value, u16 index,
-		void *data, u16 size) {
+		void *data, u16 size)
+{
 	int result;
-	unsigned int partial = 0;
 
-	US_DEBUGP("usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x "
-			"value=%04x index=%02x len=%u\n",
-			request, requesttype, value, index, size);
-	result = usb_stor_control_msg(us, pipe, request, requesttype,
-			value, index, data, size);
-
-	if (result > 0) {	/* Separate out the amount transferred */
-		partial = result;
-		result = 0;
-	}
-	return interpret_urb_result(us, pipe, size, result, partial);
+	US_DEBUGP("%s: rq=%02x rqtype=%02x value=%04x index=%02x len=%u\n",
+			__FUNCTION__, request, requesttype,
+			value, index, size);
+
+	/* fill in the devrequest structure */
+	us->dr->bRequestType = requesttype;
+	us->dr->bRequest = request;
+	us->dr->wValue = cpu_to_le16(value);
+	us->dr->wIndex = cpu_to_le16(index);
+	us->dr->wLength = cpu_to_le16(size);
+
+	/* fill and submit the URB */
+	usb_fill_control_urb(us->current_urb, us->pusb_dev, pipe, 
+			 (unsigned char*) us->dr, data, size, 
+			 usb_stor_blocking_completion, NULL);
+	result = usb_stor_msg_common(us);
+
+	return interpret_urb_result(us, pipe, size, result,
+			us->current_urb->actual_length);
 }
 
 /*
- * Receive one buffer via interrupt transfer
+ * Receive one interrupt buffer, without timeouts, but allowing early
+ * termination.  Return codes are USB_STOR_XFER_xxx.
  *
- * This function does basically the same thing as usb_stor_interrupt_msg()
- * above, except that return codes are USB_STOR_XFER_xxx rather than the
- * urb status.
+ * This routine always uses us->recv_intr_pipe as the pipe and
+ * us->ep_bInterval as the interrupt interval.
  */
-int usb_stor_intr_transfer(struct us_data *us, void *buf,
-		unsigned int length, unsigned int *act_len)
+int usb_stor_intr_transfer(struct us_data *us, void *buf, unsigned int length)
 {
 	int result;
-	unsigned int partial;
+	unsigned int pipe = us->recv_intr_pipe;
+	unsigned int maxp;
 
-	/* transfer the data */
-	US_DEBUGP("usb_stor_intr_transfer(): xfer %u bytes\n", length);
-	result = usb_stor_interrupt_msg(us, buf, length, &partial);
-	if (act_len)
-		*act_len = partial;
+	US_DEBUGP("%s: xfer %u bytes\n", __FUNCTION__, length);
+
+	/* calculate the max packet size */
+	maxp = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe));
+	if (maxp > length)
+		maxp = length;
 
-	return interpret_urb_result(us, us->recv_intr_pipe,
-			length, result, partial);
+	/* fill and submit the URB */
+	usb_fill_int_urb(us->current_urb, us->pusb_dev, pipe, buf,
+			maxp, usb_stor_blocking_completion, NULL,
+			us->ep_bInterval);
+	result = usb_stor_msg_common(us);
+
+	return interpret_urb_result(us, pipe, length, result,
+			us->current_urb->actual_length);
 }
 
 /*
- * Transfer one buffer via bulk transfer
- *
- * This function does basically the same thing as usb_stor_bulk_msg()
- * above, except that:
- *
- *	1.  If the bulk pipe stalls during the transfer, the halt is
- *	    automatically cleared;
- *	2.  Return codes are USB_STOR_XFER_xxx rather than the
- *	    urb status or transfer length.
+ * Transfer one buffer via bulk pipe, without timeouts, but allowing early
+ * termination.  Return codes are USB_STOR_XFER_xxx.  If the bulk pipe
+ * stalls during the transfer, the halt is automatically cleared.
  */
 int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
 	void *buf, unsigned int length, unsigned int *act_len)
 {
 	int result;
-	unsigned int partial;
 
-	/* transfer the data */
-	US_DEBUGP("usb_stor_bulk_transfer_buf(): xfer %u bytes\n", length);
-	result = usb_stor_bulk_msg(us, buf, pipe, length, &partial);
+	US_DEBUGP("%s: xfer %u bytes\n", __FUNCTION__, length);
+
+	/* fill and submit the URB */
+	usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, buf, length,
+		      usb_stor_blocking_completion, NULL);
+	result = usb_stor_msg_common(us);
+
+	/* store the actual length of the data transferred */
 	if (act_len)
-		*act_len = partial;
-	return interpret_urb_result(us, pipe, length, result, partial);
+		*act_len = us->current_urb->actual_length;
+	return interpret_urb_result(us, pipe, length, result, 
+			us->current_urb->actual_length);
 }
 
 /*
  * Transfer a scatter-gather list via bulk transfer
  *
  * This function does basically the same thing as usb_stor_bulk_transfer_buf()
- * above, but it uses the usbcore scatter-gather primitives
+ * above, but it uses the usbcore scatter-gather library.
  */
 int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
 		struct scatterlist *sg, int num_sg, unsigned int length,
 		unsigned int *act_len)
 {
 	int result;
-	unsigned int partial;
+
+	/* don't submit s-g requests during abort/disconnect processing */
+	if (us->flags & DONT_SUBMIT)
+		return USB_STOR_XFER_ERROR;
 
 	/* initialize the scatter-gather request block */
-	US_DEBUGP("usb_stor_bulk_transfer_sglist(): xfer %u bytes, "
-			"%d entries\n", length, num_sg);
+	US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__,
+			length, num_sg);
 	result = usb_sg_init(us->current_sg, us->pusb_dev, pipe, 0,
 			sg, num_sg, length, SLAB_NOIO);
 	if (result) {
@@ -431,13 +405,13 @@
 
 	/* since the block has been initialized successfully, it's now
 	 * okay to cancel it */
-	set_bit(US_FLIDX_CANCEL_SG, &us->flags);
+	set_bit(US_FLIDX_SG_ACTIVE, &us->flags);
 
-	/* has the current command been aborted? */
-	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
+	/* did an abort/disconnect occur during the submission? */
+	if (us->flags & DONT_SUBMIT) {
 
 		/* cancel the request, if it hasn't been cancelled already */
-		if (test_and_clear_bit(US_FLIDX_CANCEL_SG, &us->flags)) {
+		if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
 			US_DEBUGP("-- cancelling sg request\n");
 			usb_sg_cancel(us->current_sg);
 		}
@@ -445,13 +419,13 @@
 
 	/* wait for the completion of the transfer */
 	usb_sg_wait(us->current_sg);
-	clear_bit(US_FLIDX_CANCEL_SG, &us->flags);
+	clear_bit(US_FLIDX_SG_ACTIVE, &us->flags);
 
 	result = us->current_sg->status;
-	partial = us->current_sg->bytes;
 	if (act_len)
-		*act_len = partial;
-	return interpret_urb_result(us, pipe, length, result, partial);
+		*act_len = us->current_sg->bytes;
+	return interpret_urb_result(us, pipe, length, result,
+			us->current_sg->bytes);
 }
 
 /*
@@ -693,56 +667,32 @@
 	Handle_Abort:
 	srb->result = DID_ABORT << 16;
 	if (us->protocol == US_PR_BULK) {
+
+		/* permit the reset transfer to take place */
+		clear_bit(US_FLIDX_ABORTING, &us->flags);
 		us->transport_reset(us);
 	}
 }
 
-/* Abort the currently running scsi command or device reset.
- * This must be called with scsi_lock(us->srb->host) held */
-int usb_stor_abort_transport(struct us_data *us)
+/* Stop the current URB transfer */
+void usb_stor_stop_transport(struct us_data *us)
 {
-	struct Scsi_Host *host;
-	int state = atomic_read(&us->sm_state);
-
-	US_DEBUGP("usb_stor_abort_transport called\n");
-
-	/* Normally the current state is RUNNING.  If the control thread
-	 * hasn't even started processing this command, the state will be
-	 * IDLE.  Anything else is a bug. */
-	if (state != US_STATE_RUNNING && state != US_STATE_IDLE) {
-		printk(KERN_ERR USB_STORAGE "Error in %s: "
-			"invalid state %d\n", __FUNCTION__, state);
-		return FAILED;
-	}
-
-	/* set state to abort and release the lock */
-	atomic_set(&us->sm_state, US_STATE_ABORTING);
-	host = us->srb->device->host;
-	scsi_unlock(host);
+	US_DEBUGP("%s called\n", __FUNCTION__);
 
 	/* If the state machine is blocked waiting for an URB,
-	 * let's wake it up */
-
-	/* If we have an URB pending, cancel it.  The test_and_clear_bit()
-	 * call guarantees that if a URB has just been submitted, it
-	 * won't be cancelled more than once. */
-	if (test_and_clear_bit(US_FLIDX_CAN_CANCEL, &us->flags)) {
+	 * let's wake it up.  The test_and_clear_bit() call
+	 * guarantees that if a URB has just been submitted,
+	 * it won't be cancelled more than once. */
+	if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) {
 		US_DEBUGP("-- cancelling URB\n");
 		usb_unlink_urb(us->current_urb);
 	}
 
 	/* If we are waiting for a scatter-gather operation, cancel it. */
-	if (test_and_clear_bit(US_FLIDX_CANCEL_SG, &us->flags)) {
+	if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
 		US_DEBUGP("-- cancelling sg request\n");
 		usb_sg_cancel(us->current_sg);
 	}
-
-	/* Wait for the aborted command to finish */
-	wait_for_completion(&us->notify);
-
-	/* Reacquire the lock: note that us->srb is now NULL */
-	scsi_lock(host);
-	return SUCCESS;
 }
 
 /*
@@ -788,8 +738,7 @@
 	}
 
 	/* STATUS STAGE */
-	result = usb_stor_intr_transfer(us, us->irqdata,
-					sizeof(us->irqdata), NULL);
+	result = usb_stor_intr_transfer(us, us->irqdata, sizeof(us->irqdata));
 	US_DEBUGP("Got interrupt data (0x%x, 0x%x)\n", 
 			us->irqdata[0], us->irqdata[1]);
 	if (result != USB_STOR_XFER_GOOD)
diff -urN linux-2.5.70-bk4/drivers/usb/storage/transport.h linux-2.5.70-bk5/drivers/usb/storage/transport.h
--- linux-2.5.70-bk4/drivers/usb/storage/transport.h	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/storage/transport.h	2003-05-31 04:35:58.000000000 -0700
@@ -156,22 +156,18 @@
 extern int usb_stor_Bulk_reset(struct us_data*);
 
 extern void usb_stor_invoke_transport(Scsi_Cmnd*, struct us_data*);
-extern int usb_stor_abort_transport(struct us_data*);
+extern void usb_stor_stop_transport(struct us_data*);
 
-extern int usb_stor_bulk_msg(struct us_data *us, void *data,
-		unsigned int pipe, unsigned int len, unsigned int *act_len);
 extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
 		u8 request, u8 requesttype, u16 value, u16 index,
 		void *data, u16 size);
-extern int usb_stor_interrupt_msg(struct us_data *us, void *data,
-		unsigned int len, unsigned int *act_len);
 
 extern int usb_stor_clear_halt(struct us_data*, unsigned int pipe);
 extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
 		u8 request, u8 requesttype, u16 value, u16 index,
 		void *data, u16 size);
 extern int usb_stor_intr_transfer(struct us_data *us, void *buf,
-		unsigned int length, unsigned int *act_len);
+		unsigned int length);
 extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
 		void *buf, unsigned int length, unsigned int *act_len);
 extern int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
diff -urN linux-2.5.70-bk4/drivers/usb/storage/unusual_devs.h linux-2.5.70-bk5/drivers/usb/storage/unusual_devs.h
--- linux-2.5.70-bk4/drivers/usb/storage/unusual_devs.h	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/storage/unusual_devs.h	2003-05-31 04:35:58.000000000 -0700
@@ -314,33 +314,18 @@
  * Submitted by James Courtier-Dutton <James@superbug.demon.co.uk>
  */
 UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
-                "ASAHI PENTAX",
-                "PENTAX OPTIO 430",
+                "Pentax",
+                "Optio 2/3/400",
                 US_SC_8070, US_PR_CBI, NULL,
                 US_FL_FIX_INQUIRY ),
 
-/* This Pentax still camera is not conformant
- * to the USB storage specification: -
- * - It does not like the INQUIRY command. So we must handle this command
- *   of the SCSI layer ourselves.
- * Tested on Rev. 10.00 (0x1000)
- * Submitted by James Courtier-Dutton <James@superbug.demon.co.uk>
- */
-UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
-                "ASAHI PENTAX",
-                "PENTAX OPTIO 430",
+/* Submitted by Per Winkvist <per.winkvist@uk.com> */
+UNUSUAL_DEV( 0x0a17, 0x006, 0x1000, 0x9009,
+                "Pentax",
+                "Optio S",
                 US_SC_8070, US_PR_CBI, NULL,
                 US_FL_FIX_INQUIRY ),
 
-/* Pentax Optio S digital camera
- * submitted by Stefan M. Brandl <smb@smbnet.de>
- */
-UNUSUAL_DEV( 0x0a17, 0x0006, 0x0000, 0xffff,
-		"Pentax",
-		"Optio S",
-		US_SC_8070, US_PR_CB, NULL,
-		US_FL_MODE_XLATE|US_FL_FIX_INQUIRY),
-
 #ifdef CONFIG_USB_STORAGE_ISD200
 UNUSUAL_DEV(  0x05ab, 0x0031, 0x0100, 0x0110,
 		"In-System",
@@ -606,6 +591,13 @@
 		US_SC_SCSI, US_PR_BULK, NULL,
 		US_FL_FIX_CAPACITY ),
 
+/* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/
+UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001,
+        "Samsung",
+        "Digimax 410",
+        US_SC_SCSI, US_PR_BULK, NULL,
+        US_FL_FIX_INQUIRY),
+                
 UNUSUAL_DEV(  0x097a, 0x0001, 0x0000, 0x0001,
 		"Minds@Work",
 		"Digital Wallet",
@@ -639,26 +631,6 @@
 		US_SC_SCSI, US_PR_BULK, NULL,
 		US_FL_MODE_XLATE | US_FL_START_STOP | US_FL_FIX_INQUIRY ),
 
-/* This Pentax still camera is not conformant
- * to the USB storage specification: -
- * - It does not like the INQUIRY command. So we must handle this command
- *   of the SCSI layer ourselves.
- * Tested on Rev. 10.00 (0x1000)
- * Submitted by James Courtier-Dutton <James@superbug.demon.co.uk>
- */
-UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
-                "Pentax",
-                "Optio 2/3/400",
-                US_SC_8070, US_PR_CBI, NULL,
-                US_FL_FIX_INQUIRY ),
-
-/* Submitted by Per Winkvist <per.winkvist@uk.com> */
-UNUSUAL_DEV( 0x0a17, 0x006, 0x1000, 0x9009,
-                "Pentax",
-                "Optio S",
-                US_SC_8070, US_PR_CBI, NULL,
-                US_FL_FIX_INQUIRY ),
-
 /* Submitted by Brian Hall <brihall@pcisys.net>
  * Needed for START_STOP flag */
 UNUSUAL_DEV(  0x0c76, 0x0003, 0x0100, 0x0100,
diff -urN linux-2.5.70-bk4/drivers/usb/storage/usb.c linux-2.5.70-bk5/drivers/usb/storage/usb.c
--- linux-2.5.70-bk4/drivers/usb/storage/usb.c	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/storage/usb.c	2003-05-31 04:35:58.000000000 -0700
@@ -218,6 +218,7 @@
 };
 
 struct usb_driver usb_storage_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"usb-storage",
 	.probe =	storage_probe,
 	.disconnect =	storage_disconnect,
@@ -886,11 +887,8 @@
 	/* set the hostdata to prepare for scanning */
 	us->host->hostdata[0] = (unsigned long)us;
 
-	/* associate this host with our interface */
-	scsi_set_device(us->host, &intf->dev);
-
 	/* now add the host */
-	result = scsi_add_host(us->host, NULL);
+	result = scsi_add_host(us->host, &intf->dev);
 	if (result) {
 		printk(KERN_WARNING USB_STORAGE
 			"Unable to add the scsi host\n");
@@ -941,16 +939,13 @@
 		sdev->online = 0;
 	scsi_unlock(us->host);
 
+	/* prevent new USB transfers and stop the current command */
+	set_bit(US_FLIDX_DISCONNECTING, &us->flags);
+	usb_stor_stop_transport(us);
+
 	/* lock device access -- no need to unlock, as we're going away */
 	down(&(us->dev_semaphore));
 
-	/* Complete all pending commands with * cmd->result = DID_ERROR << 16.
-	 * Since we only queue one command at a time, this is pretty easy. */
-	if (us->srb) {
-		us->srb->result = DID_ERROR << 16;
-		us->srb->scsi_done(us->srb);
-	}
-
 	/* TODO: somehow, wait for the device to
 	 * be 'idle' (tasklet completion) */
 
diff -urN linux-2.5.70-bk4/drivers/usb/storage/usb.h linux-2.5.70-bk5/drivers/usb/storage/usb.h
--- linux-2.5.70-bk4/drivers/usb/storage/usb.h	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/storage/usb.h	2003-05-31 04:35:58.000000000 -0700
@@ -67,7 +67,7 @@
 	unsigned int flags;
 };
 
-/* Flag definitions */
+/* Flag definitions: these entries are static */
 #define US_FL_SINGLE_LUN      0x00000001 /* allow access to only LUN 0	    */
 #define US_FL_MODE_XLATE      0x00000002 /* translate _6 to _10 commands for
 						    Win/MacOS compatibility */
@@ -77,8 +77,13 @@
 #define US_FL_FIX_INQUIRY     0x00000040 /* INQUIRY response needs fixing   */
 #define US_FL_FIX_CAPACITY    0x00000080 /* READ CAPACITY response too big  */
 
-#define US_FLIDX_CAN_CANCEL  18  /* 0x00040000  okay to cancel current_urb? */
-#define US_FLIDX_CANCEL_SG   19  /* 0x00080000	okay to cancel current_sg?  */
+/* Dynamic flag definitions: used in set_bit() etc. */
+#define US_FLIDX_URB_ACTIVE	18  /* 0x00040000  current_urb is in use  */
+#define US_FLIDX_SG_ACTIVE	19  /* 0x00080000  current_sg is in use   */
+#define US_FLIDX_ABORTING	20  /* 0x00100000  abort is in progress   */
+#define US_FLIDX_DISCONNECTING	21  /* 0x00200000  disconnect in progress */
+#define DONT_SUBMIT	((1UL << US_FLIDX_ABORTING) || \
+			 (1UL << US_FLIDX_DISCONNECTING))
 
 
 /* processing state machine states */
diff -urN linux-2.5.70-bk4/drivers/usb/usb-skeleton.c linux-2.5.70-bk5/drivers/usb/usb-skeleton.c
--- linux-2.5.70-bk4/drivers/usb/usb-skeleton.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk5/drivers/usb/usb-skeleton.c	2003-05-31 04:35:58.000000000 -0700
@@ -172,6 +172,7 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver skel_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"skeleton",
 	.probe =	skel_probe,
 	.disconnect =	skel_disconnect,
diff -urN linux-2.5.70-bk4/fs/bio.c linux-2.5.70-bk5/fs/bio.c
--- linux-2.5.70-bk4/fs/bio.c	2003-05-31 04:35:50.000000000 -0700
+++ linux-2.5.70-bk5/fs/bio.c	2003-05-31 04:35:58.000000000 -0700
@@ -538,12 +538,6 @@
 	bio = __bio_map_user(bdev, uaddr, len, write_to_vm);
 
 	if (bio) {
-		if (bio->bi_size < len) {
-			bio_endio(bio, bio->bi_size, 0);
-			bio_unmap_user(bio, 0);
-			return NULL;
-		}
-
 		/*
 		 * subtle -- if __bio_map_user() ended up bouncing a bio,
 		 * it would normally disappear when its bi_end_io is run.
@@ -551,6 +545,12 @@
 		 * reference to it
 		 */
 		bio_get(bio);
+
+		if (bio->bi_size < len) {
+			bio_endio(bio, bio->bi_size, 0);
+			bio_unmap_user(bio, 0);
+			return NULL;
+		}
 	}
 
 	return bio;
diff -urN linux-2.5.70-bk4/fs/char_dev.c linux-2.5.70-bk5/fs/char_dev.c
--- linux-2.5.70-bk4/fs/char_dev.c	2003-05-31 04:35:50.000000000 -0700
+++ linux-2.5.70-bk5/fs/char_dev.c	2003-05-31 04:35:58.000000000 -0700
@@ -179,10 +179,10 @@
 	return PTR_ERR(cd);
 }
 
-int alloc_chrdev_region(dev_t *dev, unsigned count, char *name)
+int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, char *name)
 {
 	struct char_device_struct *cd;
-	cd = __register_chrdev_region(0, 0, count, name);
+	cd = __register_chrdev_region(0, baseminor, count, name);
 	if (IS_ERR(cd))
 		return PTR_ERR(cd);
 	*dev = MKDEV(cd->major, cd->baseminor);
diff -urN linux-2.5.70-bk4/fs/jfs/resize.c linux-2.5.70-bk5/fs/jfs/resize.c
--- linux-2.5.70-bk4/fs/jfs/resize.c	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk5/fs/jfs/resize.c	2003-05-31 04:35:58.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- *   Copyright (c) International Business Machines  Corp., 2000-2002
+ *   Copyright (c) International Business Machines  Corp., 2000-2003
  *
  *   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
@@ -348,7 +348,7 @@
 
 	/* need to grow map file ? */
 	if (nPages == newNpages)
-		goto updateImap;
+		goto finalizeBmap;
 
 	/*
 	 * grow bmap file for the new map pages required:
@@ -414,6 +414,7 @@
 	if (XSize)
 		goto extendBmap;
 
+      finalizeBmap:
 	/* finalize bmap */
 	dbFinalizeBmap(ipbmap);
 
@@ -427,7 +428,6 @@
 	 * (computation of ag number from agstart based on agsize
 	 * will correctly identify the new ag);
 	 */
-      updateImap:
 	/* if new AG size the same as old AG size, done! */
 	if (bmp->db_agsize != old_agsize) {
 		if ((rc = diExtendFS(ipimap, ipbmap)))
@@ -485,8 +485,8 @@
 
 	/* mark extendfs() completion */
 	j_sb->s_state &= cpu_to_le32(~FM_EXTENDFS);
-	j_sb->s_size = cpu_to_le64(bmp->db_mapsize) <<
-		       le16_to_cpu(j_sb->s_l2bfactor);
+	j_sb->s_size = cpu_to_le64(bmp->db_mapsize <<
+				   le16_to_cpu(j_sb->s_l2bfactor));
 	j_sb->s_agsize = cpu_to_le32(bmp->db_agsize);
 
 	/* update inline log space descriptor */
diff -urN linux-2.5.70-bk4/fs/jfs/super.c linux-2.5.70-bk5/fs/jfs/super.c
--- linux-2.5.70-bk4/fs/jfs/super.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk5/fs/jfs/super.c	2003-05-31 04:35:58.000000000 -0700
@@ -105,10 +105,14 @@
 	}
 
 #ifdef CONFIG_JFS_POSIX_ACL
-	if (ji->i_acl && (ji->i_acl != JFS_ACL_NOT_CACHED))
+	if (ji->i_acl != JFS_ACL_NOT_CACHED) {
 		posix_acl_release(ji->i_acl);
-	if (ji->i_default_acl && (ji->i_default_acl != JFS_ACL_NOT_CACHED))
+		ji->i_acl = JFS_ACL_NOT_CACHED;
+	}
+	if (ji->i_default_acl != JFS_ACL_NOT_CACHED) {
 		posix_acl_release(ji->i_default_acl);
+		ji->i_default_acl = JFS_ACL_NOT_CACHED;
+	}
 #endif
 
 	kmem_cache_free(jfs_inode_cachep, ji);
diff -urN linux-2.5.70-bk4/include/linux/fs.h linux-2.5.70-bk5/include/linux/fs.h
--- linux-2.5.70-bk4/include/linux/fs.h	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk5/include/linux/fs.h	2003-05-31 04:35:58.000000000 -0700
@@ -1059,7 +1059,7 @@
 extern void blk_run_queues(void);
 
 /* fs/char_dev.c */
-extern int alloc_chrdev_region(dev_t *, unsigned, char *);
+extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, char *);
 extern int register_chrdev_region(dev_t, unsigned, char *);
 extern int register_chrdev(unsigned int, const char *,
 			   struct file_operations *);
diff -urN linux-2.5.70-bk4/include/linux/ide.h linux-2.5.70-bk5/include/linux/ide.h
--- linux-2.5.70-bk4/include/linux/ide.h	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk5/include/linux/ide.h	2003-05-31 04:35:58.000000000 -0700
@@ -720,7 +720,7 @@
 	unsigned doorlocking	: 1;	/* for removable only: door lock/unlock works */
 	unsigned autotune	: 3;	/* 1=autotune, 2=noautotune, 
 					   3=biostimings, 0=default */
-	unsigned remap_0_to_1	: 2;	/* 0=remap if ezdrive, 1=remap, 2=noremap */
+	unsigned remap_0_to_1	: 1;	/* 0=noremap, 1=remap 0->1 (for EZDrive) */
 	unsigned ata_flash	: 1;	/* 1=present, 0=default */
 	unsigned blocked        : 1;	/* 1=powermanagment told us not to do anything, so sleep nicely */
 	unsigned vdma		: 1;	/* 1=doing PIO over DMA 0=doing normal DMA */
diff -urN linux-2.5.70-bk4/mm/filemap.c linux-2.5.70-bk5/mm/filemap.c
--- linux-2.5.70-bk4/mm/filemap.c	2003-05-31 04:35:50.000000000 -0700
+++ linux-2.5.70-bk5/mm/filemap.c	2003-05-31 04:35:58.000000000 -0700
@@ -1718,10 +1718,9 @@
 			copied = filemap_copy_from_user_iovec(page, offset,
 						cur_iov, iov_base, bytes);
 		flush_dcache_page(page);
+		status = a_ops->commit_write(file, page, offset,
+						offset + copied);
 		if (likely(copied > 0)) {
-			status = a_ops->commit_write(file, page, offset,
-						     offset + copied);
-
 			if (!status)
 				status = copied;
 
diff -urN linux-2.5.70-bk4/sound/usb/usbaudio.c linux-2.5.70-bk5/sound/usb/usbaudio.c
--- linux-2.5.70-bk4/sound/usb/usbaudio.c	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk5/sound/usb/usbaudio.c	2003-05-31 04:35:58.000000000 -0700
@@ -1615,6 +1615,7 @@
 MODULE_DEVICE_TABLE (usb, usb_audio_ids);
 
 static struct usb_driver usb_audio_driver = {
+	.owner =	THIS_MODULE,
 	.name =		"snd-usb-audio",
 	.probe =	usb_audio_probe,
 	.disconnect =	usb_audio_disconnect,
