Date: Mon, 21 Sep 2015 23:16:05 +0200 From: =?UTF-8?Q?Maxime_Soul=c3=a9?= <btik-fbsd@scoubidou.com> To: Hans Petter Selasky <hp@selasky.org>, freebsd-usb@FreeBSD.org Subject: Re: Patch to allow dynamic USB quirks at boot Message-ID: <56007395.1010006@scoubidou.com> In-Reply-To: <55FFA8EA.3030308@selasky.org> References: <55FF282D.2040003@scoubidou.com> <55FFA8EA.3030308@selasky.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Le 21.09.2015 08:51, Hans Petter Selasky a écrit : > On 09/20/15 23:42, Maxime Soulé wrote: >> 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 > > Hi, > > Can you make this patch into a PR at FreeBSD's bugzilla and I will > process it. Yes, I've been thinking about this feature, and you just > implemented it! Thank you :-) Hi, Done, bug 203249. > >> >> 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... > > There is a chicken-egg situation there. If your application using > /dev/uhidX doesn't close its device upon receiving a read/poll error, > you might not receive the detach event, depending on which kernel you > use, because the kernel waits for /dev/uhidX to be detached/closed > before generating the destruction event. > > You might want to listen to some other events. See how > /usr/local/etc/devd/webcamd.conf is doing it from > /usr/ports/multimedia/webcamd . > > --HPS I found a solution using "attach" instead of "notice" in my devd conf file. Really devd rocks! :) attach 1000 { device-name "uhid[0-9]+"; match "vendor" "0x04d9"; match "product" "0xfa50"; match "intsubclass" "0x01"; match "intprotocol" "0x01"; action "DISPLAY=:0.0 /usr/bin/usbhidaction -f $device-name \ -c /usr/local/etc/tecknet-mouse-usbhidaction.conf \ -p /var/run/usbhidaction.$ugen.pid"; }; notify 1000 { match "system" "USB"; match "subsystem" "DEVICE"; match "type" "DETACH"; match "vendor" "0x04d9"; match "product" "0xfa50"; action "[ -e /var/run/usbhidaction.$ugen.pid ] \ && kill `cat /var/run/usbhidaction.$ugen.pid`"; }; Using "attach" instead of "notice" allows to access the $ugen device corresponding to the $device-name (here uhidN). It allows too to access "intsubclass" and "intprotocol" to filter finely, avoiding a unnecessary probe using usbhidctl as I did before. So the PID file of usbhidaction can be saved in a file whose name include $ugen. Then the "notify" of the "DETACH" can easily kill it. EXCEPT, EXCEPT, that usbhidaction does not save the right PID when launched in daemon mode! I just submitted bug 203252 to correct this. Best regards, Max.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?56007395.1010006>