# 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.544.3.3 -> 1.544.3.4
#	 include/linux/usb.h	1.28    -> 1.29   
#	drivers/usb/core/usb.c	1.45    -> 1.46   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/04/25	david-b@pacbell.net	1.544.3.4
# [PATCH] PATCH 2.5.10 -- polling interval (hub + ...)
# 
# This patch is the result of that discussion a short while back
# to fix the "hub driver polls too quickly at high speed" bug.
# 
#     - redefines "interval" of usb_fill_int_urb() to be what
#       the endpoint descriptor returns, and transparently
#       does the log-to-linear conversion if it's high speed
# 
#     - (most of the patch by volume!!) moves declarations
#       forward so testing dev->speed there will compile.
# 
# No driver changes were needed -- most drivers pass the
# endpoint bInterval value already, and those that don't are
# not dealing with high speed device quirks.
# 
# p.s. Includes an unrelated one-liner:  deletes export of
#     usb_inc_dev_use() so it now shows up in kernel doc.
#     Minor oversight in an earlier patch.
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	Thu Apr 25 16:27:00 2002
+++ b/drivers/usb/core/usb.c	Thu Apr 25 16:27:00 2002
@@ -2625,7 +2625,6 @@
 
 EXPORT_SYMBOL(usb_alloc_dev);
 EXPORT_SYMBOL(usb_free_dev);
-EXPORT_SYMBOL(usb_inc_dev_use);
 
 EXPORT_SYMBOL(usb_find_interface_driver_for_ifnum);
 EXPORT_SYMBOL(usb_driver_claim_interface);
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Thu Apr 25 16:27:00 2002
+++ b/include/linux/usb.h	Thu Apr 25 16:27:00 2002
@@ -317,6 +317,223 @@
 	__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\
 		type,(void**)ptr)
 
+/* -------------------------------------------------------------------------- */
+
+/* Host Controller Driver (HCD) support */
+
+struct usb_operations;
+
+#define DEVNUM_ROUND_ROBIN	/***** OPTION *****/
+
+/*
+ * Allocated per bus we have
+ */
+struct usb_bus {
+	int busnum;			/* Bus number (in order of reg) */
+	char *bus_name;			/* stable id (PCI slot_name etc) */
+
+#ifdef DEVNUM_ROUND_ROBIN
+	int devnum_next;                /* Next open device number in round-robin allocation */
+#endif /* DEVNUM_ROUND_ROBIN */
+
+	struct usb_devmap devmap;       /* device address allocation map */
+	struct usb_operations *op;      /* Operations (specific to the HC) */
+	struct usb_device *root_hub;    /* Root hub */
+	struct list_head bus_list;	/* list of busses */
+	void *hcpriv;                   /* Host Controller private data */
+
+	int bandwidth_allocated;	/* on this bus: how much of the time
+					 * reserved for periodic (intr/iso)
+					 * requests is used, on average?
+					 * Units: microseconds/frame.
+					 * Limits: Full/low speed reserve 90%,
+					 * while high speed reserves 80%.
+					 */
+	int bandwidth_int_reqs;		/* number of Interrupt requests */
+	int bandwidth_isoc_reqs;	/* number of Isoc. requests */
+
+	struct dentry *dentry;		/* usbfs dentry entry for the bus */
+
+	atomic_t refcnt;
+};
+
+// 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);
+
+/*
+ * 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
+ * full/low speed devices using "Transaction Translators" (TTs).
+ *
+ * TTs should only be known to the hub driver, and high speed bus
+ * drivers (only EHCI for now).  They affect periodic scheduling and
+ * sometimes control/bulk error recovery.
+ */
+struct usb_tt {
+	struct usb_device	*hub;	/* upstream highspeed hub */
+	int			multi;	/* true means one TT per port */
+};
+
+
+/* -------------------------------------------------------------------------- */
+
+/* This is arbitrary.
+ * From USB 2.0 spec Table 11-13, offset 7, a hub can
+ * have up to 255 ports. The most yet reported is 10.
+ */
+#define USB_MAXCHILDREN		(16)
+
+struct usb_device {
+	int		devnum;		/* Address on USB bus */
+	char		devpath [16];	/* Use in messages: /port/port/... */
+
+	enum {
+		USB_SPEED_UNKNOWN = 0,			/* enumerating */
+		USB_SPEED_LOW, USB_SPEED_FULL,		/* usb 1.1 */
+		USB_SPEED_HIGH				/* usb 2.0 */
+	} speed;
+
+	struct usb_tt	*tt; 		/* low/full speed dev, highspeed hub */
+	int		ttport;		/* device port on that tt hub */
+
+	atomic_t refcnt;		/* Reference count */
+	struct semaphore serialize;
+
+	unsigned int toggle[2];		/* one bit for each endpoint ([0] = IN, [1] = OUT) */
+	unsigned int halted[2];		/* endpoint halts; one bit per endpoint # & direction; */
+					/* [0] = IN, [1] = OUT */
+	int epmaxpacketin[16];		/* INput endpoint specific maximums */
+	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
+
+	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 */
+
+	char **rawdescriptors;		/* Raw descriptors for each config */
+
+	int have_langid;		/* whether string_langid is valid yet */
+	int string_langid;		/* language ID for strings */
+  
+	void *hcpriv;			/* Host Controller private data */
+	
+	struct list_head filelist;
+	struct dentry *dentry;		/* usbfs dentry entry for the device */
+
+	/*
+	 * Child devices - these can be either new devices
+	 * (if this is a hub device), or different instances
+	 * of this same device.
+	 *
+	 * Each instance needs its own set of data structures.
+	 */
+
+	int maxchild;			/* Number of ports if hub */
+	struct usb_device *children[USB_MAXCHILDREN];
+};
+
+/* 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);
+
+/* for drivers using iso endpoints */
+extern int usb_get_current_frame_number (struct usb_device *usb_dev);
+
+/**
+ * usb_inc_dev_use - record another reference to a device
+ * @dev: the device being referenced
+ *
+ * Each live reference to a device should be refcounted.
+ *
+ * Drivers for USB interfaces should normally record such references in
+ * their probe() methods, when they bind to an interface, and release
+ * them usb_dec_dev_use(), in their disconnect() methods.
+ */
+static inline void usb_inc_dev_use (struct usb_device *dev)
+{
+	atomic_inc (&dev->refcnt);
+}
+
+/**
+ * usb_dec_dev_use - drop a reference to a device
+ * @dev: the device no longer being referenced
+ *
+ * Each live reference to a device should be refcounted.
+ *
+ * Drivers for USB interfaces should normally release such references in
+ * their disconnect() methods, and record them in probe().
+ *
+ * Note that driver disconnect() methods must guarantee that when they
+ * return, all of their outstanding references to the device (and its
+ * interfaces) are cleaned up.  That means that all pending URBs from
+ * this driver must have completed, and that no more copies of the device
+ * handle are saved in driver records (including other kernel threads).
+ */
+static inline void usb_dec_dev_use (struct usb_device *dev)
+{
+	if (atomic_dec_and_test (&dev->refcnt)) {
+		/* May only go to zero when usbcore finishes
+		 * usb_disconnect() processing:  khubd or HCDs.
+		 *
+		 * If you hit this BUG() it's likely a problem
+		 * with some driver's disconnect() routine.
+		 */
+		BUG ();
+	}
+}
+
+
+/* used these for multi-interface device registration */
+extern int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned int ifnum);
+extern void usb_driver_claim_interface(struct usb_driver *driver,
+			struct usb_interface *iface, void* priv);
+extern int usb_interface_claimed(struct usb_interface *iface);
+extern void usb_driver_release_interface(struct usb_driver *driver,
+			struct usb_interface *iface);
+const struct usb_device_id *usb_match_id(struct usb_device *dev,
+					 struct usb_interface *interface,
+					 const struct usb_device_id *id);
+
+/**
+ * usb_make_path - returns stable device path in the usb tree
+ * @dev: the device whose path is being constructed
+ * @buf: where to put the string
+ * @size: how big is "buf"?
+ *
+ * Returns length of the string (> 0) or negative if size was too small.
+ *
+ * This identifier is intended to be "stable", reflecting physical paths in
+ * hardware such as physical bus addresses for host controllers or ports on
+ * USB hubs.  That makes it stay the same until systems are physically
+ * reconfigured, by re-cabling a tree of USB devices or by moving USB host
+ * controllers.  Adding and removing devices, including virtual root hubs
+ * in host controller driver modules, does not change these path identifers;
+ * neither does rebooting or re-enumerating.  These are more useful identifiers
+ * than changeable ("unstable") ones like bus numbers or device addresses.
+ * 
+ * With a partial exception for devices connected to USB 2.0 root hubs, these
+ * identifiers are also predictable:  so long as the device tree isn't changed,
+ * plugging any USB device into a given hub port always gives it the same path.
+ * Because of the use of "companion" controllers, devices connected to ports on
+ * USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are
+ * high speed, and a different one if they are full or low speed.
+ */
+static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
+{
+	int actual;
+	actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath);
+	return (actual >= size) ? -1 : actual;
+}
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -826,10 +1043,14 @@
  * @buffer_length: length of the transfer buffer
  * @complete: pointer to the usb_complete_t function
  * @context: what to set the urb context to.
- * @interval: what to set the urb interval to.
+ * @interval: what to set the urb interval to, encoded like
+ *	the endpoint descriptor's bInterval value.
  *
  * Initializes a interrupt urb with the proper information needed to submit
  * it to a device.
+ * Note that high speed interrupt endpoints use a logarithmic encoding of
+ * the endpoint interval, and express polling intervals in microframes
+ * (eight per millisecond) rather than in frames (one per millisecond).
  */
 static inline void usb_fill_int_urb (struct urb *urb,
 				     struct usb_device *dev,
@@ -847,7 +1068,10 @@
 	urb->transfer_buffer_length = buffer_length;
 	urb->complete = complete;
 	urb->context = context;
-	urb->interval = interval;
+	if (dev->speed == USB_SPEED_HIGH)
+		urb->interval = 1 << (interval - 1);
+	else
+		urb->interval = interval;
 	urb->start_frame = -1;
 }
 
@@ -905,221 +1129,6 @@
 #endif
 
 #define USB_CTRL_SET_TIMEOUT 3
-
-/* -------------------------------------------------------------------------- */
-
-/* Host Controller Driver (HCD) support */
-
-struct usb_operations;
-
-#define DEVNUM_ROUND_ROBIN	/***** OPTION *****/
-
-/*
- * Allocated per bus we have
- */
-struct usb_bus {
-	int busnum;			/* Bus number (in order of reg) */
-	char *bus_name;			/* stable id (PCI slot_name etc) */
-
-#ifdef DEVNUM_ROUND_ROBIN
-	int devnum_next;                /* Next open device number in round-robin allocation */
-#endif /* DEVNUM_ROUND_ROBIN */
-
-	struct usb_devmap devmap;       /* Device map */
-	struct usb_operations *op;      /* Operations (specific to the HC) */
-	struct usb_device *root_hub;    /* Root hub */
-	struct list_head bus_list;
-	void *hcpriv;                   /* Host Controller private data */
-
-	int bandwidth_allocated;	/* on this Host Controller; */
-					  /* applies to Int. and Isoc. pipes; */
-					  /* measured in microseconds/frame; */
-					  /* range is 0..900, where 900 = */
-					  /* 90% of a 1-millisecond frame */
-	int bandwidth_int_reqs;		/* number of Interrupt requesters */
-	int bandwidth_isoc_reqs;	/* number of Isoc. requesters */
-
-	struct dentry *dentry;		/* usbfs dentry entry for the bus */
-
-	atomic_t refcnt;
-};
-
-// 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);
-
-/*
- * 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
- * full/low speed devices using "Transaction Translators" (TTs).
- *
- * TTs should only be known to the hub driver, and high speed bus
- * drivers (only EHCI for now).  They affect periodic scheduling and
- * sometimes control/bulk error recovery.
- */
-struct usb_tt {
-	struct usb_device	*hub;	/* upstream highspeed hub */
-	int			multi;	/* true means one TT per port */
-};
-
-
-/* -------------------------------------------------------------------------- */
-
-/* This is arbitrary.
- * From USB 2.0 spec Table 11-13, offset 7, a hub can
- * have up to 255 ports. The most yet reported is 10.
- */
-#define USB_MAXCHILDREN		(16)
-
-struct usb_device {
-	int		devnum;		/* Address on USB bus */
-	char		devpath [16];	/* Use in messages: /port/port/... */
-
-	enum {
-		USB_SPEED_UNKNOWN = 0,			/* enumerating */
-		USB_SPEED_LOW, USB_SPEED_FULL,		/* usb 1.1 */
-		USB_SPEED_HIGH				/* usb 2.0 */
-	} speed;
-
-	struct usb_tt	*tt; 		/* low/full speed dev, highspeed hub */
-	int		ttport;		/* device port on that tt hub */
-
-	atomic_t refcnt;		/* Reference count */
-	struct semaphore serialize;
-
-	unsigned int toggle[2];		/* one bit for each endpoint ([0] = IN, [1] = OUT) */
-	unsigned int halted[2];		/* endpoint halts; one bit per endpoint # & direction; */
-					/* [0] = IN, [1] = OUT */
-	int epmaxpacketin[16];		/* INput endpoint specific maximums */
-	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
-
-	struct usb_device *parent;
-	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 */
-
-	char **rawdescriptors;		/* Raw descriptors for each config */
-
-	int have_langid;		/* whether string_langid is valid yet */
-	int string_langid;		/* language ID for strings */
-  
-	void *hcpriv;			/* Host Controller private data */
-	
-	struct list_head filelist;
-	struct dentry *dentry;		/* usbfs dentry entry for the device */
-
-	/*
-	 * Child devices - these can be either new devices
-	 * (if this is a hub device), or different instances
-	 * of this same device.
-	 *
-	 * Each instance needs its own set of data structures.
-	 */
-
-	int maxchild;			/* Number of ports if hub */
-	struct usb_device *children[USB_MAXCHILDREN];
-};
-
-/* 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);
-
-/* for drivers using iso endpoints */
-extern int usb_get_current_frame_number (struct usb_device *usb_dev);
-
-/**
- * usb_inc_dev_use - record another reference to a device
- * @dev: the device being referenced
- *
- * Each live reference to a device should be refcounted.
- *
- * Drivers for USB interfaces should normally record such references in
- * their probe() methods, when they bind to an interface, and release
- * them usb_dec_dev_use(), in their disconnect() methods.
- */
-static inline void usb_inc_dev_use (struct usb_device *dev)
-{
-	atomic_inc (&dev->refcnt);
-}
-
-/**
- * usb_dec_dev_use - drop a reference to a device
- * @dev: the device no longer being referenced
- *
- * Each live reference to a device should be refcounted.
- *
- * Drivers for USB interfaces should normally release such references in
- * their disconnect() methods, and record them in probe().
- *
- * Note that driver disconnect() methods must guarantee that when they
- * return, all of their outstanding references to the device (and its
- * interfaces) are cleaned up.  That means that all pending URBs from
- * this driver must have completed, and that no more copies of the device
- * handle are saved in driver records (including other kernel threads).
- */
-static inline void usb_dec_dev_use (struct usb_device *dev)
-{
-	if (atomic_dec_and_test (&dev->refcnt)) {
-		/* May only go to zero when usbcore finishes
-		 * usb_disconnect() processing:  khubd or HCDs.
-		 *
-		 * If you hit this BUG() it's likely a problem
-		 * with some driver's disconnect() routine.
-		 */
-		BUG ();
-	}
-}
-
-
-/* used these for multi-interface device registration */
-extern int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned int ifnum);
-extern void usb_driver_claim_interface(struct usb_driver *driver,
-			struct usb_interface *iface, void* priv);
-extern int usb_interface_claimed(struct usb_interface *iface);
-extern void usb_driver_release_interface(struct usb_driver *driver,
-			struct usb_interface *iface);
-const struct usb_device_id *usb_match_id(struct usb_device *dev,
-					 struct usb_interface *interface,
-					 const struct usb_device_id *id);
-
-/**
- * usb_make_path - returns stable device path in the usb tree
- * @dev: the device whose path is being constructed
- * @buf: where to put the string
- * @size: how big is "buf"?
- *
- * Returns length of the string (> 0) or negative if size was too small.
- *
- * This identifier is intended to be "stable", reflecting physical paths in
- * hardware such as physical bus addresses for host controllers or ports on
- * USB hubs.  That makes it stay the same until systems are physically
- * reconfigured, by re-cabling a tree of USB devices or by moving USB host
- * controllers.  Adding and removing devices, including virtual root hubs
- * in host controller driver modules, does not change these path identifers;
- * neither does rebooting or re-enumerating.  These are more useful identifiers
- * than changeable ("unstable") ones like bus numbers or device addresses.
- * 
- * With a partial exception for devices connected to USB 2.0 root hubs, these
- * identifiers are also predictable:  so long as the device tree isn't changed,
- * plugging any USB device into a given hub port always gives it the same path.
- * Because of the use of "companion" controllers, devices connected to ports on
- * USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are
- * high speed, and a different one if they are full or low speed.
- */
-static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
-{
-	int actual;
-	actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath);
-	return (actual >= size) ? -1 : actual;
-}
 
 /* -------------------------------------------------------------------------- */
 
