8

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 ?

4

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.

  • 1
    I'm confused by the different uses of udev vs. lsusb and sys/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/… – nutty about natty Aug 9 '14 at 17:45
  • @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. – Dmitry Frank Aug 9 '14 at 22:20
0

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.