Loading drivers/usb/core/hub.c +31 −9 Original line number Diff line number Diff line Loading @@ -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. */ 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); 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; Loading Loading @@ -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); Loading Loading
drivers/usb/core/hub.c +31 −9 Original line number Diff line number Diff line Loading @@ -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. */ 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); 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; Loading Loading @@ -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); Loading