wusb: teach choose_address() about wireless devices

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@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Inaky Perez-Gonzalez 2008-04-08 13:24:46 -07:00 committed by Greg Kroah-Hartman
parent b1d8dfb0e5
commit 8af548dc8e

View file

@ -1195,21 +1195,42 @@ void usb_set_device_state(struct usb_device *udev,
spin_unlock_irqrestore(&device_state_lock, flags); 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) static void choose_address(struct usb_device *udev)
{ {
int devnum; int devnum;
struct usb_bus *bus = udev->bus; struct usb_bus *bus = udev->bus;
/* If khubd ever becomes multithreaded, this will need a lock */ /* If khubd ever becomes multithreaded, this will need a lock */
if (udev->wusb) {
/* Try to allocate the next devnum beginning at bus->devnum_next. */ devnum = udev->portnum + 1;
devnum = find_next_zero_bit(bus->devmap.devicemap, 128, BUG_ON(test_bit(devnum, bus->devmap.devicemap));
bus->devnum_next); } else {
if (devnum >= 128) /* Try to allocate the next devnum beginning at
devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1); * bus->devnum_next. */
devnum = find_next_zero_bit(bus->devmap.devicemap, 128,
bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1); 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) { if (devnum < 128) {
set_bit(devnum, bus->devmap.devicemap); set_bit(devnum, bus->devmap.devicemap);
udev->devnum = devnum; 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->speed = USB_SPEED_UNKNOWN;
udev->bus_mA = hub->mA_per_port; udev->bus_mA = hub->mA_per_port;
udev->level = hdev->level + 1; udev->level = hdev->level + 1;
udev->wusb = hub_is_wusb(hub);
/* set the address */ /* set the address */
choose_address(udev); choose_address(udev);