Skip to content

Commit 207733f

Browse files
dtorJiri Kosina
authored andcommitted
HID: split apart hid_device_probe to make logic more apparent
hid_device_probe() has a complex flow and locks and unlocks a mutex. Move the most of the logic into __hid_device_probe() and hid_check_device_match() and leave the locking in hid_device_probe() which makes the code more clear. Signed-off-by: Dmitry Torokhov <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 34da76d commit 207733f

File tree

1 file changed

+54
-47
lines changed

1 file changed

+54
-47
lines changed

drivers/hid/hid-core.c

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,64 +2587,71 @@ bool hid_compare_device_paths(struct hid_device *hdev_a,
25872587
}
25882588
EXPORT_SYMBOL_GPL(hid_compare_device_paths);
25892589

2590+
static bool hid_check_device_match(struct hid_device *hdev,
2591+
struct hid_driver *hdrv,
2592+
const struct hid_device_id **id)
2593+
{
2594+
*id = hid_match_device(hdev, hdrv);
2595+
if (!*id)
2596+
return -ENODEV;
2597+
2598+
if (hdrv->match)
2599+
return hdrv->match(hdev, hid_ignore_special_drivers);
2600+
2601+
/*
2602+
* hid-generic implements .match(), so we must be dealing with a
2603+
* different HID driver here, and can simply check if
2604+
* hid_ignore_special_drivers is set or not.
2605+
*/
2606+
return !hid_ignore_special_drivers;
2607+
}
2608+
2609+
static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
2610+
{
2611+
const struct hid_device_id *id;
2612+
int ret;
2613+
2614+
if (!hid_check_device_match(hdev, hdrv, &id))
2615+
return -ENODEV;
2616+
2617+
/* reset the quirks that has been previously set */
2618+
hdev->quirks = hid_lookup_quirk(hdev);
2619+
hdev->driver = hdrv;
2620+
2621+
if (hdrv->probe) {
2622+
ret = hdrv->probe(hdev, id);
2623+
} else { /* default probe */
2624+
ret = hid_open_report(hdev);
2625+
if (!ret)
2626+
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
2627+
}
2628+
2629+
if (ret) {
2630+
hid_close_report(hdev);
2631+
hdev->driver = NULL;
2632+
}
2633+
2634+
return ret;
2635+
}
2636+
25902637
static int hid_device_probe(struct device *dev)
25912638
{
2592-
struct hid_driver *hdrv = to_hid_driver(dev->driver);
25932639
struct hid_device *hdev = to_hid_device(dev);
2594-
const struct hid_device_id *id;
2640+
struct hid_driver *hdrv = to_hid_driver(dev->driver);
25952641
int ret = 0;
25962642

2597-
if (down_interruptible(&hdev->driver_input_lock)) {
2598-
ret = -EINTR;
2599-
goto end;
2600-
}
2601-
hdev->io_started = false;
2643+
if (down_interruptible(&hdev->driver_input_lock))
2644+
return -EINTR;
26022645

2646+
hdev->io_started = false;
26032647
clear_bit(ffs(HID_STAT_REPROBED), &hdev->status);
26042648

2605-
if (!hdev->driver) {
2606-
id = hid_match_device(hdev, hdrv);
2607-
if (id == NULL) {
2608-
ret = -ENODEV;
2609-
goto unlock;
2610-
}
2649+
if (!hdev->driver)
2650+
ret = __hid_device_probe(hdev, hdrv);
26112651

2612-
if (hdrv->match) {
2613-
if (!hdrv->match(hdev, hid_ignore_special_drivers)) {
2614-
ret = -ENODEV;
2615-
goto unlock;
2616-
}
2617-
} else {
2618-
/*
2619-
* hid-generic implements .match(), so if
2620-
* hid_ignore_special_drivers is set, we can safely
2621-
* return.
2622-
*/
2623-
if (hid_ignore_special_drivers) {
2624-
ret = -ENODEV;
2625-
goto unlock;
2626-
}
2627-
}
2628-
2629-
/* reset the quirks that has been previously set */
2630-
hdev->quirks = hid_lookup_quirk(hdev);
2631-
hdev->driver = hdrv;
2632-
if (hdrv->probe) {
2633-
ret = hdrv->probe(hdev, id);
2634-
} else { /* default probe */
2635-
ret = hid_open_report(hdev);
2636-
if (!ret)
2637-
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
2638-
}
2639-
if (ret) {
2640-
hid_close_report(hdev);
2641-
hdev->driver = NULL;
2642-
}
2643-
}
2644-
unlock:
26452652
if (!hdev->io_started)
26462653
up(&hdev->driver_input_lock);
2647-
end:
2654+
26482655
return ret;
26492656
}
26502657

0 commit comments

Comments
 (0)