Modify choose_address() so it knows about our special scheme of
addressing WUSB devices (1:1 w/ port number).
Signed-off-by: Inaky Perez-Gonzalez <[EMAIL PROTECTED]>
---
drivers/usb/core/hub.c | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
Index: linux.hg/drivers/usb/core/hub.c
===================================================================
--- linux.hg.orig/drivers/usb/core/hub.c 2007-07-31 12:18:53.000000000
-0700
+++ linux.hg/drivers/usb/core/hub.c 2007-07-31 12:18:58.000000000 -0700
@@ -1077,21 +1077,40 @@
spin_unlock_irqrestore(&device_state_lock, flags);
}
+/*
+ * WUSB devices are simple: they have no hubs behind, so the mapping
+ * device <-> virtual port number becomes 1:1. Why? to simplify the
+ * life of the device connection logic in
+ * drivers/usb/wusbcore/devconnect.c. When we do the initial secret
+ * handshake we need to assign a temporary address in the unauthorized
+ * space. For simplicity we use the first virtual port number found to
+ * be free [drivers/usb/wusbcore/devconnect.c:wusbhc_devconnect_ack()]
+ * and that becomes it's address [X < 128] or its unauthorized address
+ * [X | 0x80].
+ *
+ * We add 2 as an offset for two reasons: (1) dev addr 0 is reserved
+ * by USB for default address; (2) Linux's USB stack uses always #1 for
+ * the root hub of the controller. So port 0 has address #2.
+ */
static void choose_address(struct usb_device *udev)
{
int devnum;
struct usb_bus *bus = udev->bus;
/* If khubd ever becomes multithreaded, this will need a lock */
-
- /* Try to allocate the next devnum beginning at bus->devnum_next. */
- devnum = find_next_zero_bit(bus->devmap.devicemap, 128,
- bus->devnum_next);
- if (devnum >= 128)
- devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1);
-
- bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
-
+ if (udev->wusb) {
+ devnum = udev->portnum + 1;
+ BUG_ON(test_bit(devnum, bus->devmap.devicemap));
+ } else {
+ /* Try to allocate the next devnum beginning at
+ * bus->devnum_next. */
+ devnum = find_next_zero_bit(bus->devmap.devicemap, 128,
+ bus->devnum_next);
+ if (devnum >= 128)
+ devnum = find_next_zero_bit(bus->devmap.devicemap,
+ 128, 1);
+ bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
+ }
if (devnum < 128) {
set_bit(devnum, bus->devmap.devicemap);
udev->devnum = devnum;
@@ -2522,6 +2541,7 @@
udev->speed = USB_SPEED_UNKNOWN;
udev->bus_mA = hub->mA_per_port;
udev->level = hdev->level + 1;
+ udev->wusb = hub_is_wusb(hub);
/* set the address */
choose_address(udev);
--
Inaky
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel