From owner-freebsd-usb@freebsd.org Mon Sep 21 21:16:18 2015 Return-Path: Delivered-To: freebsd-usb@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E16D0A051D9 for ; Mon, 21 Sep 2015 21:16:17 +0000 (UTC) (envelope-from btik-fbsd@scoubidou.com) Received: from smtp4-g21.free.fr (smtp4-g21.free.fr [IPv6:2a01:e0c:1:1599::13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AD6F91BFF for ; Mon, 21 Sep 2015 21:16:17 +0000 (UTC) (envelope-from btik-fbsd@scoubidou.com) Received: from max.scoubidou.com (unknown [82.237.209.39]) by smtp4-g21.free.fr (Postfix) with ESMTP id A57EE4C8069; Mon, 21 Sep 2015 23:16:06 +0200 (CEST) Received: from zetta.scoubidou.com (unknown [192.168.1.18]) by max.scoubidou.com (Postfix) with ESMTP id D542AF255; Mon, 21 Sep 2015 23:16:05 +0200 (CEST) Subject: Re: Patch to allow dynamic USB quirks at boot To: Hans Petter Selasky , freebsd-usb@FreeBSD.org References: <55FF282D.2040003@scoubidou.com> <55FFA8EA.3030308@selasky.org> From: =?UTF-8?Q?Maxime_Soul=c3=a9?= X-Enigmail-Draft-Status: N1110 Message-ID: <56007395.1010006@scoubidou.com> Date: Mon, 21 Sep 2015 23:16:05 +0200 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <55FFA8EA.3030308@selasky.org> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Sep 2015 21:16:18 -0000 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.