diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/Makefile linux-2.5-driverfs/drivers/usb/core/Makefile
--- ../linux-2.5/drivers/usb/core/Makefile	Mon Jun  3 10:01:01 2002
+++ linux-2.5-driverfs/drivers/usb/core/Makefile	Wed Jun  5 09:40:29 2002
@@ -11,6 +11,10 @@
 	usbcore-objs	+= devio.o inode.o drivers.o devices.o
 endif
 
+ifeq ($(CONFIG_DEVFS),y)
+	usbcore-objs	+= fs.o
+endif
+
 obj-$(CONFIG_USB)	+= usbcore.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/devio.c linux-2.5-driverfs/drivers/usb/core/devio.c
--- ../linux-2.5/drivers/usb/core/devio.c	Tue May 28 09:11:55 2002
+++ linux-2.5-driverfs/drivers/usb/core/devio.c	Mon Jun  3 11:29:16 2002
@@ -431,9 +431,9 @@
 	return -ENOENT; 
 }
 
+#if 0
 extern struct list_head usb_driver_list;
 
-#if 0
 static int finddriver(struct usb_driver **driver, char *name)
 {
 	struct list_head *tmp;
@@ -1096,6 +1096,7 @@
        else switch (ctrl.ioctl_code) {
 
        /* disconnect kernel driver from interface, leaving it unbound.  */
+#if 0
        case USBDEVFS_DISCONNECT:
                driver = ifp->driver;
                if (driver) {
@@ -1113,7 +1114,7 @@
        case USBDEVFS_CONNECT:
                usb_find_interface_driver_for_ifnum (ps->dev, ctrl.ifno);
                break;
-
+#endif
        /* talk directly to the interface's driver */
        default:
                driver = ifp->driver;
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/drivers.c linux-2.5-driverfs/drivers/usb/core/drivers.c
--- ../linux-2.5/drivers/usb/core/drivers.c	Thu May 23 16:06:21 2002
+++ linux-2.5-driverfs/drivers/usb/core/drivers.c	Mon Jun  3 11:29:16 2002
@@ -50,7 +50,7 @@
  */
 static ssize_t usb_driver_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
 {
-	struct list_head *tmp = usb_driver_list.next;
+	struct list_head *tmp = &usb_bus_type.drivers.next
 	char *page, *start, *end;
 	ssize_t ret = 0;
 	unsigned int pos, len;
@@ -66,7 +66,7 @@
 	start = page;
 	end = page + (PAGE_SIZE - 100);
 	pos = *ppos;
-	for (; tmp != &usb_driver_list; tmp = tmp->next) {
+	for (; tmp != &usb_bus_type.drivers; tmp = tmp->next) {
 		struct usb_driver *driver = list_entry(tmp, struct usb_driver, driver_list);
 		int minor = driver->fops ? driver->minor : -1;
 		if (minor == -1)
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/fs.c linux-2.5-driverfs/drivers/usb/core/fs.c
--- ../linux-2.5/drivers/usb/core/fs.c	Wed Dec 31 16:00:00 1969
+++ linux-2.5-driverfs/drivers/usb/core/fs.c	Mon Jun  3 11:09:08 2002
@@ -0,0 +1,61 @@
+
+#include <linux/usb.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/module.h>
+
+devfs_handle_t usb_devfs_handle;	/* /dev/usb dir. */
+
+
+static int usb_open(struct inode * inode, struct file * file)
+{
+	int minor = minor(inode->i_rdev);
+	struct usb_driver *c;
+	int err = -ENODEV;
+	struct file_operations *old_fops, *new_fops = NULL;
+
+	spin_lock (&minor_lock);
+	c = usb_minors[minor];
+	spin_unlock (&minor_lock);
+
+	if (!c || !(new_fops = fops_get(c->fops)))
+		return err;
+	old_fops = file->f_op;
+	file->f_op = new_fops;
+	/* Curiouser and curiouser... NULL ->open() as "no device" ? */
+	if (file->f_op->open)
+		err = file->f_op->open(inode,file);
+	if (err) {
+		fops_put(file->f_op);
+		file->f_op = fops_get(old_fops);
+	}
+	fops_put(old_fops);
+	return err;
+}
+
+static struct file_operations usb_fops = {
+	owner:		THIS_MODULE,
+	open:		usb_open,
+};
+
+static int __init usb_major_init(void)
+{
+	if (devfs_register_chrdev(USB_MAJOR, "usb", &usb_fops)) {
+		err("unable to get major %d for usb devices", USB_MAJOR);
+		return -EBUSY;
+	}
+
+	usb_devfs_handle = devfs_mk_dir(NULL, "usb", NULL);
+
+	return 0;
+}
+
+static void __exit usb_major_cleanup(void)
+{
+	devfs_unregister(usb_devfs_handle);
+	devfs_unregister_chrdev(USB_MAJOR, "usb");
+}
+
+subsys_initcall(usb_major_init);
+module_exit(usb_major_cleanup);
+
+EXPORT_SYMBOL(usb_devfs_handle);
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/hcd.c linux-2.5-driverfs/drivers/usb/core/hcd.c
--- ../linux-2.5/drivers/usb/core/hcd.c	Wed May 29 12:39:43 2002
+++ linux-2.5-driverfs/drivers/usb/core/hcd.c	Mon Jun  3 11:29:16 2002
@@ -730,15 +730,7 @@
  */
 int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev)
 {
-	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);
-	if (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 ../dontdiff ../linux-2.5/drivers/usb/core/hcd.h linux-2.5-driverfs/drivers/usb/core/hcd.h
--- ../linux-2.5/drivers/usb/core/hcd.h	Mon Jun  3 10:24:32 2002
+++ linux-2.5-driverfs/drivers/usb/core/hcd.h	Mon Jun  3 11:29:16 2002
@@ -182,7 +182,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 **);
 
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/hub.c linux-2.5-driverfs/drivers/usb/core/hub.c
--- ../linux-2.5/drivers/usb/core/hub.c	Wed May 29 12:39:43 2002
+++ linux-2.5-driverfs/drivers/usb/core/hub.c	Mon Jun  3 11:29:16 2002
@@ -250,49 +250,17 @@
 	/* Enable power to the ports */
 	dbg("enabling power on all ports");
 	for (i = 0; i < hub->descriptor->bNbrPorts; i++)
-		usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER);
+		usb_set_port_feature(hub->intf->usb_device, i + 1, USB_PORT_FEAT_POWER);
 
 	/* Wait for power to be enabled */
 	wait_ms(hub->descriptor->bPwrOn2PwrGood * 2);
 }
 
-static int usb_hub_configure(struct usb_hub *hub,
-	struct usb_endpoint_descriptor *endpoint)
+static void usb_hub_report(struct usb_hub * hub)
 {
-	struct usb_device *dev = hub->dev;
-	struct usb_hub_status hubstatus;
+	struct usb_device *dev = hub->intf->usb_device;
 	char portstr[USB_MAXCHILDREN + 1];
-	unsigned int pipe;
-	int i, maxp, ret;
-
-	hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
-	if (!hub->descriptor) {
-		err("Unable to kmalloc %Zd bytes for hub descriptor",
-			sizeof(*hub->descriptor));
-		return -1;
-	}
-
-	/* Request the entire hub descriptor.
-	 * hub->descriptor can handle USB_MAXCHILDREN ports,
-	 * but the hub can/will return fewer bytes here.
-	 */
-	ret = usb_get_hub_descriptor(dev, hub->descriptor,
-			sizeof(*hub->descriptor));
-	if (ret < 0) {
-		err("Unable to get hub descriptor (err = %d)", ret);
-		kfree(hub->descriptor);
-		return -1;
-	} else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {
-		err("Hub is too big! %d children", hub->descriptor->bNbrPorts);
-		kfree(hub->descriptor);
-		return -1;
-	}
-
-	dev->maxchild = hub->descriptor->bNbrPorts;
-	info("%d port%s detected", dev->maxchild,
-		(dev->maxchild == 1) ? "" : "s");
-
-	le16_to_cpus(&hub->descriptor->wHubCharacteristics);
+	int i;
 
 	if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND)
 		dbg("part of a compound device");
@@ -376,14 +344,51 @@
 			    [((i + 1) / 8)] & (1 << ((i + 1) % 8))
 			? 'F' : 'R';
 	portstr[dev->maxchild] = 0;
-
 	dbg("port removable status: %s", portstr);
+}
+
+static int usb_hub_configure(struct usb_hub *hub,
+	struct usb_endpoint_descriptor *endpoint)
+{
+	struct usb_device *dev = hub->intf->usb_device;
+	struct usb_hub_status hubstatus;
+	unsigned int pipe;
+	int maxp, ret;
+	int error = -EIO;
+
+	hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
+	if (!hub->descriptor) {
+		err("Unable to kmalloc %Zd bytes for hub descriptor",
+			sizeof(*hub->descriptor));
+		goto Done;
+	}
+
+	/* Request the entire hub descriptor.
+	 * hub->descriptor can handle USB_MAXCHILDREN ports,
+	 * but the hub can/will return fewer bytes here.
+	 */
+	ret = usb_get_hub_descriptor(dev, hub->descriptor,
+			sizeof(*hub->descriptor));
+	if (ret < 0) {
+		err("Unable to get hub descriptor (err = %d)", ret);
+		goto Done;
+	} else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {
+		err("Hub is too big! %d children", hub->descriptor->bNbrPorts);
+		goto Done;
+	}
+
+	dev->maxchild = hub->descriptor->bNbrPorts;
+	info("%d port%s detected", dev->maxchild,
+		(dev->maxchild == 1) ? "" : "s");
+
+	le16_to_cpus(&hub->descriptor->wHubCharacteristics);
+
+	usb_hub_report(hub);
 
 	ret = usb_get_hub_status(dev, &hubstatus);
 	if (ret < 0) {
 		err("Unable to get hub status (err = %d)", ret);
-		kfree(hub->descriptor);
-		return -1;
+		goto Done;
 	}
 
 	le16_to_cpus(&hubstatus.wHubStatus);
@@ -405,147 +410,135 @@
 	hub->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!hub->urb) {
 		err("couldn't allocate interrupt urb");
-		kfree(hub->descriptor);
-		return -1;
+		goto Done;
 	}
 
 	FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,
 		hub, endpoint->bInterval);
 	ret = usb_submit_urb(hub->urb, GFP_KERNEL);
-	if (ret) {
+	if (!ret) {
+		/* Wake up khubd */
+		wake_up(&khubd_wait);
+
+		usb_hub_power_on(hub);
+		error = 0;
+	} else
 		err("usb_submit_urb failed (%d)", ret);
+ Done:
+	if (error && hub->descriptor)
 		kfree(hub->descriptor);
-		return -1;
+	return error;
+}
+
+static void hub_disconnect(struct usb_interface *intf)
+{
+	struct usb_hub *hub = (struct usb_hub *)intf->dev.driver_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hub_event_lock, flags);
+
+	/* Delete it and then reset it */
+	list_del_init(&hub->event_list);
+	list_del_init(&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);
+
+	if (hub->urb) {
+		usb_unlink_urb(hub->urb);
+		usb_free_urb(hub->urb);
+		hub->urb = NULL;
 	}
-		
-	/* Wake up khubd */
-	wake_up(&khubd_wait);
 
-	usb_hub_power_on(hub);
+	if (hub->descriptor) {
+		kfree(hub->descriptor);
+		hub->descriptor = NULL;
+	}
 
-	return 0;
+	/* Free the memory */
+	kfree(hub);
+	intf->dev.driver_data = NULL;
 }
 
-static void *hub_probe(struct usb_device *dev, unsigned int i,
-		       const struct usb_device_id *id)
+static int hub_probe(struct usb_interface * intf)
 {
-	struct usb_interface_descriptor *interface;
+	struct usb_interface_descriptor *desc;
 	struct usb_endpoint_descriptor *endpoint;
-	struct usb_hub *hub;
-	unsigned long flags;
 
-	interface = &dev->actconfig->interface[i].altsetting[0];
+	desc = intf->altsetting + intf->act_altsetting;
 
 	/* 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, intf->usb_device->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, intf->usb_device->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;
+			intf->usb_device->devnum);
+		return -EIO;
 	}
 
 	/* If it's not an interrupt endpoint, we'd better punt! */
 	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
 			!= USB_ENDPOINT_XFER_INT) {
 		err("Device #%d is hub class, but endpoint is not interrupt?",
-			dev->devnum);
-		return NULL;
+			intf->usb_device->devnum);
+		return -EIO;
 	}
 
 	/* We found a hub */
-	info("USB hub found at %s", dev->devpath);
+	info("USB hub found at %s", intf->usb_device->devpath);
+
+	return 0;
+}
+
+static int hub_init(struct usb_interface * intf)
+{
+	struct usb_hub * hub;
+	unsigned long flags;
+	struct usb_endpoint_descriptor *endpoint;
+
+	endpoint = intf->altsetting[intf->act_altsetting].endpoint;
 
 	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 */
 	spin_lock_irqsave(&hub_event_lock, flags);
-	INIT_LIST_HEAD(&hub->hub_list);
 	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)
-		return hub;
-
-	err("hub configuration failed for device at %s", dev->devpath);
-
-	/* free hub, but first clean up its list. */
-	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);
-
-	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;
-	}
+		return 0;
 
-	/* Free the memory */
-	kfree(hub);
+	err("hub configuration failed for device at %s", intf->usb_device->devpath);
+	hub_disconnect(intf);
+	return -ENODEV;
 }
 
 static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data)
@@ -582,7 +575,7 @@
 
 static int usb_hub_reset(struct usb_hub *hub)
 {
-	struct usb_device *dev = hub->dev;
+	struct usb_device *dev = hub->intf->usb_device;
 	int i;
 
 	/* Disconnect any attached devices */
@@ -793,7 +786,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 = hubstate->intf->usb_device;
 	struct usb_device *dev;
 	unsigned int delay = HUB_SHORT_RESET_TIME;
 	int i;
@@ -884,22 +877,8 @@
 		info("new USB device %s-%s, assigned address %d",
 			dev->bus->bus_name, dev->devpath, dev->devnum);
 
-		/* put the device in the global device tree */
-		dev->dev.parent = &dev->parent->dev;
-		sprintf (&dev->dev.name[0], "USB device %04x:%04x",
-			 dev->descriptor.idVendor,
-			 dev->descriptor.idProduct);
-		/* find the number of the port this device is connected to */
-		sprintf (&dev->dev.bus_id[0], "unknown_port_%03d", dev->devnum);
-		for (i = 0; i < USB_MAXCHILDREN; ++i) {
-			if (dev->parent->children[i] == dev) {
-				sprintf (&dev->dev.bus_id[0], "%02d", i);
-				break;
-			}
-		}
-
 		/* Run it through the hoops (find a driver, etc) */
-		if (!usb_new_device(dev))
+		if (!usb_new_device(dev,&hubstate->intf->dev))
 			goto done;
 
 		/* Free the configuration if there was an error */
@@ -944,7 +923,7 @@
 		tmp = hub_event_list.next;
 
 		hub = list_entry(tmp, struct usb_hub, event_list);
-		dev = hub->dev;
+		dev = hub->intf->usb_device;
 
 		list_del(tmp);
 		INIT_LIST_HEAD(tmp);
@@ -1088,20 +1067,21 @@
 
 static struct usb_driver hub_driver = {
 	name:		"hub",
-	probe:		hub_probe,
+	new_probe:	hub_probe,
+	init:		hub_init,
 	ioctl:		hub_ioctl,
-	disconnect:	hub_disconnect,
+	new_disco:	hub_disconnect,
 	id_table:	hub_id_table,
 };
 
 /*
  * This should be a separate module.
  */
-int usb_hub_init(void)
+static int __init usb_hub_init(void)
 {
 	int pid;
 
-	if (usb_register(&hub_driver) < 0) {
+	if (usb_driver_register(&hub_driver) < 0) {
 		err("Unable to register USB hub driver");
 		return -1;
 	}
@@ -1121,7 +1101,7 @@
 	return -1;
 }
 
-void usb_hub_cleanup(void)
+static void __exit usb_hub_cleanup(void)
 {
 	int ret;
 
@@ -1138,7 +1118,10 @@
 	 * individual hub resources. -greg
 	 */
 	usb_deregister(&hub_driver);
-} /* usb_hub_cleanup() */
+}
+
+module_init(usb_hub_init);
+module_exit(usb_hub_cleanup);
 
 /*
  * WARNING - If a driver calls usb_reset_device, you should simulate a
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/core/hub.h linux-2.5-driverfs/drivers/usb/core/hub.h
--- ../linux-2.5/drivers/usb/core/hub.h	Mon Jun  3 10:24:22 2002
+++ linux-2.5-driverfs/drivers/usb/core/hub.h	Mon Jun  3 11:29:16 2002
@@ -134,7 +134,7 @@
 	__u8  PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
 } __attribute__ ((packed));
 
-struct usb_device;
+struct usb_interface;
 
 /*
  * As of USB 2.0, full/low speed devices are segregated into trees.
@@ -165,7 +165,7 @@
 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_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 ../dontdiff ../linux-2.5/drivers/usb/core/usb.c linux-2.5-driverfs/drivers/usb/core/usb.c
--- ../linux-2.5/drivers/usb/core/usb.c	Mon Jun  3 10:01:01 2002
+++ linux-2.5-driverfs/drivers/usb/core/usb.c	Mon Jun  3 11:29:16 2002
@@ -30,7 +30,6 @@
 #include <linux/interrupt.h>  /* for in_interrupt() */
 #include <linux/kmod.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 
@@ -43,23 +42,6 @@
 
 #include "hcd.h"
 
-extern int  usb_hub_init(void);
-extern void usb_hub_cleanup(void);
-
-/*
- * Prototypes for the device driver probing/loading functions
- */
-static void usb_find_drivers(struct usb_device *);
-static int  usb_find_interface_driver(struct usb_device *, unsigned int);
-static void usb_check_support(struct usb_device *);
-
-/*
- * We have a per-interface "registered driver" list.
- */
-LIST_HEAD(usb_driver_list);
-
-devfs_handle_t usb_devfs_handle;	/* /dev/usb dir. */
-
 #define MAX_USB_MINORS	256
 static struct usb_driver *usb_minors[MAX_USB_MINORS];
 static spinlock_t minor_lock = SPIN_LOCK_UNLOCKED;
@@ -102,6 +84,51 @@
 	spin_unlock (&minor_lock);
 }
 
+static int usb_device_probe(struct device * dev)
+{
+	struct usb_interface * intf = list_entry(dev,struct usb_interface,dev);
+	struct usb_driver * drv = list_entry(dev->driver,struct usb_driver,driver);
+	int error = -ENODEV;
+
+	if (drv->new_probe)
+		error = drv->new_probe(intf);
+	if (!error)
+		intf->driver = drv;
+	return error;
+}
+
+static int usb_device_init(struct device * dev)
+{
+	struct usb_interface * intf = list_entry(dev,struct usb_interface, dev);
+	struct usb_driver * drv = intf->driver;
+
+	return (drv->init) ? drv->init(intf) : 0;
+}
+
+static int usb_device_remove(struct device * dev)
+{
+	struct usb_interface * intf = list_entry(dev,struct usb_interface,dev);
+
+	if (intf->driver && intf->driver->new_disco)
+		intf->driver->new_disco(intf);
+	return 0;
+}
+
+int usb_driver_register(struct usb_driver * drv)
+{
+	drv->driver.name = drv->name;
+	drv->driver.bus = &usb_bus_type;
+	drv->driver.probe = usb_device_probe;
+	drv->driver.init = usb_device_init;
+	drv->driver.remove = usb_device_remove;
+
+	info("registered new driver %s", drv->name);
+
+	init_MUTEX(&drv->serialize);
+
+	return driver_register(&drv->driver);
+}
+
 /**
  *	usb_register - register a USB driver
  *	@new_driver: USB operations for the driver
@@ -128,14 +155,17 @@
 	}
 #endif
 
+	new_driver->driver.name = new_driver->name;
+	new_driver->driver.bus = &usb_bus_type;
+	new_driver->driver.probe = usb_device_probe;
+	new_driver->driver.init = usb_device_init;
+	new_driver->driver.remove = usb_device_remove;
+
 	info("registered new driver %s", new_driver->name);
 
 	init_MUTEX(&new_driver->serialize);
 
-	/* Add it to the list of known drivers */
-	list_add_tail(&new_driver->driver_list, &usb_driver_list);
-
-	usb_scan_devices();
+	driver_register(&new_driver->driver);
 
 	usbfs_update_special();
 
@@ -228,75 +258,6 @@
 }
 #endif	/* CONFIG_USB_DYNAMIC_MINORS */
 
-
-/**
- *	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;
-
-	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_check_support(bus->root_hub);
-	}
-	up (&usb_bus_list_lock);
-}
-
-/*
- * 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;
-
-	if (!dev) {
-		err("null device being purged!!!");
-		return;
-	}
-
-	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) {
-			if (driver->owner)
-				__MOD_INC_USE_COUNT(driver->owner);
-			down(&driver->serialize);
-			driver->disconnect(dev, interface->private_data);
-			up(&driver->serialize);
-			if (driver->owner)
-				__MOD_DEC_USE_COUNT(driver->owner);
-			/* 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, i);
-		}
-	}
-}
-
 /**
  *	usb_deregister - unregister a USB driver
  *	@driver: USB operations of the driver to unregister
@@ -306,8 +267,6 @@
  */
 void usb_deregister(struct usb_driver *driver)
 {
-	struct list_head *tmp;
-
 	info("deregistering driver %s", driver->name);
 
 #ifndef CONFIG_USB_DYNAMIC_MINORS
@@ -315,21 +274,7 @@
 		usb_deregister_minors (driver, driver->num_minors, driver->minor);
 #endif
 
-	/*
-	 * 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);
+	put_driver(&driver->driver);
 
 	usbfs_update_special();
 }
@@ -410,33 +355,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, i);
-}
-
-
 /**
  * usb_driver_claim_interface - bind a driver to an interface
  * @driver: the driver to be bound
@@ -468,7 +386,7 @@
 
 	iface->driver = driver;
 	iface->private_data = priv;
-} /* usb_driver_claim_interface() */
+}
 
 /**
  * usb_interface_claimed - returns true iff an interface is claimed
@@ -487,7 +405,7 @@
 		return 0;
 
 	return (iface->driver != NULL);
-} /* usb_interface_claimed() */
+}
 
 /**
  * usb_driver_release_interface - unbind a driver from an interface
@@ -645,110 +563,70 @@
 	return NULL;
 }
 
-/*
- * This entrypoint gets called for each new device.
- *
- * 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
- */
-static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum)
+static int usb_device_bind(struct device * dev, struct device_driver * drv)
 {
-	struct list_head *tmp;
-	struct usb_interface *interface;
-	void *private;
-	const struct usb_device_id *id;
-	struct usb_driver *driver;
-	int i;
-	
-	if ((!dev) || (ifnum >= dev->actconfig->bNumInterfaces)) {
-		err("bad find_interface_driver params");
-		return -1;
-	}
-
-	down(&dev->serialize);
-
-	interface = dev->actconfig->interface + ifnum;
-
-	if (usb_interface_claimed(interface))
-		goto out_err;
-
-	private = NULL;
-	for (tmp = usb_driver_list.next; tmp != &usb_driver_list;) {
-		driver = list_entry(tmp, struct usb_driver, driver_list);
-		tmp = tmp->next;
-
-		if (driver->owner)
-			__MOD_INC_USE_COUNT(driver->owner);
-		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(dev, interface, id);
-				if (id) {
-					down(&driver->serialize);
-					private = driver->probe(dev,ifnum,id);
-					up(&driver->serialize);
-					if (private != NULL)
-						break;
-				}
-			}
+	struct usb_interface * intf = list_entry(dev,struct usb_interface,dev);
+	struct usb_interface_descriptor * desc = &intf->altsetting[intf->act_altsetting];
+	struct usb_device * usb_dev = intf->usb_device;
+	struct usb_driver * usb_drv = list_entry(drv,struct usb_driver,driver);
+	const struct usb_device_id * id = usb_drv->id_table;
 
-			/* 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)
-			__MOD_DEC_USE_COUNT(driver->owner);
+	/* It is important to check that id->driver_info is nonzero,
+	   since an entry that is all zeroes except for a nonzero
+	   id->driver_info is the way to create an entry that
+	   indicates that the driver want to examine every
+	   device and interface. */
+	for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
+	       id->driver_info; id++) {
 
-		/* probe() may have changed the config on us */
-		interface = dev->actconfig->interface + ifnum;
+		if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+		    id->idVendor != usb_dev->descriptor.idVendor)
+			continue;
 
-		if (private) {
-			usb_driver_claim_interface(driver, interface, private);
-			up(&dev->serialize);
-			return 0;
-		}
-	}
+		if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
+		    id->idProduct != usb_dev->descriptor.idProduct)
+			continue;
 
-out_err:
-	up(&dev->serialize);
-	return -1;
-}
+		/* No need to test id->bcdDevice_lo != 0, since 0 is never
+		   greater than any unsigned number. */
+		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
+		    (id->bcdDevice_lo > usb_dev->descriptor.bcdDevice))
+			continue;
 
-/**
- * usb_find_interface_driver_for_ifnum - finds a usb interface driver for the specified ifnum
- * @dev: the device to use
- * @ifnum: the interface number (bInterfaceNumber); not interface position!
- *
- * This converts a ifnum to ifpos via a call to usb_ifnum_to_ifpos and then
- * calls usb_find_interface_driver() with the found ifpos.  Note
- * usb_find_interface_driver's ifnum parameter is actually interface position.
- */
-int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned ifnum)
-{
-	int ifpos = usb_ifnum_to_ifpos(dev, ifnum);
+		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
+		    (id->bcdDevice_hi < usb_dev->descriptor.bcdDevice))
+			continue;
 
-	if (0 > ifpos)
-		return -EINVAL;
+		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
+		    (id->bDeviceClass != usb_dev->descriptor.bDeviceClass))
+			continue;
+
+		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
+		    (id->bDeviceSubClass!= usb_dev->descriptor.bDeviceSubClass))
+			continue;
+
+		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
+		    (id->bDeviceProtocol != usb_dev->descriptor.bDeviceProtocol))
+			continue;
 
-	return usb_find_interface_driver(dev, ifpos);
+		if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
+		    (id->bInterfaceClass != desc->bInterfaceClass))
+			continue;
+
+		if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
+		    (id->bInterfaceSubClass != desc->bInterfaceSubClass))
+		    continue;
+
+		if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
+		    (id->bInterfaceProtocol != desc->bInterfaceProtocol))
+		    continue;
+
+		return 1;
+	}
+	return 0;
 }
 
+
 #ifdef	CONFIG_HOTPLUG
 
 /*
@@ -886,51 +764,6 @@
 
 #endif	/* CONFIG_HOTPLUG */
 
-
-/*
- * 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;
-
-	for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) {
-		struct usb_interface *interface = &dev->actconfig->interface[ifnum];
-		
-		/* register this interface with driverfs */
-		interface->dev.parent = &dev->dev;
-		interface->dev.bus = &usb_bus_type;
-		sprintf (&interface->dev.bus_id[0], "%03d%03d", dev->devnum,ifnum);
-		sprintf (&interface->dev.name[0], "figure out some name...");
-		device_register (&interface->dev);
-
-		/* if this interface hasn't already been claimed */
-		if (!usb_interface_claimed(interface)) {
-			if (usb_find_interface_driver(dev, ifnum))
-				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
@@ -1034,7 +867,6 @@
 
 /*-------------------------------------------------------------------*/
 
-
 /* for returning string descriptors in UTF-16LE */
 static int ascii2utf (char *ascii, __u8 *utf, int utfmax)
 {
@@ -1171,7 +1003,6 @@
 	if (dev->devnum > 0) {
 		clear_bit(dev->devnum, dev->bus->devmap.devicemap);
 		usbfs_remove_device(dev);
-		put_device(&dev->dev);
 	}
 
 	/* Decrement the reference count, it'll auto free everything when */
@@ -1220,21 +1051,6 @@
 }
 
 /*
- * These are the actual routines to send
- * and receive control messages.
- */
-
-// hub-only!! ... and only exported for reset/reinit path.
-// otherwise used internally, for usb_new_device()
-int usb_set_address(struct usb_device *dev)
-{
-	return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS,
-		// FIXME USB_CTRL_SET_TIMEOUT
-		0, dev->devnum, 0, NULL, 0, HZ * USB_CTRL_GET_TIMEOUT);
-}
-
-
-/*
  * By the time we get here, the device has gotten a new device ID
  * and is in the default state. We need to identify the thing and
  * get the ball rolling..
@@ -1248,7 +1064,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;
@@ -1339,78 +1155,32 @@
 	if (dev->descriptor.iSerialNumber)
 		usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
 #endif
-
-	/* register this device in the driverfs tree */
-	err = device_register (&dev->dev);
-	if (err)
-		return err;
-
 	/* now that the basic setup is over, add a /proc/bus/usb entry */
 	usbfs_add_device(dev);
 
-	/* find drivers willing to handle this device */
-	usb_find_drivers(dev);
-
-	/* userspace may load modules and/or configure further */
-	call_policy ("add", dev);
-
-	return 0;
-}
-
-static int usb_open(struct inode * inode, struct file * file)
-{
-	int minor = minor(inode->i_rdev);
-	struct usb_driver *c;
-	int err = -ENODEV;
-	struct file_operations *old_fops, *new_fops = NULL;
-
-	spin_lock (&minor_lock);
-	c = usb_minors[minor];
-	spin_unlock (&minor_lock);
-
-	if (!c || !(new_fops = fops_get(c->fops)))
-		return err;
-	old_fops = file->f_op;
-	file->f_op = new_fops;
-	/* Curiouser and curiouser... NULL ->open() as "no device" ? */
-	if (file->f_op->open)
-		err = file->f_op->open(inode,file);
-	if (err) {
-		fops_put(file->f_op);
-		file->f_op = fops_get(old_fops);
-	}
-	fops_put(old_fops);
-	return err;
-}
-
-static struct file_operations usb_fops = {
-	owner:		THIS_MODULE,
-	open:		usb_open,
-};
+	for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) {
+		struct usb_interface *interface = &dev->actconfig->interface[ifnum];
+		int _err;
 
-int usb_major_init(void)
-{
-	if (devfs_register_chrdev(USB_MAJOR, "usb", &usb_fops)) {
-		err("unable to get major %d for usb devices", USB_MAJOR);
-		return -EBUSY;
+		/* register this interface with driverfs */
+		interface->usb_device = dev;
+		interface->dev.parent = parent;
+		interface->dev.bus = &usb_bus_type;
+		sprintf (interface->dev.bus_id, "%03d%03d", dev->devnum,ifnum);
+		sprintf (interface->dev.name, "figure out some name...");
+		device_register (&interface->dev);
 	}
 
-	usb_devfs_handle = devfs_mk_dir(NULL, "usb", NULL);
+	/* userspace may load modules and/or configure further */
+	call_policy ("add", dev);
 
 	return 0;
 }
 
-void usb_major_cleanup(void)
-{
-	devfs_unregister(usb_devfs_handle);
-	devfs_unregister_chrdev(USB_MAJOR, "usb");
-}
-
-
 #ifdef CONFIG_PROC_FS
 struct list_head *usb_driver_get_list(void)
 {
-	return &usb_driver_list;
+	return &usb_bus_type.drivers;
 }
 
 struct list_head *usb_bus_get_list(void)
@@ -1421,6 +1191,7 @@
 
 struct bus_type usb_bus_type = {
 	name:	"usb",
+	bind:	usb_device_bind,
 };
 
 /*
@@ -1429,10 +1200,7 @@
 static int __init usb_init(void)
 {
 	bus_register(&usb_bus_type);
-	usb_major_init();
 	usbfs_init();
-	usb_hub_init();
-
 	return 0;
 }
 
@@ -1441,10 +1209,7 @@
  */
 static void __exit usb_exit(void)
 {
-	put_bus(&usb_bus_type);
-	usb_major_cleanup();
 	usbfs_cleanup();
-	usb_hub_cleanup();
 }
 
 subsys_initcall(usb_init);
@@ -1461,7 +1226,6 @@
 
 EXPORT_SYMBOL(usb_register);
 EXPORT_SYMBOL(usb_deregister);
-EXPORT_SYMBOL(usb_scan_devices);
 
 #ifdef CONFIG_USB_DYNAMIC_MINORS
 EXPORT_SYMBOL(usb_register_dev);
@@ -1473,7 +1237,6 @@
 EXPORT_SYMBOL(usb_get_dev);
 EXPORT_SYMBOL(usb_hub_tt_clear_buffer);
 
-EXPORT_SYMBOL(usb_find_interface_driver_for_ifnum);
 EXPORT_SYMBOL(usb_driver_claim_interface);
 EXPORT_SYMBOL(usb_interface_claimed);
 EXPORT_SYMBOL(usb_driver_release_interface);
@@ -1489,5 +1252,4 @@
 
 EXPORT_SYMBOL(usb_get_current_frame_number);
 
-EXPORT_SYMBOL(usb_devfs_handle);
 MODULE_LICENSE("GPL");
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/hid-core.c linux-2.5-driverfs/drivers/usb/input/hid-core.c
--- ../linux-2.5/drivers/usb/input/hid-core.c	Thu May 23 16:06:21 2002
+++ linux-2.5-driverfs/drivers/usb/input/hid-core.c	Mon Jun  3 11:29:16 2002
@@ -1013,7 +1013,7 @@
 
 	hid_output_report(report, hid->outbuf);
 	hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1;
-	hid->urbout->dev = hid->dev;
+	hid->urbout->dev = hid->intf->usb_device;
 
 	dbg("submitting out urb");
 
@@ -1037,13 +1037,15 @@
 		hid_output_report(report, hid->ctrlbuf);
 
 	hid->urbctrl->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + ((report->id > 0) && (dir != USB_DIR_OUT));
-	hid->urbctrl->pipe = (dir == USB_DIR_OUT) ?  usb_sndctrlpipe(hid->dev, 0) : usb_rcvctrlpipe(hid->dev, 0);
-	hid->urbctrl->dev = hid->dev;
+	hid->urbctrl->pipe = (dir == USB_DIR_OUT) ?  
+		usb_sndctrlpipe(hid->intf->usb_device, 0) : 
+		usb_rcvctrlpipe(hid->intf->usb_device, 0);
+	hid->urbctrl->dev = hid->intf->usb_device;
 
 	hid->cr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
 	hid->cr.bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
 	hid->cr.wValue = ((report->type + 1) << 8) | report->id;
-	hid->cr.wIndex = cpu_to_le16(hid->ifnum);
+	hid->cr.wIndex = cpu_to_le16(hid->intf->ifnum);
 	hid->cr.wLength = cpu_to_le16(hid->urbctrl->transfer_buffer_length);
 
 	dbg("submitting ctrl urb");
@@ -1199,7 +1201,7 @@
 	if (hid->open++)
 		return 0;
 
-	hid->urbin->dev = hid->dev;
+	hid->urbin->dev = hid->intf->usb_device;
 
 	if (usb_submit_urb(hid->urbin, GFP_KERNEL))
 		return -EIO;
@@ -1252,9 +1254,9 @@
 		len = ((report->size - 1) >> 3) + 1 + report_enum->numbered;
 		if (len > hid->urbin->transfer_buffer_length)
 			hid->urbin->transfer_buffer_length = len < HID_BUFFER_SIZE ? len : HID_BUFFER_SIZE;
-		usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
+		usb_control_msg(hid->intf->usb_device, usb_sndctrlpipe(hid->intf->usb_device, 0),
 			0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id,
-			hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+			hid->intf->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
 		list = list->next;
 	}
 }
@@ -1293,9 +1295,10 @@
 	{ 0, 0 }
 };
 
-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 + 0;
+	struct usb_device * dev = intf->usb_device;
 	struct hid_descriptor *hdesc;
 	struct hid_device *hid;
 	unsigned quirks = 0, rsize = 0;
@@ -1385,8 +1388,11 @@
 
 	hid->version = hdesc->bcdHID;
 	hid->country = hdesc->bCountryCode;
+/*
 	hid->dev = dev;
 	hid->ifnum = interface->bInterfaceNumber;
+*/
+	hid->intf = intf;
 
 	hid->name[0] = 0;
 
@@ -1395,18 +1401,7 @@
 
 	if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) {
 		strcat(hid->name, buf);
-		if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0) {
-			n = snprintf(hid->name, sizeof(hid->name)-1, "%s %s", hid->name, buf);
-			hid->name[n] = 0;
-		}
-	} else {
-		n = snprintf(hid->name, sizeof(hid->name)-1, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
-		hid->name[n] = 0;
-	}
-
-	usb_make_path(dev, buf, 64);
-	n = snprintf(hid->phys, sizeof(hid->phys)-1, "%s/input%d", buf, ifnum);
-	hid->phys[n] = 0;
+	snprintf(hid->phys, 64, "%s/input%d", buf, intf->ifnum);
 
 	if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
 		hid->uniq[0] = 0;
@@ -1428,18 +1423,18 @@
 	return 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)
 {
+	struct usb_device * dev = intf->usb_device;
 	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 -ENODEV;
 
 	hid_init_reports(hid);
 	hid_dump_device(hid);
@@ -1451,7 +1446,7 @@
 
 	if (!hid->claimed) {
 		hid_free_device(hid);
-		return NULL;
+		return -ENODEV;
 	}
 
 	printk(KERN_INFO);
@@ -1475,12 +1470,14 @@
 	printk(": USB HID v%x.%02x %s [%s] on %s\n",
 		hid->version >> 8, hid->version & 0xff, c, hid->name, path);
 
-	return hid;
+	intf->dev.driver_data = hid;
+
+	return 0;
 }
 
-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;
 
 	dbg("cleanup called");
 	usb_unlink_urb(hid->urbin);
@@ -1509,15 +1506,25 @@
 
 static struct usb_driver hid_driver = {
 	name:		"hid",
-	probe:		hid_probe,
-	disconnect:	hid_disconnect,
 	id_table:	hid_usb_ids,
+	new_probe:	hid_probe,
+	new_disco:	hid_disconnect,
+
+#if 0
+	driver: {
+		name:		"hid",
+		id_table:	hid_usb_ids,
+		bus:		&usb_bus_type,
+		devclass:	&input_devclass,
+		probe:		hid_dev_probe,
+	},
+#endif
 };
 
 static int __init hid_init(void)
 {
 	hiddev_init();
-	usb_register(&hid_driver);
+	usb_driver_register(&hid_driver);
 	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/hid-input.c linux-2.5-driverfs/drivers/usb/input/hid-input.c
--- ../linux-2.5/drivers/usb/input/hid-input.c	Thu May 23 16:06:21 2002
+++ linux-2.5-driverfs/drivers/usb/input/hid-input.c	Mon Jun  3 11:29:16 2002
@@ -411,7 +411,7 @@
 
 int hidinput_connect(struct hid_device *hid)
 {
-	struct usb_device *dev = hid->dev;
+	struct usb_device *dev = hid->intf->usb_device;
 	struct hid_report_enum *report_enum;
 	struct hid_report *report;
 	struct list_head *list;
@@ -436,6 +436,7 @@
 	hid->input.idvendor = dev->descriptor.idVendor;
 	hid->input.idproduct = dev->descriptor.idProduct;
 	hid->input.idversion = dev->descriptor.bcdDevice;
+	hid->input.dev = &hid->intf->dev;
 
 	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
 		report_enum = hid->report_enum + k;
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/hid.h linux-2.5-driverfs/drivers/usb/input/hid.h
--- ../linux-2.5/drivers/usb/input/hid.h	Mon Jun  3 10:25:15 2002
+++ linux-2.5-driverfs/drivers/usb/input/hid.h	Mon Jun  3 11:29:16 2002
@@ -325,9 +325,11 @@
 	unsigned country;						/* HID country */
 	struct hid_report_enum report_enum[HID_REPORT_TYPES];
 
+	struct usb_interface * intf;
+#if 0
 	struct usb_device *dev;						/* USB device */
 	int ifnum;							/* USB interface number */
-
+#endif
 	unsigned long iofl;						/* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
 
 	struct urb *urbin;						/* Input URB */
diff -Naur -X ../dontdiff ../linux-2.5/drivers/usb/input/usbmouse.c linux-2.5-driverfs/drivers/usb/input/usbmouse.c
--- ../linux-2.5/drivers/usb/input/usbmouse.c	Thu May 23 16:06:21 2002
+++ linux-2.5-driverfs/drivers/usb/input/usbmouse.c	Mon Jun  3 11:29:16 2002
@@ -149,6 +149,7 @@
 	mouse->dev.idvendor = dev->descriptor.idVendor;
 	mouse->dev.idproduct = dev->descriptor.idProduct;
 	mouse->dev.idversion = dev->descriptor.bcdDevice;
+	mouse->dev.dev = &mouse->usbdev->dev;
 
 	if (!(buf = kmalloc(63, GFP_KERNEL))) {
 		kfree(mouse);
diff -Naur -X ../dontdiff ../linux-2.5/include/linux/usb.h linux-2.5-driverfs/include/linux/usb.h
--- ../linux-2.5/include/linux/usb.h	Mon Jun  3 12:03:57 2002
+++ linux-2.5-driverfs/include/linux/usb.h	Mon Jun  3 11:29:30 2002
@@ -248,11 +248,13 @@
 struct usb_interface {
 	struct usb_interface_descriptor *altsetting;
 
+	int ifnum;			/* interface number of  device */
 	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 usb_device *usb_device;	/* device this interface is on */
 	struct device dev;		/* interface specific device info */
 	void *private_data;
 };
@@ -394,8 +396,6 @@
 	struct usb_device *parent;	/* our hub, unless we're the root */
 	struct usb_bus *bus;		/* Bus we're part of */
 
-	struct device dev;		/* Generic device interface */
-
 	struct usb_device_descriptor descriptor;/* Descriptor */
 	struct usb_config_descriptor *config;	/* All of the configs */
 	struct usb_config_descriptor *actconfig;/* the active configuration */
@@ -683,6 +683,12 @@
 	struct module *owner;
 	const char *name;
 
+	int	(*new_probe)(struct usb_interface * intf);
+	int	(*init)(struct usb_interface * intf);
+	void	(*new_disco)(struct usb_interface * intf);
+
+	struct device_driver	driver;
+
 	void *(*probe)(
 	    struct usb_device *dev,		/* the device */
 	    unsigned intf,			/* what interface */
@@ -722,6 +728,10 @@
 extern int usb_register(struct usb_driver *);
 extern void usb_deregister(struct usb_driver *);
 
+/* new school */
+extern int usb_driver_register(struct usb_driver *);
+extern void usb_driver_unregister(struct usb_driver *);
+
 #ifndef CONFIG_USB_DYNAMIC_MINORS
 static inline int usb_register_dev(struct usb_driver *new_driver, int num_minors, int *start_minor) { return -ENODEV; }
 static inline void usb_deregister_dev(struct usb_driver *driver, int num_minors, int start_minor) {}
