# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.426   -> 1.427  
#	drivers/usb/usb-ohci.c	1.27    -> 1.28   
#	   drivers/usb/hcd.h	1.1     -> 1.2    
#	 include/linux/usb.h	1.21    -> 1.22   
#	drivers/usb/devices.c	1.6     -> 1.7    
#	drivers/usb/usb-uhci.c	1.28    -> 1.29   
#	   drivers/usb/usb.c	1.33    -> 1.34   
#	   drivers/usb/hcd.c	1.9     -> 1.10   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/02/27	david-b@packbell.net	1.427
# This is another USB API cleanup patch.  It's against 2.5.5:          
#   
#     - Moves 8 functions from usb.[hc] to hcd.[hc]
#     - Also moves some data structures and types
#     - Now usbdevfs and "old" HCDs #include "hcd.h"
#     - Minor tweaks to the "hcd" layer (one less FIXME)
#     - Minor kernel doc and comment cleanups
#   
# Basically this continues moving the HCD-only functionality
# out of the way of normal USB device drivers.  Converging
# "usb_bus" and "usb_hcd" (later!) will be a bit easier too.
# 
# I did basic sanity tests, there's little to break ... :)
#   
# There are still a few functions in usb.c that aren't for
# general driver use.  They're mostly for enumeration,
# in areas where the hub driver and HCD root hubs
# need to do various kinds of magic.  It wasn't clear
# how to decouple those, they can certainly wait.
# --------------------------------------------
#
diff -Nru a/drivers/usb/devices.c b/drivers/usb/devices.c
--- a/drivers/usb/devices.c	Wed Feb 27 15:44:31 2002
+++ b/drivers/usb/devices.c	Wed Feb 27 15:44:31 2002
@@ -4,8 +4,6 @@
  * (C) Copyright 1999,2000 Thomas Sailer <sailer@ife.ee.ethz.ch>. (proc file per device)
  * (C) Copyright 1999 Deti Fliegl (new USB architecture)
  *
- * $id$
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -61,6 +59,8 @@
 #include <linux/usbdevice_fs.h>
 #include <asm/uaccess.h>
 
+#include "hcd.h"
+
 #define MAX_TOPO_LEVEL		6
 
 /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */
@@ -429,6 +429,10 @@
 	 * count = device count at this level
 	 */
 	/* If this is the root hub, display the bandwidth information */
+	    /* FIXME high speed reserves 20% frametime for non-periodic,
+	     * while full/low speed reserves only 10% ... so this is wrong
+	     * for high speed busses.  also, change how bandwidth is recorded.
+	     */
 	if (level == 0)
 		data_end += sprintf(data_end, format_bandwidth, bus->bandwidth_allocated,
 				FRAME_TIME_MAX_USECS_ALLOC,
diff -Nru a/drivers/usb/hcd.c b/drivers/usb/hcd.c
--- a/drivers/usb/hcd.c	Wed Feb 27 15:44:31 2002
+++ b/drivers/usb/hcd.c	Wed Feb 27 15:44:31 2002
@@ -1,5 +1,11 @@
 /*
- * Copyright (c) 2001 by David Brownell
+ * (C) Copyright Linus Torvalds 1999
+ * (C) Copyright Johannes Erdfelt 1999-2001
+ * (C) Copyright Andreas Gal 1999
+ * (C) Copyright Gregory P. Smith 1999
+ * (C) Copyright Deti Fliegl 1999
+ * (C) Copyright Randy Dunlap 2000
+ * (C) Copyright David Brownell 2000-2002
  * 
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -33,9 +39,6 @@
 #include <linux/interrupt.h>
 #include <linux/uts.h>			/* for UTS_SYSNAME */
 
-#ifndef CONFIG_USB_DEBUG
-	#define CONFIG_USB_DEBUG	/* this is experimental! */
-#endif
 
 #ifdef CONFIG_USB_DEBUG
 	#define DEBUG
@@ -53,6 +56,8 @@
 #include <asm/byteorder.h>
 
 
+// #define USB_BANDWIDTH_MESSAGES
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -78,19 +83,28 @@
  * usb client device drivers.
  *
  * Contributors of ideas or unattributed patches include: David Brownell,
- * Roman Weissgaerber, Rory Bolt, ...
+ * Roman Weissgaerber, Rory Bolt, Greg Kroah-Hartman, ...
  *
  * HISTORY:
+ * 2002-02-21	Pull in most of the usb_bus support from usb.c; some
+ *		associated cleanup.  "usb_hcd" still != "usb_bus".
  * 2001-12-12	Initial patch version for Linux 2.5.1 kernel.
  */
 
 /*-------------------------------------------------------------------------*/
 
 /* host controllers we manage */
-static LIST_HEAD (hcd_list);
+LIST_HEAD (usb_bus_list);
+
+/* used when allocating bus numbers */
+#define USB_MAXBUS		64
+struct usb_busmap {
+	unsigned long busmap [USB_MAXBUS / (8*sizeof (unsigned long))];
+};
+static struct usb_busmap busmap;
 
 /* used when updating list of hcds */
-static DECLARE_MUTEX (hcd_list_lock);
+DECLARE_MUTEX (usb_bus_list_lock);	/* exported only for usbfs */
 
 /* used when updating hcd data */
 static spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED;
@@ -105,6 +119,9 @@
 
 /*-------------------------------------------------------------------------*/
 
+#define KERNEL_REL	((LINUX_VERSION_CODE >> 16) & 0x0ff)
+#define KERNEL_VER	((LINUX_VERSION_CODE >> 8) & 0x0ff)
+
 /* usb 2.0 root hub device descriptor */
 static const u8 usb2_rh_dev_descriptor [18] = {
 	0x12,       /*  __u8  bLength; */
@@ -118,7 +135,7 @@
 
 	0x00, 0x00, /*  __u16 idVendor; */
  	0x00, 0x00, /*  __u16 idProduct; */
- 	0x40, 0x02, /*  __u16 bcdDevice; (v2.4) */
+	KERNEL_VER, KERNEL_REL, /*  __u16 bcdDevice */
 
 	0x03,       /*  __u8  iManufacturer; */
 	0x02,       /*  __u8  iProduct; */
@@ -141,7 +158,7 @@
 
 	0x00, 0x00, /*  __u16 idVendor; */
  	0x00, 0x00, /*  __u16 idProduct; */
- 	0x40, 0x02, /*  __u16 bcdDevice; (v2.4) */
+	KERNEL_VER, KERNEL_REL, /*  __u16 bcdDevice */
 
 	0x03,       /*  __u8  iManufacturer; */
 	0x02,       /*  __u8  iProduct; */
@@ -506,6 +523,346 @@
 
 /*-------------------------------------------------------------------------*/
 
+/* exported only within usbcore */
+void usb_bus_get (struct usb_bus *bus)
+{
+	atomic_inc (&bus->refcnt);
+}
+
+/* exported only within usbcore */
+void usb_bus_put (struct usb_bus *bus)
+{
+	if (atomic_dec_and_test (&bus->refcnt))
+		kfree (bus);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* shared initialization code */
+static void usb_init_bus (struct usb_bus *bus)
+{
+	memset (&bus->devmap, 0, sizeof(struct usb_devmap));
+
+#ifdef DEVNUM_ROUND_ROBIN
+	bus->devnum_next = 1;
+#endif /* DEVNUM_ROUND_ROBIN */
+
+	bus->root_hub = NULL;
+	bus->hcpriv = NULL;
+	bus->busnum = -1;
+	bus->bandwidth_allocated = 0;
+	bus->bandwidth_int_reqs  = 0;
+	bus->bandwidth_isoc_reqs = 0;
+
+	INIT_LIST_HEAD (&bus->bus_list);
+
+	atomic_set (&bus->refcnt, 1);
+}
+
+/**
+ * usb_alloc_bus - creates a new USB host controller structure
+ * @op: pointer to a struct usb_operations that this bus structure should use
+ * Context: !in_interrupt()
+ *
+ * Creates a USB host controller bus structure with the specified 
+ * usb_operations and initializes all the necessary internal objects.
+ *
+ * If no memory is available, NULL is returned.
+ *
+ * The caller should call usb_free_bus() when it is finished with the structure.
+ */
+struct usb_bus *usb_alloc_bus (struct usb_operations *op)
+{
+	struct usb_bus *bus;
+
+	bus = kmalloc (sizeof *bus, GFP_KERNEL);
+	if (!bus)
+		return NULL;
+	usb_init_bus (bus);
+	bus->op = op;
+	return bus;
+}
+EXPORT_SYMBOL (usb_alloc_bus);
+
+/**
+ * usb_free_bus - frees the memory used by a bus structure
+ * @bus: pointer to the bus to free
+ *
+ * To be invoked by a HCD, only as the last step of decoupling from
+ * hardware.  It is an error to call this if the reference count is
+ * anything but one.  That would indicate that some system component
+ * did not correctly shut down, and thought the hardware was still
+ * accessible.
+ */
+void usb_free_bus (struct usb_bus *bus)
+{
+	if (!bus)
+		return;
+	if (atomic_read (&bus->refcnt) != 1)
+		err ("usb_free_bus #%d, count != 1", bus->busnum);
+	usb_bus_put (bus);
+}
+EXPORT_SYMBOL (usb_free_bus);
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * usb_register_bus - registers the USB host controller with the usb core
+ * @bus: pointer to the bus to register
+ * Context: !in_interrupt()
+ *
+ * Assigns a bus number, and links the controller into usbcore data
+ * structures so that it can be seen by scanning the bus list.
+ */
+void usb_register_bus(struct usb_bus *bus)
+{
+	int busnum;
+
+	down (&usb_bus_list_lock);
+	busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1);
+	if (busnum < USB_MAXBUS) {
+		set_bit (busnum, busmap.busmap);
+		bus->busnum = busnum;
+	} else
+		warn ("too many buses");
+
+	usb_bus_get (bus);
+
+	/* Add it to the list of buses */
+	list_add (&bus->bus_list, &usb_bus_list);
+	up (&usb_bus_list_lock);
+
+	usbfs_add_bus (bus);
+
+	info ("new USB bus registered, assigned bus number %d", bus->busnum);
+}
+EXPORT_SYMBOL (usb_register_bus);
+
+/**
+ * usb_deregister_bus - deregisters the USB host controller
+ * @bus: pointer to the bus to deregister
+ * Context: !in_interrupt()
+ *
+ * Recycles the bus number, and unlinks the controller from usbcore data
+ * structures so that it won't be seen by scanning the bus list.
+ */
+void usb_deregister_bus (struct usb_bus *bus)
+{
+	info ("USB bus %d deregistered", bus->busnum);
+
+	/*
+	 * NOTE: make sure that all the devices are removed by the
+	 * controller code, as well as having it call this when cleaning
+	 * itself up
+	 */
+	down (&usb_bus_list_lock);
+	list_del (&bus->bus_list);
+	up (&usb_bus_list_lock);
+
+	usbfs_remove_bus (bus);
+
+	clear_bit (bus->busnum, busmap.busmap);
+
+	usb_bus_put (bus);
+}
+EXPORT_SYMBOL (usb_deregister_bus);
+
+/**
+ * usb_register_root_hub - called by HCD to register its root hub 
+ * @usb_dev: the usb root hub device to be registered.
+ * @parent_dev: the parent device of this root hub.
+ *
+ * The USB host controller calls this function to register the root hub
+ * properly with the USB subsystem.  It sets up the device properly in
+ * the driverfs tree, and then calls usb_new_device() to register the
+ * usb device.
+ */
+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;
+}
+EXPORT_SYMBOL (usb_register_root_hub);
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * usb_calc_bus_time:
+ * Returns approximate bus time in nanoseconds for a periodic transaction.
+ * See USB 2.0 spec section 5.11.3
+ */
+static long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount)
+{
+	unsigned long	tmp;
+
+	switch (speed) {
+	case USB_SPEED_LOW: 	/* INTR only */
+		if (is_input) {
+			tmp = (67667L * (31L + 10L * BitTime (bytecount))) / 1000L;
+			return (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
+		} else {
+			tmp = (66700L * (31L + 10L * BitTime (bytecount))) / 1000L;
+			return (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
+		}
+	case USB_SPEED_FULL:	/* ISOC or INTR */
+		if (isoc) {
+			tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
+			return (((is_input) ? 7268L : 6265L) + BW_HOST_DELAY + tmp);
+		} else {
+			tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
+			return (9107L + BW_HOST_DELAY + tmp);
+		}
+	case USB_SPEED_HIGH:	/* ISOC or INTR */
+		// FIXME merge from EHCI code; caller will need to handle
+		// each part of a split separately.
+		return 0;
+	default:
+		dbg ("bogus device speed!");
+		return -1;
+	}
+}
+
+/*
+ * usb_check_bandwidth():
+ *
+ * old_alloc is from host_controller->bandwidth_allocated in microseconds;
+ * bustime is from calc_bus_time(), but converted to microseconds.
+ *
+ * returns <bustime in us> if successful,
+ * or -ENOSPC if bandwidth request fails.
+ *
+ * FIXME:
+ * This initial implementation does not use Endpoint.bInterval
+ * in managing bandwidth allocation.
+ * It probably needs to be expanded to use Endpoint.bInterval.
+ * This can be done as a later enhancement (correction).
+ *
+ * This will also probably require some kind of
+ * frame allocation tracking...meaning, for example,
+ * that if multiple drivers request interrupts every 10 USB frames,
+ * they don't all have to be allocated at
+ * frame numbers N, N+10, N+20, etc.  Some of them could be at
+ * N+11, N+21, N+31, etc., and others at
+ * N+12, N+22, N+32, etc.
+ *
+ * Similarly for isochronous transfers...
+ *
+ * Individual HCDs can schedule more directly ... this logic
+ * is not correct for high speed transfers.
+ */
+int usb_check_bandwidth (struct usb_device *dev, struct urb *urb)
+{
+	unsigned int	pipe = urb->pipe;
+	long		bustime;
+	int		is_in = usb_pipein (pipe);
+	int		is_iso = usb_pipeisoc (pipe);
+	int		old_alloc = dev->bus->bandwidth_allocated;
+	int		new_alloc;
+
+
+	bustime = NS_TO_US (usb_calc_bus_time (dev->speed, is_in, is_iso,
+			usb_maxpacket (dev, pipe, !is_in)));
+	if (is_iso)
+		bustime /= urb->number_of_packets;
+
+	new_alloc = old_alloc + (int) bustime;
+	if (new_alloc > FRAME_TIME_MAX_USECS_ALLOC) {
+#ifdef	DEBUG
+		char	*mode = 
+#ifdef CONFIG_USB_BANDWIDTH
+			"";
+#else
+			"would have ";
+#endif
+		dbg ("usb_check_bandwidth %sFAILED: %d + %ld = %d usec",
+			mode, old_alloc, bustime, new_alloc);
+#endif
+#ifdef CONFIG_USB_BANDWIDTH
+		bustime = -ENOSPC;	/* report error */
+#endif
+	}
+
+	return bustime;
+}
+EXPORT_SYMBOL (usb_check_bandwidth);
+
+
+/**
+ * usb_claim_bandwidth - records bandwidth for a periodic transfer
+ * @dev: source/target of request
+ * @urb: request (urb->dev == dev)
+ * @bustime: bandwidth consumed, in (average) microseconds per frame
+ * @isoc: true iff the request is isochronous
+ *
+ * Bus bandwidth reservations are recorded purely for diagnostic purposes.
+ * HCDs are expected not to overcommit periodic bandwidth, and to record such
+ * reservations whenever endpoints are added to the periodic schedule.
+ *
+ * FIXME averaging per-frame is suboptimal.  Better to sum over the HCD's
+ * entire periodic schedule ... 32 frames for OHCI, 1024 for UHCI, settable
+ * for EHCI (256/512/1024 frames, default 1024) and have the bus expose how
+ * large its periodic schedule is.
+ */
+void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc)
+{
+	dev->bus->bandwidth_allocated += bustime;
+	if (isoc)
+		dev->bus->bandwidth_isoc_reqs++;
+	else
+		dev->bus->bandwidth_int_reqs++;
+	urb->bandwidth = bustime;
+
+#ifdef USB_BANDWIDTH_MESSAGES
+	dbg ("bandwidth alloc increased by %d (%s) to %d for %d requesters",
+		bustime,
+		isoc ? "ISOC" : "INTR",
+		dev->bus->bandwidth_allocated,
+		dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs);
+#endif
+}
+EXPORT_SYMBOL (usb_claim_bandwidth);
+
+
+/**
+ * usb_release_bandwidth - reverses effect of usb_claim_bandwidth()
+ * @dev: source/target of request
+ * @urb: request (urb->dev == dev)
+ * @isoc: true iff the request is isochronous
+ *
+ * This records that previously allocated bandwidth has been released.
+ * Bandwidth is released when endpoints are removed from the host controller's
+ * periodic schedule.
+ */
+void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, int isoc)
+{
+	dev->bus->bandwidth_allocated -= urb->bandwidth;
+	if (isoc)
+		dev->bus->bandwidth_isoc_reqs--;
+	else
+		dev->bus->bandwidth_int_reqs--;
+
+#ifdef USB_BANDWIDTH_MESSAGES
+	dbg ("bandwidth alloc reduced by %d (%s) to %d for %d requesters",
+		urb->bandwidth,
+		isoc ? "ISOC" : "INTR",
+		dev->bus->bandwidth_allocated,
+		dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs);
+#endif
+	urb->bandwidth = 0;
+}
+EXPORT_SYMBOL (usb_release_bandwidth);
+
+
+/*-------------------------------------------------------------------------*/
+
 #ifdef CONFIG_PCI
 
 /* PCI-based HCs are normal, but custom bus glue should be ok */
@@ -522,6 +879,7 @@
  * usb_hcd_pci_probe - initialize PCI-based HCDs
  * @dev: USB Host Controller being probed
  * @id: pci hotplug id connecting controller to HCD framework
+ * Context: !in_interrupt()
  *
  * Allocates basic PCI resources for this USB host controller, and
  * then invokes the start() method for the HCD associated with it
@@ -535,7 +893,6 @@
 	unsigned long		resource, len;
 	void			*base;
 	u8			latency, limit;
-	struct usb_bus		*bus;
 	struct usb_hcd		*hcd;
 	int			retval, region;
 	char			buf [8], *bufp = buf;
@@ -631,7 +988,6 @@
 			!= 0) {
 		err ("request interrupt %s failed", bufp);
 		retval = -EBUSY;
-clean_3:
 		driver->hcd_free (hcd);
 		goto clean_2;
 	}
@@ -643,26 +999,15 @@
 		(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
 		base);
 
-// FIXME simpler: make "bus" be that data, not pointer to it.
-	bus = usb_alloc_bus (&hcd_operations);
-	if (bus == NULL) {
-		dbg ("usb_alloc_bus fail");
-		retval = -ENOMEM;
-		free_irq (dev->irq, hcd);
-		goto clean_3;
-	}
-	hcd->bus = bus;
+	usb_init_bus (&hcd->self);
+	hcd->self.op = &hcd_operations;
+	hcd->self.hcpriv = (void *) hcd;
+	hcd->bus = &hcd->self;
 	hcd->bus_name = dev->slot_name;
-	bus->hcpriv = (void *) hcd;
 
 	INIT_LIST_HEAD (&hcd->dev_list);
-	INIT_LIST_HEAD (&hcd->hcd_list);
 
-	down (&hcd_list_lock);
-	list_add (&hcd->hcd_list, &hcd_list);
-	up (&hcd_list_lock);
-
-	usb_register_bus (bus);
+	usb_register_bus (&hcd->self);
 
 	if ((retval = driver->start (hcd)) < 0)
 		usb_hcd_pci_remove (dev);
@@ -678,6 +1023,7 @@
 /**
  * usb_hcd_pci_remove - shutdown processing for PCI-based HCDs
  * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
  *
  * Reverses the effect of usb_hcd_pci_probe(), first invoking
  * the HCD's stop() method.  It is always called from a thread
@@ -717,12 +1063,9 @@
 			pci_resource_len (dev, hcd->region));
 	}
 
-	down (&hcd_list_lock);
-	list_del (&hcd->hcd_list);
-	up (&hcd_list_lock);
-
 	usb_deregister_bus (hcd->bus);
-	usb_free_bus (hcd->bus);
+	if (atomic_read (&hcd->self.refcnt) != 1)
+		err ("usb_hcd_pci_remove %s, count != 1", hcd->bus_name);
 	hcd->bus = NULL;
 
 	hcd->driver->hcd_free (hcd);
@@ -1257,6 +1600,7 @@
  * usb_hcd_giveback_urb - return URB from HCD to device driver
  * @hcd: host controller returning the URB
  * @urb: urb being returned to the USB device driver.
+ * Context: in_interrupt()
  *
  * This hands the URB from HCD to its USB device driver, using its
  * completion function.  The HCD has freed all per-urb resources
@@ -1279,16 +1623,9 @@
 	struct usb_device	*dev;
 
 	/* Release periodic transfer bandwidth */
-	if (urb->bandwidth) {
-		switch (usb_pipetype (urb->pipe)) {
-		case PIPE_INTERRUPT:
-			usb_release_bandwidth (urb->dev, urb, 0);
-			break;
-		case PIPE_ISOCHRONOUS:
-			usb_release_bandwidth (urb->dev, urb, 1);
-			break;
-		}
-	}
+	if (urb->bandwidth)
+		usb_release_bandwidth (urb->dev, urb,
+			usb_pipeisoc (urb->pipe));
 
 	/* clear all state linking urb to this dev (and hcd) */
 
diff -Nru a/drivers/usb/hcd.h b/drivers/usb/hcd.h
--- a/drivers/usb/hcd.h	Wed Feb 27 15:44:31 2002
+++ b/drivers/usb/hcd.h	Wed Feb 27 15:44:31 2002
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2001 by David Brownell
- * 
+ * Copyright (c) 2001-2002 by David Brownell
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
  * Free Software Foundation; either version 2 of the License, or (at your
@@ -17,6 +17,8 @@
  */
 
 
+#ifdef __KERNEL__
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -33,8 +35,8 @@
 	/*
 	 * housekeeping
 	 */
-	struct usb_bus		*bus;		/* hcd is-a bus */
-	struct list_head	hcd_list;
+	struct usb_bus		*bus;		/* FIXME only use "self" */
+	struct usb_bus		self;		/* hcd is-a bus */
 
 	const char		*bus_name;
 
@@ -98,6 +100,19 @@
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * FIXME usb_operations should vanish or become hc_driver,
+ * when usb_bus and usb_hcd become the same thing.
+ */
+
+struct usb_operations {
+	int (*allocate)(struct usb_device *);
+	int (*deallocate)(struct usb_device *);
+	int (*get_frame_number) (struct usb_device *usb_dev);
+	int (*submit_urb) (struct urb *urb, int mem_flags);
+	int (*unlink_urb) (struct urb *urb);
+};
+
 /* each driver provides one of these, and hardware init support */
 
 struct hc_driver {
@@ -126,8 +141,6 @@
 	/* return current frame number */
 	int	(*get_frame_number) (struct usb_hcd *hcd);
 
-// FIXME: rework generic-to-specific HCD linkage (specific contains generic)
-
 	/* memory lifecycle */
 	struct usb_hcd	*(*hcd_alloc) (void);
 	void		(*hcd_free) (struct usb_hcd *hcd);
@@ -152,7 +165,8 @@
 extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb);
 
 #ifdef CONFIG_PCI
-
+struct pci_dev;
+struct pci_device_id;
 extern int usb_hcd_pci_probe (struct pci_dev *dev,
 				const struct pci_device_id *id);
 extern void usb_hcd_pci_remove (struct pci_dev *dev);
@@ -206,6 +220,59 @@
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * Generic bandwidth allocation constants/support
+ */
+#define FRAME_TIME_USECS	1000L
+#define BitTime(bytecount)  (7 * 8 * bytecount / 6)  /* with integer truncation */
+		/* Trying not to use worst-case bit-stuffing
+                   of (7/6 * 8 * bytecount) = 9.33 * bytecount */
+		/* bytecount = data payload byte count */
+
+#define NS_TO_US(ns)	((ns + 500L) / 1000L)
+			/* convert & round nanoseconds to microseconds */
+
+extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb,
+		int bustime, int isoc);
+extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb,
+		int isoc);
+
+/*
+ * Full/low speed bandwidth allocation constants/support.
+ */
+#define BW_HOST_DELAY	1000L		/* nanoseconds */
+#define BW_HUB_LS_SETUP	333L		/* nanoseconds */
+                        /* 4 full-speed bit times (est.) */
+
+#define FRAME_TIME_BITS         12000L		/* frame = 1 millisecond */
+#define FRAME_TIME_MAX_BITS_ALLOC	(90L * FRAME_TIME_BITS / 100L)
+#define FRAME_TIME_MAX_USECS_ALLOC	(90L * FRAME_TIME_USECS / 100L)
+
+extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
+
+/*-------------------------------------------------------------------------*/
+
+extern struct usb_bus *usb_alloc_bus (struct usb_operations *);
+extern void usb_free_bus (struct usb_bus *);
+
+extern void usb_register_bus (struct usb_bus *);
+extern void usb_deregister_bus (struct usb_bus *);
+
+extern int usb_register_root_hub (struct usb_device *usb_dev,
+		struct device *parent_dev);
+
+/*-------------------------------------------------------------------------*/
+
+/* exported only within usbcore */
+
+extern struct list_head usb_bus_list;
+extern struct semaphore usb_bus_list_lock;
+
+extern void usb_bus_get (struct usb_bus *bus);
+extern void usb_bus_put (struct usb_bus *bus);
+
+/*-------------------------------------------------------------------------*/
+
 /* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
 // bleech -- resurfaced in 2.4.11 or 2.4.12
 #define bitmap 	DeviceRemovable
@@ -217,3 +284,7 @@
 
 #define	RUN_CONTEXT (in_irq () ? "in_irq" \
 		: (in_interrupt () ? "in_interrupt" : "can sleep"))
+
+
+#endif /* __KERNEL__ */
+
diff -Nru a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c
--- a/drivers/usb/usb-ohci.c	Wed Feb 27 15:44:31 2002
+++ b/drivers/usb/usb-ohci.c	Wed Feb 27 15:44:31 2002
@@ -73,6 +73,7 @@
 #define OHCI_USE_NPS		// force NoPowerSwitching mode
 // #define OHCI_VERBOSE_DEBUG	/* not always helpful */
 
+#include "hcd.h"
 #include "usb-ohci.h"
 
 
diff -Nru a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c
--- a/drivers/usb/usb-uhci.c	Wed Feb 27 15:44:31 2002
+++ b/drivers/usb/usb-uhci.c	Wed Feb 27 15:44:31 2002
@@ -57,6 +57,7 @@
 #define VERSTR "$Revision: 1.275 $ time " __TIME__ " " __DATE__
 
 #include <linux/usb.h>
+#include "hcd.h"
 #include "usb-uhci.h"
 #include "usb-uhci-debug.h"
 
diff -Nru a/drivers/usb/usb.c b/drivers/usb/usb.c
--- a/drivers/usb/usb.c	Wed Feb 27 15:44:31 2002
+++ b/drivers/usb/usb.c	Wed Feb 27 15:44:31 2002
@@ -40,12 +40,7 @@
 #endif
 #include <linux/usb.h>
 
-static const int usb_bandwidth_option =
-#ifdef CONFIG_USB_BANDWIDTH
-				1;
-#else
-				0;
-#endif
+#include "hcd.h"
 
 extern int  usb_hub_init(void);
 extern void usb_hub_cleanup(void);
@@ -61,13 +56,9 @@
  * We have a per-interface "registered driver" list.
  */
 LIST_HEAD(usb_driver_list);
-LIST_HEAD(usb_bus_list);
-struct semaphore usb_bus_list_lock;
 
 devfs_handle_t usb_devfs_handle;	/* /dev/usb dir. */
 
-static struct usb_busmap busmap;
-
 static struct usb_driver *usb_minors[16];
 
 /**
@@ -105,6 +96,7 @@
 
 /**
  *	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.
@@ -173,6 +165,7 @@
 /**
  *	usb_deregister - unregister a USB driver
  *	@driver: USB operations of the driver to unregister
+ *	Context: !in_interrupt ()
  *
  *	Unlinks the specified driver from the internal USB driver list.
  */
@@ -258,259 +251,6 @@
 }
 
 /*
- * usb_calc_bus_time:
- *
- * returns (approximate) USB bus time in nanoseconds for a USB transaction.
- */
-static long usb_calc_bus_time (int low_speed, int input_dir, int isoc, int bytecount)
-{
-	unsigned long	tmp;
-
-	if (low_speed)		/* no isoc. here */
-	{
-		if (input_dir)
-		{
-			tmp = (67667L * (31L + 10L * BitTime (bytecount))) / 1000L;
-			return (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
-		}
-		else
-		{
-			tmp = (66700L * (31L + 10L * BitTime (bytecount))) / 1000L;
-			return (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
-		}
-	}
-
-	/* for full-speed: */
-
-	if (!isoc)		/* Input or Output */
-	{
-		tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
-		return (9107L + BW_HOST_DELAY + tmp);
-	} /* end not Isoc */
-
-	/* for isoc: */
-
-	tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
-	return (((input_dir) ? 7268L : 6265L) + BW_HOST_DELAY + tmp);
-}
-
-/*
- * usb_check_bandwidth():
- *
- * old_alloc is from host_controller->bandwidth_allocated in microseconds;
- * bustime is from calc_bus_time(), but converted to microseconds.
- *
- * returns <bustime in us> if successful,
- * or -ENOSPC if bandwidth request fails.
- *
- * FIXME:
- * This initial implementation does not use Endpoint.bInterval
- * in managing bandwidth allocation.
- * It probably needs to be expanded to use Endpoint.bInterval.
- * This can be done as a later enhancement (correction).
- * This will also probably require some kind of
- * frame allocation tracking...meaning, for example,
- * that if multiple drivers request interrupts every 10 USB frames,
- * they don't all have to be allocated at
- * frame numbers N, N+10, N+20, etc.  Some of them could be at
- * N+11, N+21, N+31, etc., and others at
- * N+12, N+22, N+32, etc.
- * However, this first cut at USB bandwidth allocation does not
- * contain any frame allocation tracking.
- */
-int usb_check_bandwidth (struct usb_device *dev, struct urb *urb)
-{
-	int		new_alloc;
-	int		old_alloc = dev->bus->bandwidth_allocated;
-	unsigned int	pipe = urb->pipe;
-	long		bustime;
-
-	bustime = usb_calc_bus_time (dev->speed == USB_SPEED_LOW,
-			usb_pipein(pipe), usb_pipeisoc(pipe),
-			usb_maxpacket(dev, pipe, usb_pipeout(pipe)));
-	if (usb_pipeisoc(pipe))
-		bustime = NS_TO_US(bustime) / urb->number_of_packets;
-	else
-		bustime = NS_TO_US(bustime);
-
-	new_alloc = old_alloc + (int)bustime;
-		/* what new total allocated bus time would be */
-
-	if (new_alloc > FRAME_TIME_MAX_USECS_ALLOC)
-		dbg("usb-check-bandwidth %sFAILED: was %u, would be %u, bustime = %ld us",
-			usb_bandwidth_option ? "" : "would have ",
-			old_alloc, new_alloc, bustime);
-
-	if (!usb_bandwidth_option)	/* don't enforce it */
-		return (bustime);
-	return (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ? bustime : -ENOSPC;
-}
-
-void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc)
-{
-	dev->bus->bandwidth_allocated += bustime;
-	if (isoc)
-		dev->bus->bandwidth_isoc_reqs++;
-	else
-		dev->bus->bandwidth_int_reqs++;
-	urb->bandwidth = bustime;
-
-#ifdef USB_BANDWIDTH_MESSAGES
-	dbg("bandwidth alloc increased by %d to %d for %d requesters",
-		bustime,
-		dev->bus->bandwidth_allocated,
-		dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs);
-#endif
-}
-
-/*
- * usb_release_bandwidth():
- *
- * called to release a pipe's bandwidth (in microseconds)
- */
-void usb_release_bandwidth(struct usb_device *dev, struct urb *urb, int isoc)
-{
-	dev->bus->bandwidth_allocated -= urb->bandwidth;
-	if (isoc)
-		dev->bus->bandwidth_isoc_reqs--;
-	else
-		dev->bus->bandwidth_int_reqs--;
-
-#ifdef USB_BANDWIDTH_MESSAGES
-	dbg("bandwidth alloc reduced by %d to %d for %d requesters",
-		urb->bandwidth,
-		dev->bus->bandwidth_allocated,
-		dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs);
-#endif
-	urb->bandwidth = 0;
-}
-
-static void usb_bus_get(struct usb_bus *bus)
-{
-	atomic_inc(&bus->refcnt);
-}
-
-static void usb_bus_put(struct usb_bus *bus)
-{
-	if (atomic_dec_and_test(&bus->refcnt))
-		kfree(bus);
-}
-
-/**
- *	usb_alloc_bus - creates a new USB host controller structure (usbcore-internal)
- *	@op: pointer to a struct usb_operations that this bus structure should use
- *
- *	Creates a USB host controller bus structure with the specified 
- *	usb_operations and initializes all the necessary internal objects.
- *	(For use only by USB Host Controller Drivers.)
- *
- *	If no memory is available, NULL is returned.
- *
- *	The caller should call usb_free_bus() when it is finished with the structure.
- */
-struct usb_bus *usb_alloc_bus(struct usb_operations *op)
-{
-	struct usb_bus *bus;
-
-	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
-	if (!bus)
-		return NULL;
-
-	memset(&bus->devmap, 0, sizeof(struct usb_devmap));
-
-#ifdef DEVNUM_ROUND_ROBIN
-	bus->devnum_next = 1;
-#endif /* DEVNUM_ROUND_ROBIN */
-
-	bus->op = op;
-	bus->root_hub = NULL;
-	bus->hcpriv = NULL;
-	bus->busnum = -1;
-	bus->bandwidth_allocated = 0;
-	bus->bandwidth_int_reqs  = 0;
-	bus->bandwidth_isoc_reqs = 0;
-
-	INIT_LIST_HEAD(&bus->bus_list);
-
-	atomic_set(&bus->refcnt, 1);
-
-	return bus;
-}
-
-/**
- *	usb_free_bus - frees the memory used by a bus structure (usbcore-internal)
- *	@bus: pointer to the bus to free
- *
- *	(For use only by USB Host Controller Drivers.)
- */
-void usb_free_bus(struct usb_bus *bus)
-{
-	if (!bus)
-		return;
-
-	usb_bus_put(bus);
-}
-
-/**
- *	usb_register_bus - registers the USB host controller with the usb core (usbcore-internal)
- *	@bus: pointer to the bus to register
- *
- *	(For use only by USB Host Controller Drivers.)
- *
- * This call is synchronous, and may not be used in an interrupt context.
- */
-void usb_register_bus(struct usb_bus *bus)
-{
-	int busnum;
-
-	down (&usb_bus_list_lock);
-	busnum = find_next_zero_bit(busmap.busmap, USB_MAXBUS, 1);
-	if (busnum < USB_MAXBUS) {
-		set_bit(busnum, busmap.busmap);
-		bus->busnum = busnum;
-	} else
-		warn("too many buses");
-
-	usb_bus_get(bus);
-
-	/* Add it to the list of buses */
-	list_add(&bus->bus_list, &usb_bus_list);
-	up (&usb_bus_list_lock);
-
-	usbfs_add_bus(bus);
-
-	info("new USB bus registered, assigned bus number %d", bus->busnum);
-}
-
-/**
- *	usb_deregister_bus - deregisters the USB host controller (usbcore-internal)
- *	@bus: pointer to the bus to deregister
- *
- *	(For use only by USB Host Controller Drivers.)
- *
- * This call is synchronous, and may not be used in an interrupt context.
- */
-void usb_deregister_bus(struct usb_bus *bus)
-{
-	info("USB bus %d deregistered", bus->busnum);
-
-	/*
-	 * NOTE: make sure that all the devices are removed by the
-	 * controller code, as well as having it call this when cleaning
-	 * itself up
-	 */
-	down (&usb_bus_list_lock);
-	list_del(&bus->bus_list);
-	up (&usb_bus_list_lock);
-
-	usbfs_remove_bus(bus);
-
-	clear_bit(bus->busnum, busmap.busmap);
-
-	usb_bus_put(bus);
-}
-
-/*
  * This function is for doing a depth-first search for devices which
  * have support, for dynamic loading of driver modules.
  */
@@ -1016,6 +756,7 @@
  * usb_alloc_dev - allocate a usb device structure (usbcore-internal)
  * @parent: hub to which device is connected
  * @bus: bus used to access the device
+ * Context: !in_interrupt ()
  *
  * Only hub drivers (including virtual root hub drivers for host
  * controllers) should ever call this.
@@ -1078,14 +819,12 @@
 	atomic_inc(&dev->refcnt);
 }
 
-/* ---------------------------------------------------------------------- 
- * New USB Core Functions
- * ----------------------------------------------------------------------*/
 
 /**
  * usb_alloc_urb - creates a new urb for a USB driver to use
  * @iso_packets: number of iso packets for this urb
- * @mem_flags: the type of memory to allocate, see kmalloc() for a list of valid options for this.
+ * @mem_flags: the type of memory to allocate, see kmalloc() for a list of
+ *	valid options for this.
  *
  * Creates an urb for the USB driver to use, initializes a few internal
  * structures, incrementes the usage counter, and returns a pointer to it.
@@ -1129,8 +868,10 @@
 void usb_free_urb(struct urb *urb)
 {
 	if (urb)
-		if (atomic_dec_and_test(&urb->count))
+		if (atomic_dec_and_test(&urb->count)) {
+			info ("really freeing urb");
 			kfree(urb);
+		}
 }
 
 /**
@@ -1158,7 +899,8 @@
 /**
  * usb_submit_urb - asynchronously issue a transfer request for an endpoint
  * @urb: pointer to the urb describing the request
- * @mem_flags: the type of memory to allocate, see kmalloc() for a list of valid options for this.
+ * @mem_flags: the type of memory to allocate, see kmalloc() for a list
+ *	of valid options for this.
  *
  * This submits a transfer request, and transfers control of the URB
  * describing that request to the USB subsystem.  Request completion will
@@ -1393,7 +1135,9 @@
  *	@index: USB message index value
  *	@data: pointer to the data to send
  *	@size: length in bytes of the data to send
- *	@timeout: time to wait for the message to complete before timing out (if 0 the wait is forever)
+ *	@timeout: time in jiffies to wait for the message to complete before
+ *		timing out (if 0 the wait is forever)
+ *	Context: !in_interrupt ()
  *
  *	This function sends a simple control message to a specified endpoint
  *	and waits for the message to complete, or timeout.
@@ -1401,7 +1145,7 @@
  *	If successful, it returns 0, otherwise a negative error number.
  *
  *	Don't use this function from within an interrupt context, like a
- *	bottom half handler.  If you need a asyncronous message, or need to send
+ *	bottom half handler.  If you need an asynchronous message, or need to send
  *	a message from within interrupt context, use usb_submit_urb()
  */
 int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype,
@@ -1436,7 +1180,9 @@
  *	@data: pointer to the data to send
  *	@len: length in bytes of the data to send
  *	@actual_length: pointer to a location to put the actual length transferred in bytes
- *	@timeout: time to wait for the message to complete before timing out (if 0 the wait is forever)
+ *	@timeout: time in jiffies to wait for the message to complete before
+ *		timing out (if 0 the wait is forever)
+ *	Context: !in_interrupt ()
  *
  *	This function sends a simple bulk message to a specified endpoint
  *	and waits for the message to complete, or timeout.
@@ -1446,7 +1192,7 @@
  *	actual_length paramater.
  *
  *	Don't use this function from within an interrupt context, like a
- *	bottom half handler.  If you need a asyncronous message, or need to
+ *	bottom half handler.  If you need an asynchronous message, or need to
  *	send a message from within interrupt context, use usb_submit_urb()
  */
 int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, 
@@ -1474,6 +1220,11 @@
  * Returns the current frame number for the USB host controller
  * used with the given USB device.  This can be used when scheduling
  * isochronous requests.
+ *
+ * Note that different kinds of host controller have different
+ * "scheduling horizons".  While one type might support scheduling only
+ * 32 frames into the future, others could support scheduling up to
+ * 1024 frames into the future.
  */
 int usb_get_current_frame_number(struct usb_device *dev)
 {
@@ -1946,6 +1697,7 @@
 /**
  * usb_disconnect - disconnect a device (usbcore-internal)
  * @pdev: pointer to device being disconnected
+ * Context: !in_interrupt ()
  *
  * Something got disconnected. Get rid of it, and all of its children.
  *
@@ -2069,6 +1821,7 @@
  * @index: the number of the descriptor
  * @buf: where to put the descriptor
  * @size: how big is "buf"?
+ * Context: !in_interrupt ()
  *
  * Gets a USB descriptor.  Convenience functions exist to simplify
  * getting some types of descriptors.  Use
@@ -2110,6 +1863,7 @@
  * @index: the number of the descriptor
  * @buf: where to put the string
  * @size: how big is "buf"?
+ * Context: !in_interrupt ()
  *
  * Retrieves a string, encoded using UTF-16LE (Unicode, 16 bits per character,
  * in little-endian byte order).
@@ -2135,6 +1889,7 @@
 /**
  * usb_get_device_descriptor - (re)reads the device descriptor
  * @dev: the device whose device descriptor is being updated
+ * Context: !in_interrupt ()
  *
  * Updates the copy of the device descriptor stored in the device structure,
  * which dedicates space for this purpose.  Note that several fields are
@@ -2169,6 +1924,7 @@
  * @type: USB_RECIP_*; for device, interface, or endpoint
  * @target: zero (for device), else interface or endpoint number
  * @data: pointer to two bytes of bitmap data
+ * Context: !in_interrupt ()
  *
  * Returns device, interface, or endpoint status.  Normally only of
  * interest to see if the device is self powered, or has enabled the
@@ -2227,6 +1983,7 @@
  * usb_clear_halt - tells device to clear endpoint halt/stall condition
  * @dev: device whose endpoint is halted
  * @pipe: endpoint "pipe" being cleared
+ * Context: !in_interrupt ()
  *
  * This is used to clear halt conditions for bulk and interrupt endpoints,
  * as reported by URB completion status.  Endpoints that are halted are
@@ -2298,6 +2055,7 @@
  * @dev: the device whose interface is being updated
  * @interface: the interface being updated
  * @alternate: the setting being chosen.
+ * Context: !in_interrupt ()
  *
  * This is used to enable data transfers on interfaces that may not
  * be enabled by default.  Not all devices support such configurability.
@@ -2378,6 +2136,7 @@
  * usb_set_configuration - Makes a particular device setting be current
  * @dev: the device whose configuration is being updated
  * @configuration: the configuration being chosen.
+ * Context: !in_interrupt ()
  *
  * This is used to enable non-default device modes.  Not all devices
  * support this kind of configurability.  By default, configuration
@@ -2540,6 +2299,7 @@
  * @index: the number of the descriptor
  * @buf: where to put the string
  * @size: how big is "buf"?
+ * Context: !in_interrupt ()
  * 
  * This converts the UTF-16LE encoded strings returned by devices, from
  * usb_get_string_descriptor(), to null-terminated ISO-8859-1 encoded ones
@@ -2619,8 +2379,11 @@
  * @dev: the device whose path is being constructed
  * @buf: where to put the string
  * @size: how big is "buf"?
+ * Context: !in_interrupt ()
  *
  * Returns length of the string (>= 0) or out of memory status (< 0).
+ *
+ * NOTE:  prefer to use use dev->devpath directly.
  */
 int usb_make_path(struct usb_device *dev, char *buf, size_t size)
 {
@@ -2768,29 +2531,6 @@
 	return 0;
 }
 
-/**
- * usb_register_root_hub - called by a usb host controller to register the root hub device in the system
- * @usb_dev: the usb root hub device to be registered.
- * @parent_dev: the parent device of this root hub.
- *
- * The USB host controller calls this function to register the root hub
- * properly with the USB subsystem.  It sets up the device properly in
- * the driverfs tree, and then calls usb_new_device() to register the
- * usb device.
- */
-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;
-}
-
 static int usb_open(struct inode * inode, struct file * file)
 {
 	int minor = minor(inode->i_rdev);
@@ -2859,7 +2599,6 @@
  */
 static int __init usb_init(void)
 {
-	init_MUTEX(&usb_bus_list_lock);
 	usb_major_init();
 	usbfs_init();
 	usb_hub_init();
@@ -2892,11 +2631,7 @@
 EXPORT_SYMBOL(usb_register);
 EXPORT_SYMBOL(usb_deregister);
 EXPORT_SYMBOL(usb_scan_devices);
-EXPORT_SYMBOL(usb_alloc_bus);
-EXPORT_SYMBOL(usb_free_bus);
-EXPORT_SYMBOL(usb_register_bus);
-EXPORT_SYMBOL(usb_deregister_bus);
-EXPORT_SYMBOL(usb_register_root_hub);
+
 EXPORT_SYMBOL(usb_alloc_dev);
 EXPORT_SYMBOL(usb_free_dev);
 EXPORT_SYMBOL(usb_inc_dev_use);
@@ -2911,10 +2646,6 @@
 EXPORT_SYMBOL(usb_reset_device);
 EXPORT_SYMBOL(usb_connect);
 EXPORT_SYMBOL(usb_disconnect);
-
-EXPORT_SYMBOL(usb_check_bandwidth);
-EXPORT_SYMBOL(usb_claim_bandwidth);
-EXPORT_SYMBOL(usb_release_bandwidth);
 
 EXPORT_SYMBOL(__usb_get_extra_descriptor);
 
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Wed Feb 27 15:44:31 2002
+++ b/include/linux/usb.h	Wed Feb 27 15:44:31 2002
@@ -44,8 +44,8 @@
 /*
  * USB directions
  */
-#define USB_DIR_OUT			0
-#define USB_DIR_IN			0x80
+#define USB_DIR_OUT			0		/* to device */
+#define USB_DIR_IN			0x80		/* to host */
 
 /*
  * Endpoints
@@ -148,12 +148,6 @@
 	unsigned long devicemap[128 / (8*sizeof(unsigned long))];
 };
 
-#define USB_MAXBUS		64
-
-struct usb_busmap {
-	unsigned long busmap[USB_MAXBUS / (8*sizeof(unsigned long))];
-};
-
 struct usb_device;
 
 /*-------------------------------------------------------------------------*/
@@ -516,7 +510,8 @@
  * work to connect to a device should be done when the device is opened,
  * and undone at the last close.  The disconnect code needs to address
  * concurrency issues with respect to open() and close() methods, as
- * well as cancel any I/O requests that are still pending.
+ * well as forcing all pending I/O requests to complete (by unlinking
+ * them as necessary, and blocking until the unlinks complete).
  */
 struct usb_driver {
 	struct module *owner;
@@ -905,13 +900,7 @@
 
 /* Host Controller Driver (HCD) support */
 
-struct usb_operations {
-	int (*allocate)(struct usb_device *);
-	int (*deallocate)(struct usb_device *);
-	int (*get_frame_number) (struct usb_device *usb_dev);
-	int (*submit_urb) (struct urb *urb, int mem_flags);
-	int (*unlink_urb) (struct urb *urb);
-};
+struct usb_operations;
 
 #define DEVNUM_ROUND_ROBIN	/***** OPTION *****/
 
@@ -944,41 +933,12 @@
 	atomic_t refcnt;
 };
 
-extern struct usb_bus *usb_alloc_bus(struct usb_operations *);
-extern void usb_free_bus(struct usb_bus *);
-extern void usb_register_bus(struct usb_bus *);
-extern void usb_deregister_bus(struct usb_bus *);
-extern int usb_register_root_hub(struct usb_device *usb_dev, struct device *parent_dev);
-
-extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
-extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb,
-		int bustime, int isoc);
-extern void usb_release_bandwidth(struct usb_device *dev, struct urb *urb,
-		int isoc);
+// FIXME:  root_hub_string vanishes when "usb_hcd" conversion is done,
+// along with pre-hcd versions of the OHCI and UHCI drivers.
 extern int usb_root_hub_string(int id, int serial,
 		char *type, __u8 *data, int len);
 
 /*
- * Some USB 1.1 bandwidth allocation constants.
- */
-#define BW_HOST_DELAY	1000L		/* nanoseconds */
-#define BW_HUB_LS_SETUP	333L		/* nanoseconds */
-                        /* 4 full-speed bit times (est.) */
-
-#define FRAME_TIME_BITS         12000L		/* frame = 1 millisecond */
-#define FRAME_TIME_MAX_BITS_ALLOC	(90L * FRAME_TIME_BITS / 100L)
-#define FRAME_TIME_USECS	1000L
-#define FRAME_TIME_MAX_USECS_ALLOC	(90L * FRAME_TIME_USECS / 100L)
-
-#define BitTime(bytecount)  (7 * 8 * bytecount / 6)  /* with integer truncation */
-		/* Trying not to use worst-case bit-stuffing
-                   of (7/6 * 8 * bytecount) = 9.33 * bytecount */
-		/* bytecount = data payload byte count */
-
-#define NS_TO_US(ns)	((ns + 500L) / 1000L)
-			/* convert & round nanoseconds to microseconds */
-
-/*
  * As of USB 2.0, full/low speed devices are segregated into trees.
  * One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
  * The other type grows from high speed hubs when they connect to
@@ -1209,13 +1169,11 @@
 /* -------------------------------------------------------------------------- */
 
 /*
- * bus and driver list
+ * driver list
  * exported only for usbfs (not visible outside usbcore)
  */
 
 extern struct list_head usb_driver_list;
-extern struct list_head usb_bus_list;
-extern struct semaphore usb_bus_list_lock;
 
 /*
  * USB device fs stuff
