Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Inaky Perez-Gonzalez and committed by
Greg Kroah-Hartman
8af548dc b1d8dfb0

+31 -9
+31 -9
drivers/usb/core/hub.c
··· 1195 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 + */ 1198 1215 static void choose_address(struct usb_device *udev) 1199 1216 { 1200 1217 int devnum; 1201 1218 struct usb_bus *bus = udev->bus; 1202 1219 1203 1220 /* If khubd ever becomes multithreaded, this will need a lock */ 1204 - 1205 - /* Try to allocate the next devnum beginning at bus->devnum_next. */ 1206 - devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1207 - bus->devnum_next); 1208 - if (devnum >= 128) 1209 - devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1); 1210 - 1211 - bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1); 1212 - 1221 + if (udev->wusb) { 1222 + devnum = udev->portnum + 1; 1223 + BUG_ON(test_bit(devnum, bus->devmap.devicemap)); 1224 + } else { 1225 + /* Try to allocate the next devnum beginning at 1226 + * bus->devnum_next. */ 1227 + devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1228 + bus->devnum_next); 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 1234 if (devnum < 128) { 1214 1235 set_bit(devnum, bus->devmap.devicemap); 1215 1236 udev->devnum = devnum; ··· 2632 2611 udev->speed = USB_SPEED_UNKNOWN; 2633 2612 udev->bus_mA = hub->mA_per_port; 2634 2613 udev->level = hdev->level + 1; 2614 + udev->wusb = hub_is_wusb(hub); 2635 2615 2636 2616 /* set the address */ 2637 2617 choose_address(udev);