Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to identify a disconnecting USB device using udev rules?

Tags:

udev

I have two LCD's using Xorg's xinerama feature. Each LCD screen has a touchscreen which are connected to their respective USB lines.

Looking into the '/var/log/messages' file, I see the following:

kernel: input: Analog Resistive as /class/input/input0
kernel: input: USB HID v1.01 Mouse [Analog Resistive] on usb-0000:00:1d.3-1
kernel: input: Analog Resistive as /class/input/input1
kernel: input: USB HID v1.01 Mouse [Analog Resistive] on usb-0000:00:1d.3-2

For some reason, at some point in time the USB bus seems to reset (or something weird) and my two touchscreens get inverted (press the left LCD and the mouse moves on the right and if I press the right LCD the mouse moves on the left).

To try and debug the problem, I tried to write a udev rule to log when my devices get reset/disconnected (or whatever). But it seems as though udev will report full details (product, manufacturer, idProduct, idVendor, etc) on the device when it connects, but gives you nothing but a few bus numbers when it is removed. Why is this?

When I get an ACTION=="remove", KERNEL=="input*" rule, there is no way for me to know which device it is! Does anyone know a way around this?

like image 820
Jeach Avatar asked Sep 24 '09 21:09

Jeach


1 Answers

i'd suggest first thing check udev events on device "remove" event by running e.g. udevadm monitor --kernel --property --subsystem-match=usb and disconnecting your devices in turn and comparing outputs. Here on a single mouse disconnect i get two events:

KERNEL[6680.737678] remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
ACTION=remove
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0
DEVTYPE=usb_interface
INTERFACE=3/1/2
MODALIAS=usb:v09DAp000Ad0034dc00dsc00dp00ic03isc01ip02in00
PRODUCT=9da/a/34
SEQNUM=2835
SUBSYSTEM=usb
TYPE=0/0/0

KERNEL[6680.739577] remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
ACTION=remove
BUSNUM=002
DEVNAME=/dev/bus/usb/002/006
DEVNUM=006
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2
DEVTYPE=usb_device
MAJOR=189
MINOR=133
PRODUCT=9da/a/34
SEQNUM=2836
SUBSYSTEM=usb
TYPE=0/0/0

You can write your rule invoking a script which should do some job after examining some specific environment variable. A rule may be as simple as

SUBSYSTEM=="usb", ACTION=="remove", RUN+="/usr/local/sbin/usbdevgone.sh"

In your case i'd suggest checking $DEVPATH inside usbdevgone.sh as they should differ for your two otherwise identical devices. Also you may pass devpath (this is a path in /sys/ filesystem) as an argument to your script like this (see man udev for a list of available substitutions):

SUBSYSTEM=="usb", ACTION=="remove", RUN+="/usr/local/sbin/usbdevgone.sh $devpath"

Do not forget to notify udevd of your new or changed rule with udevadm control --reload-rules

like image 172
mz0 Avatar answered Oct 06 '22 16:10

mz0