0

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
EEALNT
  • 145
  • 1
  • 13
  • While very interesting, wIthout a [mcve] , your "deep" research question is off-topic for may readers, as there is no code to fix. Edit your question to include the smallest code that illustrates your issue, and define some inputs and expect actions/outputs and you may get help (I haven't voted-to-close or down-voted (yet?) ). Good luck! – shellter Aug 29 '23 at 23:09
  • @shellter Thanks for your input. I've edited my question based on your comments. I hope I understood them correctly. Note though that I don't have any example of the potential solution to which the link I've provided points. That is what I hope will come out of this post. – EEALNT Aug 30 '23 at 06:40
  • Done. I would be happy to get an answer in most any language at this point though. But I added the tag for the preferred one. – EEALNT Aug 31 '23 at 11:27
  • OK, well one final thing, the purpose of StackOverflow is to help people fix their failing code, not to write it for them. As I mentioned in my first comment, a [mcve] shows that you have tried to solve your problem, then did research and honed the problem down to the smallest set of code that can demonstrate the problem. Readers need code they can copy/paste into their environment and work from there. As you said *"...trying to programmatically determine the exact physical USB port."* I had assumed you had at least some code. It doesn't have to be perfect, but include your best attempt. G.L. – shellter Aug 31 '23 at 14:07

0 Answers0