Custom Search

Re: [PATCH 0/3] hid: Enable report fixup on rebind

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


Hi Jiri, Henrik,

On 04/23/2012 12:27 AM, Jiri Kosina wrote:
On Sun, 22 Apr 2012, Henrik Rydberg wrote:

This patchset contains a resolution to the problem with
driver-specific modification of the report descriptor. The core of the
problem lies with the dual semantics of hid_parse_report(), which is
therefore split into two functions. As a consequence, the hid core can
handle the rebind case internally, with no changes to the
drivers. Out-of-tree drivers will work fine as long as they operate in
the same way as the in-kernel drivers.

The first two patches are bug fixes found in the process. I am hoping
for some test feedback on those. The third patch is the main one.

Hi Henrik,

thanks a lot for looking into this. I will look into the patches in more
detail tomorrow. I am now just adding Nikolai to CC, as he was the first
one to bring this up and actually has a driver that exposed the fact that
just freeing/reinstatiating rdesc is not enough.

I've managed to throw together a script which rebinds a device to a specific
out-of-tree HID driver automatically. Please find it attached. I'll be
bundling it with the modules, probably.

I'm planning to use it with udev rules looking like this one:

SUBSYSTEM=="hid", ACTION=="add", ENV{HID_ID}=="0003:0000172F:*", \
        RUN+="/usr/local/bin/digimend-rebind"

So, the out-of-tree HID module problem is finally solved, at least for my
current uses. Thanks a lot!

Sincerely,
Nick
#!/bin/sh
#
# DIGImend specific driver rebinding script. To be invoked by udev.
# Author: Nikolai Kondrashov <spbnick@xxxxxxxxx>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# Write a string to a file, ignoring ENODEV.
write_ignore_enodev() {
    local str="$1"
    local path="$2"
    local output=""

    # Write the string with tee, capturing error output
    if ! output="`(echo \"$str\" | tee \"$path\" >/dev/null) 2>&1`"; then
        # Raise anything except ENODEV
        if [ "${output##*: }" != "No such device" ]; then
            echo "$output" >&2
            return 1
        fi
    fi
}

(
	set -e -u

    progname="`basename \"$0\"`"

	id="`basename $DEVPATH`"

    current_driver_path="`readlink -v -f /sys${DEVPATH}/driver`"
    if [ -e "$current_driver_path" ]; then
        current_driver="`basename \"$current_driver_path\"`"
    else
        current_driver=""
    fi

	specific_module="`modprobe -R $MODALIAS`"

	# Assume the driver would be called the same as module,
	# but without the "hid_" or "hid-" prefix
	specific_driver="${specific_module#hid[_-]}"
    specific_driver_path="/sys/bus/hid/drivers/$specific_driver"

	if [ "$current_driver" != "$specific_driver" ]; then
        logger -p daemon.notice -t "$progname" "rebinding $DEVPATH"

		# Ensure the specific driver module is loaded
		modprobe "$specific_module"

		# Unbind from the current driver, if any
        if [ -n "$current_driver" ]; then
            write_ignore_enodev "$id" "$current_driver_path/unbind"
        fi

		# Bind to the specific driver
        write_ignore_enodev "$id" "$specific_driver_path/bind"
	fi
) 2>&1 | logger -p daemon.warning -t "$progname"

[Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Free Online Dating]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux