I am trying to programmatically determine the exact physical USB port. It shouldn't matter whether a USB device is plugged into that port or not. The use case is such that I am trying to write a PC application which creates clones of USB block devices. In other words, I have an SD card image which I want to burn to 10 SD cards inserted into the PC using USB SD card readers. If anything goes wrong, I want to be able to signal in the application which cards can't be used and should be discarded. Also, when the burn process is done, each image on the freshly written SD cards gets modified slightly. A unique ID is written onto them. Again, I want to let the user know which card had which ID written to it. (I would put labels/stickers next to physical ports and map what's written on those stickers to GUI "slots" in the PC application.)
After spending a day searching online I was all but convinced that what I am trying to do can't be done. I was only able to find device paths if devices were inserted but paths depended on the order of insertion and not on their physical location on the USB hub (see example in the "edited" section below). So I was about to give up. But then I found this:
https://stackoverflow.com/questions/6416931/can-the-physical-usb-port-be-identified-programmatically-for-a-device-in-windows#:~:text=It%20requires%20opening%20the%20low%2Dlevel%20USB%20root%20hub%20devices%20and%20directly%20sending%20driver%20IOCTL%20commands%20to%20them.
It requires opening the low-level USB root hub devices and directly sending driver IOCTL commands to them.
To be honest it's a bit much for me so before I dive in I wanted to check here if anyone can confirm this would work and perhaps o point me into the right direction for achieving this on Linux (the link above disucsses a solution on Windows). Or offer any other way of achieving what I am describing above.
Note: The operating system I am using is Linux (Ubuntu 20.04).
Thanks!
Edited
Below are outputs of two commands I came across frequently when searching for the answer. One USB SD card reader with an inserted SD card is in one of the free USB ports when running the commands. Lines marked with ####### disapear if I disconnect the USB SD card reader. If I then insert it into another physical USB port, the exact same lines come back. I therefore can't use theese commands to identify a particular pysical USB port.
$ lsusb -t
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
|__ Port 4: Dev 2, If 0, Class=Hub, Driver=hub/7p, 5000M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/7p, 12M
|__ Port 1: Dev 4, If 0, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 2: Dev 3, If 0, Class=Hub, Driver=hub/7p, 480M #######
|__ Port 1: Dev 30, If 0, Class=Mass Storage, Driver=usb-storage, 480M #######
|__ Port 3: Dev 5, If 0, Class=Hub, Driver=hub/7p, 12M
|__ Port 4: Dev 6, If 0, Class=Hub, Driver=hub/7p, 480M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
|__ Port 1: Dev 4, If 0, Class=Wireless, Driver=btusb, 12M
|__ Port 1: Dev 4, If 1, Class=Wireless, Driver=btusb, 12M
|__ Port 2: Dev 3, If 0, Class=Hub, Driver=hub/7p, 12M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/6p, 480M
$ /sys/bus/usb/devices
1-0:1.0 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-0:1.0
2-0:1.0 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb2/2-0:1.0
2-1 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb2/2-1
2-1:1.0 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb2/2-1/2-1:1.0
2-1:1.1 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb2/2-1/2-1:1.1
2-2 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb2/2-2
2-2:1.0 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb2/2-2/2-2:1.0
3-0:1.0 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-0:1.0
3-1 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-1
3-1.1 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-1/3-1.1
3-1.1:1.0 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-1/3-1.1/3-1.1:1.0
3-1:1.0 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-1/3-1:1.0
3-2 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-2
3-2.1 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-2/3-2.1 #######
3-2.1:1.0 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-2/3-2.1/3-2.1:1.0 #######
3-2:1.0 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-2/3-2:1.0
3-3 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-3
3-3:1.0 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-3/3-3:1.0
3-4 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-4
3-4:1.0 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3/3-4/3-4:1.0
4-0:1.0 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb4/4-0:1.0
4-4 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb4/4-4
4-4:1.0 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb4/4-4/4-4:1.0
usb1 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1
usb2 -> ../../../devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb2
usb3 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb3
usb4 -> ../../../devices/pci0000:00/0000:00:15.0/0000:03:00.0/usb4
When researching I've also found lsusb.py. It doesn't seem to help me much though. If I switch physical USB ports, the output of the script is the same as its output when the USB SD card reader is in a different physical port. Output is below. The lines starting with "3-2" and "3-2.1" disappear if no USB SD card reader is inserted and come back when inserted in any of the available USB ports.
$ python3 lsusb.py
WARNING: Failure to read usb.ids
usb1 1d6b:0002 09 1IF [USB 2.00, 480 Mbps, 0mA] (ehci_hcd 0000:02:03.0) hub
usb2 1d6b:0001 09 1IF [USB 1.10, 12 Mbps, 0mA] (uhci_hcd 0000:02:00.0) hub
2-1 0e0f:0008 e0 2IFs [USB 2.00, 12 Mbps, 0mA] (VMware Virtual Bluetooth Adapter 000650268328)
2-2 0e0f:0002 09 1IF [USB 1.10, 12 Mbps, 0mA] (VMware, Inc. VMware Virtual USB Hub) hub
usb3 1d6b:0002 09 1IF [USB 2.00, 480 Mbps, 0mA] (xhci-hcd 0000:03:00.0) hub
3-1 0e0f:0002 09 1IF [USB 1.10, 12 Mbps, 0mA] (VMware, Inc. VMware Virtual USB Hub) hub
3-1.1 0e0f:0003 00 1IF [USB 1.10, 12 Mbps, 0mA] (VMware VMware Virtual USB Mouse)
3-2 0e0f:0002 09 1IF [USB 2.00, 480 Mbps, 0mA] (VMware, Inc. VMware Virtual USB Hub) hub
3-2.1 058f:6366 00 1IF [USB 2.00, 480 Mbps, 100mA] (Generic Mass Storage Device 058F63666433)
3-3 0e0f:0002 09 1IF [USB 1.10, 12 Mbps, 0mA] (VMware, Inc. VMware Virtual USB Hub) hub
3-4 0e0f:0002 09 1IF [USB 2.00, 480 Mbps, 0mA] (VMware, Inc. VMware Virtual USB Hub) hub
usb4 1d6b:0003 09 1IF [USB 3.00, 5000 Mbps, 0mA] (xhci-hcd 0000:03:00.0) hub
4-4 0e0f:0002 09 1IF [USB 3.10, 5000 Mbps, 0mA] (VMware, Inc. VMware Virtual USB Hub) hub