I am trying to write a udev rule that will activate / deactivate my touchpad based on whether a usb mouse is plugged in.
I have a script in /usr/local/bin that adds / removes the ps-mouse module, based on what ACTION is sent by udev:
Code:
root@asus-n56v:/usr/local/bin$ cat usb-mouse-hotplug.sh
#!/bin/bash
if [ ${ACTION} == "add" ];then
modprobe -r psmouse
elif [ ${ACTION} == "remove" ];then
modprobe psmouse
fi
echo "Mouse hotplug on "$(date) > /tmp/hotplug.log
echo "" >> /tmp/hotplug.log
env >> /tmp/hotplug.log
The script is executable.
It also writes some info and a timestamp into /tmp/hotplug.log as you can see.
I am testing with this mouse:
Code:
root@asus-n56v:$ udevadm info -a -p /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/input/input56
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/input/input56':
KERNEL=="input56"
SUBSYSTEM=="input"
DRIVER==""
ATTR{name}=="USB Optical Mouse"
ATTR{phys}=="usb-0000:00:14.0-4/input0"
ATTR{uniq}==""
ATTR{properties}=="0"
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0':
KERNELS=="1-4:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="usbhid"
ATTRS{bInterfaceClass}=="03"
ATTRS{bInterfaceSubClass}=="01"
ATTRS{bInterfaceProtocol}=="02"
ATTRS{bNumEndpoints}=="01"
ATTRS{supports_autosuspend}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceNumber}=="00"
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-4':
KERNELS=="1-4"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{devpath}=="4"
ATTRS{idVendor}=="192f"
ATTRS{speed}=="1.5"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="8"
ATTRS{busnum}=="1"
ATTRS{devnum}=="39"
ATTRS{configuration}==""
ATTRS{bMaxPower}=="98mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="a0"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="0"
ATTRS{bcdDevice}=="0200"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="12305"
ATTRS{ltm_capable}=="no"
ATTRS{removable}=="unknown"
ATTRS{idProduct}=="0416"
ATTRS{bDeviceClass}=="00"
ATTRS{product}=="USB Optical Mouse"
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1':
KERNELS=="usb1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="01"
ATTRS{devpath}=="0"
ATTRS{idVendor}=="1d6b"
ATTRS{speed}=="480"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{authorized_default}=="1"
ATTRS{busnum}=="1"
ATTRS{devnum}=="1"
ATTRS{configuration}==""
ATTRS{bMaxPower}=="0mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="e0"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="4"
ATTRS{bcdDevice}=="0310"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{serial}=="0000:00:14.0"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="6466"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="Linux 3.10.60.edr.1 xhci_hcd"
ATTRS{removable}=="unknown"
ATTRS{idProduct}=="0002"
ATTRS{bDeviceClass}=="09"
ATTRS{product}=="xHCI Host Controller"
looking at parent device '/devices/pci0000:00/0000:00:14.0':
KERNELS=="0000:00:14.0"
SUBSYSTEMS=="pci"
DRIVERS=="xhci_hcd"
ATTRS{irq}=="44"
ATTRS{subsystem_vendor}=="0x1043"
ATTRS{broken_parity_status}=="0"
ATTRS{class}=="0x0c0330"
ATTRS{consistent_dma_mask_bits}=="32"
ATTRS{dma_mask_bits}=="64"
ATTRS{local_cpus}=="00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,000000ff"
ATTRS{device}=="0x1e31"
ATTRS{enable}=="1"
ATTRS{msi_bus}==""
ATTRS{local_cpulist}=="0-7"
ATTRS{vendor}=="0x8086"
ATTRS{subsystem_device}=="0x1477"
ATTRS{numa_node}=="-1"
ATTRS{d3cold_allowed}=="1"
looking at parent device '/devices/pci0000:00':
KERNELS=="pci0000:00"
SUBSYSTEMS==""
DRIVERS==""
and
Code:
root@asus-n56v:~$ lsusb -d 192f:0416 -v
Bus 001 Device 040: ID 192f:0416 Avago Technologies, Pte.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x192f Avago Technologies, Pte.
idProduct 0x0416
bcdDevice 2.00
iManufacturer 0
iProduct 2 USB Optical Mouse
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 98mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 2 Mouse
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 71
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0006 1x 6 bytes
bInterval 10
Device Status: 0x0000
(Bus Powered)
Here my udev rules file:
Code:
ATTRS{bInterfaceProtocol}=="02", ATTRS{bInterfaceClass}=="03", ATTRS{bInterfaceSubClass}=="01", RUN+="/usr/local/bin/usb-mouse-hotplug.sh"
As far as I understand this should match all usb mouses, not just one specific product.
The funny thing is that this works upon plugin, but not upon unplug.
So for testing purposes I tested with a more specific rule:
Code:
ATTRS{idVendor}=="192f", ATTRS{idProduct}=="0416", RUN+="/usr/local/bin/usb-mouse-hotplug.sh"
This works fine. Both for plug and unplug. If I use this rule, the logfile of the unplug event looks as follows:
Code:
root@asus-n56v:/etc/udev/rules.d$ cat /tmp/hotplug.log
Mouse hotplug on Mon Nov 17 23:00:26 CET 2014
ID_USB_DRIVER=usbhid
ID_MODEL=USB_Optical_Mouse
ID_PATH_TAG=pci-0000_00_14_0-usb-0_4_1_0
ID_MODEL_ENC=USB\x20Optical\x20Mouse
ID_REVISION=0200
ID_BUS=usb
SUBSYSTEM=input
EV=17
ID_SERIAL=192f_USB_Optical_Mouse
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/input/input57
NAME="USB Optical Mouse"
ID_MODEL_ID=0416
ID_VENDOR_ENC=192f
ID_INPUT_MOUSE=1
ACTION=remove
MODALIAS=input:b0003v192Fp0416e0111-e0,1,2,4,k110,111,112,r0,1,6,8,am4,lsfw
PWD=/
UDEV_LOG=3
REL=143
KEY=70000 0 0 0 0
USEC_INITIALIZED=10222831102
ID_VENDOR_ID=192f
SHLVL=1
MSC=10
PHYS="usb-0000:00:14.0-4/input0"
ID_TYPE=hid
PRODUCT=3/192f/416/111
PROP=0
ID_VENDOR=192f
ID_USB_INTERFACE_NUM=00
ID_INPUT=1
UNIQ=""
SEQNUM=2437
ID_USB_INTERFACES=:030102:
ID_PATH=pci-0000:00:14.0-usb-0:4:1.0
_=/usr/bin/env
SUBSYSTEM=hidraw
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/0003:192F:0416.0027/hidraw/hidraw0
MINOR=0
ACTION=remove
PWD=/
UDEV_LOG=3
USEC_INITIALIZED=11145880798
MAJOR=251
DEVNAME=/dev/hidraw0
SHLVL=1
SEQNUM=2438
_=/usr/bin/env
How can I get the more generic rule to work for the unplug event?
EDIT: I think I found what goes wrong. According to syslog the unplug event is detected on a higher level. It says:
Code:
Nov 17 23:16:15 asus-n56v kernel: [12089.086935] usb 1-4: USB disconnect, device number 46
So I tried a rule based on the attributes given after the line looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-4': in the udevadm output:
Code:
KERNELS=="1-4", SUBSYSTEMS=="usb", DRIVERS=="usb", RUN+="/usr/local/bin/usb-mouse-hotplug.sh"
But I am assuming this is not specific enough to limit the behavior to usb mouses?
Is there any good documentation on all the attributes?