Augier
Augier

Reputation: 364

How to reliably determine which USB device under /sys/device corresponds to the plug at the front of the computer

Here my problem: most of Qnap's NAS feature a "copy" button on the front, next to a USB-A port. That button will copy the content of any hard-drive plugged to the USB port next to it.

Image of a Qnap TVS-x72XT front panel showing the button and the USB port

I want to develop that feature for Linux. But I'm having troubles finding a way to reliably determine which device under /sys/devices corresponds to that USB port. On my machine, the device plugged to that port shows up under /sys/devices/.../usb2/2-4/2-4:1.0 for a USB3 HDD and /sys/devices/.../usb1/1-4/1-4:1.0 for an USB2 flash thumb.

I thought I solved my problem with /sys/devices/.../physical_location but the port doesn't declare the same location for a USB2 device than for a USB3. ({"horizontal_position": "left", "vertical_position": "lower", "panel": "left"} for USB3, {"horizontal_position": "center", "vertical_position": "lower", "panel": "left"} for USB2).

There must be a way to match that USB port to the storage plugged to it since Qnap's OS does it, but after several days searching, I can't find it.

Edit

For precision, here it what lsusb -tv gives me when a USB2 device is plugged to the port on the front:

# lsusb -tv
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 2: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        ID 2537:1081 Norelsys 
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 4: Dev 4, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        ID 090c:1000 Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) Flash Drive

Here is what I get when a USB3 is plugged in the front:

# lsusb -tv
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 2: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        ID 2537:1081 Norelsys 
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
    |__ Port 4: Dev 20, If 0, Class=Mass Storage, Driver=uas, 5000M
        ID 04e8:61b5 Samsung Electronics Co., Ltd M3 Portable Hard Drive 2TB
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub

Then I tested 3 more cases:

  1. One USB2 device plugged to one of the port at the back and one USB3 plugged to the other port; nothing plugged to the front:
# lsusb -tv
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 2: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        ID 2537:1081 Norelsys 
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
    |__ Port 3: Dev 21, If 0, Class=Mass Storage, Driver=uas, 5000M
        ID 04e8:61b5 Samsung Electronics Co., Ltd M3 Portable Hard Drive 2TB
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 2: Dev 5, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        ID 090c:1000 Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) Flash Drive
  1. Same as before be with the 2 device switched; still nothing plugged to the front:
# lsusb -tv 
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 2: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        ID 2537:1081 Norelsys 
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
    |__ Port 2: Dev 22, If 0, Class=Mass Storage, Driver=uas, 5000M
        ID 04e8:61b5 Samsung Electronics Co., Ltd M3 Portable Hard Drive 2TB
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 3: Dev 6, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        ID 090c:1000 Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) Flash Drive
  1. 3 USB2 device plugged on all 3 USB-A ports:
# lsusb -tv
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 2: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        ID 2537:1081 Norelsys 
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 2: Dev 12, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        ID 058f:6387 Alcor Micro Corp. Flash Drive
    |__ Port 3: Dev 11, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        ID 058f:6387 Alcor Micro Corp. Flash Drive
    |__ Port 4: Dev 10, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        ID 090c:1000 Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) Flash Drive

When the device is USB2, it always use Bus 01.Port 1 so this doesn't help me discriminate whether is is plugged on the front or at the back. Also note that Bus 03.Port 1 seems to be exclusively the internal storage that hosts the Qnap OS.

Upvotes: 0

Views: 49

Answers (1)

Augier
Augier

Reputation: 364

So I could reach someone involved in the kernel development. What they told me is that the results provided by lsusb should be consistent. Except for the bus variation between USB2 and 3, everything should stay the same if the hub firmware behaves itself. It's not something that's under the kernel's control.

So here is the process I followed:

  1. plug a USB3 disk,
  2. note the path it is assigned in /dev
  3. get the udev properties with udevadm info --attribute-walk --path=$(udevadm info --query=path --name=/dev/<device>)
  4. reiterate for a USB2 device.

With those results, I wrote the following udev rule:

SUBSYSTEM=="block", KERNELS=="1-4|2-4", SUBSYSTEMS=="usb", ENV{DEVTYPE}=="disk", SYMLINK+="qnap-one-touch-copy"

I hope it will be enough to

Upvotes: 0

Related Questions