# 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 [EMAIL PROTECTED] 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;
-}
/* -------------------------------------------------------------------------- */
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel