lkml.org 
[lkml]   [2018]   [Jul]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.17 44/56] HID: core: allow concurrent registration of drivers
    Date
    4.17-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Benjamin Tissoires <benjamin.tissoires@redhat.com>

    commit 8f732850df1b2b4d8d719f7e606dfb3050e7ea11 upstream.

    Detected on the Dell XPS 9365.

    The laptop has 2 devices that benefit from the hid-generic auto-unbinding.
    When those 2 devices are presented to the userspace, udev loads both wacom and
    hid-multitouch. When this happens, the code in __hid_bus_reprobe_drivers() is
    called concurrently and the second device gets reprobed twice.

    An other bug in the power_supply subsystem prevent to remove the wacom driver
    if it just finished its initialization, which basically kills the wacom node.

    [jkosina@suse.cz: reformat changelog a bit]
    Fixes c17a7476e4c4 ("HID: core: rewrite the hid-generic automatic unbind")
    Cc: stable@vger.kernel.org # v4.17
    Tested-by: Mario Limonciello <mario.limonciello@dell.com>
    Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
    Signed-off-by: Jiri Kosina <jkosina@suse.cz>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/hid/hid-core.c | 5 ++++-
    include/linux/hid.h | 3 ++-
    2 files changed, 6 insertions(+), 2 deletions(-)

    --- a/drivers/hid/hid-core.c
    +++ b/drivers/hid/hid-core.c
    @@ -1942,6 +1942,8 @@ static int hid_device_probe(struct devic
    }
    hdev->io_started = false;

    + clear_bit(ffs(HID_STAT_REPROBED), &hdev->status);
    +
    if (!hdev->driver) {
    id = hid_match_device(hdev, hdrv);
    if (id == NULL) {
    @@ -2205,7 +2207,8 @@ static int __hid_bus_reprobe_drivers(str
    struct hid_device *hdev = to_hid_device(dev);

    if (hdev->driver == hdrv &&
    - !hdrv->match(hdev, hid_ignore_special_drivers))
    + !hdrv->match(hdev, hid_ignore_special_drivers) &&
    + !test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status))
    return device_reprobe(dev);

    return 0;
    --- a/include/linux/hid.h
    +++ b/include/linux/hid.h
    @@ -502,6 +502,7 @@ struct hid_output_fifo {

    #define HID_STAT_ADDED BIT(0)
    #define HID_STAT_PARSED BIT(1)
    +#define HID_STAT_REPROBED BIT(3)

    struct hid_input {
    struct list_head list;
    @@ -568,7 +569,7 @@ struct hid_device { /* device repo
    bool battery_avoid_query;
    #endif

    - unsigned int status; /* see STAT flags above */
    + unsigned long status; /* see STAT flags above */
    unsigned claimed; /* Claimed by hidinput, hiddev? */
    unsigned quirks; /* Various quirks the device can pull on us */
    bool io_started; /* If IO has started */

    \
     
     \ /
      Last update: 2018-07-10 20:59    [W:4.161 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site