Message ID | 20240910-hid-bpf-hid-generic-v2-8-083dfc189e97@kernel.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | HID: bpf: add a new hook to control hid-generic | expand |
On Tue, Sep 10, 2024 at 11:43:44PM +0900, Benjamin Tissoires wrote: > We already have the possibility to force not binding to hid-generic and > rely on a dedicated driver, but we couldn't do the other way around. > > This is useful for BPF programs where we are fixing the report descriptor > and the events, but want to avoid a specialized driver to come after BPF > which would unwind everything that is done there. > > Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> > > --- > > changes in v2: > - rely on hdev->quirks for that instead of a new struct for hid_driver I like this one a lot more than the previous approach, series is Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> although for 01 and 06 this should be taken with a grain of salt :) Cheers, Peter > --- > drivers/hid/hid-core.c | 5 +++-- > drivers/hid/hid-generic.c | 3 +++ > include/linux/hid.h | 2 ++ > 3 files changed, 8 insertions(+), 2 deletions(-) > > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c > index 37e52759a931..bf63e2819baf 100644 > --- a/drivers/hid/hid-core.c > +++ b/drivers/hid/hid-core.c > @@ -2665,9 +2665,10 @@ static bool hid_check_device_match(struct hid_device *hdev, > /* > * hid-generic implements .match(), so we must be dealing with a > * different HID driver here, and can simply check if > - * hid_ignore_special_drivers is set or not. > + * hid_ignore_special_drivers or HID_QUIRK_IGNORE_SPECIAL_DRIVER > + * are set or not. > */ > - return !hid_ignore_special_drivers; > + return !hid_ignore_special_drivers && !(hdev->quirks & HID_QUIRK_IGNORE_SPECIAL_DRIVER); > } > > static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) > diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c > index f9db991d3c5a..88882c1bfffe 100644 > --- a/drivers/hid/hid-generic.c > +++ b/drivers/hid/hid-generic.c > @@ -40,6 +40,9 @@ static bool hid_generic_match(struct hid_device *hdev, > if (ignore_special_driver) > return true; > > + if (hdev->quirks & HID_QUIRK_IGNORE_SPECIAL_DRIVER) > + return true; > + > if (hdev->quirks & HID_QUIRK_HAVE_SPECIAL_DRIVER) > return false; > > diff --git a/include/linux/hid.h b/include/linux/hid.h > index d41fa18f1e03..b3a9586363c9 100644 > --- a/include/linux/hid.h > +++ b/include/linux/hid.h > @@ -359,6 +359,7 @@ struct hid_item { > * | @HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP: > * | @HID_QUIRK_HAVE_SPECIAL_DRIVER: > * | @HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE: > + * | @HID_QUIRK_IGNORE_SPECIAL_DRIVER > * | @HID_QUIRK_FULLSPEED_INTERVAL: > * | @HID_QUIRK_NO_INIT_REPORTS: > * | @HID_QUIRK_NO_IGNORE: > @@ -384,6 +385,7 @@ struct hid_item { > #define HID_QUIRK_HAVE_SPECIAL_DRIVER BIT(19) > #define HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE BIT(20) > #define HID_QUIRK_NOINVERT BIT(21) > +#define HID_QUIRK_IGNORE_SPECIAL_DRIVER BIT(22) > #define HID_QUIRK_FULLSPEED_INTERVAL BIT(28) > #define HID_QUIRK_NO_INIT_REPORTS BIT(29) > #define HID_QUIRK_NO_IGNORE BIT(30) > > -- > 2.46.0 >
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 37e52759a931..bf63e2819baf 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2665,9 +2665,10 @@ static bool hid_check_device_match(struct hid_device *hdev, /* * hid-generic implements .match(), so we must be dealing with a * different HID driver here, and can simply check if - * hid_ignore_special_drivers is set or not. + * hid_ignore_special_drivers or HID_QUIRK_IGNORE_SPECIAL_DRIVER + * are set or not. */ - return !hid_ignore_special_drivers; + return !hid_ignore_special_drivers && !(hdev->quirks & HID_QUIRK_IGNORE_SPECIAL_DRIVER); } static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c index f9db991d3c5a..88882c1bfffe 100644 --- a/drivers/hid/hid-generic.c +++ b/drivers/hid/hid-generic.c @@ -40,6 +40,9 @@ static bool hid_generic_match(struct hid_device *hdev, if (ignore_special_driver) return true; + if (hdev->quirks & HID_QUIRK_IGNORE_SPECIAL_DRIVER) + return true; + if (hdev->quirks & HID_QUIRK_HAVE_SPECIAL_DRIVER) return false; diff --git a/include/linux/hid.h b/include/linux/hid.h index d41fa18f1e03..b3a9586363c9 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -359,6 +359,7 @@ struct hid_item { * | @HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP: * | @HID_QUIRK_HAVE_SPECIAL_DRIVER: * | @HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE: + * | @HID_QUIRK_IGNORE_SPECIAL_DRIVER * | @HID_QUIRK_FULLSPEED_INTERVAL: * | @HID_QUIRK_NO_INIT_REPORTS: * | @HID_QUIRK_NO_IGNORE: @@ -384,6 +385,7 @@ struct hid_item { #define HID_QUIRK_HAVE_SPECIAL_DRIVER BIT(19) #define HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE BIT(20) #define HID_QUIRK_NOINVERT BIT(21) +#define HID_QUIRK_IGNORE_SPECIAL_DRIVER BIT(22) #define HID_QUIRK_FULLSPEED_INTERVAL BIT(28) #define HID_QUIRK_NO_INIT_REPORTS BIT(29) #define HID_QUIRK_NO_IGNORE BIT(30)
We already have the possibility to force not binding to hid-generic and rely on a dedicated driver, but we couldn't do the other way around. This is useful for BPF programs where we are fixing the report descriptor and the events, but want to avoid a specialized driver to come after BPF which would unwind everything that is done there. Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> --- changes in v2: - rely on hdev->quirks for that instead of a new struct for hid_driver --- drivers/hid/hid-core.c | 5 +++-- drivers/hid/hid-generic.c | 3 +++ include/linux/hid.h | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-)