3

Hello I am working on debian system installed on embedded system. The PC has 3 ports usb let's call it A, B, C. I want to execute different script based on the usb port. How can I achieve this?

I found a lot of articles about the udev rules and I have the below rule that it works if I connect a usb.

ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[a-z]1", SYMLINK+="usb_to_check", RUN+="/usr/local/bin/check-usb1.sh"

How can I extend this rule to work only if I connect a device let's say to usb A??

shellter
  • 36,525
  • 7
  • 83
  • 90
user1521944
  • 317
  • 1
  • 2
  • 14
  • This Q is doesn't seem to be about programming as defined for StackOverflow. It **may** be more appropriate on either http://unix.stackexchange.com (Unix & Linux) OR http://superuser.com . Use the `flag` link at the bottom of your Q and ask the moderator to move it. Please don't post the same Q on 2 different sites. Please read http://stackoverflow.com/help/how-to-ask http://stackoverflow.com/help/dont-ask and http://stackoverflow.com/help/mcve before posting more Qs here. Good luck. – shellter Feb 13 '17 at 20:49

2 Answers2

0

lsusb outputs the USB bus and USB ports to which devices are attached. in the output some of the USB root hubs are internal USB hubs to that also bluetooth and webcam and so on are attached, see https://unix.stackexchange.com/questions/144029/command-to-determine-ports-of-a-device-like-dev-tty-usb0

you should figure out on which USB bus your external ports are linked. on my computer all external USB ports are linked to Bus 01

to do this check the output of lsusb -t, then attach a usb device and check the output of lsusb -t again. then you know what 'adresses' your three external usb ports have in your devices internal usb structure tree:

internal USB ports:

/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=ohci_hcd/5p, 12M
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=ohci_hcd/5p, 12M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/5p, 480M
    |__ Port 1: Dev 64, If 0, Class='bInterfaceClass 0x0e not yet handled', Driver=uvcvideo, 480M
    |__ Port 1: Dev 64, If 1, Class='bInterfaceClass 0x0e not yet handled', Driver=uvcvideo, 480M

external USB ports:

/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/5p, 480M
    |__ Port 3: Dev 116, If 0, Class='bInterfaceClass 0xe0 not yet handled', Driver=rndis_host, 480M
    |__ Port 3: Dev 116, If 1, Class=data, Driver=rndis_host, 480M

USB stick attached to external port # 2

/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/5p, 480M
    |__ Port 2: Dev 119, If 0, Class=stor., Driver=usb-storage, 480M
    |__ Port 3: Dev 116, If 0, Class='bInterfaceClass 0xe0 not yet handled', Driver=rndis_host, 480M
    |__ Port 3: Dev 116, If 1, Class=data, Driver=rndis_host, 480M

after this procedure you the 'addresses' of your external USB ports

in dmesg an attached USB device always appears with a line that contains the USB bus and port number:

[186067.360139] usb 1-1: new high-speed USB device number 123 using ehci_hcd is bus 001 port 001

[186067.360139] usb 1-2: new high-speed USB device number 123 using ehci_hcd is bus 001 port 002

[186067.360139] usb 1-3: new high-speed USB device number 123 using ehci_hcd is bus 001 port 003

in your script you grep this line using the command dmesg | grep "usb 1" | tail -1 (the tail -1 greps the last occurence, see http://www.stackoverflow.com/questions/24014194/how-to-grep-the-last-occurence-of-the-line-pattern )

you can get the port number directly using the command

dmesg | grep -o -P 'usb 1.{0,3}' | tail -1 | head -c 7 | tail -c 1 (if all your external ports are on Bus 001)

( Grep characters before and after match?, http://www.unix.com/unix-for-dummies-questions-and-answers/28542-how-do-i-get-nth-character-string.html )

so with this you get the USB port number to that the latest USB device (your device) was attached and this you can use in your udev script (if ...)


you can also find the USB bus tree structure in the /dev/bus/usb/ file sytem i.e. Bus 01 Port 1 is /dev/bus/usb/001/001

see http://www.linuxnix.com/find-usb-device-details-in-linuxunix-using-lsusb-command/

Community
  • 1
  • 1
ralf htp
  • 9,149
  • 4
  • 22
  • 34
0

there is a better solution. you can assign a specific /dev/x device node based on vendorID and productID of your stick using udev, see https://askubuntu.com/questions/127695/force-specific-letter-for-usb-drive-in-dev-sd (x is an arbitrary name)

with this fixed device node you can use udevadm to query the USB port to which the device is attached

udevadm info --query=all --attribute-walk --name/dev/x

and grep the USB port number from it (see other answer ...)

Community
  • 1
  • 1
ralf htp
  • 9,149
  • 4
  • 22
  • 34