Map physical USB device path to the Bus/Device number returned by lsusb
Solution 1
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.
Solution 2
The accepted answer really didn't help me that much. I finally found out a way by probing the idProduct and idVendor if they exist. Here's a shell script
#!/bin/bash
{
cd /sys/bus/usb/devices
for i in *; do
[ -e $i/idProduct ] && echo $(cat $i/idVendor $i/idProduct) $i
done
}
Here's what I get on my system.
$ ./script
0424 2514 1-3
8087 0024 2-1
0a5c 21e6 2-1.4
8087 0024 4-1
1d6b 0002 usb1
1d6b 0002 usb2
1d6b 0003 usb3
1d6b 0002 usb4
$ lsusb
Bus 004 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 006: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 [ThinkPad]
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Here I can see, that for instance 0a5c:21e6
, which is a bluetooth device, maps to 2-1.4
.
For even greater convenience you could define this as a function in your shell, something like
$ cat >> ~/.bashrc << ENDL
gousb() {
for i in /sys/bus/usb/devices/*; do
if [ -e \$i/idProduct ]; then
if [ \$(cat \$i/idVendor):\$(cat \$i/idProduct) = \$1 ]; then
cd \$i
return
fi
fi
done
echo "\$1 not found :-("
}
ENDL
$ source ~/.bashrc
$ gousb 0a5c:21e6
$ pwd
/sys/bus/usb/devices/2-1.4
Related videos on Youtube
Dmitry Frank
I'm a passionate software engineer with strong background in low-level parts (MCU real-time kernels, C, Assembler), and experienced in higher-level technologies as well: Go, C++, JavaScript, and many others. Author of the well-formed and carefully tested real-time kernel for 16- and 32-bit MCUs: TNeo, which is now used by several companies. One of my hobby projects is a geeky bookmarking service written in Go and PostgreSQL: Geekmarks. Some of my articles: How I ended up writing a new real-time kernel How do JavaScript closures work under the hood Unit-testing (embedded) C applications with Ceedling Object-oriented techniques in C See more at dmitryfrank.com
Updated on September 18, 2022Comments
-
Dmitry Frank over 1 year
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), and2
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
? -
nutty about natty over 9 yearsI'm confused by the different uses of
udev
vs.lsusb
andsys/devices/..
vs./dev/bus/usb/..
and judging by your answer you seem to be in the know :) Maybe you can shed some light on these two questions? askubuntu.com/questions/342061/power-on-off-usb-ports and askubuntu.com/questions/498950/… -
Dmitry Frank over 9 years@nuttyaboutnatty, unfortunately I can't give you any clue on your issue (about powering the device down). I'm just learning linux stuff these days, and I'm quite far from any kind of guru. Very little about
/sys/devices/...
vs/dev/...
:/sys
is populated by the kernel, it's a representation of actual kernel devices hierarchy. Udev is a user-space daemon that handles/sys
hierarchy and populates/dev/...
(taking rules in account). So, udev is completely responsible for/dev
contents.