Date: Sun, 20 Sep 2015 23:42:05 +0200 From: =?UTF-8?Q?Maxime_Soul=c3=a9?= <btik-fbsd@scoubidou.com> To: freebsd-usb@FreeBSD.org Subject: Patch to allow dynamic USB quirks at boot Message-ID: <55FF282D.2040003@scoubidou.com>
next in thread | raw e-mail | index | archive | help
Hi all, I own a X9800 Tecknet mouse with 3 side buttons. When I plug it in, a ukbd device appears handling each 3 buttons with key modifiers Control, Shift and Alt, with one device uhid. As I wanted to see these buttons as buttons under X and not as key modifiers, I first thought about using USB quirk UQ_KBD_IGNORE and devd to hack it. I succeeded (more or less) but devd starts to late during boot to be able to apply the quirk when the mouse is already plugged in, so I needed to always plug the mouse in once the system has booted... Not very cool... When the USB quirk UQ_KBD_IGNORE is applied, the ukbd device does not appear, but two uhid devices appear, including the one dedicated to the "keyboard" feature of the mouse. During my searches on the net, I found the Bug 122819 in which Maurice Castro implemented dynamic quirks in 2008, allowing quirks to be defined dynamically and also through the environment. Unfortunately, this code was for the old USB 1 stack. Indeed, the new USB 2 stack allows dynamic additions to the quirk table, but not at boot time (or I did not find the way). So, I made a patch, with the help of Maurice one, allowing the modification of the quirks table through the environment: http://scoubidou.com/usb_quirk/usb_quirk.diff Now in my loader.conf, I have: usb.quirk.0="0x04d9 0xfa50 0 0xffff UQ_KBD_IGNORE" The value format is "VendorId ProductId LowRevision HighRevision Quirk1,...,QuirkN". One can have usb.quirk.1, .2, ..., .99 if there is enough space in the quirks table... In a devd conf file: notify 1000 { match "system" "DEVFS"; match "subsystem" "CDEV"; match "type" "CREATE"; match "cdev" "uhid[0-9]+"; action "/usr/bin/usbhidctl -f /dev/$cdev \ Keyboard:Keyboard_LeftShift \ Keyboard:Keyboard_LeftAlt \ Keyboard:Keyboard_LeftControl > /dev/null 2>&1 \ && DISPLAY=:0.0 /usr/bin/usbhidaction -f $cdev \ -c /usr/local/etc/tecknet-mouse-usbhidaction.conf \ -p /var/run/usbhidaction.$cdev.pid"; }; The usbhidctl is to check that we handle the right uhid device, the one with Keyboard_LeftShift, Keyboard_LeftAlt AND Keyboard_LeftControl features. Then, usbhidaction daemon can be launched to handle all the "keyboard" events. And the contents of my /usr/local/etc/tecknet-mouse-usbhidaction.conf file: Keyboard:Keyboard_LeftShift 1 0 /usr/local/bin/xdotool mousedown 8 Keyboard:Keyboard_LeftShift 0 1 /usr/local/bin/xdotool mouseup 8 Keyboard:Keyboard_LeftAlt 1 0 /usr/local/bin/xdotool mousedown 9 Keyboard:Keyboard_LeftAlt 0 1 /usr/local/bin/xdotool mouseup 9 Keyboard:Keyboard_LeftControl 1 0 /usr/local/bin/xdotool mousedown 6 Keyboard:Keyboard_LeftControl 0 1 /usr/local/bin/xdotool mouseup 6 to translate "keyboard" actions to buttons clicks thanks to xdotool (from ports). And all works like a charm :) Finally, I have two questions: First, is there a way to link the uhid device with the USB vendor/product ID in devd? Without doing it using a script and parsing devinfo output of course... Second, when I unplug the mouse, devd did not receive the "DESTROY" event for the uhid device, until the usbhidaction daemon is killed. But I would have liked to be able to kill usbhidaction daemon automatically when the mouse is unplugged using devd... With USB vendor/product details available at uhid level, I could have done it when the corresponding ugen device is DETACHed by caching this information... Best regards, Max.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?55FF282D.2040003>