Как был назначен номер шины USB и номер устройства?

19

При использовании lsusbя понимаю, что номер шины и номер устройства USB могут время от времени меняться. Из того, что я понимаю, номер шины можно менять при каждой перезагрузке. Номер устройства будет меняться при каждом переподключении.

У меня вопрос, какой алгоритм используется системой для получения номера шины и номера устройства? Особенно номер устройства, это монотонный? Будет ли когда-нибудь случай, когда: без перезагрузки ОС одно переподключенное устройство использует старый номер шины другого переподключенного устройства и номер устройства?

Конан
источник
6
Одна вещь заставила меня задуматься о вашем вопросе: вы действительно видели, как менялись номера автобусов после перезагрузки? Я всегда был уверен, что если вы не смените аппаратное обеспечение или не обновите BIOS, номера шин не изменятся. Шины USB - это просто концентраторы / контроллеры, подключенные к шинам PCI (во всех случаях, которые я видел, по крайней мере), а информация о шине PCI поступает из BIOS. Но я могу ошибаться, не хочу делать ответ и говорить об этом.
Грохмал
Правильно, только когда у меня смена оборудования выглядит так.
Конан

Ответы:

23

Примечание: это ответ Linux ; другие ядра будут иметь немного другой способ справиться с этим.

контекст

Трудно говорить о шинах USB, не говоря о шинах PCI. Процессор не может подключиться к шине USB, в результате процессор взаимодействует с шиной PCI, к которой подключен контроллер USB (а контроллер / концентратор USB - это то, что lsusbвызывает шину USB). Шины PCI нумеруются в зависимости от того, как далеко они находятся от процессора, например:

    +-----+
    | CPU |
    +-----+
       |              PCI Bus 0
 ---+--+-----------------------------+
    |                                |
+---+----+                      +----+---+
| Bridge |                      | Bridge |
+---+----+                      +----+---+
    |  PCI bus 1                     |  PCI bus 2
  --+--------+               +-------+-------------+
             |               |                     |
       Disk Controller    USB Controller      Network Card
         (Device 00)       (Device 00)         (Device 01)

Заглядывая в man lspciмы видим следующее:

   Slot   The  name of the slot where the device resides
          ([domain:]bus:device.function).  This tag is
          always the first in a record.

Поэтому теперь мы знаем, как интерпретировать числа PCI. Далее мы рассмотрим контроллеры USB, подключенные к шинам PCI. Машина, на которой я сейчас работаю, имеет интересную конфигурацию USB, поэтому я буду использовать ее в качестве примера:

$ lspci -tv
-[0000:00]-+-00.0  Advanced Micro Devices, Inc. [AMD] RS780 Host Bridge
           +-01.0-[01]----05.0  Advanced Micro Devices, Inc. [AMD/ATI] RS780M [Mobility Radeon HD 3200]
           +-04.0-[02]----00.0  Qualcomm Atheros AR928X Wireless Network Adapter (PCI-Express)
           +-05.0-[03]----00.0  Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
           +-06.0-[04-06]--
           +-11.0  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode]
           +-12.0  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
           +-12.1  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0 USB OHCI1 Controller
           +-12.2  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller
           +-13.0  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
           +-13.1  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0 USB OHCI1 Controller
           +-13.2  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller
           +-14.0  Advanced Micro Devices, Inc. [AMD/ATI] SBx00 SMBus Controller
           +-14.1  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 IDE Controller
           +-14.2  Advanced Micro Devices, Inc. [AMD/ATI] SBx00 Azalia (Intel HDA)
           +-14.3  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 LPC host controller
           +-14.4-[07]--
           +-14.5  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI2 Controller
           +-18.0  Advanced Micro Devices, Inc. [AMD] Family 11h Processor HyperTransport Configuration
           +-18.1  Advanced Micro Devices, Inc. [AMD] Family 11h Processor Address Map
           +-18.2  Advanced Micro Devices, Inc. [AMD] Family 11h Processor DRAM Controller
           +-18.3  Advanced Micro Devices, Inc. [AMD] Family 11h Processor Miscellaneous Control
           \-18.4  Advanced Micro Devices, Inc. [AMD] Family 11h Processor Link Control

Подожди, подожди, подожди, что это за плюсы? Вверху у нас есть домен и шина PCI -[0000:00](у этой машины только одна шина PCI). И затем у нас есть несколько устройств, подключенных к этой шине. Давайте посмотрим, какие устройства USB:

$ lspci -tv | grep -i usb
       +-12.0  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
       +-12.1  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0 USB OHCI1 Controller
       +-12.2  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller
       +-13.0  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
       +-13.1  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0 USB OHCI1 Controller
       +-13.2  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller
       +-14.5  Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI2 Controller

Хорошо, теперь давайте сравним это с lsusb(я использую sortтолько для упрощения поиска в списке позже):

$ lsusb | sort
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 174f:5a31 Syntek Sonix USB 2.0 Camera
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 002: ID 046d:c019 Logitech, Inc. Optical Tilt Wheel Mouse
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 002: ID 0b05:1751 ASUSTek Computer, Inc. BT-253 Bluetooth Adapter

Подожди еще раз. У нас есть 7 USB-устройств в соответствии с lspci10 устройств в соответствии с lsusb! lspciтолько списки контроллеров USB; К контроллеру может быть подключено более одного USB-устройства. Давайте /sys/bus/посмотрим, как это происходит.

$ ls -l /sys/bus/usb/devices/
... 1-0:1.0 -> ../../../devices/pci0000:00/0000:00:12.2/usb1/1-0:1.0
... 2-0:1.0 -> ../../../devices/pci0000:00/0000:00:13.2/usb2/2-0:1.0
... 2-1 -> ../../../devices/pci0000:00/0000:00:13.2/usb2/2-1
... 2-1:1.0 -> ../../../devices/pci0000:00/0000:00:13.2/usb2/2-1/2-1:1.0
... 2-1:1.1 -> ../../../devices/pci0000:00/0000:00:13.2/usb2/2-1/2-1:1.1
... 3-0:1.0 -> ../../../devices/pci0000:00/0000:00:12.0/usb3/3-0:1.0
... 3-1 -> ../../../devices/pci0000:00/0000:00:12.0/usb3/3-1
... 3-1:1.0 -> ../../../devices/pci0000:00/0000:00:12.0/usb3/3-1/3-1:1.0
... 4-0:1.0 -> ../../../devices/pci0000:00/0000:00:12.1/usb4/4-0:1.0
... 5-0:1.0 -> ../../../devices/pci0000:00/0000:00:13.0/usb5/5-0:1.0
... 6-0:1.0 -> ../../../devices/pci0000:00/0000:00:13.1/usb6/6-0:1.0
... 7-0:1.0 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-0:1.0
... 7-1 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-1
... 7-1:1.0 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-1/7-1:1.0
... 7-1:1.1 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-1/7-1:1.1
... 7-1:1.2 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-1/7-1:1.2
... 7-1:1.3 -> ../../../devices/pci0000:00/0000:00:14.5/usb7/7-1/7-1:1.3
... usb1 -> ../../../devices/pci0000:00/0000:00:12.2/usb1
... usb2 -> ../../../devices/pci0000:00/0000:00:13.2/usb2
... usb3 -> ../../../devices/pci0000:00/0000:00:12.0/usb3
... usb4 -> ../../../devices/pci0000:00/0000:00:12.1/usb4
... usb5 -> ../../../devices/pci0000:00/0000:00:13.0/usb5
... usb6 -> ../../../devices/pci0000:00/0000:00:13.1/usb6
... usb7 -> ../../../devices/pci0000:00/0000:00:14.5/usb7

Теперь это начинает иметь смысл, у нас есть 7 USB-контроллеров, которые подключены к шине PCI как устройства. Например, шина USB 001 соответствует устройству PCI, 0000:00:12.2а шина USB 007 соответствует 0000:00:14.5устройству.

Нумерация устройств

Каталоги, начинающиеся с номера шины USB (например 7-1:1.2), являются фактическими устройствами, подключенными к контроллеру USB. Точно так же, как к шине PCI может быть подключено несколько устройств, к контроллеру USB (концентратору) может быть подключено несколько USB-устройств.

Номера устройств - просто счетчики: первое подключенное устройство получает 1, следующее получает 2 и так далее. Но есть еще немного: USB был разработан для горячей замены; поэтому вы можете подключать и отключать устройства. Когда вы отключаете устройство USB, номер устройства больше не будет использоваться ядром для любого другого устройства на этом контроллере USB. Например, если вы подключите и отключите перьевой диск и продолжите работу, lsusbвы увидите, что номер устройства для вашего перьевого диска увеличивается.

Нумерация автобусов

Если вы внимательно прочитали вышеизложенное, возможно, вы удивляетесь одной вещи, которой я не коснулся. Порядок нумерации PCI не соответствует порядку нумерации контроллеров USB! Давайте посмотрим, что еще раз:

USB  | PCI
-----+----
usb1 | 0000:00/0000:00:12.2
usb2 | 0000:00/0000:00:13.2
usb3 | 0000:00/0000:00:12.0
usb4 | 0000:00/0000:00:12.1
usb5 | 0000:00/0000:00:13.0
usb6 | 0000:00/0000:00:13.1
usb7 | 0000:00/0000:00:14.5

Список в порядке, но не совсем. Первые два контроллера USB, похоже, вышли из строя. Тем не менее, есть причина, почему: если вы посмотрите lspciвыше, вы увидите, что это EHCIUSB (USB 2.0), в то время как все остальные контроллеры OHCIUSB - USB (USB 1.x).

Поэтому мы можем перерисовать эту таблицу как:

USB  | PCI
-----+----
usb1 | 0000:00/0000:00:12.2
usb2 | 0000:00/0000:00:13.2     USB 2.0
-----+---------------------------------
usb3 | 0000:00/0000:00:12.0     USB 1.x
usb4 | 0000:00/0000:00:12.1
usb5 | 0000:00/0000:00:13.0
usb6 | 0000:00/0000:00:13.1
usb7 | 0000:00/0000:00:14.5

И назначение номера становится понятным.

grochmal
источник
так что будет, когда будет использовано максимальное количество номеров устройств. скажем, я продолжаю переподключать свое устройство. Номер устройства скоро пойдет на макс. Я на самом деле сделал тест, похоже, это не простой счетчик. Он не возвращается обратно 001, вместо этого ядро ​​повторно использует самый большой номер устройства. Есть ли простой способ изменить это поведение?
Конан
@ Конан - Хм ... ну, как я могу это сказать: я просто не знаю. Я никогда не пытался переполнить счетчик устройства, как вы. Опять же, вряд ли нужно заранее знать номер устройства. Например, если вы пытаетесь найти USB-накопитель при его подключении, вы должны делать это по метке файловой системы или по UUID (что даже udevболее-менее понятно). Что касается понимания нумерации ради обучения, я считаю, что единственное место, где есть информация, - это код ядра.
Grochmal
Спасибо @grochmal, я думаю, что сделал ошибку при переполнении теста. Более поздние тесты показали мне, когда переполнение, счетчик действительно искал от более низкого числа.
Конан