[patch 1/7] wusb: teach choose_address() about wireless devices

Inaky Perez-Gonzalez <inaky-VuQAYsv1563Yd54FQh9/[email protected]>
Newsgroups gmane.linux.drivers.uwb,gmane.linux.usb.devel
Message-ID <[email protected]>
wusb-teach-choose-address-about-wireless-devices.patch (text/plain, 2.6 KB)
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 <inaky-VuQAYsv1563Yd54FQh9/[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.