|
@@ -1195,21 +1195,42 @@ void usb_set_device_state(struct usb_device *udev,
|
|
|
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 1 as an offset to the one-based USB-stack port number
|
|
|
+ * (zero-based wusb virtual port index) for two reasons: (a) dev addr
|
|
|
+ * 0 is reserved by USB for default address; (b) Linux's USB stack
|
|
|
+ * uses always #1 for the root hub of the controller. So USB stack's
|
|
|
+ * port #1, which is wusb virtual-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;
|
|
@@ -2611,6 +2632,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
|
|
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);
|