Map physical USB device path to the Bus/Device number returned by lsusb

devicesudevusb

I need to get the title of the attached USB device. I can do that with lsusb.

udev allows some substitutions when I write rules: say, we can use $kernel to get name of the device, or $devpath to get path to the device.

But problem is that lsusb returns string like that:

Bus 005 Device 032: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC

But udev's devpath is:

/devices/pci0000:00/0000:00:1d.0/usb5/5-2 

Bus number is the same (5), but numbers are different: Device 032 seems to be some logical number (when I reattach the device, this number increases), and 2 seems to be physical device number.

So udev returns physical number, and I need to get logical number. Then, i can retrieve data like this: lsusb -D /dev/bus/usb/005/032

So, how can I get logical device number 032 by physical path like /devices/pci0000:00/0000:00:1d.0/usb5/5-2 ?

Best Answer

Firstly, we need to prepend /sys to the path returned by udev, so that path becomes something like: /sys/devices/pci0000:00/0000:00:1d.0/usb5/5-2. Then go to this directory, and there will be several files in it. Among others, there are busnum and devnum files, they contain these "logical" numbers. So, in bash script, we can retrieve them like that:

devpath='/devices/pci0000:00/0000:00:1d.0/usb5/5-2'

busnum=$(cat "/sys/$devpath/busnum")
devnum=$(cat "/sys/$devpath/devnum")

# we might want to make busnum and devnum have leading zeros
# (say, "003" instead of "3", and "012" instead of "12")
busnum=$(printf %03d $busnum)
devnum=$(printf %03d $devnum)

# now, we can retrieve device data by   lsusb -D /dev/bus/usb/$busnum/$devnum

echo "busnum=$busnum, devnum=$devnum"

Also note that udev can return these busnum and devnum directly: in RUN+="..." we can use substitutions $attr{busnum} and $attr{devnum} respectively.

Related Question