aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorInaky Perez-Gonzalez <inaky@linux.intel.com>2008-04-08 16:24:46 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-04-25 00:16:58 -0400
commit8af548dc8e36f845943ffcba07fafaa56c844221 (patch)
tree2f87553398bba3b4c868e51d1748cfb1c963dc4c /drivers/usb
parentb1d8dfb0e548543b1645362e80e1fff522645299 (diff)
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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/hub.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 06c3acb161ee..baae2aa0dbf6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1195,21 +1195,42 @@ void usb_set_device_state(struct usb_device *udev,
1195 spin_unlock_irqrestore(&device_state_lock, flags); 1195 spin_unlock_irqrestore(&device_state_lock, flags);
1196} 1196}
1197 1197
1198/*
1199 * WUSB devices are simple: they have no hubs behind, so the mapping
1200 * device <-> virtual port number becomes 1:1. Why? to simplify the
1201 * life of the device connection logic in
1202 * drivers/usb/wusbcore/devconnect.c. When we do the initial secret
1203 * handshake we need to assign a temporary address in the unauthorized
1204 * space. For simplicity we use the first virtual port number found to
1205 * be free [drivers/usb/wusbcore/devconnect.c:wusbhc_devconnect_ack()]
1206 * and that becomes it's address [X < 128] or its unauthorized address
1207 * [X | 0x80].
1208 *
1209 * We add 1 as an offset to the one-based USB-stack port number
1210 * (zero-based wusb virtual port index) for two reasons: (a) dev addr
1211 * 0 is reserved by USB for default address; (b) Linux's USB stack
1212 * uses always #1 for the root hub of the controller. So USB stack's
1213 * port #1, which is wusb virtual-port #0 has address #2.
1214 */
1198static void choose_address(struct usb_device *udev) 1215static void choose_address(struct usb_device *udev)
1199{ 1216{
1200 int devnum; 1217 int devnum;
1201 struct usb_bus *bus = udev->bus; 1218 struct usb_bus *bus = udev->bus;
1202 1219
1203 /* If khubd ever becomes multithreaded, this will need a lock */ 1220 /* If khubd ever becomes multithreaded, this will need a lock */
1204 1221 if (udev->wusb) {
1205 /* Try to allocate the next devnum beginning at bus->devnum_next. */ 1222 devnum = udev->portnum + 1;
1206 devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1223 BUG_ON(test_bit(devnum, bus->devmap.devicemap));
1207 bus->devnum_next); 1224 } else {
1208 if (devnum >= 128) 1225 /* Try to allocate the next devnum beginning at
1209 devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1); 1226 * bus->devnum_next. */
1210 1227 devnum = find_next_zero_bit(bus->devmap.devicemap, 128,
1211 bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1); 1228 bus->devnum_next);
1212 1229 if (devnum >= 128)
1230 devnum = find_next_zero_bit(bus->devmap.devicemap,
1231 128, 1);
1232 bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
1233 }
1213 if (devnum < 128) { 1234 if (devnum < 128) {
1214 set_bit(devnum, bus->devmap.devicemap); 1235 set_bit(devnum, bus->devmap.devicemap);
1215 udev->devnum = devnum; 1236 udev->devnum = devnum;
@@ -2611,6 +2632,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
2611 udev->speed = USB_SPEED_UNKNOWN; 2632 udev->speed = USB_SPEED_UNKNOWN;
2612 udev->bus_mA = hub->mA_per_port; 2633 udev->bus_mA = hub->mA_per_port;
2613 udev->level = hdev->level + 1; 2634 udev->level = hdev->level + 1;
2635 udev->wusb = hub_is_wusb(hub);
2614 2636
2615 /* set the address */ 2637 /* set the address */
2616 choose_address(udev); 2638 choose_address(udev);