From patchwork Tue Apr 2 14:18:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 10881805 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8AF4417EE for ; Tue, 2 Apr 2019 14:18:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7728928837 for ; Tue, 2 Apr 2019 14:18:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6AF6E28856; Tue, 2 Apr 2019 14:18:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A5CD28837 for ; Tue, 2 Apr 2019 14:18:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727280AbfDBOSw (ORCPT ); Tue, 2 Apr 2019 10:18:52 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41304 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726142AbfDBOSw (ORCPT ); Tue, 2 Apr 2019 10:18:52 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 687D4C057F3F; Tue, 2 Apr 2019 14:18:52 +0000 (UTC) Received: from shalem.localdomain.com (ovpn-117-220.ams2.redhat.com [10.36.117.220]) by smtp.corp.redhat.com (Postfix) with ESMTP id 62D7183EB0; Tue, 2 Apr 2019 14:18:48 +0000 (UTC) From: Hans de Goede To: Jiri Kosina , Benjamin Tissoires Cc: Hans de Goede , linux-input@vger.kernel.org Subject: [PATCH v2] HID: core: Call request_module before doing device_add Date: Tue, 2 Apr 2019 16:18:46 +0200 Message-Id: <20190402141846.11027-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 02 Apr 2019 14:18:52 +0000 (UTC) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Recent kernels allow the generic-hid driver to be used as fallback for devices with a specialized driver, when the hiddev is not listed in hid_have_special_driver. Over time we are removing more and more devices from the hid_have_special_driver table as devices get tested to support this setup. Before this commit the following happens when a HID device which has a special-driver and is no longer listed in hid_have_special_driver, gets enumerated: 1) device_add() gets called 2) bus_add_device() looks for a matching already registered hid driver, and bind hid-generic to the new device 3) kobject_uevent(&dev->kobj, KOBJ_ADD) gets called notifying userspace of the new hid_dev. udev calls modprobe based on the modalias in the uevent 4) The special driver gets loaded by modprobe 5) __hid_bus_reprobe_drivers() unbinds hid-generic and binds the new driver There are a couple of downsides to this: a) The probing messages printend when a HID driver bounds show up twice in dmesg, which is confusing for the user b) The (un)binding typically causes one or more evdev device-nodes to get (un)registed firing of udev events to which e.g. the xserver responds by (un)registering xinput devices and reporting this to interested clients. IOW the i. bind generic, ii. unbind generic, iii. bind special driver dance sets in motion a whole chain of events each step, while we really only want the events from step iii. to be reported to userspace. This commits introduces a request_module call before the device_add() call, so that the special-driver is loaded when step 2) looks for a matching driver and we directly bind the specialized driver. Note the request_module call translates to an execve("/sbin/modprobe", ...) and we now do this for each HID device added. So this is not entirely free, but adding HID devices is not something which happens 100s of times a second, so this should be fine. Signed-off-by: Hans de Goede --- Changes in v2: -Things work better if we don't add '\n' at the end of the modalias --- drivers/hid/hid-core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 9993b692598f..b321bd08d94c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2349,6 +2349,14 @@ int hid_add_device(struct hid_device *hdev) dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, hdev->vendor, hdev->product, atomic_inc_return(&id)); + /* + * Try loading the module for the device before the add, so that we do + * not first have hid-generic binding only to have it replaced + * immediately afterwards with a specialized driver. + */ + request_module("hid:b%04Xg%04Xv%08Xp%08X", + hdev->bus, hdev->group, hdev->vendor, hdev->product); + hid_debug_register(hdev, dev_name(&hdev->dev)); ret = device_add(&hdev->dev); if (!ret)