diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/base/core.c linux-2.5.34-greg/drivers/base/core.c
--- linux-2.5.34/drivers/base/core.c	Mon Sep  9 10:35:01 2002
+++ linux-2.5.34-greg/drivers/base/core.c	Wed Sep 11 15:33:33 2002
@@ -103,12 +103,13 @@
 		devclass_remove_device(dev);
 		spin_lock(&device_lock);
 		drv = dev->driver;
-		dev->driver = NULL;
 		spin_unlock(&device_lock);
 
 		/* detach from driver */
 		if (drv && drv->remove)
 			drv->remove(dev);
+
+		dev->driver = NULL;
 	}
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/class/audio.c linux-2.5.34-greg/drivers/usb/class/audio.c
--- linux-2.5.34/drivers/usb/class/audio.c	Mon Sep  9 10:35:26 2002
+++ linux-2.5.34-greg/drivers/usb/class/audio.c	Wed Sep 11 15:33:33 2002
@@ -2740,9 +2740,9 @@
 
 /* --------------------------------------------------------------------- */
 
-static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
-			      const struct usb_device_id *id);
-static void usb_audio_disconnect(struct usb_device *dev, void *ptr);
+static int usb_audio_probe(struct usb_interface *iface,
+			   const struct usb_device_id *id);
+static void usb_audio_disconnect(struct usb_interface *iface);
 
 static struct usb_device_id usb_audio_ids [] = {
     { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
@@ -2756,7 +2756,6 @@
 	.name =		"audio",
 	.probe =	usb_audio_probe,
 	.disconnect =	usb_audio_disconnect,
-	.driver_list =	LIST_HEAD_INIT(usb_audio_driver.driver_list), 
 	.id_table =	usb_audio_ids,
 };
 
@@ -3643,7 +3642,7 @@
 	list_add_tail(&ms->list, &s->mixerlist);
 }
 
-static void *usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif)
+static struct usb_audio_state *usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif)
 {
 	struct usb_audio_state *s;
 	struct usb_config_descriptor *config = dev->actconfig;
@@ -3766,10 +3765,12 @@
 
 /* we only care for the currently active configuration */
 
-static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
-			     const struct usb_device_id *id)
+static int usb_audio_probe(struct usb_interface *iface,
+			   const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev (iface);
 	struct usb_config_descriptor *config = dev->actconfig;	
+	struct usb_audio_state *s;
 	unsigned char *buffer;
 	unsigned char buf[8];
 	unsigned int i, buflen;
@@ -3789,39 +3790,47 @@
 
 	if (usb_set_configuration(dev, config->bConfigurationValue) < 0) {
 		printk(KERN_ERR "usbaudio: set_configuration failed (ConfigValue 0x%x)\n", config->bConfigurationValue);
-		return NULL;
+		return -EIO;
 	}
 	ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buf, 8);
 	if (ret < 0) {
 		printk(KERN_ERR "usbaudio: cannot get first 8 bytes of config descriptor %d of device %d (error %d)\n", i, dev->devnum, ret);
-		return NULL;
+		return -EIO;
 	}
 	if (buf[1] != USB_DT_CONFIG || buf[0] < 9) {
 		printk(KERN_ERR "usbaudio: invalid config descriptor %d of device %d\n", i, dev->devnum);
-		return NULL;
+		return -EIO;
 	}
 	buflen = buf[2] | (buf[3] << 8);
 	if (!(buffer = kmalloc(buflen, GFP_KERNEL)))
-		return NULL;
+		return -ENOMEM;
 	ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buffer, buflen);
 	if (ret < 0) {
 		kfree(buffer);
 		printk(KERN_ERR "usbaudio: cannot get config descriptor %d of device %d (error %d)\n", i, dev->devnum, ret);
-		return NULL;
+		return -EIO;
 	}
-	return usb_audio_parsecontrol(dev, buffer, buflen, ifnum);
+	s = usb_audio_parsecontrol(dev, buffer, buflen, iface->altsetting->bInterfaceNumber);
+	if (s) {
+		iface->dev.driver_data = s;
+		return 0;
+	}
+	return -ENODEV;
 }
 
 
 /* a revoke facility would make things simpler */
 
-static void usb_audio_disconnect(struct usb_device *dev, void *ptr)
+static void usb_audio_disconnect(struct usb_interface *iface)
 {
-	struct usb_audio_state *s = (struct usb_audio_state *)ptr;
+	struct usb_audio_state *s = (struct usb_audio_state *)iface->dev.driver_data;
 	struct list_head *list;
 	struct usb_audiodev *as;
 	struct usb_mixerdev *ms;
 
+	if (!s)
+		return;
+
 	/* we get called with -1 for every audiostreaming interface registered */
 	if (s == (struct usb_audio_state *)-1) {
 		dprintk((KERN_DEBUG "usbaudio: note, usb_audio_disconnect called with -1\n"));
@@ -3835,6 +3844,8 @@
 	list_del(&s->audiodev);
 	INIT_LIST_HEAD(&s->audiodev);
 	s->usbdev = NULL;
+	iface->dev.driver_data = NULL;
+
 	/* deregister all audio and mixer devices, so no new processes can open this device */
 	for(list = s->audiolist.next; list != &s->audiolist; list = list->next) {
 		as = list_entry(list, struct usb_audiodev, list);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/class/bluetty.c linux-2.5.34-greg/drivers/usb/class/bluetty.c
--- linux-2.5.34/drivers/usb/class/bluetty.c	Mon Sep  9 10:35:05 2002
+++ linux-2.5.34-greg/drivers/usb/class/bluetty.c	Wed Sep 11 15:33:33 2002
@@ -221,9 +221,9 @@
 static void bluetooth_read_bulk_callback	(struct urb *urb);
 static void bluetooth_write_bulk_callback	(struct urb *urb);
 
-static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum,
-			 	  const struct usb_device_id *id);
-static void usb_bluetooth_disconnect	(struct usb_device *dev, void *ptr);
+static int usb_bluetooth_probe (struct usb_interface *intf, 
+				const struct usb_device_id *id);
+static void usb_bluetooth_disconnect	(struct usb_interface *intf);
 
 
 static struct usb_device_id usb_bluetooth_ids [] = {
@@ -1033,9 +1033,10 @@
 }
 
 
-static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum,
-			 	  const struct usb_device_id *id)
+static int usb_bluetooth_probe (struct usb_interface *iface, 
+				const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev (iface);
 	struct usb_bluetooth *bluetooth = NULL;
 	struct usb_interface_descriptor *interface;
 	struct usb_endpoint_descriptor *endpoint;
@@ -1051,7 +1052,7 @@
 	int num_bulk_in = 0;
 	int num_bulk_out = 0;
 
-	interface = &dev->actconfig->interface[ifnum].altsetting[0];
+	interface = &iface->altsetting[0];
 	control_out_endpoint = interface->bInterfaceNumber;
 
 	/* find the endpoints that we need */
@@ -1088,7 +1089,7 @@
 	    (num_bulk_out != 1) ||
 	    (num_interrupt_in != 1)) {
 		dbg ("%s - improper number of endpoints. Bluetooth driver not bound.", __FUNCTION__);
-		return NULL;
+		return -EIO;
 	}
 
 	MOD_INC_USE_COUNT;
@@ -1099,13 +1100,13 @@
 	if (bluetooth_table[minor]) {
 		err("No more free Bluetooth devices");
 		MOD_DEC_USE_COUNT;
-		return NULL;
+		return -ENODEV;
 	}
 
 	if (!(bluetooth = kmalloc(sizeof(struct usb_bluetooth), GFP_KERNEL))) {
 		err("Out of memory");
 		MOD_DEC_USE_COUNT;
-		return NULL;
+		return -ENOMEM;
 	}
 
 	memset(bluetooth, 0, sizeof(struct usb_bluetooth));
@@ -1191,7 +1192,9 @@
 
 	bluetooth_table[minor] = bluetooth;
 
-	return bluetooth; /* success */
+	/* success */
+	iface->dev.driver_data = bluetooth;
+	return 0;
 
 probe_error:
 	if (bluetooth->read_urb)
@@ -1220,13 +1223,13 @@
 	/* free up any memory that we allocated */
 	kfree (bluetooth);
 	MOD_DEC_USE_COUNT;
-	return NULL;
+	return -EIO;
 }
 
 
-static void usb_bluetooth_disconnect(struct usb_device *dev, void *ptr)
+static void usb_bluetooth_disconnect(struct usb_interface *iface)
 {
-	struct usb_bluetooth *bluetooth = (struct usb_bluetooth *) ptr;
+	struct usb_bluetooth *bluetooth = iface->dev.driver_data;
 	int i;
 
 	if (bluetooth) {
@@ -1274,7 +1277,7 @@
 
 		/* free up any memory that we allocated */
 		kfree (bluetooth);
-
+		iface->dev.driver_data = NULL;
 	} else {
 		info("device disconnected");
 	}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/class/cdc-acm.c linux-2.5.34-greg/drivers/usb/class/cdc-acm.c
--- linux-2.5.34/drivers/usb/class/cdc-acm.c	Mon Sep  9 10:35:02 2002
+++ linux-2.5.34-greg/drivers/usb/class/cdc-acm.c	Wed Sep 11 15:33:33 2002
@@ -507,9 +507,10 @@
  * USB probe and disconnect routines.
  */
 
-static void *acm_probe(struct usb_device *dev, unsigned int ifnum,
-		       const struct usb_device_id *id)
+static int acm_probe (struct usb_interface *iface,
+		      const struct usb_device_id *id)
 {
+	struct usb_device *dev;
 	struct acm *acm;
 	struct usb_config_descriptor *cfacm;
 	struct usb_interface_descriptor *ifcom, *ifdata;
@@ -517,6 +518,7 @@
 	int readsize, ctrlsize, minor, i;
 	unsigned char *buf;
 
+	dev = interface_to_usbdev (iface);
 	for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
 
 		cfacm = dev->config + i;
@@ -561,12 +563,12 @@
 		for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
 		if (acm_table[minor]) {
 			err("no more free acm devices");
-			return NULL;
+			return -ENODEV;
 		}
 
 		if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
 			err("out of memory");
-			return NULL;
+			return -ENOMEM;
 		}
 		memset(acm, 0, sizeof(struct acm));
 
@@ -583,21 +585,21 @@
 		if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
 			err("out of memory");
 			kfree(acm);
-			return NULL;
+			return -ENOMEM;
 		}
 
 		acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!acm->ctrlurb) {
 			err("out of memory");
 			kfree(acm);
-			return NULL;
+			return -ENOMEM;
 		}
 		acm->readurb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!acm->readurb) {
 			err("out of memory");
 			usb_free_urb(acm->ctrlurb);
 			kfree(acm);
-			return NULL;
+			return -ENOMEM;
 		}
 		acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!acm->writeurb) {
@@ -605,7 +607,7 @@
 			usb_free_urb(acm->readurb);
 			usb_free_urb(acm->ctrlurb);
 			kfree(acm);
-			return NULL;
+			return -ENOMEM;
 		}
 
 		usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
@@ -631,15 +633,18 @@
 		usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm);
 
 		tty_register_devfs(&acm_tty_driver, 0, minor);
-		return acm_table[minor] = acm;
+
+		acm_table[minor] = acm;
+		iface->dev.driver_data = acm;
+		return 0;
 	}
 
-	return NULL;
+	return -EIO;
 }
 
-static void acm_disconnect(struct usb_device *dev, void *ptr)
+static void acm_disconnect(struct usb_interface *iface)
 {
-	struct acm *acm = ptr;
+	struct acm *acm = iface->dev.driver_data;
 
 	if (!acm || !acm->dev) {
 		dbg("disconnect on nonexisting interface");
@@ -647,6 +652,7 @@
 	}
 
 	acm->dev = NULL;
+	iface->dev.driver_data = NULL;
 
 	usb_unlink_urb(acm->ctrlurb);
 	usb_unlink_urb(acm->readurb);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/class/usb-midi.c linux-2.5.34-greg/drivers/usb/class/usb-midi.c
--- linux-2.5.34/drivers/usb/class/usb-midi.c	Mon Sep  9 10:35:01 2002
+++ linux-2.5.34-greg/drivers/usb/class/usb-midi.c	Wed Sep 11 15:33:33 2002
@@ -2020,13 +2020,16 @@
 
 /* ------------------------------------------------------------------------- */
 
-static void *usb_midi_probe(struct usb_device *dev, unsigned int ifnum,
-			    const struct usb_device_id *id)
+static int usb_midi_probe(struct usb_interface *iface, 
+			  const struct usb_device_id *id)
 {
 	struct usb_midi_state *s;
+	struct usb_device *dev = interface_to_usbdev(iface);
+	int ifnum = iface->altsetting->bInterfaceNumber;
 
 	s = (struct usb_midi_state *)kmalloc(sizeof(struct usb_midi_state), GFP_KERNEL);
-	if ( !s ) { return NULL; }
+	if ( !s )
+		return -ENOMEM;
 
 	memset( s, 0, sizeof(struct usb_midi_state) );
 	INIT_LIST_HEAD(&s->midiDevList);
@@ -2042,7 +2045,7 @@
 		detect_vendor_specific_device( dev, ifnum, s ) &&
 		detect_yamaha_device( dev, ifnum, s) ) {
 		kfree(s);
-		return NULL;
+		return -EIO;
 	}
 
 	down(&open_sem);
@@ -2053,16 +2056,20 @@
 	MOD_INC_USE_COUNT;
 #endif
 
-	return s;
+	iface->dev.driver_data = s;
+	return 0;
 }
 
 
-static void usb_midi_disconnect(struct usb_device *dev, void *ptr)
+static void usb_midi_disconnect(struct usb_interface *iface)
 {
-	struct usb_midi_state *s = (struct usb_midi_state *)ptr;
+	struct usb_midi_state *s = (struct usb_midi_state *)iface->dev.driver_data;
 	struct list_head      *list;
 	struct usb_mididev    *m;
 
+	if ( !s )
+		return;
+
 	if ( s == (struct usb_midi_state *)-1 ) {
 		return;
 	}
@@ -2073,6 +2080,7 @@
 	list_del(&s->mididev);
 	INIT_LIST_HEAD(&s->mididev);
 	s->usbdev = NULL;
+	iface->dev.driver_data = NULL;
 
 	for ( list = s->midiDevList.next; list != &s->midiDevList; list = list->next ) {
 		m = list_entry(list, struct usb_mididev, list);
@@ -2092,14 +2100,17 @@
 	return;
 }
 
-
+/* we want to look at all devices by hand */
+static struct usb_device_id id_table[] = {
+	{.driver_info = 42},
+	{}
+};
 
 static struct usb_driver usb_midi_driver = {
-	.name = "midi",
-	.probe = usb_midi_probe,
-	.disconnect = usb_midi_disconnect,
-	.id_table =	NULL, 			/* check all devices */
-	.driver_list = LIST_HEAD_INIT(usb_midi_driver.driver_list)
+	.name =		"midi",
+	.probe =	usb_midi_probe,
+	.disconnect =	usb_midi_disconnect,
+	.id_table =	id_table,
 };
 
 /* ------------------------------------------------------------------------- */
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/class/usblp.c linux-2.5.34-greg/drivers/usb/class/usblp.c
--- linux-2.5.34/drivers/usb/class/usblp.c	Mon Sep  9 10:35:04 2002
+++ linux-2.5.34-greg/drivers/usb/class/usblp.c	Wed Sep 11 15:33:33 2002
@@ -795,9 +795,10 @@
 	.release =	usblp_release,
 };
 
-static void *usblp_probe(struct usb_device *dev, unsigned int ifnum,
-			 const struct usb_device_id *id)
+static int usblp_probe(struct usb_interface *iface,
+		       const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev (iface);
 	struct usblp *usblp = 0;
 	int protocol;
 	int retval;
@@ -813,7 +814,7 @@
 	usblp->dev = dev;
 	init_MUTEX (&usblp->sem);
 	init_waitqueue_head(&usblp->wait);
-	usblp->ifnum = ifnum;
+	usblp->ifnum = iface->altsetting->bInterfaceNumber;
 
 	retval = usb_register_dev(&usblp_fops, USBLP_MINOR_BASE, 1, &usblp->minor);
 	if (retval) {
@@ -886,12 +887,14 @@
 
 	info("usblp%d: USB %sdirectional printer dev %d "
 		"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
-		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, ifnum,
+		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
+		usblp->ifnum,
 		usblp->protocol[usblp->current_protocol].alt_setting,
 		usblp->current_protocol, usblp->dev->descriptor.idVendor,
 		usblp->dev->descriptor.idProduct);
 
-	return usblp;
+	iface->dev.driver_data = usblp;
+	return 0;
 
 abort_minor:
 	usb_deregister_dev (1, usblp->minor);
@@ -903,7 +906,7 @@
 		if (usblp->device_id_string) kfree(usblp->device_id_string);
 		kfree(usblp);
 	}
-	return NULL;
+	return -EIO;
 }
 
 /*
@@ -1065,9 +1068,9 @@
 	return length;
 }
 
-static void usblp_disconnect(struct usb_device *dev, void *ptr)
+static void usblp_disconnect(struct usb_interface *iface)
 {
-	struct usblp *usblp = ptr;
+	struct usblp *usblp = iface->dev.driver_data;
 
 	if (!usblp || !usblp->dev) {
 		err("bogus disconnect");
@@ -1077,6 +1080,7 @@
 	down (&usblp->sem);
 	lock_kernel();
 	usblp->dev = NULL;
+	iface->dev.driver_data = NULL;
 
 	usblp_unlink_urbs(usblp);
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/devices.c linux-2.5.34-greg/drivers/usb/core/devices.c
--- linux-2.5.34/drivers/usb/core/devices.c	Mon Sep  9 10:35:09 2002
+++ linux-2.5.34-greg/drivers/usb/core/devices.c	Wed Sep 11 15:33:33 2002
@@ -111,7 +111,6 @@
 
 /*
  * Need access to the driver and USB bus lists.
- * extern struct list_head usb_driver_list;
  * extern struct list_head usb_bus_list;
  * However, these will come from functions that return ptrs to each of them.
  */
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/devio.c linux-2.5.34-greg/drivers/usb/core/devio.c
--- linux-2.5.34/drivers/usb/core/devio.c	Mon Sep  9 10:35:11 2002
+++ linux-2.5.34-greg/drivers/usb/core/devio.c	Wed Sep 11 15:33:33 2002
@@ -298,15 +298,15 @@
  * they're also undone when devices disconnect.
  */
 
-static void *driver_probe(struct usb_device *dev, unsigned int intf,
-			  const struct usb_device_id *id)
+static int driver_probe (struct usb_interface *intf,
+			 const struct usb_device_id *id)
 {
-	return NULL;
+	return -ENODEV;
 }
 
-static void driver_disconnect(struct usb_device *dev, void *context)
+static void driver_disconnect(struct usb_interface *intf)
 {
-	struct dev_state *ps = (struct dev_state *)context;
+	struct dev_state *ps = (struct dev_state *)intf->dev.driver_data;
 
 	if (!ps)
 		return;
@@ -317,6 +317,7 @@
 	/* prevent new I/O requests */
 	ps->dev = 0;
 	ps->ifclaimed = 0;
+	intf->dev.driver_data = NULL;
 
 	/* force async requests to complete */
 	destroy_all_async (ps);
@@ -427,30 +428,6 @@
 	return -ENOENT; 
 }
 
-extern struct list_head usb_driver_list;
-
-#if 0
-static int finddriver(struct usb_driver **driver, char *name)
-{
-	struct list_head *tmp;
-
-	tmp = usb_driver_list.next;
-	while (tmp != &usb_driver_list) {
-		struct usb_driver *d = list_entry(tmp, struct usb_driver,
-							driver_list);
-
-		if (!strcmp(d->name, name)) {
-			*driver = d;
-			return 0;
-		}
-
-		tmp = tmp->next;
-	}
-
-	return -EINVAL;
-}
-#endif
-
 static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsigned int index)
 {
 	int ret;
@@ -723,11 +700,10 @@
 		if (test_bit(i, &ps->ifclaimed))
 			continue;
 
-		lock_kernel();
+		err ("%s - this function is broken", __FUNCTION__);
 		if (intf->driver && ps->dev) {
-			usb_bind_driver (intf->driver, intf);
+			usb_device_probe (&intf->dev);
 		}
-		unlock_kernel();
 	}
 
 	return 0;
@@ -1090,22 +1066,19 @@
 
        /* disconnect kernel driver from interface, leaving it unbound.  */
        case USBDEVFS_DISCONNECT:
-       	/* this function is voodoo. without locking it is a maybe thing */
-		lock_kernel();
-               driver = ifp->driver;
-               if (driver) {
-                       dbg ("disconnect '%s' from dev %d interface %d",
-                               driver->name, ps->dev->devnum, ctrl.ifno);
-		       usb_unbind_driver(ps->dev, ifp);
-                       usb_driver_release_interface (driver, ifp);
-               } else
+		/* this function is voodoo. */
+		driver = ifp->driver;
+		if (driver) {
+			dbg ("disconnect '%s' from dev %d interface %d",
+			     driver->name, ps->dev->devnum, ctrl.ifno);
+			usb_device_remove(&ifp->dev);
+		} else
 			retval = -EINVAL;
-		unlock_kernel();
-               break;
+		break;
 
 	/* let kernel drivers try to (re)bind to the interface */
 	case USBDEVFS_CONNECT:
-		usb_find_interface_driver (ps->dev, ifp);
+		retval = usb_device_probe (&ifp->dev);
 		break;
 
        /* talk directly to the interface's driver */
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/hcd.c linux-2.5.34-greg/drivers/usb/core/hcd.c
--- linux-2.5.34/drivers/usb/core/hcd.c	Mon Sep  9 10:35:13 2002
+++ linux-2.5.34-greg/drivers/usb/core/hcd.c	Wed Sep 11 15:33:33 2002
@@ -722,13 +722,16 @@
 {
 	int retval;
 
-	usb_dev->dev.parent = parent_dev;
-	strcpy (&usb_dev->dev.name[0], "usb_name");
-	strcpy (&usb_dev->dev.bus_id[0], "usb_bus");
-	retval = usb_new_device (usb_dev);
+//	usb_dev->dev.parent = parent_dev;
+//	strcpy (&usb_dev->dev.name[0], "usb_name");
+//	strcpy (&usb_dev->dev.bus_id[0], "usb_bus");
+	sprintf (&usb_dev->dev.bus_id[0], "usb%d", usb_dev->bus->busnum);
+	retval = usb_new_device (usb_dev, parent_dev);
 	if (retval)
-		put_device (&usb_dev->dev);
+		err("%s - usb_new_device failed with value %d", __FUNCTION__, retval);
+//		put_device (&usb_dev->dev);
 	return retval;
+//	return usb_new_device (usb_dev, parent_dev);
 }
 EXPORT_SYMBOL (usb_register_root_hub);
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/hcd.h linux-2.5.34-greg/drivers/usb/core/hcd.h
--- linux-2.5.34/drivers/usb/core/hcd.h	Mon Sep  9 10:35:07 2002
+++ linux-2.5.34-greg/drivers/usb/core/hcd.h	Wed Sep 11 15:33:33 2002
@@ -270,7 +270,7 @@
 /* -------------------------------------------------------------------------- */
 
 /* Enumeration is only for the hub driver, or HCD virtual root hubs */
-extern int usb_new_device(struct usb_device *dev);
+extern int usb_new_device(struct usb_device *dev, struct device *parent);
 extern void usb_connect(struct usb_device *dev);
 extern void usb_disconnect(struct usb_device **);
 
@@ -396,12 +396,6 @@
 
 #define usb_endpoint_out(ep_dir)	(!((ep_dir) & USB_DIR_IN))
 
-/* for probe/disconnect with correct module usage counting */
-void *usb_bind_driver(struct usb_driver *driver, struct usb_interface *intf);
-void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf);
-
-extern struct list_head usb_driver_list;
-
 /*
  * USB device fs stuff
  */
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/hub.c linux-2.5.34-greg/drivers/usb/core/hub.c
--- linux-2.5.34/drivers/usb/core/hub.c	Mon Sep  9 10:35:11 2002
+++ linux-2.5.34-greg/drivers/usb/core/hub.c	Wed Sep 11 15:33:33 2002
@@ -175,6 +175,7 @@
 	while (!list_empty (&hub->tt.clear_list)) {
 		struct list_head	*temp;
 		struct usb_tt_clear	*clear;
+		struct usb_device	*dev;
 		int			status;
 
 		temp = hub->tt.clear_list.next;
@@ -183,13 +184,13 @@
 
 		/* drop lock so HCD can concurrently report other TT errors */
 		spin_unlock_irqrestore (&hub->tt.lock, flags);
-		status = hub_clear_tt_buffer (hub->dev,
-				clear->devinfo, clear->tt);
+		dev = interface_to_usbdev (hub->intf);
+		status = hub_clear_tt_buffer (dev, clear->devinfo, clear->tt);
 		spin_lock_irqsave (&hub->tt.lock, flags);
 
 		if (status)
 			err ("usb-%s-%s clear tt %d (%04x) error %d",
-				hub->dev->bus->bus_name, hub->dev->devpath,
+				dev->bus->bus_name, dev->devpath,
 				clear->tt, clear->devinfo, status);
 		kfree (clear);
 	}
@@ -245,12 +246,14 @@
 
 static void usb_hub_power_on(struct usb_hub *hub)
 {
+	struct usb_device *dev;
 	int i;
 
 	/* Enable power to the ports */
 	dbg("enabling power on all ports");
+	dev = interface_to_usbdev(hub->intf);
 	for (i = 0; i < hub->descriptor->bNbrPorts; i++)
-		usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER);
+		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
 
 	/* Wait for power to be enabled */
 	wait_ms(hub->descriptor->bPwrOn2PwrGood * 2);
@@ -259,7 +262,7 @@
 static int usb_hub_configure(struct usb_hub *hub,
 	struct usb_endpoint_descriptor *endpoint)
 {
-	struct usb_device *dev = hub->dev;
+	struct usb_device *dev = interface_to_usbdev (hub->intf);
 	struct usb_hub_status hubstatus;
 	unsigned int pipe;
 	int maxp, ret;
@@ -425,39 +428,81 @@
 	return 0;
 }
 
-static void *hub_probe(struct usb_device *dev, unsigned int i,
-		       const struct usb_device_id *id)
+static void hub_disconnect(struct usb_interface *intf)
 {
-	struct usb_interface_descriptor *interface;
+	struct usb_hub *hub = (struct usb_hub *)intf->dev.driver_data;
+	unsigned long flags;
+
+	if (!hub)
+		return;
+
+	spin_lock_irqsave(&hub_event_lock, flags);
+
+	/* Delete it and then reset it */
+	list_del(&hub->event_list);
+	INIT_LIST_HEAD(&hub->event_list);
+	list_del(&hub->hub_list);
+	INIT_LIST_HEAD(&hub->hub_list);
+
+	spin_unlock_irqrestore(&hub_event_lock, flags);
+
+	down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */
+	up(&hub->khubd_sem);
+
+	/* assuming we used keventd, it must quiesce too */
+	if (hub->tt.hub)
+		flush_scheduled_tasks ();
+
+	if (hub->urb) {
+		usb_unlink_urb(hub->urb);
+		usb_free_urb(hub->urb);
+		hub->urb = NULL;
+	}
+
+	if (hub->descriptor) {
+		kfree(hub->descriptor);
+		hub->descriptor = NULL;
+	}
+
+	/* Free the memory */
+	kfree(hub);
+	intf->dev.driver_data = NULL;
+}
+
+static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct usb_interface_descriptor *desc;
 	struct usb_endpoint_descriptor *endpoint;
+	struct usb_device *dev;
 	struct usb_hub *hub;
 	unsigned long flags;
 
-	interface = &dev->actconfig->interface[i].altsetting[0];
+	desc = intf->altsetting + intf->act_altsetting;
+	dev = interface_to_usbdev(intf);
 
 	/* Some hubs have a subclass of 1, which AFAICT according to the */
 	/*  specs is not defined, but it works */
-	if ((interface->bInterfaceSubClass != 0) &&
-	    (interface->bInterfaceSubClass != 1)) {
+	if ((desc->bInterfaceSubClass != 0) &&
+	    (desc->bInterfaceSubClass != 1)) {
 		err("invalid subclass (%d) for USB hub device #%d",
-			interface->bInterfaceSubClass, dev->devnum);
-		return NULL;
+			desc->bInterfaceSubClass, dev->devnum);
+		return -EIO;
 	}
 
 	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
-	if (interface->bNumEndpoints != 1) {
+	if (desc->bNumEndpoints != 1) {
 		err("invalid bNumEndpoints (%d) for USB hub device #%d",
-			interface->bNumEndpoints, dev->devnum);
-		return NULL;
+			desc->bNumEndpoints, dev->devnum);
+		return -EIO;
 	}
 
-	endpoint = &interface->endpoint[0];
+	endpoint = &desc->endpoint[0];
 
 	/* Output endpoint? Curiousier and curiousier.. */
 	if (!(endpoint->bEndpointAddress & USB_DIR_IN)) {
 		err("Device #%d is hub class, but has output endpoint?",
 			dev->devnum);
-		return NULL;
+		return -EIO;
 	}
 
 	/* If it's not an interrupt endpoint, we'd better punt! */
@@ -465,7 +510,7 @@
 			!= USB_ENDPOINT_XFER_INT) {
 		err("Device #%d is hub class, but endpoint is not interrupt?",
 			dev->devnum);
-		return NULL;
+		return -EIO;
 	}
 
 	/* We found a hub */
@@ -474,13 +519,13 @@
 	hub = kmalloc(sizeof(*hub), GFP_KERNEL);
 	if (!hub) {
 		err("couldn't kmalloc hub struct");
-		return NULL;
+		return -ENOMEM;
 	}
 
 	memset(hub, 0, sizeof(*hub));
 
 	INIT_LIST_HEAD(&hub->event_list);
-	hub->dev = dev;
+	hub->intf = intf;
 	init_MUTEX(&hub->khubd_sem);
 
 	/* Record the new hub's existence */
@@ -489,14 +534,18 @@
 	list_add(&hub->hub_list, &hub_list);
 	spin_unlock_irqrestore(&hub_event_lock, flags);
 
+	intf->dev.driver_data = hub;
+
 	if (usb_hub_configure(hub, endpoint) >= 0) {
-		strcpy (dev->actconfig->interface[i].dev.name,
-			"Hub/Port Status Changes");
-		return hub;
+		strcpy (intf->dev.name, "Hub/Port Status Changes");
+		return 0;
 	}
 
 	err("hub configuration failed for device at %s", dev->devpath);
 
+	hub_disconnect (intf);
+	return -ENODEV;
+#if 0
 	/* free hub, but first clean up its list. */
 	spin_lock_irqsave(&hub_event_lock, flags);
 
@@ -511,43 +560,7 @@
 	kfree(hub);
 
 	return NULL;
-}
-
-static void hub_disconnect(struct usb_device *dev, void *ptr)
-{
-	struct usb_hub *hub = (struct usb_hub *)ptr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&hub_event_lock, flags);
-
-	/* Delete it and then reset it */
-	list_del(&hub->event_list);
-	INIT_LIST_HEAD(&hub->event_list);
-	list_del(&hub->hub_list);
-	INIT_LIST_HEAD(&hub->hub_list);
-
-	spin_unlock_irqrestore(&hub_event_lock, flags);
-
-	down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */
-	up(&hub->khubd_sem);
-
-	/* assuming we used keventd, it must quiesce too */
-	if (hub->tt.hub)
-		flush_scheduled_tasks ();
-
-	if (hub->urb) {
-		usb_unlink_urb(hub->urb);
-		usb_free_urb(hub->urb);
-		hub->urb = NULL;
-	}
-
-	if (hub->descriptor) {
-		kfree(hub->descriptor);
-		hub->descriptor = NULL;
-	}
-
-	/* Free the memory */
-	kfree(hub);
+#endif
 }
 
 static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data)
@@ -584,7 +597,7 @@
 
 static int usb_hub_reset(struct usb_hub *hub)
 {
-	struct usb_device *dev = hub->dev;
+	struct usb_device *dev = interface_to_usbdev(hub->intf);
 	int i;
 
 	/* Disconnect any attached devices */
@@ -796,7 +809,7 @@
 static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
 					u16 portstatus, u16 portchange)
 {
-	struct usb_device *hub = hubstate->dev;
+	struct usb_device *hub = interface_to_usbdev(hubstate->intf);
 	struct usb_device *dev;
 	unsigned int delay = HUB_SHORT_RESET_TIME;
 	int i;
@@ -891,11 +904,15 @@
 		/* put the device in the global device tree. the hub port
 		 * is the "bus_id"; hubs show in hierarchy like bridges
 		 */
-		dev->dev.parent = &dev->parent->dev;
-		sprintf (&dev->dev.bus_id[0], "%d", port + 1);
+//		dev->dev.parent = &dev->parent->dev;
+//		if (dev->parent->dev.parent)
+			dev->dev.parent = dev->parent->dev.parent->parent;
+//		else
+//			dev->dev.parent = &dev->parent->dev;
+//		sprintf (&dev->dev.bus_id[0], "%d", port + 1);
 
 		/* Run it through the hoops (find a driver, etc) */
-		if (!usb_new_device(dev))
+		if (!usb_new_device(dev, &hub->dev))
 			goto done;
 
 		/* Free the configuration if there was an error */
@@ -940,7 +957,7 @@
 		tmp = hub_event_list.next;
 
 		hub = list_entry(tmp, struct usb_hub, event_list);
-		dev = hub->dev;
+		dev = interface_to_usbdev(hub->intf);
 
 		list_del(tmp);
 		INIT_LIST_HEAD(tmp);
@@ -1081,8 +1098,8 @@
 static struct usb_driver hub_driver = {
 	.name =		"hub",
 	.probe =	hub_probe,
-	.ioctl =	hub_ioctl,
 	.disconnect =	hub_disconnect,
+	.ioctl =	hub_ioctl,
 	.id_table =	hub_id_table,
 };
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/hub.h linux-2.5.34-greg/drivers/usb/core/hub.h
--- linux-2.5.34/drivers/usb/core/hub.h	Mon Sep  9 10:35:02 2002
+++ linux-2.5.34-greg/drivers/usb/core/hub.h	Wed Sep 11 15:33:33 2002
@@ -170,7 +170,8 @@
 extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe);
 
 struct usb_hub {
-	struct usb_device	*dev;		/* the "real" device */
+//	struct usb_device	*dev;		/* the "real" device */
+	struct usb_interface	*intf;		/* the "real" device */
 	struct urb		*urb;		/* for interrupt polling pipe */
 
 	/* buffer for urb ... 1 bit each for hub and children, rounded up */
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/usb.c linux-2.5.34-greg/drivers/usb/core/usb.c
--- linux-2.5.34/drivers/usb/core/usb.c	Mon Sep  9 10:35:12 2002
+++ linux-2.5.34-greg/drivers/usb/core/usb.c	Wed Sep 11 15:33:33 2002
@@ -48,225 +48,140 @@
 extern int usb_major_init(void);
 extern void usb_major_cleanup(void);
 
-/*
- * Prototypes for the device driver probing/loading functions
- */
-static void usb_find_drivers(struct usb_device *);
-static void usb_check_support(struct usb_device *);
-
-/*
- * We have a per-interface "registered driver" list.
- */
-LIST_HEAD(usb_driver_list);
 
 
-/**
- * usb_register - register a USB driver
- * @new_driver: USB operations for the driver
- *
- * Registers a USB driver with the USB core.  The list of unattached
- * interfaces will be rescanned whenever a new driver is added, allowing
- * the new driver to attach to any recognized devices.
- * Returns a negative error code on failure and 0 on success.
- * 
- * NOTE: if you want your driver to use the USB major number, you must call
- * usb_register_dev() to enable that functionality.  This function no longer
- * takes care of that.
- */
-int usb_register(struct usb_driver *new_driver)
+static int generic_probe (struct device *dev)
 {
-	int retval = 0;
-
-	info("registered new driver %s", new_driver->name);
-
-	init_MUTEX(&new_driver->serialize);
+	return 0;
+}
+static int generic_remove (struct device *dev)
+{
+	return 0;
+}
+static void generic_release (struct device_driver * drv)
+{
+}
 
-	/* Add it to the list of known drivers */
-	list_add_tail(&new_driver->driver_list, &usb_driver_list);
+static struct device_driver usb_generic_driver = {
+	.name =	"generic usb driver",
+	.probe = generic_probe,
+	.remove = generic_remove,
+	.release = generic_release,
+};
+	
 
-	usb_scan_devices();
+int usb_device_probe(struct device *dev)
+{
+	struct usb_interface * intf = to_usb_interface(dev);
+	struct usb_driver * driver = to_usb_driver(dev->driver);
+	const struct usb_device_id *id;
+	int error = -ENODEV;
+	int m;
 
-	usbfs_update_special();
+	dbg("%s", __FUNCTION__);
 
-	return retval;
-}
+	if (!driver->probe)
+		return error;
 
+	if (driver->owner) {
+		m = try_inc_mod_count(driver->owner);
+		if (m == 0)
+			return error;
+	}
 
-/**
- *	usb_scan_devices - scans all unclaimed USB interfaces
- *	Context: !in_interrupt ()
- *
- *	Goes through all unclaimed USB interfaces, and offers them to all
- *	registered USB drivers through the 'probe' function.
- *	This will automatically be called after usb_register is called.
- *	It is called by some of the subsystems layered over USB
- *	after one of their subdrivers are registered.
- */
-void usb_scan_devices(void)
-{
-	struct list_head *tmp;
+	id = usb_match_id (intf, driver->id_table);
+	if (id) {
+		dbg ("%s - got id", __FUNCTION__);
+		down (&driver->serialize);
+		error = driver->probe (intf, id);
+		up (&driver->serialize);
+	}
+	if (!error)
+		intf->driver = driver;
 
-	down (&usb_bus_list_lock);
-	tmp = usb_bus_list.next;
-	while (tmp != &usb_bus_list) {
-		struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list);
+	if (driver->owner)
+		__MOD_DEC_USE_COUNT(driver->owner);
 
-		tmp = tmp->next;
-		usb_check_support(bus->root_hub);
-	}
-	up (&usb_bus_list_lock);
+	return error;
 }
 
-/**
- *	usb_unbind_driver - disconnects a driver from a device (usbcore-internal)
- *	@device: usb device to be disconnected
- *	@intf: interface of the device to be disconnected
- *	Context: BKL held
- *
- *	Handles module usage count correctly
- */
-
-void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf)
+int usb_device_remove(struct device *dev)
 {
+	struct usb_interface *intf;
 	struct usb_driver *driver;
-	void *priv;
 	int m;
-	
 
-	driver = intf->driver;
-	priv = intf->private_data;
-	
-	if (!driver || !driver->disconnect)
-		return;
+	intf = list_entry(dev,struct usb_interface,dev);
+	driver = to_usb_driver(dev->driver);
+
+	if (!driver) {
+		err("%s does not have a valid driver to work with!",
+		    __FUNCTION__);
+		return -ENODEV;
+	}
 
-	/* as soon as we increase the module use count we drop the BKL
-	   before that we must not sleep */
 	if (driver->owner) {
 		m = try_inc_mod_count(driver->owner);
 		if (m == 0) {
 			err("Dieing driver still bound to device.\n");
-			return;
+			return -EIO;
 		}
-		unlock_kernel();
 	}
-	down(&driver->serialize); 	/* if we sleep here on an umanaged driver
-					   the holder of the lock guards against
-					   module unload */
 
-	driver->disconnect(device, priv);
+	/* if we sleep here on an umanaged driver 
+	 * the holder of the lock guards against 
+	 * module unload */
+	down(&driver->serialize);
+
+	if (intf->driver && intf->driver->disconnect)
+		intf->driver->disconnect(intf);
+
+	/* if driver->disconnect didn't release the interface */
+	if (intf->driver)
+		usb_driver_release_interface(driver, intf);
 
 	up(&driver->serialize);
-	if (driver->owner) {
-		lock_kernel();
+	if (driver->owner)
 		__MOD_DEC_USE_COUNT(driver->owner);
-	}
+
+	return 0;
 }
 
 /**
- *	usb_bind_driver - connect a driver to a device's interface (usbcore-internal)
- *	@driver: device driver to be bound to interface
- *	@interface: interface that the driver will be using
- *	Context: BKL held
- *
- *	Does a safe binding of a driver to one of a device's interfaces.
- *	Returns the driver's data for the binding, or null indicating
- *	that the driver did not bind to this interface.
- *
- *	This differs from usb_driver_claim_interface(), which is called from
- *	drivers and neither calls the driver's probe() entry nor does any
- *	locking to guard against removing driver modules.
+ * usb_register - register a USB driver
+ * @new_driver: USB operations for the driver
+ *
+ * Registers a USB driver with the USB core.  The list of unattached
+ * interfaces will be rescanned whenever a new driver is added, allowing
+ * the new driver to attach to any recognized devices.
+ * Returns a negative error code on failure and 0 on success.
+ * 
+ * NOTE: if you want your driver to use the USB major number, you must call
+ * usb_register_dev() to enable that functionality.  This function no longer
+ * takes care of that.
  */
-void *
-usb_bind_driver (struct usb_driver *driver, struct usb_interface *interface)
+int usb_register(struct usb_driver *new_driver)
 {
-	int i,m;
-	void *private = NULL;
-	const struct usb_device_id *id;
-	struct usb_device *dev = interface_to_usbdev (interface);
-	int ifnum;
-
-	if (driver->owner) {
-		m = try_inc_mod_count(driver->owner);
-		if (m == 0)
-			return NULL; /* this horse is dead - don't ride*/
-		unlock_kernel();
-	}
-
-	// START TEMPORARY
-	// driver->probe() hasn't yet changed to take interface not dev+ifnum,
-	// so we still need ifnum here.
-	for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++)
-		if (&dev->actconfig->interface [ifnum] == interface)
-			break;
-	BUG_ON (ifnum == dev->actconfig->bNumInterfaces);
-	// END TEMPORARY
-
-	id = driver->id_table;
-	/* new style driver? */
-	if (id) {
-		for (i = 0; i < interface->num_altsetting; i++) {
-		  	interface->act_altsetting = i;
-			id = usb_match_id(interface, id);
-			if (id) {
-				down(&driver->serialize);
-				private = driver->probe(dev,ifnum,id);
-				up(&driver->serialize);
-				if (private != NULL)
-					break;
-			}
-		}
+	int retval = 0;
 
-		/* if driver not bound, leave defaults unchanged */
-		if (private == NULL)
-			interface->act_altsetting = 0;
-	} else { /* "old style" driver */
-		down(&driver->serialize);
-		private = driver->probe(dev, ifnum, NULL);
-		up(&driver->serialize);
-	}
-	if (driver->owner) {
-		lock_kernel();
-		__MOD_DEC_USE_COUNT(driver->owner);
-	}
+	new_driver->driver.name = (char *)new_driver->name;
+	new_driver->driver.bus = &usb_bus_type;
+	new_driver->driver.probe = usb_device_probe;
+	new_driver->driver.remove = usb_device_remove;
 
-	return private;
-}
+	init_MUTEX(&new_driver->serialize);
 
-/*
- * This function is part of a depth-first search down the device tree,
- * removing any instances of a device driver.
- */
-static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev)
-{
-	int i;
+	retval = driver_register(&new_driver->driver);
 
-	if (!dev) {
-		err("null device being purged!!!");
-		return;
+	if (!retval) {
+		info("registered new driver %s", new_driver->name);
+		usbfs_update_special();
+	} else {
+		err("problem %d when registering driver %s",
+			retval, new_driver->name);
 	}
 
-	for (i=0; i<USB_MAXCHILDREN; i++)
-		if (dev->children[i])
-			usb_drivers_purge(driver, dev->children[i]);
-
-	if (!dev->actconfig)
-		return;
-
-	for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
-		struct usb_interface *interface = &dev->actconfig->interface[i];
-
-		if (interface->driver == driver) {
-			usb_unbind_driver(dev, interface);
-			/* if driver->disconnect didn't release the interface */
-			if (interface->driver)
-				usb_driver_release_interface(driver, interface);
-			/*
-			 * This will go through the list looking for another
-			 * driver that can handle the device
-			 */
-			usb_find_interface_driver(dev, interface);
-		}
-	}
+	return retval;
 }
 
 /**
@@ -282,25 +197,9 @@
  */
 void usb_deregister(struct usb_driver *driver)
 {
-	struct list_head *tmp;
-
 	info("deregistering driver %s", driver->name);
 
-	/*
-	 * first we remove the driver, to be sure it doesn't get used by
-	 * another thread while we are stepping through removing entries
-	 */
-	list_del(&driver->driver_list);
-
-	down (&usb_bus_list_lock);
-	tmp = usb_bus_list.next;
-	while (tmp != &usb_bus_list) {
-		struct usb_bus *bus = list_entry(tmp,struct usb_bus,bus_list);
-
-		tmp = tmp->next;
-		usb_drivers_purge(driver, bus->root_hub);
-	}
-	up (&usb_bus_list_lock);
+	remove_driver (&driver->driver);
 
 	usbfs_update_special();
 }
@@ -359,34 +258,6 @@
 	return NULL;
 }
 
-/*
- * This function is for doing a depth-first search for devices which
- * have support, for dynamic loading of driver modules.
- */
-static void usb_check_support(struct usb_device *dev)
-{
-	int i;
-
-	if (!dev) {
-		err("null device being checked!!!");
-		return;
-	}
-
-	for (i=0; i<USB_MAXCHILDREN; i++)
-		if (dev->children[i])
-			usb_check_support(dev->children[i]);
-
-	if (!dev->actconfig)
-		return;
-
-	/* now we check this device */
-	if (dev->devnum > 0)
-		for (i = 0; i < dev->actconfig->bNumInterfaces; i++)
-			usb_find_interface_driver (dev,
-				dev->actconfig->interface + i);
-}
-
-
 /**
  * usb_driver_claim_interface - bind a driver to an interface
  * @driver: the driver to be bound
@@ -595,72 +466,25 @@
 	return NULL;
 }
 
-/*
- * This entrypoint gets called for unclaimed interfaces.
- *
- * We now walk the list of registered USB drivers,
- * looking for one that will accept this interface.
- *
- * "New Style" drivers use a table describing the devices and interfaces
- * they handle.  Those tables are available to user mode tools deciding
- * whether to load driver modules for a new device.
- *
- * The probe return value is changed to be a private pointer.  This way
- * the drivers don't have to dig around in our structures to set the
- * private pointer if they only need one interface. 
- *
- * Returns: 0 if a driver accepted the interface, -1 otherwise
- */
-int usb_find_interface_driver (
-	struct usb_device *dev,
-	struct usb_interface *interface
-)
+static int usb_device_match (struct device *dev, struct device_driver *drv)
 {
-	struct list_head *tmp;
-	void *private;
-	struct usb_driver *driver;
-	int ifnum;
-	
-	down(&dev->serialize);
-
-	/* FIXME It's just luck that for some devices with drivers that set
-	 * configuration in probe(), the interface numbers still make sense.
-	 * That's one of several unsafe assumptions involved in configuring
-	 * devices, and in binding drivers to their interfaces.
-	 */
-	for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++)
-		if (&dev->actconfig->interface [ifnum] == interface)
-			break;
-	BUG_ON (ifnum == dev->actconfig->bNumInterfaces);
+	struct usb_interface *intf;
+	struct usb_driver *usb_drv;
+	const struct usb_device_id *id;
 
-	if (usb_interface_claimed(interface))
-		goto out_err;
+	intf = to_usb_interface(dev);
 
-	private = NULL;
-	lock_kernel();
-	for (tmp = usb_driver_list.next; tmp != &usb_driver_list;) {
-		driver = list_entry(tmp, struct usb_driver, driver_list);
-		tmp = tmp->next;
-
-		private = usb_bind_driver(driver, interface);
-
-		/* probe() may have changed the config on us */
-		interface = dev->actconfig->interface + ifnum;
-
-		if (private) {
-			usb_driver_claim_interface(driver, interface, private);
-			up(&dev->serialize);
-			unlock_kernel();
-			return 0;
-		}
-	}
-	unlock_kernel();
+	usb_drv = to_usb_driver(drv);
+	id = usb_drv->id_table;
+	
+	id = usb_match_id (intf, usb_drv->id_table);
+	if (id)
+		return 1;
 
-out_err:
-	up(&dev->serialize);
-	return -1;
+	return 0;
 }
 
+
 #ifdef	CONFIG_HOTPLUG
 
 /*
@@ -890,71 +714,6 @@
 }
 static DEVICE_ATTR(serial,S_IRUGO,show_serial,NULL);
 
-/*
- * This entrypoint gets called for each new device.
- *
- * All interfaces are scanned for matching drivers.
- */
-static void usb_find_drivers(struct usb_device *dev)
-{
-	unsigned ifnum;
-	unsigned rejected = 0;
-	unsigned claimed = 0;
-
-	/* FIXME should get called for each new configuration not just the
-	 * first one for a device. switching configs (or altsettings) should
-	 * undo driverfs and HCD state for the previous interfaces.
-	 */
-	for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) {
-		struct usb_interface *interface = &dev->actconfig->interface[ifnum];
-		struct usb_interface_descriptor *desc = interface->altsetting;
-
-		/* register this interface with driverfs */
-		interface->dev.parent = &dev->dev;
-		interface->dev.bus = &usb_bus_type;
-		sprintf (&interface->dev.bus_id[0], "%s-%s:%d",
-			 dev->bus->bus_name, dev->devpath,
-			 interface->altsetting->bInterfaceNumber);
-		if (!desc->iInterface
-				|| usb_string (dev, desc->iInterface,
-					interface->dev.name,
-					sizeof interface->dev.name) <= 0) {
-			/* typically devices won't bother with interface
-			 * descriptions; this is the normal case.  an
-			 * interface's driver might describe it better.
-			 * (also: iInterface is per-altsetting ...)
-			 */
-			sprintf (&interface->dev.name[0],
-				"usb-%s-%s interface %d",
-				dev->bus->bus_name, dev->devpath,
-				interface->altsetting->bInterfaceNumber);
-		}
-		device_register (&interface->dev);
-		device_create_file (&interface->dev, &dev_attr_altsetting);
-
-		/* if this interface hasn't already been claimed */
-		if (!usb_interface_claimed(interface)) {
-			if (usb_find_interface_driver(dev, interface))
-				rejected++;
-			else
-				claimed++;
-		}
-	}
- 
-	if (rejected)
-		dbg("unhandled interfaces on device");
-
-	if (!claimed) {
-		warn("USB device %d (vend/prod 0x%x/0x%x) is not claimed by any active driver.",
-			dev->devnum,
-			dev->descriptor.idVendor,
-			dev->descriptor.idProduct);
-#ifdef DEBUG
-		usb_show_device(dev);
-#endif
-	}
-}
-
 /**
  * usb_alloc_dev - allocate a usb device structure (usbcore-internal)
  * @parent: hub to which device is connected
@@ -1109,32 +868,21 @@
 
 	info("USB disconnect on device %d", dev->devnum);
 
-	lock_kernel();
-	if (dev->actconfig) {
-		for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
-			struct usb_interface *interface = &dev->actconfig->interface[i];
-			struct usb_driver *driver = interface->driver;
-			if (driver) {
-				usb_unbind_driver(dev, interface);
-				/* if driver->disconnect didn't release the interface */
-				if (interface->driver)
-					usb_driver_release_interface(driver, interface);
-			}
-			/* remove our device node for this interface */
-			put_device(&interface->dev);
-		}
-	}
-	unlock_kernel();
-
-	/* Free up all the children.. */
+	/* Free up all the children before we remove this device */
 	for (i = 0; i < USB_MAXCHILDREN; i++) {
 		struct usb_device **child = dev->children + i;
 		if (*child)
 			usb_disconnect(child);
 	}
 
-	/* Let policy agent unload modules etc */
-	call_policy ("remove", dev);
+	if (dev->actconfig) {
+		for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
+			struct usb_interface *interface = &dev->actconfig->interface[i];
+
+			/* remove this interface */
+			put_device(&interface->dev);
+		}
+	}
 
 	/* Free the device number and remove the /proc/bus/usb entry */
 	if (dev->devnum > 0) {
@@ -1143,6 +891,9 @@
 		put_device(&dev->dev);
 	}
 
+	/* Let policy agent unload modules etc */
+	call_policy ("remove", dev);
+
 	/* Decrement the reference count, it'll auto free everything when */
 	/* it hits 0 which could very well be now */
 	usb_put_dev(dev);
@@ -1271,7 +1022,7 @@
  */
 #define NEW_DEVICE_RETRYS	2
 #define SET_ADDRESS_RETRYS	2
-int usb_new_device(struct usb_device *dev)
+int usb_new_device(struct usb_device *dev, struct device *parent)
 {
 	int err = 0;
 	int i;
@@ -1361,10 +1112,25 @@
 		usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
 #endif
 
-	/* register this device in the driverfs tree */
+	/*
+	 * Set the driver for the usb device to point to the "generic" driver.
+	 * This prevents the main usb device from being sent to the usb bus
+	 * probe function.  Yes, it's a hack, but a nice one :)
+	 */
+	usb_generic_driver.bus = &usb_bus_type;
+	dev->dev.parent = parent;
+	dev->dev.driver = &usb_generic_driver;
+	dev->dev.bus = &usb_bus_type;
+//	sprintf (&dev->dev.bus_id[0], "%s-%s",
+//		 dev->bus->bus_name, dev->devpath);
+	if (dev->dev.bus_id[0] == 0)
+		sprintf (&dev->dev.bus_id[0], "%d-%s",
+			 dev->bus->busnum, dev->devpath);
 	err = device_register (&dev->dev);
 	if (err)
 		return err;
+
+	/* add the USB device specific driverfs files */
 	device_create_file (&dev->dev, &dev_attr_configuration);
 	if (dev->descriptor.iManufacturer)
 		device_create_file (&dev->dev, &dev_attr_manufacturer);
@@ -1373,11 +1139,41 @@
 	if (dev->descriptor.iSerialNumber)
 		device_create_file (&dev->dev, &dev_attr_serial);
 
-	/* now that the basic setup is over, add a /proc/bus/usb entry */
-	usbfs_add_device(dev);
+	/* Register all of the interfaces for this device with the driver core.
+	 * Remember, interfaces get bound to drivers, not devices. */
+	for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
+		struct usb_interface *interface = &dev->actconfig->interface[i];
+		struct usb_interface_descriptor *desc = interface->altsetting;
+
+		interface->dev.parent = &dev->dev;
+		interface->dev.bus = &usb_bus_type;
+//		sprintf (&interface->dev.bus_id[0], "%s-%s:%d",
+//			 dev->bus->bus_name, dev->devpath,
+//			 interface->altsetting->bInterfaceNumber);
+		sprintf (&interface->dev.bus_id[0], "%d-%s:%d",
+			 dev->bus->busnum, dev->devpath,
+			 interface->altsetting->bInterfaceNumber);
+		if (!desc->iInterface
+				|| usb_string (dev, desc->iInterface,
+					interface->dev.name,
+					sizeof interface->dev.name) <= 0) {
+			/* typically devices won't bother with interface
+			 * descriptions; this is the normal case.  an
+			 * interface's driver might describe it better.
+			 * (also: iInterface is per-altsetting ...)
+			 */
+			sprintf (&interface->dev.name[0],
+				"usb-%s-%s interface %d",
+				dev->bus->bus_name, dev->devpath,
+				interface->altsetting->bInterfaceNumber);
+		}
+		dbg ("%s - registering %s", __FUNCTION__, interface->dev.bus_id);
+		device_register (&interface->dev);
+		device_create_file (&interface->dev, &dev_attr_altsetting);
+	}
 
-	/* find drivers willing to handle this device */
-	usb_find_drivers(dev);
+	/* add a /proc/bus/usb entry */
+	usbfs_add_device(dev);
 
 	/* userspace may load modules and/or configure further */
 	call_policy ("add", dev);
@@ -1385,7 +1181,6 @@
 	return 0;
 }
 
-
 /**
  * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_DMA_MAP
  * @dev: device the buffer will be used with
@@ -1531,7 +1326,6 @@
 				? USB_DIR_IN
 				: USB_DIR_OUT);
 }
-
 /**
  * usb_buffer_map_sg - create scatterlist DMA mapping(s) for an endpoint
  * @dev: device to which the scatterlist will be mapped
@@ -1642,20 +1436,10 @@
 				     : USB_DIR_OUT);
 }
 
-#ifdef CONFIG_PROC_FS
-struct list_head *usb_driver_get_list(void)
-{
-	return &usb_driver_list;
-}
-
-struct list_head *usb_bus_get_list(void)
-{
-	return &usb_bus_list;
-}
-#endif
 
 struct bus_type usb_bus_type = {
-	.name =	"usb",
+	.name =		"usb",
+	.match =	usb_device_match,
 };
 
 /*
@@ -1694,7 +1478,9 @@
 
 EXPORT_SYMBOL(usb_register);
 EXPORT_SYMBOL(usb_deregister);
-EXPORT_SYMBOL(usb_scan_devices);
+
+EXPORT_SYMBOL(usb_device_probe);
+EXPORT_SYMBOL(usb_device_remove);
 
 EXPORT_SYMBOL(usb_alloc_dev);
 EXPORT_SYMBOL(usb_free_dev);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/image/hpusbscsi.c linux-2.5.34-greg/drivers/usb/image/hpusbscsi.c
--- linux-2.5.34/drivers/usb/image/hpusbscsi.c	Mon Sep  9 10:35:29 2002
+++ linux-2.5.34-greg/drivers/usb/image/hpusbscsi.c	Wed Sep 11 15:33:33 2002
@@ -30,13 +30,14 @@
 
 /* USB related parts */
 
-static void *
-hpusbscsi_usb_probe (struct usb_device *dev, unsigned int interface,
+static int
+hpusbscsi_usb_probe (struct usb_interface *intf, 
 		     const struct usb_device_id *id)
 {
 	struct hpusbscsi *new;
+	struct usb_device *dev = interface_to_usbdev (intf);
 	struct usb_interface_descriptor *altsetting =
-		&(dev->actconfig->interface[interface].altsetting[0]);
+		&(intf->altsetting[0]);
 
 	int i, result;
 
@@ -44,7 +45,7 @@
 
 	if (altsetting->bNumEndpoints != 3) {
 		printk (KERN_ERR "Wrong number of endpoints\n");
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* descriptor allocation */
@@ -53,19 +54,19 @@
 		(struct hpusbscsi *) kmalloc (sizeof (struct hpusbscsi),
 					      GFP_KERNEL);
 	if (new == NULL)
-		return NULL;
+		return -ENOMEM;
 	DEBUG ("Allocated memory\n");
 	memset (new, 0, sizeof (struct hpusbscsi));
 	new->dataurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!new->dataurb) {
 		kfree (new);
-		return NULL;
+		return -ENOMEM;
 	}
 	new->controlurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!new->controlurb) {
 		usb_free_urb (new->dataurb);
 		kfree (new);
-		return NULL;
+		return -ENOMEM;
 	}
 	new->dev = dev;
 	init_waitqueue_head (&new->pending);
@@ -135,20 +136,24 @@
 	/* adding to list for module unload */
 	list_add (&hpusbscsi_devices, &new->lh);
 
-	return new;
+	dev_set_drvdata(&intf->dev, new);
+	return 0;
 
       err_out:
 	usb_free_urb (new->controlurb);
 	usb_free_urb (new->dataurb);
 	kfree (new);
-	return NULL;
+	return -ENODEV;
 }
 
 static void
-hpusbscsi_usb_disconnect (struct usb_device *dev, void *ptr)
+hpusbscsi_usb_disconnect (struct usb_interface *intf)
 {
-                 usb_unlink_urb((((struct hpusbscsi *) ptr)->controlurb));
-	((struct hpusbscsi *) ptr)->dev = NULL;
+	struct hpusbscsi *desc = dev_get_drvdata(&intf->dev);
+
+	dev_set_drvdata(&intf->dev, NULL);
+	if (desc)
+		usb_unlink_urb(desc->controlurb);
 }
 
 static struct usb_device_id hpusbscsi_usb_ids[] = {
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/image/mdc800.c linux-2.5.34-greg/drivers/usb/image/mdc800.c
--- linux-2.5.34/drivers/usb/image/mdc800.c	Mon Sep  9 10:34:59 2002
+++ linux-2.5.34-greg/drivers/usb/image/mdc800.c	Wed Sep 11 15:33:33 2002
@@ -406,11 +406,12 @@
 /*
  * Callback to search the Mustek MDC800 on the USB Bus
  */
-static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum,
+static int mdc800_usb_probe (struct usb_interface *intf,
 			       const struct usb_device_id *id)
 {
 	int i,j;
 	struct usb_interface_descriptor	*intf_desc;
+	struct usb_device *dev = interface_to_usbdev (intf);
 	int irq_interval=0;
 	int retval;
 
@@ -420,15 +421,15 @@
 	if (mdc800->dev != 0)
 	{
 		warn ("only one Mustek MDC800 is supported.");
-		return 0;
+		return -ENODEV;
 	}
 
 	if (dev->descriptor.bNumConfigurations != 1)
 	{
 		err ("probe fails -> wrong Number of Configuration");
-		return 0;
+		return -ENODEV;
 	}
-	intf_desc=&dev->actconfig->interface[ifnum].altsetting[0];
+	intf_desc = &intf->altsetting[0];
 
 	if (
 			( intf_desc->bInterfaceClass != 0xff )
@@ -438,7 +439,7 @@
 	)
 	{
 		err ("probe fails -> wrong Interface");
-		return 0;
+		return -ENODEV;
 	}
 
 	/* Check the Endpoints */
@@ -461,16 +462,16 @@
 		if (mdc800->endpoint[i] == -1)
 		{
 			err ("probe fails -> Wrong Endpoints.");
-			return 0;
+			return -ENODEV;
 		}
 	}
 
 
-	usb_driver_claim_interface (&mdc800_usb_driver, &dev->actconfig->interface[ifnum], mdc800);
-	if (usb_set_interface (dev, ifnum, 0) < 0)
+	usb_driver_claim_interface (&mdc800_usb_driver, intf, mdc800);
+	if (usb_set_interface (dev, intf_desc->bInterfaceNumber, 0) < 0)
 	{
 		err ("MDC800 Configuration fails.");
-		return 0;
+		return -ENODEV;
 	}
 
 	info ("Found Mustek MDC800 on USB.");
@@ -480,7 +481,7 @@
 	retval = usb_register_dev (&mdc800_device_ops, MDC800_DEVICE_MINOR_BASE, 1, &mdc800->minor);
 	if (retval && (retval != -ENODEV)) {
 		err ("Not able to get a minor for this device.");
-		return 0;
+		return -ENODEV;
 	}
 
 	mdc800->dev=dev;
@@ -522,33 +523,37 @@
 
 	up (&mdc800->io_lock);
 	
-	return mdc800;
+	dev_set_drvdata(&intf->dev, mdc800);
+	return 0;
 }
 
 
 /*
  * Disconnect USB device (maybe the MDC800)
  */
-static void mdc800_usb_disconnect (struct usb_device *dev,void* ptr)
+static void mdc800_usb_disconnect (struct usb_interface *intf)
 {
-	struct mdc800_data* mdc800=(struct mdc800_data*) ptr;
+	struct mdc800_data* mdc800 = dev_get_drvdata(&intf->dev);
 
 	dbg ("(mdc800_usb_disconnect) called");
 
-	if (mdc800->state == NOT_CONNECTED)
-		return;
-	
-	usb_deregister_dev (1, mdc800->minor);
+	if (mdc800) {
+		if (mdc800->state == NOT_CONNECTED)
+			return;
+
+		usb_deregister_dev (1, mdc800->minor);
 
-	mdc800->state=NOT_CONNECTED;
+		mdc800->state=NOT_CONNECTED;
 
-	usb_unlink_urb (mdc800->irq_urb);
-	usb_unlink_urb (mdc800->write_urb);
-	usb_unlink_urb (mdc800->download_urb);
+		usb_unlink_urb (mdc800->irq_urb);
+		usb_unlink_urb (mdc800->write_urb);
+		usb_unlink_urb (mdc800->download_urb);
 
-	usb_driver_release_interface (&mdc800_usb_driver, &dev->actconfig->interface[1]);
+		usb_driver_release_interface (&mdc800_usb_driver, intf);
 
-	mdc800->dev=0;
+		mdc800->dev=0;
+		dev_set_drvdata(&intf->dev, NULL);
+	}
 	info ("Mustek MDC800 disconnected from USB.");
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/image/microtek.c linux-2.5.34-greg/drivers/usb/image/microtek.c
--- linux-2.5.34/drivers/usb/image/microtek.c	Mon Sep  9 10:35:12 2002
+++ linux-2.5.34-greg/drivers/usb/image/microtek.c	Wed Sep 11 15:33:33 2002
@@ -154,9 +154,9 @@
 
 /* USB layer driver interface */
 
-static void *mts_usb_probe(struct usb_device *dev, unsigned int interface,
+static int mts_usb_probe(struct usb_interface *intf,
 			 const struct usb_device_id *id);
-static void mts_usb_disconnect(struct usb_device *dev, void *ptr);
+static void mts_usb_disconnect(struct usb_interface *intf);
 
 static struct usb_device_id mts_usb_ids [];
 
@@ -764,18 +764,21 @@
 
 /* USB layer driver interface implementation */
 
-static void mts_usb_disconnect (struct usb_device *dev, void *ptr)
+static void mts_usb_disconnect (struct usb_interface *intf)
 {
-	struct mts_desc* to_remove = (struct mts_desc*)ptr;
+	struct mts_desc* to_remove = dev_get_drvdata(&intf->dev);
 
 	MTS_DEBUG_GOT_HERE();
 
-	/* leave the list - lock it */
-	down(&mts_list_semaphore);
+	dev_set_drvdata(&intf->dev, NULL);
+	if (to_remove) {
+		/* leave the list - lock it */
+		down(&mts_list_semaphore);
 
-	mts_remove_nolock(to_remove);
+		mts_remove_nolock(to_remove);
 
-	up(&mts_list_semaphore);
+		up(&mts_list_semaphore);
+	}
 }
 
 struct vendor_product
@@ -825,8 +828,8 @@
 MODULE_DEVICE_TABLE (usb, mts_usb_ids);
 
 
-static void * mts_usb_probe (struct usb_device *dev, unsigned int interface,
-			     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;
@@ -837,6 +840,7 @@
 
 	struct mts_desc * new_desc;
 	struct vendor_product const* p;
+	struct usb_device *dev = interface_to_usbdev (intf);
 
 	/* the altsettting 0 on the interface we're probing */
 	struct usb_interface_descriptor *altsetting;
@@ -860,8 +864,7 @@
 			     p->name );
 
 	/* the altsettting 0 on the interface we're probing */
-	altsetting =
-		&(dev->actconfig->interface[interface].altsetting[0]);
+	altsetting = &(intf->altsetting[0]);
 
 
 	/* Check if the config is sane */
@@ -869,7 +872,7 @@
 	if ( altsetting->bNumEndpoints != MTS_EP_TOTAL ) {
 		MTS_WARNING( "expecting %d got %d endpoints! Bailing out.\n",
 			     (int)MTS_EP_TOTAL, (int)altsetting->bNumEndpoints );
-		return NULL;
+		return -ENODEV;
 	}
 
 	for( i = 0; i < altsetting->bNumEndpoints; i++ ) {
@@ -887,7 +890,7 @@
 			else {
 				if ( ep_out != -1 ) {
 					MTS_WARNING( "can only deal with one output endpoints. Bailing out." );
-					return NULL;
+					return -ENODEV;
 				}
 
 				ep_out = altsetting->endpoint[i].bEndpointAddress &
@@ -900,7 +903,7 @@
 
 	if ( ep_out == -1 ) {
 		MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" );
-		return NULL;
+		return -ENODEV;
 	}
 
 
@@ -923,7 +926,7 @@
 	default:
 		MTS_DEBUG( "unknown error %d from usb_set_interface\n",
 			(int)result );
- 		return NULL;
+ 		return -ENODEV;
 	}
 	
 	
@@ -932,19 +935,18 @@
 	if (new_desc == NULL)
 	{
 		MTS_ERROR("couldn't allocate scanner desc, bailing out!\n");
-		return NULL;
+		return -ENOMEM;
 	}
 
 	memset( new_desc, 0, sizeof(*new_desc) );
 	new_desc->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!new_desc->urb) {
 		kfree(new_desc);
-		return NULL;
+		return -ENOMEM;
 	}
 		
 	/* initialising that descriptor */
 	new_desc->usb_dev = dev;
-	new_desc->interface = interface;
 
 	init_MUTEX(&new_desc->lock);
 
@@ -991,7 +993,7 @@
 
 		/* FIXME: need more cleanup? */
 		kfree( new_desc );
-		return NULL;
+		return -ENOMEM;
 	}
 	MTS_DEBUG_GOT_HERE();
 
@@ -1006,7 +1008,8 @@
 
 	MTS_DEBUG("completed probe and exiting happily\n");
 
-	return (void *)new_desc;
+	dev_set_drvdata(&intf->dev, new_desc);
+	return 0;
 }
 
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/image/microtek.h linux-2.5.34-greg/drivers/usb/image/microtek.h
--- linux-2.5.34/drivers/usb/image/microtek.h	Mon Sep  9 10:35:05 2002
+++ linux-2.5.34-greg/drivers/usb/image/microtek.h	Wed Sep 11 15:33:33 2002
@@ -33,8 +33,6 @@
 
 	struct usb_device *usb_dev;
 
-	int interface;
-
 	/* Endpoint addresses */
 	u8 ep_out;
 	u8 ep_response;
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/image/scanner.c linux-2.5.34-greg/drivers/usb/image/scanner.c
--- linux-2.5.34/drivers/usb/image/scanner.c	Mon Sep  9 10:35:06 2002
+++ linux-2.5.34-greg/drivers/usb/image/scanner.c	Wed Sep 11 15:33:33 2002
@@ -818,10 +818,11 @@
 	.release =	close_scanner,
 };
 
-static void *
-probe_scanner(struct usb_device *dev, unsigned int ifnum,
+static int
+probe_scanner(struct usb_interface *intf,
 	      const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev (intf);
 	struct scn_usb_data *scn;
 	struct usb_interface_descriptor *interface;
 	struct usb_endpoint_descriptor *endpoint;
@@ -876,8 +877,8 @@
 		valid_device = 1;
 	}
 
-        if (!valid_device)
-                return NULL;    /* We didn't find anything pleasing */
+	if (!valid_device)
+		return -ENODEV;	/* We didn't find anything pleasing */
 
 /*
  * After this point we can be a little noisy about what we are trying to
@@ -886,16 +887,16 @@
 
 	if (dev->descriptor.bNumConfigurations != 1) {
 		info("probe_scanner: Only one device configuration is supported.");
-		return NULL;
+		return -ENODEV;
 	}
 
 	if (dev->config[0].bNumInterfaces != 1) {
 		info("probe_scanner: Only one device interface is supported.");
-		return NULL;
+		return -ENODEV;
 	}
 
-	interface = dev->config[0].interface[ifnum].altsetting;
-	endpoint = interface[ifnum].endpoint;
+	interface = intf->altsetting;
+	endpoint = interface->endpoint;
 
 /*
  * Start checking for two bulk endpoints OR two bulk endpoints *and* one
@@ -907,7 +908,7 @@
 
 	if ((interface->bNumEndpoints != 2) && (interface->bNumEndpoints != 3)) {
 		info("probe_scanner: Only two or three endpoints supported.");
-		return NULL;
+		return -ENODEV;
 	}
 
 	ep_cnt = have_bulk_in = have_bulk_out = have_intr = 0;
@@ -935,7 +936,7 @@
 			continue;
 		}
 		info("probe_scanner: Undetected endpoint -- consult Documentation/usb/scanner.txt.");
-		return NULL;	/* Shouldn't ever get here unless we have something weird */
+		return -EIO;	/* Shouldn't ever get here unless we have something weird */
 	}
 
 
@@ -948,18 +949,18 @@
 	case 2:
 		if (!have_bulk_in || !have_bulk_out) {
 			info("probe_scanner: Two bulk endpoints required.");
-			return NULL;
+			return -EIO;
 		}
 		break;
 	case 3:
 		if (!have_bulk_in || !have_bulk_out || !have_intr) {
 			info("probe_scanner: Two bulk endpoints and one interrupt endpoint required.");
-			return NULL;
+			return -EIO;
 		}
 		break;
 	default:
 		info("probe_scanner: Endpoint determination failed --  consult Documentation/usb/scanner.txt");
-		return NULL;
+		return -EIO;
 	}
 
 
@@ -975,14 +976,14 @@
 	if (retval) {
 		err ("Not able to get a minor for this device.");
 		up(&scn_mutex);
-		return NULL;
+		return -ENOMEM;
 	}
 
 /* Check to make sure that the last slot isn't already taken */
 	if (p_scn_table[scn_minor]) {
 		err("probe_scanner: No more minor devices remaining.");
 		up(&scn_mutex);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	dbg("probe_scanner: Allocated minor:%d", scn_minor);
@@ -990,7 +991,7 @@
 	if (!(scn = kmalloc (sizeof (struct scn_usb_data), GFP_KERNEL))) {
 		err("probe_scanner: Out of memory.");
 		up(&scn_mutex);
-		return NULL;
+		return -ENOMEM;
 	}
 	memset (scn, 0, sizeof(struct scn_usb_data));
 
@@ -998,7 +999,7 @@
 	if (!scn->scn_irq) {
 		kfree(scn);
 		up(&scn_mutex);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	init_MUTEX(&(scn->sem)); /* Initializes to unlocked */
@@ -1018,7 +1019,7 @@
 			err("probe_scanner(%d): Unable to allocate INT URB.", scn_minor);
                 	kfree(scn);
 			up(&scn_mutex);
-                	return NULL;
+                	return -ENOMEM;
         	}
 	}
 
@@ -1028,7 +1029,7 @@
 		err("probe_scanner(%d): Not enough memory for the output buffer.", scn_minor);
 		kfree(scn);
 		up(&scn_mutex);
-		return NULL;
+		return -ENOMEM;
 	}
 	dbg("probe_scanner(%d): obuf address:%p", scn_minor, scn->obuf);
 
@@ -1037,7 +1038,7 @@
 		kfree(scn->obuf);
 		kfree(scn);
 		up(&scn_mutex);
-		return NULL;
+		return -ENOMEM;
 	}
 	dbg("probe_scanner(%d): ibuf address:%p", scn_minor, scn->ibuf);
 	
@@ -1083,45 +1084,54 @@
 
 	up(&scn_mutex);
 
-	return scn;
+	dev_set_drvdata(&intf->dev, scn);
+	return 0;
 }
 
 static void
-disconnect_scanner(struct usb_device *dev, void *ptr)
+disconnect_scanner(struct usb_interface *intf)
 {
-	struct scn_usb_data *scn = (struct scn_usb_data *) ptr;
+	struct scn_usb_data *scn = dev_get_drvdata(&intf->dev);
 
-	down (&scn_mutex);
-	down (&(scn->sem));
+	dev_set_drvdata(&intf->dev, NULL);
+	if (scn) {
+		down (&scn_mutex);
+		down (&(scn->sem));
+
+		if(scn->intr_ep) {
+			dbg("disconnect_scanner(%d): Unlinking IRQ URB", scn->scn_minor);
+			usb_unlink_urb(scn->scn_irq);
+		}
+		usb_driver_release_interface(&scanner_driver,
+			&scn->scn_dev->actconfig->interface[scn->ifnum]);
+
+		kfree(scn->ibuf);
+		kfree(scn->obuf);
 
-	if(scn->intr_ep) {
-		dbg("disconnect_scanner(%d): Unlinking IRQ URB", scn->scn_minor);
-		usb_unlink_urb(scn->scn_irq);
-	}
-        usb_driver_release_interface(&scanner_driver,
-                &scn->scn_dev->actconfig->interface[scn->ifnum]);
-
-	kfree(scn->ibuf);
-	kfree(scn->obuf);
-
-	dbg("disconnect_scanner: De-allocating minor:%d", scn->scn_minor);
-	devfs_unregister(scn->devfs);
-	usb_deregister_dev(1, scn->scn_minor);
-	p_scn_table[scn->scn_minor] = NULL;
-	usb_free_urb(scn->scn_irq);
-	up (&(scn->sem));
-	kfree (scn);
-	up (&scn_mutex);
+		dbg("disconnect_scanner: De-allocating minor:%d", scn->scn_minor);
+		devfs_unregister(scn->devfs);
+		usb_deregister_dev(1, scn->scn_minor);
+		p_scn_table[scn->scn_minor] = NULL;
+		usb_free_urb(scn->scn_irq);
+		up (&(scn->sem));
+		kfree (scn);
+		up (&scn_mutex);
+	}
 }
 
+/* we want to look at all devices, as the vendor/product id can change
+ * depending on the command line argument */
+static struct usb_device_id ids[] = {
+	{.driver_info = 42},
+	{}
+};
+
 static struct
 usb_driver scanner_driver = {
 	.name =		"usbscanner",
 	.probe =	probe_scanner,
 	.disconnect =	disconnect_scanner,
-	.id_table =	NULL, /* This would be scanner_device_ids, but we
-				 need to check every USB device, in case
-				 we match a user defined vendor/product ID. */
+	.id_table =	ids,
 };
 
 void __exit
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/aiptek.c linux-2.5.34-greg/drivers/usb/input/aiptek.c
--- linux-2.5.34/drivers/usb/input/aiptek.c	Mon Sep  9 10:35:05 2002
+++ linux-2.5.34-greg/drivers/usb/input/aiptek.c	Wed Sep 11 15:33:33 2002
@@ -204,6 +204,11 @@
 		usb_unlink_urb(aiptek->irq);
 }
 
+/* 
+ * FIXME, either remove this call, or talk the maintainer into 
+ * adding usb_set_report back into the core.
+ */
+#if 0
 static void
 aiptek_command(struct usb_device *dev, unsigned int ifnum,
 	       unsigned char command, unsigned char data)
@@ -214,47 +219,43 @@
 	buf[1] = command;
 	buf[2] = data;
 
-	/* 
-	 * FIXME, either remove this call, or talk the maintainer into 
-	 * adding it back into the core.
-	 */
-#if 0
 	if (usb_set_report(dev, ifnum, 3, 2, buf, 3) != 3) {
 		dbg("aiptek_command: 0x%x 0x%x\n", command, data);
 	}
-#endif
 }
+#endif
 
-static void*
-aiptek_probe(struct usb_device *dev, unsigned int ifnum,
+static int 
+aiptek_probe(struct usb_interface *intf,
 	     const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev (intf);
 	struct usb_endpoint_descriptor *endpoint;
 	struct aiptek *aiptek;
 
 	if (!(aiptek = kmalloc(sizeof (struct aiptek), GFP_KERNEL)))
-		return NULL;
+		return -ENOMEM;
 
 	memset(aiptek, 0, sizeof (struct aiptek));
 
 	aiptek->data = usb_buffer_alloc(dev, 10, SLAB_ATOMIC, &aiptek->data_dma);
 	if (!aiptek->data) {
 		kfree(aiptek);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	aiptek->irq = usb_alloc_urb(0, GFP_KERNEL);
 	if (!aiptek->irq) {
 		usb_buffer_free(dev, 10, aiptek->data, aiptek->data_dma);
 		kfree(aiptek);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	// Resolution500LPI
-	aiptek_command(dev, ifnum, 0x18, 0x04);
+//	aiptek_command(dev, ifnum, 0x18, 0x04);
 
 	// SwitchToTablet
-	aiptek_command(dev, ifnum, 0x10, 0x01);
+//	aiptek_command(dev, ifnum, 0x10, 0x01);
 
 	aiptek->features = aiptek_features + id->driver_info;
 
@@ -294,7 +295,7 @@
 	aiptek->dev.id.version = dev->descriptor.bcdDevice;
 	aiptek->usbdev = dev;
 
-	endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
+	endpoint = intf->altsetting[0].endpoint + 0;
 
 	if (aiptek->features->pktlen > 10)
 		BUG();
@@ -308,28 +309,33 @@
 
 	input_register_device(&aiptek->dev);
 
-	printk(KERN_INFO "input: %s on usb%d:%d.%d\n",
-	       aiptek->features->name, dev->bus->busnum, dev->devnum, ifnum);
+	printk(KERN_INFO "input: %s on usb%d:%d\n",
+	       aiptek->features->name, dev->bus->busnum, dev->devnum);
 
-	return aiptek;
+	dev_set_drvdata(&intf->dev, aiptek);
+	return 0;
 }
 
 static void
-aiptek_disconnect(struct usb_device *dev, void *ptr)
+aiptek_disconnect(struct usb_interface *intf)
 {
-	struct aiptek *aiptek = ptr;
-	usb_unlink_urb(aiptek->irq);
-	input_unregister_device(&aiptek->dev);
-	usb_free_urb(aiptek->irq);
-	usb_buffer_free(dev, 10, aiptek->data, aiptek->data_dma);
-	kfree(aiptek);
+	struct aiptek *aiptek  = dev_get_drvdata(&intf->dev);
+
+	dev_set_drvdata(&intf->dev, NULL);
+	if (aiptek) {
+		usb_unlink_urb(aiptek->irq);
+		input_unregister_device(&aiptek->dev);
+		usb_free_urb(aiptek->irq);
+		usb_buffer_free(interface_to_usbdev(intf), 10, aiptek->data, aiptek->data_dma);
+		kfree(aiptek);
+	}
 }
 
 static struct usb_driver aiptek_driver = {
-	.name ="aiptek",
-	.probe =aiptek_probe,
-	.disconnect =aiptek_disconnect,
-	.id_table =aiptek_ids,
+	.name =		"aiptek",
+	.probe =	aiptek_probe,
+	.disconnect =	aiptek_disconnect,
+	.id_table =	aiptek_ids,
 };
 
 static int __init
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/hid-core.c linux-2.5.34-greg/drivers/usb/input/hid-core.c
--- linux-2.5.34/drivers/usb/input/hid-core.c	Mon Sep  9 10:35:13 2002
+++ linux-2.5.34-greg/drivers/usb/input/hid-core.c	Wed Sep 11 15:33:33 2002
@@ -1349,9 +1349,10 @@
 		usb_buffer_free(dev, HID_BUFFER_SIZE, hid->ctrlbuf, hid->ctrlbuf_dma);
 }
 
-static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
+static struct hid_device *usb_hid_configure(struct usb_interface *intf)
 {
-	struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0;
+	struct usb_interface_descriptor *interface = intf->altsetting + intf->act_altsetting;
+	struct usb_device *dev = interface_to_usbdev (intf);
 	struct hid_descriptor *hdesc;
 	struct hid_device *hid;
 	unsigned quirks = 0, rsize = 0;
@@ -1472,7 +1473,7 @@
 		snprintf(hid->name, 128, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
 
 	usb_make_path(dev, buf, 64);
-	snprintf(hid->phys, 64, "%s/input%d", buf, ifnum);
+	snprintf(hid->phys, 64, "%s/input%d", buf, intf->altsetting[0].bInterfaceNumber);
 
 	if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
 		hid->uniq[0] = 0;
@@ -1499,9 +1500,12 @@
 	return NULL;
 }
 
-static void hid_disconnect(struct usb_device *dev, void *ptr)
+static void hid_disconnect(struct usb_interface *intf)
 {
-	struct hid_device *hid = ptr;
+	struct hid_device *hid = intf->dev.driver_data;
+
+	if (!hid)
+		return;
 
 	usb_unlink_urb(hid->urbin);
 	usb_unlink_urb(hid->urbout);
@@ -1517,22 +1521,22 @@
 	if (hid->urbout)
 		usb_free_urb(hid->urbout);
 
-	hid_free_buffers(dev, hid);
+	hid_free_buffers(hid->dev, hid);
 	hid_free_device(hid);
+	intf->dev.driver_data = NULL;
 }
 
-static void* hid_probe(struct usb_device *dev, unsigned int ifnum,
-		       const struct usb_device_id *id)
+static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct hid_device *hid;
 	char path[64];
 	int i;
 	char *c;
 
-	dbg("HID probe called for ifnum %d", ifnum);
+	dbg("HID probe called for ifnum %d", intf->ifnum);
 
-	if (!(hid = usb_hid_configure(dev, ifnum)))
-		return NULL;
+	if (!(hid = usb_hid_configure(intf)))
+		return -EIO;
 
 	hid_init_reports(hid);
 	hid_dump_device(hid);
@@ -1544,9 +1548,11 @@
 	if (!hiddev_connect(hid))
 		hid->claimed |= HID_CLAIMED_HIDDEV;
 
+	intf->dev.driver_data = hid;
+
 	if (!hid->claimed) {
-		hid_disconnect(dev, hid);
-		return NULL;
+		hid_disconnect(intf);
+		return -EIO;
 	}
 
 	printk(KERN_INFO);
@@ -1568,12 +1574,12 @@
 		}
 	}
 
-	usb_make_path(dev, path, 63);
+	usb_make_path(interface_to_usbdev(intf), path, 63);
 
 	printk(": USB HID v%x.%02x %s [%s] on %s\n",
 		hid->version >> 8, hid->version & 0xff, c, hid->name, path);
 
-	return hid;
+	return 0;
 }
 
 static struct usb_device_id hid_usb_ids [] = {
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/hiddev.c linux-2.5.34-greg/drivers/usb/input/hiddev.c
--- linux-2.5.34/drivers/usb/input/hiddev.c	Mon Sep  9 10:35:09 2002
+++ linux-2.5.34-greg/drivers/usb/input/hiddev.c	Wed Sep 11 15:33:33 2002
@@ -751,10 +751,10 @@
 /* We never attach in this manner, and rely on HID to connect us.  This
  * is why there is no disconnect routine defined in the usb_driver either.
  */
-static void *hiddev_usbd_probe(struct usb_device *dev, unsigned int ifnum,
-			  const struct usb_device_id *hiddev_info)
+static int hiddev_usbd_probe(struct usb_interface *intf, 
+			     const struct usb_device_id *hiddev_info)
 {
-	return NULL;
+	return -ENODEV;
 }
 
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/powermate.c linux-2.5.34-greg/drivers/usb/input/powermate.c
--- linux-2.5.34/drivers/usb/input/powermate.c	Mon Sep  9 10:35:13 2002
+++ linux-2.5.34-greg/drivers/usb/input/powermate.c	Wed Sep 11 15:33:33 2002
@@ -268,18 +268,21 @@
 }
 
 /* Called whenever a USB device matching one in our supported devices table is connected */
-static void *powermate_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
+static int powermate_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
+	struct usb_device *udev = interface_to_usbdev (intf);
 	struct usb_interface_descriptor *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct powermate_device *pm;
 	int pipe, maxp;
 	char path[64];
 
-	interface = udev->config[0].interface[ifnum].altsetting + 0;
+	interface = intf->altsetting + 0;
 	endpoint = interface->endpoint + 0;
-	if (!(endpoint->bEndpointAddress & 0x80)) return NULL;
-	if ((endpoint->bmAttributes & 3) != 3) return NULL;
+	if (!(endpoint->bEndpointAddress & 0x80))
+		return -EIO;
+	if ((endpoint->bmAttributes & 3) != 3)
+		return -EIO;
 
 	usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 		0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
@@ -287,7 +290,7 @@
 		HZ * USB_CTRL_SET_TIMEOUT);
 
 	if (!(pm = kmalloc(sizeof(struct powermate_device), GFP_KERNEL)))
-		return NULL;
+		return -ENOMEM;
 
 	memset(pm, 0, sizeof(struct powermate_device));
 	pm->udev = udev;
@@ -295,14 +298,14 @@
 	if (powermate_alloc_buffers(udev, pm)) {
 		powermate_free_buffers(udev, pm);
 		kfree(pm);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	pm->irq = usb_alloc_urb(0, GFP_KERNEL);
 	if (!pm->irq) {
 		powermate_free_buffers(udev, pm);
 		kfree(pm);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	pm->config = usb_alloc_urb(0, GFP_KERNEL);
@@ -310,7 +313,7 @@
 		usb_free_urb(pm->irq);
 		powermate_free_buffers(udev, pm);
 		kfree(pm);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	init_MUTEX(&pm->lock);
@@ -333,7 +336,7 @@
 	if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
 		powermate_free_buffers(udev, pm);
 		kfree(pm);
-		return NULL; /* failure */
+		return -EIO; /* failure */
 	}
 
 	switch (udev->descriptor.idProduct) {
@@ -365,22 +368,27 @@
 	pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS;
 	powermate_pulse_led(pm, 0x80, 255, 0, 1, 0); // set default pulse parameters
   
-	return pm;
+	dev_set_drvdata(&intf->dev, pm);
+	return 0;
 }
 
 /* Called when a USB device we've accepted ownership of is removed */
-static void powermate_disconnect(struct usb_device *dev, void *ptr)
+static void powermate_disconnect(struct usb_interface *intf)
 {
-	struct powermate_device *pm = ptr;
-	down(&pm->lock);
-	pm->requires_update = 0;
-	usb_unlink_urb(pm->irq);
-	input_unregister_device(&pm->input);
-	usb_free_urb(pm->irq);
-	usb_free_urb(pm->config);
-	powermate_free_buffers(dev, pm);
-  
-	kfree(pm);
+	struct powermate_device *pm = dev_get_drvdata(&intf->dev);
+
+	dev_set_drvdata(&intf->dev, NULL);
+	if (pm) {
+		down(&pm->lock);
+		pm->requires_update = 0;
+		usb_unlink_urb(pm->irq);
+		input_unregister_device(&pm->input);
+		usb_free_urb(pm->irq);
+		usb_free_urb(pm->config);
+		powermate_free_buffers(interface_to_usbdev(intf), pm);
+
+		kfree(pm);
+	}
 }
 
 static struct usb_device_id powermate_devices [] = {
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/usbmouse.c linux-2.5.34-greg/drivers/usb/input/usbmouse.c
--- linux-2.5.34/drivers/usb/input/usbmouse.c	Mon Sep  9 10:35:16 2002
+++ linux-2.5.34-greg/drivers/usb/input/usbmouse.c	Wed Sep 11 15:33:33 2002
@@ -100,10 +100,9 @@
 		usb_unlink_urb(mouse->irq);
 }
 
-static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum,
-			     const struct usb_device_id *id)
+static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id)
 {
-	struct usb_interface *iface;
+	struct usb_device * dev = interface_to_usbdev(intf);
 	struct usb_interface_descriptor *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_mouse *mouse;
@@ -111,19 +110,22 @@
 	char path[64];
 	char *buf;
 
-	iface = &dev->actconfig->interface[ifnum];
-	interface = &iface->altsetting[iface->act_altsetting];
+	interface = &intf->altsetting[intf->act_altsetting];
 
-	if (interface->bNumEndpoints != 1) return NULL;
+	if (interface->bNumEndpoints != 1) 
+		return -ENODEV;
 
 	endpoint = interface->endpoint + 0;
-	if (!(endpoint->bEndpointAddress & 0x80)) return NULL;
-	if ((endpoint->bmAttributes & 3) != 3) return NULL;
+	if (!(endpoint->bEndpointAddress & 0x80)) 
+		return -ENODEV;
+	if ((endpoint->bmAttributes & 3) != 3) 
+		return -ENODEV;
 
 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
-	if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL;
+	if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) 
+		return -ENOMEM;
 	memset(mouse, 0, sizeof(struct usb_mouse));
 
 	mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma);
@@ -136,7 +138,7 @@
 	if (!mouse->irq) {
 		usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
 		kfree(mouse);
-		return NULL;
+		return -ENODEV;
 	}
 
 	mouse->usbdev = dev;
@@ -164,7 +166,7 @@
 	if (!(buf = kmalloc(63, GFP_KERNEL))) {
 		usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
 		kfree(mouse);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	if (dev->descriptor.iManufacturer &&
@@ -187,20 +189,24 @@
 	mouse->irq->transfer_flags |= URB_NO_DMA_MAP;
 
 	input_register_device(&mouse->dev);
-
 	printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
 
-	return mouse;
+	intf->dev.driver_data = mouse;
+	return 0;
 }
 
-static void usb_mouse_disconnect(struct usb_device *dev, void *ptr)
+static void usb_mouse_disconnect(struct usb_interface * intf)
 {
-	struct usb_mouse *mouse = ptr;
-	usb_unlink_urb(mouse->irq);
-	input_unregister_device(&mouse->dev);
-	usb_free_urb(mouse->irq);
-	usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
-	kfree(mouse);
+	struct usb_mouse *mouse = intf->dev.driver_data;
+	intf->dev.driver_data = NULL;
+
+	if (mouse) {
+		usb_unlink_urb(mouse->irq);
+		input_unregister_device(&mouse->dev);
+		usb_free_urb(mouse->irq);
+		usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
+		kfree(mouse);
+	}
 }
 
 static struct usb_device_id usb_mouse_id_table [] = {
@@ -211,10 +217,10 @@
 MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
 
 static struct usb_driver usb_mouse_driver = {
-	.name =		"usb_mouse",
-	.probe =	usb_mouse_probe,
-	.disconnect =	usb_mouse_disconnect,
-	.id_table =	usb_mouse_id_table,
+	.name		= "usb_mouse",
+	.probe		= usb_mouse_probe,
+	.disconnect	= usb_mouse_disconnect,
+	.id_table	= usb_mouse_id_table,
 };
 
 static int __init usb_mouse_init(void)
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/wacom.c linux-2.5.34-greg/drivers/usb/input/wacom.c
--- linux-2.5.34/drivers/usb/input/wacom.c	Mon Sep  9 10:35:01 2002
+++ linux-2.5.34-greg/drivers/usb/input/wacom.c	Wed Sep 11 15:33:33 2002
@@ -356,26 +356,28 @@
 		usb_unlink_urb(wacom->irq);
 }
 
-static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
+static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev (intf);
 	struct usb_endpoint_descriptor *endpoint;
 	struct wacom *wacom;
 	char path[64];
 
-	if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) return NULL;
+	if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL)))
+		return -ENOMEM;
 	memset(wacom, 0, sizeof(struct wacom));
 
 	wacom->data = usb_buffer_alloc(dev, 10, SLAB_ATOMIC, &wacom->data_dma);
 	if (!wacom->data) {
 		kfree(wacom);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
 	if (!wacom->irq) {
 		usb_buffer_free(dev, 10, wacom->data, wacom->data_dma);
 		kfree(wacom);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	wacom->features = wacom_features + id->driver_info;
@@ -419,7 +421,7 @@
 	wacom->dev.id.version = dev->descriptor.bcdDevice;
 	wacom->usbdev = dev;
 
-	endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
+	endpoint = intf->altsetting[0].endpoint + 0;
 
 	if (wacom->features->pktlen > 10)
 		BUG();
@@ -435,17 +437,22 @@
 
 	printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path);
 
-	return wacom;
+	dev_set_drvdata(&intf->dev, wacom);
+	return 0;
 }
 
-static void wacom_disconnect(struct usb_device *dev, void *ptr)
+static void wacom_disconnect(struct usb_interface *intf)
 {
-	struct wacom *wacom = ptr;
-	usb_unlink_urb(wacom->irq);
-	input_unregister_device(&wacom->dev);
-	usb_free_urb(wacom->irq);
-	usb_buffer_free(dev, 10, wacom->data, wacom->data_dma);
-	kfree(wacom);
+	struct wacom *wacom = dev_get_drvdata(&intf->dev);
+
+	dev_set_drvdata(&intf->dev, NULL);
+	if (wacom) {
+		usb_unlink_urb(wacom->irq);
+		input_unregister_device(&wacom->dev);
+		usb_free_urb(wacom->irq);
+		usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma);
+		kfree(wacom);
+	}
 }
 
 static struct usb_driver wacom_driver = {
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/xpad.c linux-2.5.34-greg/drivers/usb/input/xpad.c
--- linux-2.5.34/drivers/usb/input/xpad.c	Mon Sep  9 10:35:11 2002
+++ linux-2.5.34-greg/drivers/usb/input/xpad.c	Wed Sep 11 15:33:33 2002
@@ -195,8 +195,9 @@
 		usb_unlink_urb(xpad->irq_in);
 }
 
-static void * xpad_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
+static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
+	struct usb_device *udev = interface_to_usbdev (intf);
 	struct usb_xpad *xpad = NULL;
 	struct usb_endpoint_descriptor *ep_irq_in;
 	char path[64];
@@ -210,7 +211,7 @@
 	
 	if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) {
 		err("cannot allocate memory for new pad");
-		return NULL;
+		return -ENOMEM;
 	}
 	memset(xpad, 0, sizeof(struct usb_xpad));
 	
@@ -218,7 +219,7 @@
 				       SLAB_ATOMIC, &xpad->idata_dma);
 	if (!xpad->idata) {
 		kfree(xpad);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
@@ -226,10 +227,10 @@
 		err("cannot allocate memory for new pad irq urb");
 		usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
                 kfree(xpad);
-                return NULL;
+		return -ENOMEM;
         }
 	
-	ep_irq_in = udev->actconfig->interface[ifnum].altsetting[0].endpoint + 0;
+	ep_irq_in = intf->altsetting[0].endpoint + 0;
 	
 	usb_fill_int_urb(xpad->irq_in, udev,
 			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
@@ -291,18 +292,22 @@
 	
 	printk(KERN_INFO "input: %s on %s", xpad->dev.name, path);
 	
-	return xpad;
+	dev_set_drvdata(&intf->dev, xpad);
+	return 0;
 }
 
-static void xpad_disconnect(struct usb_device *udev, void *ptr)
+static void xpad_disconnect(struct usb_interface *intf)
 {
-	struct usb_xpad *xpad = ptr;
+	struct usb_xpad *xpad = dev_get_drvdata(&intf->dev);
 	
-	usb_unlink_urb(xpad->irq_in);
-	input_unregister_device(&xpad->dev);
-	usb_free_urb(xpad->irq_in);
-	usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
-	kfree(xpad);
+	dev_set_drvdata(&intf->dev, NULL);
+	if (xpad) {
+		usb_unlink_urb(xpad->irq_in);
+		input_unregister_device(&xpad->dev);
+		usb_free_urb(xpad->irq_in);
+		usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
+		kfree(xpad);
+	}
 }
 
 static struct usb_driver xpad_driver = {
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/dabusb.c linux-2.5.34-greg/drivers/usb/media/dabusb.c
--- linux-2.5.34/drivers/usb/media/dabusb.c	Mon Sep  9 10:35:12 2002
+++ linux-2.5.34-greg/drivers/usb/media/dabusb.c	Wed Sep 11 15:33:33 2002
@@ -713,9 +713,10 @@
 };
 
 /* --------------------------------------------------------------------- */
-static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum,
-			   const struct usb_device_id *id)
+static int dabusb_probe (struct usb_interface *intf, 
+			 const struct usb_device_id *id)
 {
+	struct usb_device *usbdev = interface_to_usbdev(intf);
 	int devnum;
 	int retval;
 	pdabusb_t s;
@@ -725,14 +726,14 @@
 
 	/* We don't handle multiple configurations */
 	if (usbdev->descriptor.bNumConfigurations != 1)
-		return NULL;
+		return -ENODEV;
 
-	if (ifnum != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999)
-		return NULL;
+	if (intf->altsetting->bInterfaceNumber != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999)
+		return -ENODEV;
 
 	retval = usb_register_dev (&dabusb_fops, DABUSB_MINOR, 1, &devnum);
 	if (retval)
-		return NULL;
+		return -ENOMEM;
 
 	s = &dabusb[devnum];
 
@@ -760,28 +761,32 @@
 	dbg("bound to interface: %d", ifnum);
 	up (&s->mutex);
 	MOD_INC_USE_COUNT;
-	return s;
+	dev_set_drvdata (&intf->dev, s);
+	return 0;
 
       reject:
 	up (&s->mutex);
 	s->usbdev = NULL;
-	return NULL;
+	return -ENODEV;
 }
 
-static void dabusb_disconnect (struct usb_device *usbdev, void *ptr)
+static void dabusb_disconnect (struct usb_interface *intf)
 {
-	pdabusb_t s = (pdabusb_t) ptr;
+	pdabusb_t s = dev_get_drvdata (&intf->dev);
 
 	dbg("dabusb_disconnect");
 
-	usb_deregister_dev (1, s->devnum);
-	s->remove_pending = 1;
-	wake_up (&s->wait);
-	if (s->state == _started)
-		sleep_on (&s->remove_ok);
-	s->usbdev = NULL;
-	s->overruns = 0;
-	MOD_DEC_USE_COUNT;
+	dev_set_drvdata (&intf->dev, NULL);
+	if (s) {
+		usb_deregister_dev (1, s->devnum);
+		s->remove_pending = 1;
+		wake_up (&s->wait);
+		if (s->state == _started)
+			sleep_on (&s->remove_ok);
+		s->usbdev = NULL;
+		s->overruns = 0;
+		MOD_DEC_USE_COUNT;
+	}
 }
 
 static struct usb_device_id dabusb_ids [] = {
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/dsbr100.c linux-2.5.34-greg/drivers/usb/media/dsbr100.c
--- linux-2.5.34/drivers/usb/media/dsbr100.c	Mon Sep  9 10:35:08 2002
+++ linux-2.5.34-greg/drivers/usb/media/dsbr100.c	Wed Sep 11 15:33:33 2002
@@ -78,9 +78,9 @@
 
 #define TB_LEN 16
 
-static void *usb_dsbr100_probe(struct usb_device *dev, unsigned int ifnum,
-			 const struct usb_device_id *id);
-static void usb_dsbr100_disconnect(struct usb_device *dev, void *ptr);
+static int usb_dsbr100_probe(struct usb_interface *intf,
+			     const struct usb_device_id *id);
+static void usb_dsbr100_disconnect(struct usb_interface *intf);
 static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
 			     unsigned int cmd, unsigned long arg);
 static int usb_dsbr100_open(struct inode *inode, struct file *file);
@@ -95,7 +95,6 @@
 	unsigned char transfer_buffer[TB_LEN];
 	int curfreq;
 	int stereo;
-	int ifnum;
 } usb_dsbr100;
 
 
@@ -181,32 +180,36 @@
 }
 
 
-static void *usb_dsbr100_probe(struct usb_device *dev, unsigned int ifnum,
+static int usb_dsbr100_probe(struct usb_interface *intf, 
 			 const struct usb_device_id *id)
 {
 	usb_dsbr100 *radio;
 
 	if (!(radio = kmalloc(sizeof(usb_dsbr100),GFP_KERNEL)))
-		return NULL;
+		return -ENOMEM;
 	usb_dsbr100_radio.priv = radio;
-	radio->dev = dev;
-	radio->ifnum = ifnum;
+	radio->dev = interface_to_usbdev (intf);
 	radio->curfreq = 1454000;
-	return (void*)radio;
+	dev_set_drvdata (&intf->dev, radio);
+	return 0;
 }
 
-static void usb_dsbr100_disconnect(struct usb_device *dev, void *ptr)
+static void usb_dsbr100_disconnect(struct usb_interface *intf)
 {
-	usb_dsbr100 *radio=ptr;
+	usb_dsbr100 *radio = dev_get_drvdata (&intf->dev);
 
-	lock_kernel();
-	if (users) {
+	dev_set_drvdata (&intf->dev, NULL);
+
+	if (radio) {
+		lock_kernel();
+		if (users) {
+			unlock_kernel();
+			return;
+		}
+		kfree(radio);
+		usb_dsbr100_radio.priv = NULL;
 		unlock_kernel();
-		return;
 	}
-	kfree(radio);
-	usb_dsbr100_radio.priv = NULL;
-	unlock_kernel();
 }
 
 static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/ibmcam.c linux-2.5.34-greg/drivers/usb/media/ibmcam.c
--- linux-2.5.34/drivers/usb/media/ibmcam.c	Mon Sep  9 10:35:06 2002
+++ linux-2.5.34-greg/drivers/usb/media/ibmcam.c	Wed Sep 11 15:33:33 2002
@@ -3656,39 +3656,41 @@
  * 12-Nov-2000 Reworked to comply with new probe() signature.
  * 23-Jan-2001 Added compatibility with 2.2.x kernels.
  */
-static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *devid)
+static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *devid)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct uvd *uvd = NULL;
 	int i, nas, model=0, canvasX=0, canvasY=0;
 	int actInterface=-1, inactInterface=-1, maxPS=0;
+	__u8 ifnum = intf->altsetting->bInterfaceNumber;
 	unsigned char video_ep = 0;
 
 	if (debug >= 1)
-		info("ibmcam_probe(%p,%u.)", dev, ifnum);
+		info("ibmcam_probe(%p,%u.)", intf, ifnum);
 
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1)
-		return NULL;
+		return -ENODEV;
 
 	/* Is it an IBM camera? */
 	if (dev->descriptor.idVendor != IBMCAM_VENDOR_ID)
-		return NULL;
+		return -ENODEV;
 	if ((dev->descriptor.idProduct != IBMCAM_PRODUCT_ID) &&
 	    (dev->descriptor.idProduct != VEO_800C_PRODUCT_ID) &&
 	    (dev->descriptor.idProduct != VEO_800D_PRODUCT_ID) &&
 	    (dev->descriptor.idProduct != NETCAM_PRODUCT_ID))
-		return NULL;
+		return -ENODEV;
 
 	/* Check the version/revision */
 	switch (dev->descriptor.bcdDevice) {
 	case 0x0002:
 		if (ifnum != 2)
-			return NULL;
+			return -ENODEV;
 		model = IBMCAM_MODEL_1;
 		break;
 	case 0x030A:
 		if (ifnum != 0)
-			return NULL;
+			return -ENODEV;
 		if ((dev->descriptor.idProduct == NETCAM_PRODUCT_ID) ||
 		    (dev->descriptor.idProduct == VEO_800D_PRODUCT_ID))
 			model = IBMCAM_MODEL_4;
@@ -3697,13 +3699,13 @@
 		break;
 	case 0x0301:
 		if (ifnum != 0)
-			return NULL;
+			return -ENODEV;
 		model = IBMCAM_MODEL_3;
 		break;
 	default:
 		err("IBM camera with revision 0x%04x is not supported.",
 			dev->descriptor.bcdDevice);
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* Print detailed info on what we found so far */
@@ -3734,7 +3736,7 @@
 		info("Number of alternate settings=%d.", nas);
 	if (nas < 2) {
 		err("Too few alternate settings for this camera!");
-		return NULL;
+		return -ENODEV;
 	}
 	/* Validate all alternate settings */
 	for (i=0; i < nas; i++) {
@@ -3745,29 +3747,29 @@
 		if (interface->bNumEndpoints != 1) {
 			err("Interface %d. has %u. endpoints!",
 			    ifnum, (unsigned)(interface->bNumEndpoints));
-			return NULL;
+			return -ENODEV;
 		}
 		endpoint = &interface->endpoint[0];
 		if (video_ep == 0)
 			video_ep = endpoint->bEndpointAddress;
 		else if (video_ep != endpoint->bEndpointAddress) {
 			err("Alternate settings have different endpoint addresses!");
-			return NULL;
+			return -ENODEV;
 		}
 		if ((endpoint->bmAttributes & 0x03) != 0x01) {
 			err("Interface %d. has non-ISO endpoint!", ifnum);
-			return NULL;
+			return -ENODEV;
 		}
 		if ((endpoint->bEndpointAddress & 0x80) == 0) {
 			err("Interface %d. has ISO OUT endpoint!", ifnum);
-			return NULL;
+			return -ENODEV;
 		}
 		if (endpoint->wMaxPacketSize == 0) {
 			if (inactInterface < 0)
 				inactInterface = i;
 			else {
 				err("More than one inactive alt. setting!");
-				return NULL;
+				return -ENODEV;
 			}
 		} else {
 			if (actInterface < 0) {
@@ -3781,7 +3783,7 @@
 	}
 	if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
 		err("Failed to recognize the camera!");
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* Validate options */
@@ -3861,7 +3863,7 @@
 		break;
 	default:
 		err("IBM camera: Model %d. not supported!", model);
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* Code below may sleep, need to lock module while we are here */
@@ -3896,7 +3898,8 @@
 		}
 	}
 	MOD_DEC_USE_COUNT;
-	return uvd;
+	dev_set_drvdata (&intf->dev, uvd);
+	return 0;
 }
 
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/konicawc.c linux-2.5.34-greg/drivers/usb/media/konicawc.c
--- linux-2.5.34/drivers/usb/media/konicawc.c	Mon Sep  9 10:34:59 2002
+++ linux-2.5.34-greg/drivers/usb/media/konicawc.c	Wed Sep 11 15:33:33 2002
@@ -717,38 +717,40 @@
 }
 
 
-static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *devid)
+static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct uvd *uvd = NULL;
 	int i, nas;
 	int actInterface=-1, inactInterface=-1, maxPS=0;
 	unsigned char video_ep = 0;
 
-	DEBUG(1, "konicawc_probe(%p,%u.)", dev, ifnum);
+	DEBUG(1, "konicawc_probe(%p)", intf);
 
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1)
-		return NULL;
+		return -ENODEV;
 
 	info("Konica Webcam (rev. 0x%04x)", dev->descriptor.bcdDevice);
 	RESTRICT_TO_RANGE(speed, 0, MAX_SPEED);
 
 	/* Validate found interface: must have one ISO endpoint */
-	nas = dev->actconfig->interface[ifnum].num_altsetting;
+	nas = intf->num_altsetting;
 	if (nas != 8) {
 		err("Incorrect number of alternate settings (%d) for this camera!", nas);
-		return NULL;
+		return -ENODEV;
 	}
 	/* Validate all alternate settings */
 	for (i=0; i < nas; i++) {
 		const struct usb_interface_descriptor *interface;
 		const struct usb_endpoint_descriptor *endpoint;
 
-		interface = &dev->actconfig->interface[ifnum].altsetting[i];
+		interface = &intf->altsetting[i];
 		if (interface->bNumEndpoints != 2) {
 			err("Interface %d. has %u. endpoints!",
-			    ifnum, (unsigned)(interface->bNumEndpoints));
-			return NULL;
+			    interface->bInterfaceNumber,
+			    (unsigned)(interface->bNumEndpoints));
+			return -ENODEV;
 		}
 		endpoint = &interface->endpoint[1];
 		DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x",
@@ -757,22 +759,24 @@
 			video_ep = endpoint->bEndpointAddress;
 		else if (video_ep != endpoint->bEndpointAddress) {
 			err("Alternate settings have different endpoint addresses!");
-			return NULL;
+			return -ENODEV;
 		}
 		if ((endpoint->bmAttributes & 0x03) != 0x01) {
-			err("Interface %d. has non-ISO endpoint!", ifnum);
-			return NULL;
+			err("Interface %d. has non-ISO endpoint!",
+			    interface->bInterfaceNumber);
+			return -ENODEV;
 		}
 		if ((endpoint->bEndpointAddress & 0x80) == 0) {
-			err("Interface %d. has ISO OUT endpoint!", ifnum);
-			return NULL;
+			err("Interface %d. has ISO OUT endpoint!",
+			    interface->bInterfaceNumber);
+			return -ENODEV;
 		}
 		if (endpoint->wMaxPacketSize == 0) {
 			if (inactInterface < 0)
 				inactInterface = i;
 			else {
 				err("More than one inactive alt. setting!");
-				return NULL;
+				return -ENODEV;
 			}
 		} else {
 			if (i == spd_to_iface[speed]) {
@@ -785,7 +789,7 @@
 	}
 	if(actInterface == -1) {
 		err("Cant find required endpoint");
-		return NULL;
+		return -ENODEV;
 	}
 
 	DEBUG(1, "Selecting requested active setting=%d. maxPS=%d.", actInterface, maxPS);
@@ -803,7 +807,7 @@
 					usb_free_urb(cam->sts_urb[i]);
 				}
 				err("cant allocate urbs");
-				return NULL;
+				return -ENOMEM;
 			}
 		}
 		cam->speed = speed;
@@ -815,7 +819,7 @@
 		uvd->flags = 0;
 		uvd->debug = debug;
 		uvd->dev = dev;
-		uvd->iface = ifnum;
+		uvd->iface = intf->altsetting->bInterfaceNumber;
 		uvd->ifaceAltInactive = inactInterface;
 		uvd->ifaceAltActive = actInterface;
 		uvd->video_endp = video_ep;
@@ -854,7 +858,12 @@
 #endif
 	}
 	MOD_DEC_USE_COUNT;
-	return uvd;
+
+	if (uvd) {
+		dev_set_drvdata (&intf->dev, uvd);
+		return 0;
+	}
+	return -EIO;
 }
 
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/ov511.c linux-2.5.34-greg/drivers/usb/media/ov511.c
--- linux-2.5.34/drivers/usb/media/ov511.c	Mon Sep  9 10:35:07 2002
+++ linux-2.5.34-greg/drivers/usb/media/ov511.c	Wed Sep 11 15:33:33 2002
@@ -6043,10 +6043,11 @@
  *
  ***************************************************************************/
 
-static void *
-ov51x_probe(struct usb_device *dev, unsigned int ifnum,
+static int
+ov51x_probe(struct usb_interface *intf, 
 	    const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_interface_descriptor *interface;
 	struct usb_ov511 *ov;
 	int i;
@@ -6056,15 +6057,15 @@
 
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1)
-		return NULL;
+		return -ENODEV;
 
-	interface = &dev->actconfig->interface[ifnum].altsetting[0];
+	interface = &intf->altsetting[0];
 
 	/* Checking vendor/product should be enough, but what the hell */
 	if (interface->bInterfaceClass != 0xFF)
-		return NULL;
+		return -ENODEV;
 	if (interface->bInterfaceSubClass != 0x00)
-		return NULL;
+		return -ENODEV;
 
 	if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) {
 		err("couldn't kmalloc ov struct");
@@ -6188,7 +6189,8 @@
 	create_proc_ov511_cam(ov);
 #endif
 
-     	return ov;
+	dev_set_drvdata (&intf->dev, ov);
+     	return 0;
 
 error:
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
@@ -6211,17 +6213,21 @@
 
 error_out:
 	err("Camera initialization failed");
-	return NULL;
+	return -ENOMEM;
 }
 
 static void
-ov51x_disconnect(struct usb_device *dev, void *ptr)
+ov51x_disconnect(struct usb_interface *intf)
 {
-	struct usb_ov511 *ov = (struct usb_ov511 *) ptr;
+	struct usb_ov511 *ov = dev_get_drvdata (&intf->dev);
 	int n;
 
 	PDEBUG(3, "");
 
+	dev_set_drvdata (&intf->dev, NULL);
+	if (!ov)
+		return;
+
 	video_unregister_device(&ov->vdev);
 	if (ov->user)
 		PDEBUG(3, "Device open...deferring video_unregister_device");
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/pwc-if.c linux-2.5.34-greg/drivers/usb/media/pwc-if.c
--- linux-2.5.34/drivers/usb/media/pwc-if.c	Mon Sep  9 10:35:14 2002
+++ linux-2.5.34-greg/drivers/usb/media/pwc-if.c	Wed Sep 11 15:33:33 2002
@@ -86,8 +86,8 @@
 };
 MODULE_DEVICE_TABLE(usb, pwc_device_table);
 
-static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id);
-static void usb_pwc_disconnect(struct usb_device *udev, void *ptr);
+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 =
 {
@@ -1539,8 +1539,9 @@
  * is loaded.
  */
 
-static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
+static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
+	struct usb_device *udev = interface_to_usbdev(intf);
 	struct pwc_device *pdev = NULL;
 	struct video_device *vdev;
 	int vendor_id, product_id, type_id;
@@ -1551,14 +1552,14 @@
 	free_mem_leak();
 	
 	/* Check if we can handle this device */
-	Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", udev->descriptor.idVendor, udev->descriptor.idProduct, ifnum);
+	Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", udev->descriptor.idVendor, udev->descriptor.idProduct, intf->altsetting->bInterfaceNumber);
 
 	/* the interfaces are probed one by one. We are only interested in the
 	   video interface (0) now.
 	   Interface 1 is the Audio Control, and interface 2 Audio itself.
 	 */
-	if (ifnum > 0) 
-		return NULL;
+	if (intf->altsetting->bInterfaceNumber > 0)
+		return -ENODEV;
 
 	vendor_id = udev->descriptor.idVendor;
 	product_id = udev->descriptor.idProduct;
@@ -1602,7 +1603,7 @@
 			type_id = 750;
 			break;
 		default:
-			return NULL;
+			return -ENODEV;
 			break;
 		}
 	}
@@ -1613,7 +1614,7 @@
 			type_id = 645;
 			break;
 		default:
-			return NULL;
+			return -ENODEV;
 			break;
 		}
 	}
@@ -1624,7 +1625,7 @@
 			type_id = 730;
         		break;
         	default:
-        		return NULL;
+			return -ENODEV;
         		break;
         	}
         }
@@ -1643,7 +1644,7 @@
 			type_id = 675;
 			break;
 		default:
-			return NULL;
+			return -ENODEV;
 			break;
 		}
 	}
@@ -1654,7 +1655,7 @@
 			type_id = 730;
 			break;
 		default:
-			return NULL;
+			return -ENODEV;
 			break;
 		}
 	}
@@ -1665,11 +1666,11 @@
 			type_id = 730;
 			break;  
 		default:
-			return NULL;
+			return -ENODEV;
 			break;
 		}
 	}
-	else return NULL; /* Not Philips, Askey, Logitech, Samsung, Creative or SOTEC, for sure. */
+	else return -ENODEV; /* Not Philips, Askey, Logitech, Samsung, Creative or SOTEC, for sure. */
 
 	memset(serial_number, 0, 30);
 	usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
@@ -1682,7 +1683,7 @@
 	pdev = kmalloc(sizeof(struct pwc_device), GFP_KERNEL);
 	if (pdev == NULL) {
 		Err("Oops, could not allocate memory for pwc_device.\n");
-		return NULL;
+		return -ENOMEM;
 	}
 	memset(pdev, 0, sizeof(struct pwc_device));
 	pdev->type = type_id;
@@ -1700,7 +1701,7 @@
 	vdev = kmalloc(sizeof(struct video_device), GFP_KERNEL);
 	if (vdev == NULL) {
 		Err("Oops, could not allocate memory for video_device.\n");
-		return NULL;
+		return -ENOMEM;
 	}
 	memcpy(vdev, &pwc_template, sizeof(pwc_template));
 	sprintf(vdev->name, "Philips %d webcam", pdev->type);
@@ -1729,7 +1730,7 @@
 	i = video_register_device(vdev, VFL_TYPE_GRABBER, video_nr);
 	if (i < 0) {
 		Err("Failed to register as video device (%d).\n", i);
-		return NULL;
+		return -EIO;
 	}
 	else {
 		Trace(TRACE_PROBE, "Registered video struct at 0x%p.\n", vdev);
@@ -1740,11 +1741,12 @@
 		device_hint[hint].pdev = pdev;
 
 	Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev);
-	return pdev;
+	dev_set_drvdata (&intf->dev, pdev);
+	return 0;
 }
 
 /* The user janked out the cable... */
-static void usb_pwc_disconnect(struct usb_device *udev, void *ptr)
+static void usb_pwc_disconnect(struct usb_interface *intf)
 {
 	struct pwc_device *pdev;
 	int hint;
@@ -1753,7 +1755,8 @@
 	lock_kernel();
 	free_mem_leak();
 
-	pdev = (struct pwc_device *)ptr;
+	pdev = dev_get_drvdata (&intf->dev);
+	dev_set_drvdata (&intf->dev, NULL);
 	if (pdev == NULL) {
 		Err("pwc_disconnect() Called without private pointer.\n");
 		goto out_err;
@@ -1762,7 +1765,7 @@
 		Err("pwc_disconnect() already called for %p\n", pdev);
 		goto out_err;
 	}
-	if (pdev->udev != udev) {
+	if (pdev->udev != interface_to_usbdev(intf)) {
 		Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n");
 		goto out_err;
 	}
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/stv680.c linux-2.5.34-greg/drivers/usb/media/stv680.c
--- linux-2.5.34/drivers/usb/media/stv680.c	Mon Sep  9 10:35:14 2002
+++ linux-2.5.34-greg/drivers/usb/media/stv680.c	Wed Sep 11 15:33:33 2002
@@ -1448,8 +1448,9 @@
 	.fops =         &stv680_fops,
 };
 
-static void *stv680_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
+static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_interface_descriptor *interface;
 	struct usb_stv *stv680;
 	char *camera_name = NULL;
@@ -1457,10 +1458,10 @@
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1) {
 		PDEBUG (0, "STV(e): Number of Configurations != 1");
-		return NULL;
+		return -ENODEV;
 	}
 
-	interface = &dev->actconfig->interface[ifnum].altsetting[0];
+	interface = &intf->altsetting[0];
 	/* Is it a STV680? */
 	if ((dev->descriptor.idVendor == USB_PENCAM_VENDOR_ID) && (dev->descriptor.idProduct == USB_PENCAM_PRODUCT_ID)) {
 		camera_name = "STV0680";
@@ -1468,12 +1469,12 @@
 	} else {
 		PDEBUG (0, "STV(e): Vendor/Product ID do not match STV0680 values.");
 		PDEBUG (0, "STV(e): Check that the STV0680 camera is connected to the computer.");
-		return NULL;
+		return -ENODEV;
 	}
 	/* We found one */
 	if ((stv680 = kmalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) {
 		PDEBUG (0, "STV(e): couldn't kmalloc stv680 struct.");
-		return NULL;
+		return -ENOMEM;
 	}
 
 	memset (stv680, 0, sizeof (*stv680));
@@ -1490,14 +1491,15 @@
 	if (video_register_device (&stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
 		kfree (stv680);
 		PDEBUG (0, "STV(e): video_register_device failed");
-		return NULL;
+		return -EIO;
 	}
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
 	create_proc_stv680_cam (stv680);
 #endif
 	PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev.minor);
 
-	return stv680;
+	dev_set_drvdata (&intf->dev, stv680);
+	return 0;
 }
 
 static inline void usb_stv680_remove_disconnected (struct usb_stv *stv680)
@@ -1531,16 +1533,20 @@
 	kfree (stv680);
 }
 
-static void stv680_disconnect (struct usb_device *dev, void *ptr)
+static void stv680_disconnect (struct usb_interface *intf)
 {
-	struct usb_stv *stv680 = (struct usb_stv *) ptr;
+	struct usb_stv *stv680 = dev_get_drvdata (&intf->dev);
 
-	/* We don't want people trying to open up the device */
-	video_unregister_device (&stv680->vdev);
-	if (!stv680->user) {
-		usb_stv680_remove_disconnected (stv680);
-	} else {
-		stv680->removed = 1;
+	dev_set_drvdata (&intf->dev, NULL);
+
+	if (stv680) {
+		/* We don't want people trying to open up the device */
+		video_unregister_device (&stv680->vdev);
+		if (!stv680->user) {
+			usb_stv680_remove_disconnected (stv680);
+		} else {
+			stv680->removed = 1;
+		}
 	}
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/ultracam.c linux-2.5.34-greg/drivers/usb/media/ultracam.c
--- linux-2.5.34/drivers/usb/media/ultracam.c	Mon Sep  9 10:35:04 2002
+++ linux-2.5.34-greg/drivers/usb/media/ultracam.c	Wed Sep 11 15:33:33 2002
@@ -537,67 +537,71 @@
  * 12-Nov-2000 Reworked to comply with new probe() signature.
  * 23-Jan-2001 Added compatibility with 2.2.x kernels.
  */
-static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum ,const struct usb_device_id *devid)
+static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id *devid)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct uvd *uvd = NULL;
 	int i, nas;
 	int actInterface=-1, inactInterface=-1, maxPS=0;
 	unsigned char video_ep = 0;
 
 	if (debug >= 1)
-		info("ultracam_probe(%p,%u.)", dev, ifnum);
+		info("ultracam_probe(%p)", intf);
 
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1)
-		return NULL;
+		return -ENODEV;
 
 	/* Is it an IBM camera? */
 	if ((dev->descriptor.idVendor != ULTRACAM_VENDOR_ID) ||
 	    (dev->descriptor.idProduct != ULTRACAM_PRODUCT_ID))
-		return NULL;
+		return -ENODEV;
 
 	info("IBM Ultra camera found (rev. 0x%04x)", dev->descriptor.bcdDevice);
 
 	/* Validate found interface: must have one ISO endpoint */
-	nas = dev->actconfig->interface[ifnum].num_altsetting;
+	nas = intf->num_altsetting;
 	if (debug > 0)
 		info("Number of alternate settings=%d.", nas);
 	if (nas < 8) {
 		err("Too few alternate settings for this camera!");
-		return NULL;
+		return -ENODEV;
 	}
 	/* Validate all alternate settings */
 	for (i=0; i < nas; i++) {
 		const struct usb_interface_descriptor *interface;
 		const struct usb_endpoint_descriptor *endpoint;
 
-		interface = &dev->actconfig->interface[ifnum].altsetting[i];
+		interface = &intf->altsetting[i];
 		if (interface->bNumEndpoints != 1) {
 			err("Interface %d. has %u. endpoints!",
-			    ifnum, (unsigned)(interface->bNumEndpoints));
-			return NULL;
+			    interface->bInterfaceNumber,
+			    (unsigned)(interface->bNumEndpoints));
+			return -ENODEV;
 		}
 		endpoint = &interface->endpoint[0];
 		if (video_ep == 0)
 			video_ep = endpoint->bEndpointAddress;
 		else if (video_ep != endpoint->bEndpointAddress) {
 			err("Alternate settings have different endpoint addresses!");
-			return NULL;
+			return -ENODEV;
 		}
 		if ((endpoint->bmAttributes & 0x03) != 0x01) {
-			err("Interface %d. has non-ISO endpoint!", ifnum);
-			return NULL;
+			err("Interface %d. has non-ISO endpoint!",
+			    interface->bInterfaceNumber);
+			return -ENODEV;
 		}
 		if ((endpoint->bEndpointAddress & 0x80) == 0) {
-			err("Interface %d. has ISO OUT endpoint!", ifnum);
-			return NULL;
+			err("Interface %d. has ISO OUT endpoint!",
+			    interface->bInterfaceNumber);
+			return -ENODEV;
 		}
 		if (endpoint->wMaxPacketSize == 0) {
 			if (inactInterface < 0)
 				inactInterface = i;
 			else {
 				err("More than one inactive alt. setting!");
-				return NULL;
+				return -ENODEV;
 			}
 		} else {
 			if (actInterface < 0) {
@@ -621,7 +625,7 @@
 	}
 	if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
 		err("Failed to recognize the camera!");
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* Code below may sleep, need to lock module while we are here */
@@ -632,7 +636,7 @@
 		uvd->flags = flags;
 		uvd->debug = debug;
 		uvd->dev = dev;
-		uvd->iface = ifnum;
+		uvd->iface = intf->altsetting->bInterfaceNumber;
 		uvd->ifaceAltInactive = inactInterface;
 		uvd->ifaceAltActive = actInterface;
 		uvd->video_endp = video_ep;
@@ -656,7 +660,12 @@
 		}
 	}
 	MOD_DEC_USE_COUNT;
-	return uvd;
+
+	if (uvd) {
+		dev_set_drvdata (&intf->dev, uvd);
+		return 0;
+	}
+	return -EIO;
 }
 
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/usbvideo.c linux-2.5.34-greg/drivers/usb/media/usbvideo.c
--- linux-2.5.34/drivers/usb/media/usbvideo.c	Mon Sep  9 10:35:37 2002
+++ linux-2.5.34-greg/drivers/usb/media/usbvideo.c	Wed Sep 11 15:33:33 2002
@@ -54,7 +54,7 @@
 	unsigned long count, void *data);
 #endif
 
-static void usbvideo_Disconnect(struct usb_device *dev, void *ptr);
+static void usbvideo_Disconnect(struct usb_interface *intf);
 static void usbvideo_CameraRelease(struct uvd *uvd);
 
 static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file,
@@ -966,18 +966,21 @@
  * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
  * 19-Oct-2000 Moved to usbvideo module.
  */
-static void usbvideo_Disconnect(struct usb_device *dev, void *ptr)
+static void usbvideo_Disconnect(struct usb_interface *intf)
 {
-	struct uvd *uvd = (struct uvd *) ptr;
+	struct uvd *uvd = dev_get_drvdata (&intf->dev);
 	int i;
 
-	if ((dev == NULL) || (uvd == NULL)) {
-		err("%s($%p,$%p): Illegal call.", __FUNCTION__, dev, ptr);
+	if (uvd == NULL) {
+		err("%s($%p): Illegal call.", __FUNCTION__, intf);
 		return;
 	}
+
+	dev_set_drvdata (&intf->dev, NULL);
+
 	usbvideo_ClientIncModCount(uvd);
 	if (uvd->debug > 0)
-		info("%s(%p,%p.)", __FUNCTION__, dev, ptr);
+		info("%s(%p.)", __FUNCTION__, intf);
 
 	down(&uvd->lock);
 	uvd->remove_pending = 1; /* Now all ISO data will be ignored */
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/usbvideo.h linux-2.5.34-greg/drivers/usb/media/usbvideo.h
--- linux-2.5.34/drivers/usb/media/usbvideo.h	Mon Sep  9 10:35:09 2002
+++ linux-2.5.34-greg/drivers/usb/media/usbvideo.h	Wed Sep 11 15:33:33 2002
@@ -254,9 +254,9 @@
  * that default to usbvideo-provided methods.
  */
 struct usbvideo_cb {
-	void *(*probe)(struct usb_device *, unsigned int,const struct usb_device_id *);
+	int (*probe)(struct usb_interface *, const struct usb_device_id *);
 	void (*userFree)(struct uvd *);
-	void (*disconnect)(struct usb_device *, void *);
+	void (*disconnect)(struct usb_interface *);
 	int (*setupOnOpen)(struct uvd *);
 	void (*videoStart)(struct uvd *);
 	void (*videoStop)(struct uvd *);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/vicam.c linux-2.5.34-greg/drivers/usb/media/vicam.c
--- linux-2.5.34/drivers/usb/media/vicam.c	Mon Sep  9 10:35:07 2002
+++ linux-2.5.34-greg/drivers/usb/media/vicam.c	Wed Sep 11 15:33:33 2002
@@ -787,9 +787,10 @@
 	return 1;
 }
 
-static void *vicam_probe(struct usb_device *udev, unsigned int ifnum,
+static int vicam_probe(struct usb_interface *intf, 
 	const struct usb_device_id *id)
 {
+	struct usb_device *udev = interface_to_usbdev(intf);
 	struct usb_vicam *vicam;
 	char *camera_name=NULL;
 
@@ -798,7 +799,7 @@
 	/* See if the device offered us matches what we can accept */
 	if ((udev->descriptor.idVendor != USB_VICAM_VENDOR_ID) ||
 	    (udev->descriptor.idProduct != USB_VICAM_PRODUCT_ID)) {
-		return NULL;
+		return -ENODEV;
 	}
 	
 	camera_name="3Com HomeConnect USB";
@@ -807,14 +808,14 @@
 	vicam = kmalloc (sizeof(struct usb_vicam), GFP_KERNEL);
 	if (vicam == NULL) {
 		err ("couldn't kmalloc vicam struct");
-		return NULL;
+		return -ENOMEM;
 	}
 	memset(vicam, 0, sizeof(*vicam));
 
 	vicam->readurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!vicam->readurb) {
 		kfree(vicam);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	vicam->udev = udev;
@@ -826,7 +827,7 @@
 	if (vicam_init(vicam)) {
 		usb_free_urb(vicam->readurb);
 		kfree(vicam);
-		return NULL;
+		return -ENOMEM;
 	}
 	memcpy(&vicam->vdev, &vicam_template, sizeof(vicam_template));
 	memcpy(vicam->vdev.name, vicam->camera_name, strlen(vicam->camera_name));
@@ -835,7 +836,7 @@
 		err("video_register_device");
 		usb_free_urb(vicam->readurb);
 		kfree(vicam);
-		return NULL;
+		return -EIO;
 	}
 
 	info("registered new video device: video%d", vicam->vdev.minor);
@@ -843,34 +844,38 @@
 	init_MUTEX (&vicam->sem);
 	init_waitqueue_head(&vicam->wait);
 	
-	return vicam;
+	dev_set_drvdata (&intf->dev, vicam);
+	return 0;
 }
 
 
 /* FIXME - vicam_disconnect - important */
-static void vicam_disconnect(struct usb_device *udev, void *ptr)
+static void vicam_disconnect(struct usb_interface *intf)
 {
 	struct usb_vicam *vicam;
 
-	vicam = (struct usb_vicam *) ptr;
+	vicam = dev_get_drvdata (&intf->dev);
 
-	video_unregister_device(&vicam->vdev);
-	vicam->udev = NULL;
+	dev_set_drvdata (&intf->dev, NULL);
+
+	if (vicam) {
+		video_unregister_device(&vicam->vdev);
+		vicam->udev = NULL;
 /*
-	vicam->frame[0].grabstate = FRAME_ERROR;
-	vicam->frame[1].grabstate = FRAME_ERROR;
+		vicam->frame[0].grabstate = FRAME_ERROR;
+		vicam->frame[1].grabstate = FRAME_ERROR;
 */
 
-	/* Free buffers and shit */
-
-	info("%s disconnected", vicam->camera_name);
-	synchronize(vicam);
-
-	if (!vicam->open_count) {
-		/* Other random junk */
-		usb_free_urb(vicam->readurb);
-		kfree(vicam);
-		vicam = NULL;
+		/* Free buffers and shit */
+		info("%s disconnected", vicam->camera_name);
+		synchronize(vicam);
+
+		if (!vicam->open_count) {
+			/* Other random junk */
+			usb_free_urb(vicam->readurb);
+			kfree(vicam);
+			vicam = NULL;
+		}
 	}
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/net/usbnet.c linux-2.5.34-greg/drivers/usb/net/usbnet.c
--- linux-2.5.34/drivers/usb/net/usbnet.c	Mon Sep  9 10:34:59 2002
+++ linux-2.5.34-greg/drivers/usb/net/usbnet.c	Wed Sep 11 15:33:33 2002
@@ -1921,12 +1921,16 @@
  
 // precondition: never called in_interrupt
 
-static void usbnet_disconnect (struct usb_device *udev, void *ptr)
+static void usbnet_disconnect (struct usb_interface *udev)
 {
-	struct usbnet	*dev = (struct usbnet *) ptr;
+	struct usbnet		*dev;
+	struct usb_device	*xdev;
+
+	dev = (struct usbnet *) udev->dev.driver_data;
+	xdev = interface_to_usbdev (udev);
 
 	devinfo (dev, "unregister usbnet usb-%s-%s, %s",
-		udev->bus->bus_name, udev->devpath,
+		xdev->bus->bus_name, xdev->devpath,
 		dev->driver_info->description);
 	
 	unregister_netdev (&dev->net);
@@ -1940,7 +1944,7 @@
 	flush_scheduled_tasks ();
 
 	kfree (dev);
-	usb_put_dev (udev);
+	usb_put_dev (xdev);
 }
 
 
@@ -1948,46 +1952,38 @@
 
 // precondition: never called in_interrupt
 
-static void *
-usbnet_probe (struct usb_device *udev, unsigned ifnum,
-			const struct usb_device_id *prod)
+int
+usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 {
 	struct usbnet			*dev;
 	struct net_device 		*net;
 	struct usb_interface_descriptor	*interface;
 	struct driver_info		*info;
-	int				altnum = 0;
+	struct usb_device		*xdev;
 
 	info = (struct driver_info *) prod->driver_info;
 
-	// sanity check; expect dedicated interface/devices for now.
-	interface = &udev->actconfig->interface [ifnum].altsetting [altnum];
-	if (udev->descriptor.bNumConfigurations != 1
-			|| udev->config[0].bNumInterfaces != 1
-//			|| interface->bInterfaceClass != USB_CLASS_VENDOR_SPEC
-			) {
-		dbg ("Bogus config info");
-		return 0;
-	}
+	xdev = interface_to_usbdev (udev);
+	interface = &udev->altsetting [udev->act_altsetting];
 
-	// more sanity (unless the device is broken)
 	if (!(info->flags & FLAG_NO_SETINT)) {
-		if (usb_set_interface (udev, ifnum, altnum) < 0) {
+		if (usb_set_interface (xdev, interface->bInterfaceNumber,
+				interface->bAlternateSetting) < 0) {
 			err ("set_interface failed");
-			return 0;
+			return -EIO;
 		}
 	}
 
 	// set up our own records
 	if (!(dev = kmalloc (sizeof *dev, GFP_KERNEL))) {
 		dbg ("can't kmalloc dev");
-		return 0;
+		return -ENOMEM;
 	}
 	memset (dev, 0, sizeof *dev);
 
 	init_MUTEX_LOCKED (&dev->mutex);
-	usb_get_dev (udev);
-	dev->udev = udev;
+	usb_get_dev (xdev);
+	dev->udev = xdev;
 	dev->driver_info = info;
 	dev->msg_level = msg_level;
 	INIT_LIST_HEAD (&dev->dev_list);
@@ -2020,10 +2016,11 @@
 
 	register_netdev (&dev->net);
 	devinfo (dev, "register usbnet usb-%s-%s, %s",
-		udev->bus->bus_name, udev->devpath,
+		xdev->bus->bus_name, xdev->devpath,
 		dev->driver_info->description);
 
 	// ok, it's ready to go.
+	udev->dev.driver_data = net;
 	mutex_lock (&usbnet_mutex);
 	list_add (&dev->dev_list, &usbnet_list);
 	mutex_unlock (&dev->mutex);
@@ -2032,7 +2029,7 @@
 	netif_device_attach (&dev->net);
 
 	mutex_unlock (&usbnet_mutex);
-	return dev;
+	return 0;
 }
 
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/belkin_sa.c linux-2.5.34-greg/drivers/usb/serial/belkin_sa.c
--- linux-2.5.34/drivers/usb/serial/belkin_sa.c	Mon Sep  9 10:35:13 2002
+++ linux-2.5.34-greg/drivers/usb/serial/belkin_sa.c	Wed Sep 11 15:33:33 2002
@@ -114,6 +114,13 @@
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
+static struct usb_driver belkin_driver = {
+	.name =		"belkin",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table_combined,
+};
+
 /* All of the device info needed for the serial converters */
 static struct usb_serial_device_type belkin_device = {
 	.owner =		THIS_MODULE,
@@ -526,6 +533,7 @@
 static int __init belkin_sa_init (void)
 {
 	usb_serial_register (&belkin_device);
+	usb_register (&belkin_driver);
 	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
 }
@@ -533,6 +541,7 @@
 
 static void __exit belkin_sa_exit (void)
 {
+	usb_deregister (&belkin_driver);
 	usb_serial_deregister (&belkin_device);
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/cyberjack.c linux-2.5.34-greg/drivers/usb/serial/cyberjack.c
--- linux-2.5.34/drivers/usb/serial/cyberjack.c	Mon Sep  9 10:35:15 2002
+++ linux-2.5.34-greg/drivers/usb/serial/cyberjack.c	Wed Sep 11 15:33:33 2002
@@ -73,6 +73,13 @@
 
 MODULE_DEVICE_TABLE (usb, id_table);
 
+static struct usb_driver cyberjack_driver = {
+	.name =		"cyberjack",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+};
+
 static struct usb_serial_device_type cyberjack_device = {
 	.owner =		THIS_MODULE,
 	.name =			"Reiner SCT Cyberjack USB card reader",
@@ -461,6 +468,7 @@
 static int __init cyberjack_init (void)
 {
 	usb_serial_register (&cyberjack_device);
+	usb_register (&cyberjack_driver);
 
 	info(DRIVER_VERSION " " DRIVER_AUTHOR);
 	info(DRIVER_DESC);
@@ -470,6 +478,7 @@
 
 static void __exit cyberjack_exit (void)
 {
+	usb_deregister (&cyberjack_driver);
 	usb_serial_deregister (&cyberjack_device);
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/digi_acceleport.c linux-2.5.34-greg/drivers/usb/serial/digi_acceleport.c
--- linux-2.5.34/drivers/usb/serial/digi_acceleport.c	Mon Sep  9 10:35:11 2002
+++ linux-2.5.34-greg/drivers/usb/serial/digi_acceleport.c	Wed Sep 11 15:33:33 2002
@@ -477,7 +477,7 @@
 
 /* Statics */
 
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) },
 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) },
 	{ }						/* Terminating entry */
@@ -495,6 +495,14 @@
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
+static struct usb_driver digi_driver = {
+	.name =		"digi_acceleport",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table_combined,
+};
+
+
 /* device info needed for the Digi serial converter */
 
 static struct usb_serial_device_type digi_acceleport_2_device = {
@@ -2025,6 +2033,7 @@
 {
 	usb_serial_register (&digi_acceleport_2_device);
 	usb_serial_register (&digi_acceleport_4_device);
+	usb_register (&digi_driver);
 	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
@@ -2032,6 +2041,7 @@
 
 static void __exit digi_exit (void)
 {
+	usb_deregister (&digi_driver);
 	usb_serial_deregister (&digi_acceleport_2_device);
 	usb_serial_deregister (&digi_acceleport_4_device);
 }
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/empeg.c linux-2.5.34-greg/drivers/usb/serial/empeg.c
--- linux-2.5.34/drivers/usb/serial/empeg.c	Mon Sep  9 10:35:11 2002
+++ linux-2.5.34-greg/drivers/usb/serial/empeg.c	Wed Sep 11 15:33:33 2002
@@ -110,6 +110,13 @@
 
 MODULE_DEVICE_TABLE (usb, id_table);
 
+static struct usb_driver empeg_driver = {
+	.name =		"empeg",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+};
+
 static struct usb_serial_device_type empeg_device = {
 	.owner =		THIS_MODULE,
 	.name =			"Empeg",
@@ -550,8 +557,6 @@
 	struct urb *urb;
 	int i;
 
-	usb_serial_register (&empeg_device);
-
 	/* create our write urb pool and transfer buffers */ 
 	spin_lock_init (&write_urb_pool_lock);
 	for (i = 0; i < NUM_URBS; ++i) {
@@ -571,10 +576,12 @@
 		}
 	}
 
+	usb_serial_register (&empeg_device);
+	usb_register (&empeg_driver);
+
 	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
-
 }
 
 
@@ -583,6 +590,7 @@
 	int i;
 	unsigned long flags;
 
+	usb_register (&empeg_driver);
 	usb_serial_deregister (&empeg_device);
 
 	spin_lock_irqsave (&write_urb_pool_lock, flags);
@@ -600,7 +608,6 @@
 	}
 
 	spin_unlock_irqrestore (&write_urb_pool_lock, flags);
-
 }
 
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/ftdi_sio.c linux-2.5.34-greg/drivers/usb/serial/ftdi_sio.c
--- linux-2.5.34/drivers/usb/serial/ftdi_sio.c	Mon Sep  9 10:35:05 2002
+++ linux-2.5.34-greg/drivers/usb/serial/ftdi_sio.c	Wed Sep 11 15:33:33 2002
@@ -140,7 +140,7 @@
 };
 
 
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
 	{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
@@ -149,6 +149,13 @@
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
+static struct usb_driver ftdi_driver = {
+	.name =		"ftdi_sio",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table_combined,
+};
+
 
 struct ftdi_private {
 	enum ftdi_type ftdi_type;
@@ -944,6 +951,7 @@
 	dbg("%s", __FUNCTION__);
 	usb_serial_register (&ftdi_sio_device);
 	usb_serial_register (&ftdi_8U232AM_device);
+	usb_register (&ftdi_driver);
 	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
@@ -952,6 +960,7 @@
 static void __exit ftdi_sio_exit (void)
 {
 	dbg("%s", __FUNCTION__);
+	usb_deregister (&ftdi_driver);
 	usb_serial_deregister (&ftdi_sio_device);
 	usb_serial_deregister (&ftdi_8U232AM_device);
 }
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/io_edgeport.c linux-2.5.34-greg/drivers/usb/serial/io_edgeport.c
--- linux-2.5.34/drivers/usb/serial/io_edgeport.c	Mon Sep  9 10:35:01 2002
+++ linux-2.5.34-greg/drivers/usb/serial/io_edgeport.c	Wed Sep 11 15:33:33 2002
@@ -457,6 +457,12 @@
 
 #include "io_tables.h"	/* all of the devices that this driver supports */
 
+static struct usb_driver io_driver = {
+	.name =		"io_edgeport",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table_combined,
+};
 
 /* function prototypes for all of our local functions */
 static int  process_rcvd_data		(struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength);
@@ -3050,6 +3056,7 @@
 	usb_serial_register (&edgeport_2port_device);
 	usb_serial_register (&edgeport_4port_device);
 	usb_serial_register (&edgeport_8port_device);
+	usb_register (&io_driver);
 	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
 }
@@ -3062,6 +3069,7 @@
  ****************************************************************************/
 void __exit edgeport_exit (void)
 {
+	usb_deregister (&io_driver);
 	usb_serial_deregister (&edgeport_1port_device);
 	usb_serial_deregister (&edgeport_2port_device);
 	usb_serial_deregister (&edgeport_4port_device);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/io_tables.h linux-2.5.34-greg/drivers/usb/serial/io_tables.h
--- linux-2.5.34/drivers/usb/serial/io_tables.h	Mon Sep  9 10:35:02 2002
+++ linux-2.5.34-greg/drivers/usb/serial/io_tables.h	Wed Sep 11 15:33:33 2002
@@ -61,7 +61,7 @@
 };
 
 /* Devices that this driver supports */
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION,	ION_DEVICE_ID_EDGEPORT_4) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION,	ION_DEVICE_ID_RAPIDPORT_4) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION,	ION_DEVICE_ID_EDGEPORT_4T) },
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/io_ti.c linux-2.5.34-greg/drivers/usb/serial/io_ti.c
--- linux-2.5.34/drivers/usb/serial/io_ti.c	Mon Sep  9 10:35:09 2002
+++ linux-2.5.34-greg/drivers/usb/serial/io_ti.c	Wed Sep 11 15:33:33 2002
@@ -142,7 +142,7 @@
 };
 
 /* Devices that this driver supports */
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) },
@@ -161,6 +161,13 @@
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
+static struct usb_driver io_driver = {
+	.name =		"io_ti",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table_combined,
+};
+
 
 static struct EDGE_FIRMWARE_VERSION_INFO OperationalCodeImageVersion;
 
@@ -2658,12 +2665,14 @@
 {
 	usb_serial_register (&edgeport_1port_device);
 	usb_serial_register (&edgeport_2port_device);
+	usb_register (&io_driver);
 	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
 }
 
 static void __exit edgeport_exit (void)
 {
+	usb_deregister (&io_driver);
 	usb_serial_deregister (&edgeport_1port_device);
 	usb_serial_deregister (&edgeport_2port_device);
 }
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/ipaq.c linux-2.5.34-greg/drivers/usb/serial/ipaq.c
--- linux-2.5.34/drivers/usb/serial/ipaq.c	Mon Sep  9 10:35:06 2002
+++ linux-2.5.34-greg/drivers/usb/serial/ipaq.c	Wed Sep 11 15:33:33 2002
@@ -94,6 +94,14 @@
 
 MODULE_DEVICE_TABLE (usb, ipaq_id_table);
 
+static struct usb_driver ipaq_driver = {
+	.name =		"ipaq",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	ipaq_id_table,
+};
+
+
 /* All of the device info needed for the Compaq iPAQ */
 struct usb_serial_device_type ipaq_device = {
 	.owner =		THIS_MODULE,
@@ -516,6 +524,7 @@
 static int __init ipaq_init(void)
 {
 	usb_serial_register(&ipaq_device);
+	usb_register(&ipaq_driver);
 	info(DRIVER_DESC " " DRIVER_VERSION);
 
 	return 0;
@@ -524,6 +533,7 @@
 
 static void __exit ipaq_exit(void)
 {
+	usb_deregister(&ipaq_driver);
 	usb_serial_deregister(&ipaq_device);
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/ir-usb.c linux-2.5.34-greg/drivers/usb/serial/ir-usb.c
--- linux-2.5.34/drivers/usb/serial/ir-usb.c	Mon Sep  9 10:35:11 2002
+++ linux-2.5.34-greg/drivers/usb/serial/ir-usb.c	Wed Sep 11 15:33:33 2002
@@ -129,6 +129,13 @@
 
 MODULE_DEVICE_TABLE (usb, id_table);
 
+static struct usb_driver ir_driver = {
+	.name =		"ir-usb",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+};
+
 
 struct usb_serial_device_type ir_device = {
 	.owner =		THIS_MODULE,
@@ -606,6 +613,7 @@
 static int __init ir_init (void)
 {
 	usb_serial_register (&ir_device);
+	usb_register (&ir_driver);
 	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
 }
@@ -613,6 +621,7 @@
 
 static void __exit ir_exit (void)
 {
+	usb_deregister (&ir_driver);
 	usb_serial_deregister (&ir_device);
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/keyspan.c linux-2.5.34-greg/drivers/usb/serial/keyspan.c
--- linux-2.5.34/drivers/usb/serial/keyspan.c	Mon Sep  9 10:35:02 2002
+++ linux-2.5.34-greg/drivers/usb/serial/keyspan.c	Wed Sep 11 15:33:33 2002
@@ -183,6 +183,7 @@
 	usb_serial_register (&keyspan_1port_device);
 	usb_serial_register (&keyspan_2port_device);
 	usb_serial_register (&keyspan_4port_device);
+	usb_register (&keyspan_driver);
 
 	info(DRIVER_VERSION ":" DRIVER_DESC);
 
@@ -191,6 +192,7 @@
 
 static void __exit keyspan_exit (void)
 {
+	usb_deregister (&keyspan_driver);
 	usb_serial_deregister (&keyspan_pre_device);
 	usb_serial_deregister (&keyspan_1port_device);
 	usb_serial_deregister (&keyspan_2port_device);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/keyspan.h linux-2.5.34-greg/drivers/usb/serial/keyspan.h
--- linux-2.5.34/drivers/usb/serial/keyspan.h	Mon Sep  9 10:35:14 2002
+++ linux-2.5.34-greg/drivers/usb/serial/keyspan.h	Wed Sep 11 15:33:33 2002
@@ -408,7 +408,7 @@
 	NULL,
 };
 
-static __devinitdata struct usb_device_id keyspan_ids_combined[] = {
+static struct usb_device_id keyspan_ids_combined[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) },
@@ -434,6 +434,13 @@
 
 MODULE_DEVICE_TABLE(usb, keyspan_ids_combined);
 
+static struct usb_driver keyspan_driver = {
+	.name =		"keyspan",                
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	keyspan_ids_combined,
+};
+
 /* usb_device_id table for the pre-firmware download keyspan devices */
 static struct usb_device_id keyspan_pre_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) },
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/keyspan_pda.c linux-2.5.34-greg/drivers/usb/serial/keyspan_pda.c
--- linux-2.5.34/drivers/usb/serial/keyspan_pda.c	Mon Sep  9 10:35:13 2002
+++ linux-2.5.34-greg/drivers/usb/serial/keyspan_pda.c	Wed Sep 11 15:33:33 2002
@@ -140,7 +140,7 @@
 #define ENTREGRA_VENDOR_ID		0x1645
 #define ENTREGRA_FAKE_ID		0x8093
 
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
 #ifdef KEYSPAN
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
 #endif
@@ -154,6 +154,13 @@
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
+static struct usb_driver keyspan_pda_driver = {
+	.name =		"keyspan_pda",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table_combined,
+};
+
 static struct usb_device_id id_table_std [] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
 	{ }						/* Terminating entry */
@@ -862,6 +869,7 @@
 #ifdef XIRCOM
 	usb_serial_register (&xircom_pgs_fake_device);
 #endif
+	usb_register (&keyspan_pda_driver);
 	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
 }
@@ -869,6 +877,7 @@
 
 static void __exit keyspan_pda_exit (void)
 {
+	usb_deregister (&keyspan_pda_driver);
 	usb_serial_deregister (&keyspan_pda_device);
 #ifdef KEYSPAN
 	usb_serial_deregister (&keyspan_pda_fake_device);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/kl5kusb105.c linux-2.5.34-greg/drivers/usb/serial/kl5kusb105.c
--- linux-2.5.34/drivers/usb/serial/kl5kusb105.c	Mon Sep  9 10:35:12 2002
+++ linux-2.5.34-greg/drivers/usb/serial/kl5kusb105.c	Wed Sep 11 15:33:33 2002
@@ -117,6 +117,12 @@
 
 MODULE_DEVICE_TABLE (usb, id_table);
 
+static struct usb_driver kl5kusb105d_driver = {
+	.name =		"kl5kusb105d",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+};
 
 static struct usb_serial_device_type kl5kusb105d_device = {
 	.owner =             THIS_MODULE,
@@ -1009,6 +1015,7 @@
 static int __init klsi_105_init (void)
 {
 	usb_serial_register (&kl5kusb105d_device);
+	usb_register (&kl5kusb105d_driver);
 
 	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
@@ -1017,6 +1024,7 @@
 
 static void __exit klsi_105_exit (void)
 {
+	usb_deregister (&kl5kusb105d_driver);
 	usb_serial_deregister (&kl5kusb105d_device);
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/mct_u232.c linux-2.5.34-greg/drivers/usb/serial/mct_u232.c
--- linux-2.5.34/drivers/usb/serial/mct_u232.c	Mon Sep  9 10:35:13 2002
+++ linux-2.5.34-greg/drivers/usb/serial/mct_u232.c	Wed Sep 11 15:33:33 2002
@@ -139,6 +139,12 @@
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
+static struct usb_driver mct_u232_driver = {
+	.name =		"mct_u232",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table_combined,
+};
 
 static struct usb_serial_device_type mct_u232_device = {
 	.owner =	     THIS_MODULE,
@@ -782,6 +788,7 @@
 static int __init mct_u232_init (void)
 {
 	usb_serial_register (&mct_u232_device);
+	usb_register (&mct_u232_driver);
 	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
 }
@@ -789,6 +796,7 @@
 
 static void __exit mct_u232_exit (void)
 {
+	usb_deregister (&mct_u232_driver);
 	usb_serial_deregister (&mct_u232_device);
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/omninet.c linux-2.5.34-greg/drivers/usb/serial/omninet.c
--- linux-2.5.34/drivers/usb/serial/omninet.c	Mon Sep  9 10:35:07 2002
+++ linux-2.5.34-greg/drivers/usb/serial/omninet.c	Wed Sep 11 15:33:33 2002
@@ -83,6 +83,13 @@
 
 MODULE_DEVICE_TABLE (usb, id_table);
 
+static struct usb_driver omninet_driver = {
+	.name =		"omninet",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+};
+
 
 static struct usb_serial_device_type zyxel_omninet_device = {
 	.owner =		THIS_MODULE,
@@ -370,6 +377,7 @@
 static int __init omninet_init (void)
 {
 	usb_serial_register (&zyxel_omninet_device);
+	usb_register (&omninet_driver);
 	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
@@ -377,6 +385,7 @@
 
 static void __exit omninet_exit (void)
 {
+	usb_deregister (&omninet_driver);
 	usb_serial_deregister (&zyxel_omninet_device);
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/pl2303.c linux-2.5.34-greg/drivers/usb/serial/pl2303.c
--- linux-2.5.34/drivers/usb/serial/pl2303.c	Mon Sep  9 10:35:11 2002
+++ linux-2.5.34-greg/drivers/usb/serial/pl2303.c	Wed Sep 11 15:33:33 2002
@@ -78,6 +78,12 @@
 
 MODULE_DEVICE_TABLE (usb, id_table);
 
+static struct usb_driver pl2303_driver = {
+	.name =		"pl2303",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+};
 
 #define SET_LINE_REQUEST_TYPE		0x21
 #define SET_LINE_REQUEST		0x20
@@ -709,6 +715,7 @@
 static int __init pl2303_init (void)
 {
 	usb_serial_register (&pl2303_device);
+	usb_register (&pl2303_driver);
 	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
 }
@@ -716,6 +723,7 @@
 
 static void __exit pl2303_exit (void)
 {
+	usb_deregister (&pl2303_driver);
 	usb_serial_deregister (&pl2303_device);
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/safe_serial.c linux-2.5.34-greg/drivers/usb/serial/safe_serial.c
--- linux-2.5.34/drivers/usb/serial/safe_serial.c	Mon Sep  9 10:35:05 2002
+++ linux-2.5.34-greg/drivers/usb/serial/safe_serial.c	Wed Sep 11 15:33:33 2002
@@ -161,6 +161,13 @@
 
 MODULE_DEVICE_TABLE (usb, id_table);
 
+static struct usb_driver safe_driver = {
+	.name =		"safe_serial",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+};
+
 static __u16 crc10_table[256] = {
 	0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
 	0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
@@ -434,12 +441,14 @@
 	}
 
 	usb_serial_register (&safe_device);
+	usb_register (&safe_driver);
 
 	return 0;
 }
 
 static void __exit safe_exit (void)
 {
+	usb_deregister (&safe_driver);
 	usb_serial_deregister (&safe_device);
 }
 
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/usb-serial.h linux-2.5.34-greg/drivers/usb/serial/usb-serial.h
--- linux-2.5.34/drivers/usb/serial/usb-serial.h	Mon Sep  9 10:35:12 2002
+++ linux-2.5.34-greg/drivers/usb/serial/usb-serial.h	Wed Sep 11 15:33:33 2002
@@ -233,6 +233,9 @@
 extern int  usb_serial_register(struct usb_serial_device_type *new_device);
 extern void usb_serial_deregister(struct usb_serial_device_type *device);
 
+extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
+extern void usb_serial_disconnect(struct usb_interface *iface);
+
 /* determine if we should include the EzUSB loader functions */
 #undef USES_EZUSB_FUNCTIONS
 #if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE)
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/usbserial.c linux-2.5.34-greg/drivers/usb/serial/usbserial.c
--- linux-2.5.34/drivers/usb/serial/usbserial.c	Mon Sep  9 10:35:09 2002
+++ linux-2.5.34-greg/drivers/usb/serial/usbserial.c	Wed Sep 11 15:33:33 2002
@@ -379,30 +379,23 @@
 	.num_ports =		1,
 	.shutdown =		generic_shutdown,
 };
-#endif
-
 
-/* local function prototypes */
-static int  serial_open (struct tty_struct *tty, struct file * filp);
-static void serial_close (struct tty_struct *tty, struct file * filp);
-static int  serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count);
-static int  serial_write_room (struct tty_struct *tty);
-static int  serial_chars_in_buffer (struct tty_struct *tty);
-static void serial_throttle (struct tty_struct * tty);
-static void serial_unthrottle (struct tty_struct * tty);
-static int  serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
-static void serial_set_termios (struct tty_struct *tty, struct termios * old);
-static void serial_shutdown (struct usb_serial *serial);
-
-static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
-			       const struct usb_device_id *id);
-static void usb_serial_disconnect(struct usb_device *dev, void *ptr);
+/* we want to look at all devices, as the vendor/product id can change
+ * depending on the command line argument */
+static struct usb_device_id generic_serial_ids[] = {
+	{.driver_info = 42},
+	{}
+};
+#endif
 
+/* Driver structure we register with the USB core */
 static struct usb_driver usb_serial_driver = {
 	.name =		"serial",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
-	.id_table =	NULL, 			/* check all devices */
+#ifdef CONFIG_USB_SERIAL_GENERIC
+	.id_table =	generic_serial_ids,
+#endif
 };
 
 /* There is no MODULE_DEVICE_TABLE for usbserial.c.  Instead
@@ -412,7 +405,6 @@
    drivers depend on it.
 */
 
-
 static int			serial_refcount;
 static struct tty_driver	serial_tty_driver;
 static struct tty_struct *	serial_tty[SERIAL_TTY_MINORS];
@@ -1161,12 +1153,12 @@
 	return serial;
 }
 
-static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
+int usb_serial_probe(struct usb_interface *interface,
 			       const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev (interface);
 	struct usb_serial *serial = NULL;
 	struct usb_serial_port *port;
-	struct usb_interface *interface;
 	struct usb_interface_descriptor *iface_desc;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
@@ -1189,7 +1181,6 @@
 	/* loop through our list of known serial converters, and see if this
 	   device matches. */
 	found = 0;
-	interface = &dev->actconfig->interface[ifnum];
 	list_for_each (tmp, &usb_serial_driver_list) {
 		type = list_entry(tmp, struct usb_serial_device_type, driver_list);
 		id_pattern = usb_match_id(interface, type->id_table);
@@ -1202,13 +1193,13 @@
 	if (!found) {
 		/* no match */
 		dbg("none matched");
-		return(NULL);
+		return -ENODEV;
 	}
 
 	serial = create_serial (dev, interface, type);
 	if (!serial) {
 		err ("%s - out of memory", __FUNCTION__);
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* if this device type has a probe function, call it */
@@ -1222,7 +1213,7 @@
 		if (retval < 0) {
 			dbg ("sub driver rejected device");
 			kfree (serial);
-			return NULL;
+			return -ENODEV;
 		}
 	}
 
@@ -1258,6 +1249,7 @@
 	}
 
 #if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
+#if 0
 	/* BEGIN HORRIBLE HACK FOR PL2303 */ 
 	/* this is needed due to the looney way its endpoints are set up */
 	if (ifnum == 1) {
@@ -1282,6 +1274,7 @@
 	}
 	/* END HORRIBLE HACK FOR PL2303 */
 #endif
+#endif
 
 	/* found all that we need */
 	info("%s converter detected", type->name);
@@ -1292,7 +1285,7 @@
 		if (num_ports == 0) {
 			err("Generic device with no bulk out, not allowed.");
 			kfree (serial);
-			return NULL;
+			return -EIO;
 		}
 	}
 #endif
@@ -1312,7 +1305,7 @@
 	if (get_free_serial (serial, num_ports, &minor) == NULL) {
 		err("No more free serial devices");
 		kfree (serial);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	serial->minor = minor;
@@ -1424,7 +1417,8 @@
 		if (retval > 0) {
 			/* quietly accept this device, but don't bind to a serial port
 			 * as it's about to disappear */
-			return serial;
+			interface->dev.driver_data = serial;
+			return 0;
 		}
 	}
 
@@ -1455,7 +1449,9 @@
 	}
 #endif
 
-	return serial; /* success */
+	/* success */
+	interface->dev.driver_data = serial;
+	return 0;
 
 
 probe_error:
@@ -1486,16 +1482,18 @@
 
 	/* free up any memory that we allocated */
 	kfree (serial);
-	return NULL;
+	return -EIO;
 }
 
-static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
+void usb_serial_disconnect(struct usb_interface *interface)
 {
-	struct usb_serial *serial = (struct usb_serial *) ptr;
+	struct usb_serial *serial = (struct usb_serial *)interface->dev.driver_data;
 	struct usb_serial_port *port;
 	int i;
 
 	dbg ("%s", __FUNCTION__);
+
+	interface->dev.driver_data = NULL;
 	if (serial) {
 		/* fail all future close/read/write/ioctl/etc calls */
 		for (i = 0; i < serial->num_ports; ++i) {
@@ -1554,10 +1552,8 @@
 
 		/* free up any memory that we allocated */
 		kfree (serial);
-
-	} else {
-		info("device disconnected");
 	}
+	info("device disconnected");
 
 }
 
@@ -1663,8 +1659,6 @@
 
 	info ("USB Serial support registered for %s", new_device->name);
 
-	usb_scan_devices();
-
 	return 0;
 }
 
@@ -1681,7 +1675,7 @@
 		serial = serial_table[i];
 		if ((serial != NULL) && (serial->type == device)) {
 			usb_driver_release_interface (&usb_serial_driver, serial->interface);
-			usb_serial_disconnect (NULL, serial);
+			usb_serial_disconnect (serial->interface);
 		}
 	}
 
@@ -1694,6 +1688,8 @@
    need these symbols to load properly as modules. */
 EXPORT_SYMBOL(usb_serial_register);
 EXPORT_SYMBOL(usb_serial_deregister);
+EXPORT_SYMBOL(usb_serial_probe);
+EXPORT_SYMBOL(usb_serial_disconnect);
 #ifdef USES_EZUSB_FUNCTIONS
 	EXPORT_SYMBOL(ezusb_writememory);
 	EXPORT_SYMBOL(ezusb_set_reset);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/visor.c linux-2.5.34-greg/drivers/usb/serial/visor.c
--- linux-2.5.34/drivers/usb/serial/visor.c	Mon Sep  9 10:35:07 2002
+++ linux-2.5.34-greg/drivers/usb/serial/visor.c	Wed Sep 11 15:33:33 2002
@@ -197,7 +197,7 @@
 	{ }					/* Terminating entry */
 };
 
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
@@ -214,7 +214,12 @@
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
-
+static struct usb_driver visor_driver = {
+	.name =		"visor",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table_combined,
+};
 
 /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
 static struct usb_serial_device_type handspring_device = {
@@ -763,6 +768,7 @@
 {
 	usb_serial_register (&handspring_device);
 	usb_serial_register (&clie_3_5_device);
+	usb_register (&visor_driver);
 	info(DRIVER_DESC " " DRIVER_VERSION);
 
 	return 0;
@@ -771,6 +777,7 @@
 
 static void __exit visor_exit (void)
 {
+	usb_deregister (&visor_driver);
 	usb_serial_deregister (&handspring_device);
 	usb_serial_deregister (&clie_3_5_device);
 }
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/whiteheat.c linux-2.5.34-greg/drivers/usb/serial/whiteheat.c
--- linux-2.5.34/drivers/usb/serial/whiteheat.c	Mon Sep  9 10:35:08 2002
+++ linux-2.5.34-greg/drivers/usb/serial/whiteheat.c	Wed Sep 11 15:33:33 2002
@@ -110,7 +110,7 @@
 	{ }						/* Terminating entry */
 };
 
-static __devinitdata struct usb_device_id id_table_combined [] = {
+static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) },
 	{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) },
 	{ }						/* Terminating entry */
@@ -118,6 +118,13 @@
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
+static struct usb_driver whiteheat_driver = {
+	.name =		"whiteheat",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table_combined,
+};
+
 /* function prototypes for the Connect Tech WhiteHEAT serial converter */
 static int  whiteheat_open		(struct usb_serial_port *port, struct file *filp);
 static void whiteheat_close		(struct usb_serial_port *port, struct file *filp);
@@ -674,6 +681,7 @@
 {
 	usb_serial_register (&whiteheat_fake_device);
 	usb_serial_register (&whiteheat_device);
+	usb_register (&whiteheat_driver);
 	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
 }
@@ -681,6 +689,7 @@
 
 static void __exit whiteheat_exit (void)
 {
+	usb_deregister (&whiteheat_driver);
 	usb_serial_deregister (&whiteheat_fake_device);
 	usb_serial_deregister (&whiteheat_device);
 }
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/storage/scsiglue.c linux-2.5.34-greg/drivers/usb/storage/scsiglue.c
--- linux-2.5.34/drivers/usb/storage/scsiglue.c	Mon Sep  9 10:35:11 2002
+++ linux-2.5.34-greg/drivers/usb/storage/scsiglue.c	Wed Sep 11 15:33:33 2002
@@ -252,7 +252,6 @@
 	for (i = 0; i < pusb_dev_save->actconfig->bNumInterfaces; i++) {
  		struct usb_interface *intf =
 			&pusb_dev_save->actconfig->interface[i];
-		const struct usb_device_id *id;
 
 		/* if this is an unclaimed interface, skip it */
 		if (!intf->driver) {
@@ -263,11 +262,8 @@
 
 		/* simulate a disconnect and reconnect for all interfaces */
 		US_DEBUGPX("simulating disconnect/reconnect.\n");
-		down(&intf->driver->serialize);
-		intf->driver->disconnect(pusb_dev_save, intf->private_data);
-		id = usb_match_id(intf, intf->driver->id_table);
-		intf->driver->probe(pusb_dev_save, i, id);
-		up(&intf->driver->serialize);
+		usb_device_remove (&intf->dev);
+		usb_device_probe (&intf->dev);
 	}
 	US_DEBUGP("bus_reset() complete\n");
 	scsi_lock(srb->host);
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/storage/usb.c linux-2.5.34-greg/drivers/usb/storage/usb.c
--- linux-2.5.34/drivers/usb/storage/usb.c	Mon Sep  9 10:35:06 2002
+++ linux-2.5.34-greg/drivers/usb/storage/usb.c	Wed Sep 11 15:33:33 2002
@@ -103,10 +103,10 @@
 struct us_data *us_list;
 struct semaphore us_list_semaphore;
 
-static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
-			    const struct usb_device_id *id);
+static int storage_probe(struct usb_interface *iface,
+			 const struct usb_device_id *id);
 
-static void storage_disconnect(struct usb_device *dev, void *ptr);
+static void storage_disconnect(struct usb_interface *iface);
 
 /* The entries in this table, except for final ones here
  * (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
@@ -617,9 +617,11 @@
 }
 
 /* Probe to see if a new device is actually a SCSI device */
-static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
-			    const struct usb_device_id *id)
+static int storage_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
+	int ifnum = intf->altsetting->bInterfaceNumber;
 	int i;
 	const int id_index = id - storage_usb_ids; 
 	char mf[USB_STOR_STRING_LEN];		     /* manufacturer */
@@ -644,7 +646,6 @@
 	/* the altsetting on the interface we're probing that matched our
 	 * usb_match_id table
 	 */
-	struct usb_interface *intf = dev->actconfig->interface;
 	struct usb_interface_descriptor *altsetting =
 		intf[ifnum].altsetting + intf[ifnum].act_altsetting;
 	US_DEBUGP("act_altsetting is %d\n", intf[ifnum].act_altsetting);
@@ -674,7 +675,7 @@
 			US_DEBUGP("Product: %s\n", unusual_dev->productName);
 	} else
 		/* no, we can't support it */
-		return NULL;
+		return -EIO;
 
 	/* At this point, we know we've got a live one */
 	US_DEBUGP("USB Mass Storage device detected\n");
@@ -723,7 +724,7 @@
 		} else if (result != 0) {
 			/* it's not a stall, but another error -- time to bail */
 			US_DEBUGP("-- Unknown error.  Rejecting device\n");
-			return NULL;
+			return -EIO;
 		}
 	}
 #endif
@@ -731,7 +732,7 @@
 	/* Do some basic sanity checks, and bail if we find a problem */
 	if (!ep_in || !ep_out || (protocol == US_PR_CBI && !ep_int)) {
 		US_DEBUGP("Endpoint sanity check failed! Rejecting dev.\n");
-		return NULL;
+		return -EIO;
 	}
 
 	/* At this point, we've decided to try to use the device */
@@ -810,7 +811,7 @@
 						    GFP_KERNEL)) == NULL) {
 			printk(KERN_WARNING USB_STORAGE "Out of memory\n");
 			usb_put_dev(dev);
-			return NULL;
+			return -ENOMEM;
 		}
 		memset(ss, 0, sizeof(struct us_data));
 		new_device = 1;
@@ -1087,8 +1088,9 @@
 	printk(KERN_DEBUG 
 	       "USB Mass Storage device found at %d\n", dev->devnum);
 
-	/* return a pointer for the disconnect function */
-	return ss;
+	/* save a pointer to our structure */
+	intf->dev.driver_data = ss;
+	return 0;
 
 	/* we come here if there are any problems */
 	/* ss->dev_semaphore must be locked */
@@ -1098,16 +1100,18 @@
 	up(&ss->dev_semaphore);
 	if (new_device)
 		kfree(ss);
-	return NULL;
+	return -EIO;
 }
 
 /* Handle a disconnect event from the USB core */
-static void storage_disconnect(struct usb_device *dev, void *ptr)
+static void storage_disconnect(struct usb_interface *intf)
 {
-	struct us_data *ss = ptr;
+	struct us_data *ss = intf->dev.driver_data;
 
 	US_DEBUGP("storage_disconnect() called\n");
 
+	intf->dev.driver_data = NULL;
+
 	/* this is the odd case -- we disconnected but weren't using it */
 	if (!ss) {
 		US_DEBUGP("-- device was not in use\n");
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/include/linux/device.h linux-2.5.34-greg/include/linux/device.h
--- linux-2.5.34/include/linux/device.h	Mon Sep  9 10:35:08 2002
+++ linux-2.5.34-greg/include/linux/device.h	Wed Sep 11 15:33:33 2002
@@ -306,6 +306,18 @@
 	return list_entry(g_list, struct device, g_list);
 }
 
+static inline void *
+dev_get_drvdata (struct device *dev)
+{
+	return dev->driver_data;
+}
+
+static inline void
+dev_set_drvdata (struct device *dev, void *data)
+{
+	dev->driver_data = data;
+}
+
 /*
  * High level routines for use by the bus drivers
  */
diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/include/linux/usb.h linux-2.5.34-greg/include/linux/usb.h
--- linux-2.5.34/include/linux/usb.h	Mon Sep  9 10:35:09 2002
+++ linux-2.5.34-greg/include/linux/usb.h	Wed Sep 11 15:33:33 2002
@@ -227,7 +227,7 @@
 	int act_altsetting;		/* active alternate setting */
 	int num_altsetting;		/* number of alternate settings */
 	int max_altsetting;		/* total memory allocated */
- 
+
 	struct usb_driver *driver;	/* driver */
 	struct device dev;		/* interface specific device info */
 	void *private_data;
@@ -399,9 +399,6 @@
 extern void usb_free_dev(struct usb_device *);
 #define usb_put_dev usb_free_dev
 
-/* for when layers above USB add new non-USB drivers */
-extern void usb_scan_devices(void);
-
 /* mostly for devices emulating SCSI over USB */
 extern int usb_reset_device(struct usb_device *dev);
 
@@ -623,10 +620,10 @@
  *	expose information to user space regardless of where they
  *	do (or don't) show up otherwise in the filesystem.
  * @id_table: USB drivers use ID table to support hotplugging.
- *	Export this with MODULE_DEVICE_TABLE(usb,...), or use NULL to
- *	say that probe() should be called for any unclaimed interfce.
+ *	Export this with MODULE_DEVICE_TABLE(usb,...).  This must be set
+ *	or your driver's probe function will never get called. 
  *
- * USB drivers should provide a name, probe() and disconnect() methods,
+ * USB drivers must provide a name, probe() and disconnect() methods,
  * and an id_table.  Other driver fields are optional.
  *
  * The id_table is used in hotplugging.  It holds a set of descriptors,
@@ -643,32 +640,23 @@
  */
 struct usb_driver {
 	struct module *owner;
+
 	const char *name;
 
-	void *(*probe)(
-	    struct usb_device *dev,		/* the device */
-	    unsigned intf,			/* what interface */
-	    const struct usb_device_id *id	/* from id_table */
-	    );
-	void (*disconnect)(
-	    struct usb_device *dev,		/* the device */
-	    void *handle			/* as returned by probe() */
-	    );
+	int (*probe) (struct usb_interface *intf,
+		      const struct usb_device_id *id);
 
-	struct list_head driver_list;
-	struct semaphore serialize;
+	void (*disconnect) (struct usb_interface *intf);
 
-	/* ioctl -- userspace apps can talk to drivers through usbfs */
-	int (*ioctl)(struct usb_device *dev, unsigned int code, void *buf);
+	int (*ioctl) (struct usb_device *dev, unsigned int code, void *buf);
 
-	/* support for "new-style" USB hotplugging */
 	const struct usb_device_id *id_table;
 
-	/* suspend before the bus suspends;
-	 * disconnect or resume when the bus resumes */
-	/* void (*suspend)(struct usb_device *dev); */
-	/* void (*resume)(struct usb_device *dev); */
+	struct device_driver driver;
+
+	struct semaphore serialize;
 };
+#define	to_usb_driver(d) container_of(d, struct usb_driver, driver)
 
 extern struct bus_type usb_bus_type;
 
@@ -682,6 +670,9 @@
 extern int usb_register_dev(struct file_operations *fops, int minor, int num_minors, int *start_minor);
 extern void usb_deregister_dev(int num_minors, int start_minor);
 
+extern int usb_device_probe(struct device *dev);
+extern int usb_device_remove(struct device *dev);
+
 /* -------------------------------------------------------------------------- */
 
 /*
