Jak przypisano numer magistrali USB i numer urządzenia?

19

Podczas używania lsusbzdaję sobie sprawę, że numer magistrali i numer urządzenia USB może się zmieniać od czasu do czasu. Z tego, co rozumiem, numer magistrali można zmienić przy każdym ponownym uruchomieniu. Numer urządzenia zmieni się przy każdym ponownym połączeniu.

Moje pytanie brzmi: jakiego algorytmu system użył do uzyskania numeru magistrali i numeru urządzenia? Zwłaszcza numer urządzenia, czy jest monotoniczny? Czy kiedykolwiek zdarzy się przypadek, że: bez ponownego uruchomienia systemu operacyjnego jedno ponownie podłączone urządzenie używa starego numeru magistrali i numeru innego podłączonego urządzenia?

Conan
źródło
6
Jedno sprawiło, że ciekawi mnie twoje pytanie: czy naprawdę widziałeś, jak zmieniają się numery BUS po ponownym uruchomieniu? Zawsze byłem pewien, że jeśli nie zmienisz sprzętu lub nie zaktualizujesz BIOS-u, numery magistrali się nie zmienią. Magistrale USB to po prostu koncentratory / kontrolery podłączone do magistrali PCI (we wszystkich przypadkach widziałem przynajmniej), a informacje o magistrali PCI pochodzą z BIOS-u. Ale mogę się mylić, nie chcę udzielać odpowiedzi i gadać bzdur.
grochmal
tak, tylko kiedy wygląda zmiana sprzętu.
Conan,

Odpowiedzi:

23

Uwaga: To jest odpowiedź na Linuksa ; inne jądra będą miały nieco inny sposób radzenia sobie z tym.

Kontekst

Trudno mówić o magistralach USB bez mówienia o magistralach PCI. Procesor nie może komunikować się z magistralą USB, co się dzieje, gdy procesor komunikuje się z magistralą PCI, do której podłączony jest kontroler USB (a kontroler / koncentrator lsusbUSB to tak zwana magistrala USB). Magistrale PCI są ponumerowane na podstawie odległości od procesora, na przykład:

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

Przyglądając się man lspci, widzimy:

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

Dlatego wiemy już, jak interpretować numery PCI. Następnie przyjrzymy się kontrolerom USB podłączonym do magistrali PCI. Maszyna, na której aktualnie jestem, ma ciekawą konfigurację USB, więc wykorzystam ją jako przykład:

$ 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

Czekaj, czekaj, czekaj, jakie są wszystkie plusy? Na górze mamy domenę i magistralę PCI -[0000:00](to urządzenie ma tylko jedną magistralę PCI). A potem mamy kilka urządzeń podłączonych do tej magistrali. Zobaczmy, które są urządzeniami 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

Dobrze, teraz porównajmy to lsusb(używam sorttylko, aby ułatwić późniejsze przeszukiwanie listy):

$ 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

Poczekaj jeszcze raz Mamy 7 urządzeń USB według, lspciale 10 urządzeń według lsusb! lspciwymienia tylko kontrolery USB; do kontrolera może być podłączone więcej niż jedno urządzenie USB. Pozwól nam zbadać, /sys/bus/jak to się dzieje.

$ 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

Teraz zaczyna to mieć sens, mamy 7 kontrolerów USB, które są podłączone do magistrali PCI jako urządzenia. Na przykład magistrala USB 001 odpowiada urządzeniu PCI, 0000:00:12.2a magistrala USB 007 odpowiada 0000:00:14.5urządzeniu.

Numeracja urządzeń

Katalogi zaczynające się od numeru magistrali USB (np. 7-1:1.2) Są rzeczywistymi urządzeniami podłączonymi do kontrolera USB. Podobnie jak magistrala PCI może mieć podłączonych kilka urządzeń, kontroler USB (hub) może mieć podłączonych kilka urządzeń USB.

Numery urządzeń to po prostu liczniki: pierwsze podłączone urządzenie otrzymuje 1, następne 2 i tak dalej. Ale jest jeszcze coś więcej: USB został zaprojektowany tak, aby można go było podłączać podczas pracy; dlatego możesz podłączać i odłączać urządzenia. Po odłączeniu urządzenia USB numer urządzenia nie będzie ponownie używany przez jądro dla żadnego innego urządzenia na tym kontrolerze USB. Na przykład, jeśli podłączysz i odłączysz pendrive'a i lsusbbędziesz kontynuować , zobaczysz numer urządzenia dla pendrivea w górę.

Numeracja autobusów

Jeśli przeczytałeś powyższe z uwagą, możesz zastanawiać się nad jedną rzeczą, której nie dotknąłem. Kolejność numeracji PCI nie odpowiada kolejności, w której kontrolery USB zostały ponumerowane! Zobaczmy to jeszcze raz:

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

Lista jest w porządku, ale nie do końca. Pierwsze dwa kontrolery USB wydają się nie działać. Istnieje jednak powód: Jeśli spojrzysz na to lspcipowyżej, zobaczysz, że są to EHCIUSB (USB 2.0), podczas gdy wszystkie inne kontrolery OHCIUSB to USB (USB 1.x).

Dlatego możemy przerysować tę tabelę jako:

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

Przypisanie liczb staje się jasne.

grochmal
źródło
co się stanie, gdy zostanie użyta maksymalna liczba numerów urządzeń. powiedzmy, że ciągle podłączam urządzenie. Numer urządzenia wkrótce osiągnie maksimum. Zrobiłem test, wygląda na to, że nie jest to zwykły licznik. Nie wraca do 001, zamiast tego jądro ponownie używa największej liczby urządzeń. Czy istnieje prosty sposób na zmianę tego zachowania?
Conan,
@ Conan - Hmm ... cóż, jak mogę to powiedzieć: po prostu nie wiem. Nigdy nie próbowałem przepełnić licznika urządzeń, tak jak ty. Z drugiej strony, nie ma potrzeby wcześniejszego znać numeru urządzenia. Na przykład, jeśli próbujesz znaleźć dysk USB, gdy się łączy, powinieneś to zrobić według etykiety systemu plików lub identyfikatora UUID (który udevmniej więcej rozumie). Aby zrozumieć numerację w celu nauki, uważam, że jedynym miejscem, w którym są informacje, jest kod jądra.
grochmal
Dziękuję @grochmal, myślę, że popełniłem błąd podczas przepełnienia testu. Późniejsze testy pokazały mi, kiedy nastąpiło przepełnienie, licznik rzeczywiście szukał niższej liczby.
Conan