Skip site navigation (1)Skip section navigation (2)
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>