3
votes

How can you identify individual USB devices to unbind and bind them? Specifically, devices like mice, keyboard, dongles, etc. which are not storage.

For example, on Debian (Raspbian GNU/Linux v8.0 in this case), I have a few devices listed in /sys/bus/usb/drivers/usbhid/:

ls /sys/bus/usb/drivers/usbhid/ shows USB devices:

1-1.2:1.0  1-1.2:1.1  1-1.2:1.2  1-1.3:1.0  1-1.3:1.1  1-1.4:2.2

lsusb shows:

Bus 001 Device 006: ID 1410:9020 Novatel Wireless
Bus 001 Device 009: ID 045e:00db Microsoft Corp. Natural Ergonomic Keyboard 4000 V1.0
Bus 001 Device 008: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

lsusb -t shows:

/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/5p, 480M
        |__ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=smsc95xx, 480M
        |__ Port 2: Dev 8, If 0, Class=Human Interface Device, Driver=usbhid, 12M
        |__ Port 2: Dev 8, If 1, Class=Human Interface Device, Driver=usbhid, 12M
        |__ Port 2: Dev 8, If 2, Class=Human Interface Device, Driver=usbhid, 12M
        |__ Port 3: Dev 9, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
        |__ Port 3: Dev 9, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M
        |__ Port 4: Dev 6, If 0, Class=Communications, Driver=cdc_ether, 480M
        |__ Port 4: Dev 6, If 1, Class=CDC Data, Driver=cdc_ether, 480M
        |__ Port 4: Dev 6, If 2, Class=Human Interface Device, Driver=usbhid, 480M

I know that the Novatel Wireless is 1-1.4:2.2 from guessing.

I can then reset it by running echo -n '1-1.4:2.2' > /sys/bus/usb/drivers/usbhid/unbind and echo -n '1-1.4:2.2' > /sys/bus/usb/drivers/usbhid/bind

It would be great if there was an obvious way to identify it and reset it in a bash script. Also, how can a device be identified and reset if there are more than one of the same hardware on different ports?

1

1 Answers

0
votes

Both pieces of information are in the /dev or /sys/class directory.

You can use ls -l /sys/class/xxx, where xxx substitutes the device category you want to query.

ls -l /sys/class/block:

/sys/devices/pci0000:00/0000:00:12.2/usb1/1-3/1-3:1.0/host251/target251:0:0/251:0:0:0/block/sdb/sdb1

The problem is that you have to know which device you are looking for, i.e., have a name or bus number. However, you can get this information by lsusb or commands used for the specific device class, i.e., ip link (an LTE modem is normally implemented as an RNDIS host and shows up in ip link as usb0), lsblk --output NAME,KNAME,FSTYPE,MOUNTPOINT,RM,UUID, ...

For any USB device, ls - l /sys/class/xxx will output USB port and udev path

Your Novatel Wireless (Ethernet over USB) will be in sys/class/ǹet. You can also identify devices using vendorid and productID.

If you need more information, you can use udevadm:

sudo udevadm info --query=all --attribute-walk --path=/devices/pci0000:00/0000:00:12.2/usb1/1-3/1-3:1.0/host251/target251:0:0/251:0:0:0/block/sdb/sdb1

 looking at device '/devices/pci0000:00/0000:00:12.2/usb1/1-3/1-3:1.0/host237/target237:0:0/237:0:0:0/block/sdb/sdb1':
    KERNEL=="sdb1"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{partition}=="1"
    ATTR{start}=="64"
    ATTR{size}=="62517184"
    ATTR{ro}=="0"
    ATTR{alignment_offset}=="0"
    ATTR{discard_alignment}=="0"
    ATTR{stat}=="     156        7     1304      132        0        0        0        0        0      128      128"
    ATTR{inflight}=="       0        0"

Another possibility is to use run udevadm monitor and then attach the device.

(https://unix.stackexchange.com/questions/116664/map-physical-usb-device-path-to-bus-device-number-returned-by-lsusb, https://unix.stackexchange.com/questions/74513/udev-how-do-you-identify-the-physical-device-that-a-sys-device-belongs-to)

For a mouse (input device), try:

sudo udevadm info --query=all --attribute-walk --name=/dev/input/mouse0