mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
hid-for-linus-2026092202
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEL65usyKPHcrRDEicpmLzj2vtYEkFAmqyY7EACgkQpmLzj2vt YEnprxAAofmpQUorlic97WALU2CamXN/hdzLGlra2RPW6eJyxQUlwqR8xcUptx3e 14OM5X4WDHfFD1lRFx7/flzn2J5h5CLXUWnNUp5DR7W0GLQSnSwOiuawfb5/Enkd aqhgsqC2nfEjxQ3iqdsY1MTASN/MEjolNU66tP31DQH5D+CGY6eZtivNwFHaHjJI Ps4/vr2nuddSCsXaWRKwdBQ9wMr8g+F7dIeI8vqAJlWg5IdN0tu3ClAuHUqMr6X3 zMHJ7xkkrRg7S40xeQsajDiPGRRWPkC6G3lrJ1OSFOP1IEMKT5dLLg5HB2wLwfzI Xzw4CJZiSIaNKyMQLQJcik8wZZbc60A2ulDscbpk9PLlr9nweBc+7wzVZ0mOQ6Lo rD2iYG7ROG684Jt5HVd9SPrIgjCDnlOXDBT9JLyPCw38eEysEHOdSlwA0CSJyR21 cD0UmfIUgFDXxR/omcPbZDVng8683eRR3W/Tj2XPBOyKZYF/JtnIsrbowIN2dmGe PKnsrtp2LW5/xiO/lTfEsiiHL8WoxtXj/Mwoq/NuZm4TvZ/C3nd3ZiEaL5UQeYYc AyTFOqBe4DoLauyS2M50gitvDpSBFS9i5xrjCukalpJGfTUlX8lQjU7kdH7O5rbh VlMjlYqPNSyd4Yo/nveqIS3ELrKGs5z3oDSxwSB05h1nCgn3dgo= =k0Hr -----END PGP SIGNATURE----- Merge tag 'hid-for-linus-2026092202' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid Pull HID fixes from Jiri Kosina: - new device IDs/quirks (Logitech G502X, Elecom M-XT4DRBK, Steelseries Arctis 7, Asus Rog Z13 Folio, Lenovo Yoga Slim Gen 11) - fixes for various code issues found by LLMs * tag 'hid-for-linus-2026092202' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: selftests/hid: add unnumbered variant to the hid_bpf tests HID: bpf: fix __hid_bpf_hw_check_params report length selftests/hid: add define for commonly used buf size HID: amd_sfh: Validate PCI BAR size before mapping HID: elecom: fix bus type for M-XGL20DLBK HID: elecom: Add support for ELECOM M-XT4DRBK (018E) HID: corsair-void: Fix firmware event packet description HID: i2c-hid: Add i2c-hid-quirk-bad-input-size quirk for 0911:5288 device HID: hid-oxp: use cancel_delayed_work_sync() in remove HID: i2c-hid: add reset quirk for Lenovo Yoga Slim 7x Gen 11 keyboard HID: roccat: fix locking in roccat_connect() and roccat_disconnect() HID: steelseries: Add support for Arctis 7 (2018) HID: logitech-hidpp: Add support for G502 X Lightspeed USB mouse HID: fix semantic patch and improve its performance HID: alps: fix use-after-free on input2 registration failure HID: alps: unregister DualPoint Stick input device on remove HID: winwing: fix use-after-free in force feedback teardown HID: multitouch: Add report ID mismatch quirk for ASUS ROG Z13 Folio HID: wacom: fix OOB read in wacom_wac_pen_serial_enforce() HID: quirks: add ALWAYS_POLL quirk for SDINNOVATION gaming keyboard
This commit is contained in:
commit
fe2ec83746
|
|
@ -1210,7 +1210,8 @@ config HID_STEELSERIES
|
|||
depends on USB_HID
|
||||
help
|
||||
Support for Steelseries SRW-S1 steering wheel, and the Steelseries
|
||||
Arctis 1 Wireless for XBox headset.
|
||||
Arctis 1 Wireless for XBox, Arctis 7 (2018), Arctis 9, and Arctis
|
||||
Nova headsets.
|
||||
|
||||
config HID_SUNPLUS
|
||||
tristate "Sunplus wireless desktop"
|
||||
|
|
|
|||
|
|
@ -13,11 +13,15 @@
|
|||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/sizes.h>
|
||||
#include "amd_sfh_hid.h"
|
||||
|
||||
#define PCI_DEVICE_ID_AMD_MP2 0x15E4
|
||||
#define PCI_DEVICE_ID_AMD_MP2_1_1 0x164A
|
||||
|
||||
/* The BAR 2 size must cover the highest register offset (0x10958) */
|
||||
#define AMD_SFH_MIN_BAR_SIZE SZ_128K
|
||||
|
||||
#define AMD_C2P_MSG(regno) (0x10500 + ((regno) * 4))
|
||||
#define AMD_P2C_MSG(regno) (0x10680 + ((regno) * 4))
|
||||
|
||||
|
|
|
|||
|
|
@ -497,6 +497,16 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
|
||||
dev_err(&pdev->dev, "BAR 2 is not IORESOURCE_MEM\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (pci_resource_len(pdev, 2) < AMD_SFH_MIN_BAR_SIZE) {
|
||||
dev_err(&pdev->dev, "BAR 2 is too small\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = pcim_iomap_regions(pdev, BIT(2), DRIVER_NAME);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ hid_bpf_release_context(struct hid_bpf_ctx *ctx)
|
|||
|
||||
static int
|
||||
__hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz,
|
||||
enum hid_report_type rtype)
|
||||
enum hid_report_type rtype, bool hw_request)
|
||||
{
|
||||
struct hid_report_enum *report_enum;
|
||||
struct hid_report *report;
|
||||
|
|
@ -388,6 +388,10 @@ __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz,
|
|||
|
||||
report_len = hid_report_len(report);
|
||||
|
||||
/* unnumbered reports need to have a report ID reserved in the first byte */
|
||||
if (hw_request && report_enum->numbered == 0)
|
||||
report_len += 1;
|
||||
|
||||
if (*buf__sz > report_len)
|
||||
*buf__sz = report_len;
|
||||
|
||||
|
|
@ -420,7 +424,7 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
|
|||
return -EDEADLOCK;
|
||||
|
||||
/* check arguments */
|
||||
ret = __hid_bpf_hw_check_params(ctx, buf, &size, rtype);
|
||||
ret = __hid_bpf_hw_check_params(ctx, buf, &size, rtype, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -480,7 +484,7 @@ hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz)
|
|||
return -EDEADLOCK;
|
||||
|
||||
/* check arguments */
|
||||
ret = __hid_bpf_hw_check_params(ctx, buf, &size, HID_OUTPUT_REPORT);
|
||||
ret = __hid_bpf_hw_check_params(ctx, buf, &size, HID_OUTPUT_REPORT, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -506,7 +510,7 @@ __hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *b
|
|||
return -EDEADLOCK;
|
||||
|
||||
/* check arguments */
|
||||
ret = __hid_bpf_hw_check_params(ctx, buf, &size, type);
|
||||
ret = __hid_bpf_hw_check_params(ctx, buf, &size, type, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -407,6 +407,8 @@ static int u1_raw_event(struct alps_dev *hdata, u8 *data, int size)
|
|||
return 1;
|
||||
|
||||
case U1_SP_ABSOLUTE_REPORT_ID:
|
||||
if (!hdata->input2)
|
||||
return 0;
|
||||
sp_x = get_unaligned_le16(data+2);
|
||||
sp_y = get_unaligned_le16(data+4);
|
||||
|
||||
|
|
@ -738,7 +740,6 @@ static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
data->input2 = input2;
|
||||
input2->phys = input->phys;
|
||||
input2->name = "DualPoint Stick";
|
||||
input2->id.bustype = BUS_I2C;
|
||||
|
|
@ -762,11 +763,12 @@ static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi)
|
|||
__set_bit(INPUT_PROP_POINTER, input2->propbit);
|
||||
__set_bit(INPUT_PROP_POINTING_STICK, input2->propbit);
|
||||
|
||||
if (input_register_device(data->input2)) {
|
||||
if (input_register_device(input2)) {
|
||||
input_free_device(input2);
|
||||
ret = -ENOENT;
|
||||
goto exit;
|
||||
}
|
||||
data->input2 = input2;
|
||||
}
|
||||
|
||||
exit:
|
||||
|
|
@ -823,6 +825,24 @@ static int alps_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void alps_remove(struct hid_device *hdev)
|
||||
{
|
||||
struct alps_dev *data = hid_get_drvdata(hdev);
|
||||
|
||||
/*
|
||||
* input2 ("DualPoint Stick") is allocated separately and is not
|
||||
* tracked in hdev->inputs, so the default remove path
|
||||
* (hid_hw_stop -> hidinput_disconnect) does not unregister it.
|
||||
*
|
||||
* Stop the device first so that no URB callback can touch input2
|
||||
* while it is being unregistered, then drop it explicitly.
|
||||
*/
|
||||
hid_hw_stop(hdev);
|
||||
|
||||
if (data->input2)
|
||||
input_unregister_device(data->input2);
|
||||
}
|
||||
|
||||
static const struct hid_device_id alps_id[] = {
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
|
||||
USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
|
||||
|
|
@ -845,6 +865,7 @@ static struct hid_driver alps_driver = {
|
|||
.input_configured = alps_input_configured,
|
||||
.resume = pm_ptr(alps_post_resume),
|
||||
.reset_resume = pm_ptr(alps_post_reset),
|
||||
.remove = alps_remove,
|
||||
};
|
||||
|
||||
module_hid_driver(alps_driver);
|
||||
|
|
|
|||
|
|
@ -51,20 +51,23 @@
|
|||
/* Receiver report information: (ID 102) */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/*
|
||||
* When queried, the recevier responds with 4 bytes to describe the firmware
|
||||
* The first 2 bytes are for the receiver, the second 2 are the headset
|
||||
* When queried, the receiver responds with 5 bytes to describe the firmware
|
||||
* The first byte is the ID, then 2 bytes for the receiver, then 2 for the headset
|
||||
* The headset firmware version will be 0 if no headset is connected
|
||||
*
|
||||
* 0: Recevier firmware major version
|
||||
* 0: Report ID
|
||||
* 102 for the firmware packet
|
||||
*
|
||||
* 1: Receiver firmware major version
|
||||
* Major version of the receiver's firmware
|
||||
*
|
||||
* 1: Recevier firmware minor version
|
||||
* 2: Receiver firmware minor version
|
||||
* Minor version of the receiver's firmware
|
||||
*
|
||||
* 2: Headset firmware major version
|
||||
* 3: Headset firmware major version
|
||||
* Major version of the headset's firmware
|
||||
*
|
||||
* 3: Headset firmware minor version
|
||||
* 4: Headset firmware minor version
|
||||
* Minor version of the headset's firmware
|
||||
*/
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ static const __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|||
case USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB:
|
||||
case USB_DEVICE_ID_ELECOM_M_XT3URBK_018F:
|
||||
case USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC:
|
||||
case USB_DEVICE_ID_ELECOM_M_XT4DRBK:
|
||||
case USB_DEVICE_ID_ELECOM_M_XT4DRBK_00FD:
|
||||
/*
|
||||
* Report descriptor format:
|
||||
* 12: button bit count
|
||||
|
|
@ -104,6 +104,7 @@ static const __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|||
mouse_button_fixup(hdev, rdesc, *rsize, 12, 30, 14, 20, 8);
|
||||
break;
|
||||
case USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C:
|
||||
case USB_DEVICE_ID_ELECOM_M_XT4DRBK_018E:
|
||||
/*
|
||||
* Report descriptor format:
|
||||
* 22: button bit count
|
||||
|
|
@ -148,7 +149,8 @@ static const struct hid_device_id elecom_devices[] = {
|
|||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK_00FD) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK_018E) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT2DRBK) },
|
||||
|
|
|
|||
|
|
@ -477,7 +477,8 @@
|
|||
#define USB_DEVICE_ID_ELECOM_M_XT3URBK_018F 0x018f
|
||||
#define USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC 0x00fc
|
||||
#define USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C 0x018c
|
||||
#define USB_DEVICE_ID_ELECOM_M_XT4DRBK 0x00fd
|
||||
#define USB_DEVICE_ID_ELECOM_M_XT4DRBK_00FD 0x00fd
|
||||
#define USB_DEVICE_ID_ELECOM_M_XT4DRBK_018E 0x018e
|
||||
#define USB_DEVICE_ID_ELECOM_M_DT1URBK 0x00fe
|
||||
#define USB_DEVICE_ID_ELECOM_M_DT1DRBK 0x00ff
|
||||
#define USB_DEVICE_ID_ELECOM_M_DT2DRBK 0x018d
|
||||
|
|
@ -765,6 +766,7 @@
|
|||
#define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a
|
||||
#define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396
|
||||
#define I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD 0x8987
|
||||
#define I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_G11_KEYBOARD 0x83db
|
||||
#define USB_DEVICE_ID_ITE8595 0x8595
|
||||
#define USB_DEVICE_ID_ITE_MEDION_E1239T 0xce50
|
||||
|
||||
|
|
@ -1296,6 +1298,9 @@
|
|||
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD 0xa006
|
||||
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD 0xa064
|
||||
|
||||
#define USB_VENDOR_ID_SDINNOVATION 0x36ae
|
||||
#define USB_DEVICE_ID_SDINNOVATION_GAMING_KBD 0xfeab
|
||||
|
||||
#define USB_VENDOR_ID_SEMICO 0x1a2c
|
||||
#define USB_DEVICE_ID_SEMICO_USB_KEYKOARD 0x0023
|
||||
#define USB_DEVICE_ID_SEMICO_USB_KEYKOARD2 0x0027
|
||||
|
|
@ -1395,6 +1400,7 @@
|
|||
#define USB_VENDOR_ID_STEELSERIES 0x1038
|
||||
#define USB_DEVICE_ID_STEELSERIES_SRWS1 0x1410
|
||||
#define USB_DEVICE_ID_STEELSERIES_ARCTIS_1_X 0x12b6
|
||||
#define USB_DEVICE_ID_STEELSERIES_ARCTIS_7_2018 0x12ad
|
||||
#define USB_DEVICE_ID_STEELSERIES_ARCTIS_9 0x12c2
|
||||
#define USB_DEVICE_ID_STEELSERIES_ARCTIS_NOVA_5_X 0x2253
|
||||
#define USB_DEVICE_ID_STEELSERIES_ARCTIS_NOVA_7 0x2202
|
||||
|
|
|
|||
|
|
@ -4924,6 +4924,8 @@ static const struct hid_device_id hidpp_devices[] = {
|
|||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC08D) },
|
||||
{ /* Logitech G502 X Plus Wireless Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC095) },
|
||||
{ /* Logitech G502 X Lightspeed Wireless Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC098) },
|
||||
{ /* Logitech G703 Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC087) },
|
||||
{ /* Logitech G703 Hero Gaming Mouse over USB */
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ MODULE_LICENSE("GPL");
|
|||
#define MT_QUIRK_APPLE_TOUCHBAR BIT(23)
|
||||
#define MT_QUIRK_YOGABOOK9I BIT(24)
|
||||
#define MT_QUIRK_KEEP_LATENCY_ON_CLOSE BIT(25)
|
||||
#define MT_QUIRK_IGNORE_FEATURE_ID_MISMATCH BIT(26)
|
||||
|
||||
#define MT_INPUTMODE_TOUCHSCREEN 0x02
|
||||
#define MT_INPUTMODE_TOUCHPAD 0x03
|
||||
|
|
@ -235,6 +236,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app);
|
|||
#define MT_CLS_APPLE_TOUCHBAR 0x0114
|
||||
#define MT_CLS_YOGABOOK9I 0x0115
|
||||
#define MT_CLS_EGALAX_P80H84 0x0116
|
||||
#define MT_CLS_ASUS_ROG_Z13_FOLIO 0x0117
|
||||
#define MT_CLS_SIS 0x0457
|
||||
|
||||
#define MT_DEFAULT_MAXCONTACT 10
|
||||
|
|
@ -405,6 +407,16 @@ static const struct mt_class mt_classes[] = {
|
|||
.quirks = MT_QUIRK_ALWAYS_VALID |
|
||||
MT_QUIRK_CONTACT_CNT_ACCURATE |
|
||||
MT_QUIRK_ASUS_CUSTOM_UP },
|
||||
{ .name = MT_CLS_ASUS_ROG_Z13_FOLIO,
|
||||
.quirks = MT_QUIRK_ALWAYS_VALID |
|
||||
MT_QUIRK_IGNORE_DUPLICATES |
|
||||
MT_QUIRK_HOVERING |
|
||||
MT_QUIRK_CONTACT_CNT_ACCURATE |
|
||||
MT_QUIRK_STICKY_FINGERS |
|
||||
MT_QUIRK_WIN8_PTP_BUTTONS |
|
||||
MT_QUIRK_CONFIDENCE |
|
||||
MT_QUIRK_IGNORE_FEATURE_ID_MISMATCH,
|
||||
.export_all_inputs = true },
|
||||
{ .name = MT_CLS_VTL,
|
||||
.quirks = MT_QUIRK_ALWAYS_VALID |
|
||||
MT_QUIRK_CONTACT_CNT_ACCURATE |
|
||||
|
|
@ -507,6 +519,7 @@ static const struct attribute_group mt_attribute_group = {
|
|||
|
||||
static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
|
||||
{
|
||||
struct mt_device *td = hid_get_drvdata(hdev);
|
||||
int ret;
|
||||
u32 size = hid_report_len(report);
|
||||
u8 *buf;
|
||||
|
|
@ -528,8 +541,14 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
|
|||
dev_warn(&hdev->dev, "failed to fetch feature %d\n",
|
||||
report->id);
|
||||
} else {
|
||||
/* The report ID in the request and the response should match */
|
||||
if (report->id != buf[0]) {
|
||||
/*
|
||||
* The report ID in the request and the response should match.
|
||||
* Some firmware (e.g. the ASUS ROG Z13 Folio
|
||||
* touchpad) returns a mismatched ID on this specific fetch;
|
||||
* tolerate it only for devices explicitly flagged as such.
|
||||
*/
|
||||
if (report->id != buf[0] &&
|
||||
!(td->mtclass.quirks & MT_QUIRK_IGNORE_FEATURE_ID_MISMATCH)) {
|
||||
hid_err(hdev, "Returned feature report did not match the request\n");
|
||||
goto free;
|
||||
}
|
||||
|
|
@ -2715,6 +2734,12 @@ static const struct hid_device_id mt_devices[] = {
|
|||
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288) },
|
||||
|
||||
/* Asus ROG Flow Z13 (2025) GZ302EA keyboard-cover touchpad */
|
||||
{ .driver_data = MT_CLS_ASUS_ROG_Z13_FOLIO,
|
||||
HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
USB_VENDOR_ID_ASUSTEK,
|
||||
USB_DEVICE_ID_ASUSTEK_ROG_Z13_FOLIO) },
|
||||
|
||||
/* Generic MT device */
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) },
|
||||
|
||||
|
|
|
|||
|
|
@ -1552,9 +1552,9 @@ static int oxp_hid_probe(struct hid_device *hdev,
|
|||
|
||||
static void oxp_hid_remove(struct hid_device *hdev)
|
||||
{
|
||||
cancel_delayed_work(&drvdata.oxp_rgb_queue);
|
||||
cancel_delayed_work(&drvdata.oxp_btn_queue);
|
||||
cancel_delayed_work(&drvdata.oxp_mcu_init);
|
||||
cancel_delayed_work_sync(&drvdata.oxp_rgb_queue);
|
||||
cancel_delayed_work_sync(&drvdata.oxp_btn_queue);
|
||||
cancel_delayed_work_sync(&drvdata.oxp_mcu_init);
|
||||
hid_hw_close(hdev);
|
||||
hid_hw_stop(hdev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ static const struct hid_device_id hid_quirks[] = {
|
|||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_PRO), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X65), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SDINNOVATION, USB_DEVICE_ID_SDINNOVATION_GAMING_KBD), HID_QUIRK_ALWAYS_POLL },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2), HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD), HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB), HID_QUIRK_NOGET },
|
||||
|
|
@ -425,13 +426,14 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
|||
#endif
|
||||
#if IS_ENABLED(CONFIG_HID_ELECOM)
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AC) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK_00FD) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK_018E) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT2DRBK) },
|
||||
|
|
@ -751,6 +753,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
|||
#if IS_ENABLED(CONFIG_HID_STEELSERIES)
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_1_X) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_7_2018) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_9) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_NOVA_5_X) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_NOVA_7) },
|
||||
|
|
|
|||
|
|
@ -344,8 +344,6 @@ int roccat_connect(const struct class *klass, struct hid_device *hid, int report
|
|||
return temp;
|
||||
}
|
||||
|
||||
mutex_unlock(&devices_lock);
|
||||
|
||||
init_waitqueue_head(&device->wait);
|
||||
INIT_LIST_HEAD(&device->readers);
|
||||
mutex_init(&device->readers_lock);
|
||||
|
|
@ -356,6 +354,7 @@ int roccat_connect(const struct class *klass, struct hid_device *hid, int report
|
|||
device->cbuf_end = 0;
|
||||
device->report_size = report_size;
|
||||
|
||||
mutex_unlock(&devices_lock);
|
||||
return minor;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(roccat_connect);
|
||||
|
|
@ -369,15 +368,12 @@ void roccat_disconnect(int minor)
|
|||
|
||||
mutex_lock(&devices_lock);
|
||||
device = devices[minor];
|
||||
mutex_unlock(&devices_lock);
|
||||
|
||||
device->exist = 0; /* TODO exist maybe not needed */
|
||||
|
||||
device_destroy(device->dev->class, MKDEV(roccat_major, minor));
|
||||
|
||||
mutex_lock(&devices_lock);
|
||||
devices[minor] = NULL;
|
||||
mutex_unlock(&devices_lock);
|
||||
|
||||
if (device->open) {
|
||||
hid_hw_close(device->hid);
|
||||
|
|
@ -385,6 +381,8 @@ void roccat_disconnect(int minor)
|
|||
} else {
|
||||
roccat_free_device(device);
|
||||
}
|
||||
|
||||
mutex_unlock(&devices_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(roccat_disconnect);
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,19 @@ static int steelseries_arctis_1_request_status(struct hid_device *hdev)
|
|||
return steelseries_send_output_report(hdev, data, sizeof(data));
|
||||
}
|
||||
|
||||
static int steelseries_arctis_7_2018_request_status(struct hid_device *hdev)
|
||||
{
|
||||
const u8 connection[] = { 0x06, 0x14 };
|
||||
const u8 battery[] = { 0x06, 0x18 };
|
||||
int ret;
|
||||
|
||||
ret = steelseries_send_output_report(hdev, connection, sizeof(connection));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return steelseries_send_output_report(hdev, battery, sizeof(battery));
|
||||
}
|
||||
|
||||
static int steelseries_arctis_9_request_status(struct hid_device *hdev)
|
||||
{
|
||||
const u8 data[] = { 0x00, 0x20 };
|
||||
|
|
@ -152,6 +165,27 @@ static void steelseries_arctis_1_parse_status(struct steelseries_device *sd,
|
|||
sd->battery_capacity = data[3];
|
||||
}
|
||||
|
||||
static void steelseries_arctis_7_2018_parse_status(struct steelseries_device *sd,
|
||||
u8 *data, int size)
|
||||
{
|
||||
if (size < 3 || data[0] != 0x06)
|
||||
return;
|
||||
|
||||
switch (data[1]) {
|
||||
case 0x14:
|
||||
/* 0x03 means that the headset is connected to the transmitter. */
|
||||
sd->headset_connected = data[2] == 0x03;
|
||||
break;
|
||||
case 0x18:
|
||||
if (!sd->headset_connected)
|
||||
break;
|
||||
|
||||
/* The Arctis 7 sometimes overreports battery. Cap to 100. */
|
||||
sd->battery_capacity = steelseries_map_capacity(data[2], 0, 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void steelseries_arctis_9_parse_status(struct steelseries_device *sd,
|
||||
u8 *data, int size)
|
||||
{
|
||||
|
|
@ -232,6 +266,13 @@ static const struct steelseries_device_info arctis_1_info = {
|
|||
.parse_status = steelseries_arctis_1_parse_status,
|
||||
};
|
||||
|
||||
static const struct steelseries_device_info arctis_7_2018_info = {
|
||||
.sync_interface = 5,
|
||||
.capabilities = SS_CAP_BATTERY,
|
||||
.request_status = steelseries_arctis_7_2018_request_status,
|
||||
.parse_status = steelseries_arctis_7_2018_parse_status,
|
||||
};
|
||||
|
||||
static const struct steelseries_device_info arctis_9_info = {
|
||||
.sync_interface = 0,
|
||||
.capabilities = SS_CAP_BATTERY,
|
||||
|
|
@ -653,6 +694,9 @@ static const struct hid_device_id steelseries_arctis_devices[] = {
|
|||
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES,
|
||||
USB_DEVICE_ID_STEELSERIES_ARCTIS_1_X),
|
||||
.driver_data = (unsigned long)&arctis_1_info },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES,
|
||||
USB_DEVICE_ID_STEELSERIES_ARCTIS_7_2018),
|
||||
.driver_data = (unsigned long)&arctis_7_2018_info },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES,
|
||||
USB_DEVICE_ID_STEELSERIES_ARCTIS_9),
|
||||
.driver_data = (unsigned long)&arctis_9_info },
|
||||
|
|
|
|||
|
|
@ -315,7 +315,8 @@ static void winwing_haptic_rumble_cb(struct work_struct *work)
|
|||
static int winwing_play_effect(struct input_dev *dev, void *context,
|
||||
struct ff_effect *effect)
|
||||
{
|
||||
struct winwing_drv_data *data = (struct winwing_drv_data *) context;
|
||||
struct hid_device *hdev = input_get_drvdata(dev);
|
||||
struct winwing_drv_data *data = hid_get_drvdata(hdev);
|
||||
|
||||
if (effect->type != FF_RUMBLE)
|
||||
return 0;
|
||||
|
|
@ -342,7 +343,12 @@ static int winwing_init_ff(struct hid_device *hdev, struct hid_input *hidinput)
|
|||
|
||||
input_set_capability(hidinput->input, EV_FF, FF_RUMBLE);
|
||||
|
||||
return input_ff_create_memless(hidinput->input, data,
|
||||
/*
|
||||
* input_ff_create_memless() takes ownership of the context pointer
|
||||
* and frees it on teardown; do not hand it the devm-managed drvdata.
|
||||
* winwing_play_effect() fetches it from the input device instead.
|
||||
*/
|
||||
return input_ff_create_memless(hidinput->input, NULL,
|
||||
winwing_play_effect);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,9 +123,11 @@ static const struct i2c_hid_quirks {
|
|||
__u32 quirks;
|
||||
} i2c_hid_quirks[] = {
|
||||
{ I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
|
||||
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
|
||||
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET | I2C_HID_QUIRK_BAD_INPUT_SIZE },
|
||||
{ I2C_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15,
|
||||
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
|
||||
{ USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_G11_KEYBOARD,
|
||||
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
|
||||
{ I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_3118,
|
||||
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
|
||||
{ USB_VENDOR_ID_ALPS_JP, HID_ANY_ID,
|
||||
|
|
|
|||
|
|
@ -113,8 +113,9 @@ static int wacom_wac_pen_serial_enforce(struct hid_device *hdev,
|
|||
|
||||
/* Queue events which have invalid tool type or serial number */
|
||||
for (i = 0; i < report->maxfield; i++) {
|
||||
for (j = 0; j < report->field[i]->maxusage; j++) {
|
||||
struct hid_field *field = report->field[i];
|
||||
struct hid_field *field = report->field[i];
|
||||
|
||||
for (j = 0; j < field->report_count; j++) {
|
||||
struct hid_usage *usage = &field->usage[j];
|
||||
unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
|
||||
unsigned int offset;
|
||||
|
|
|
|||
|
|
@ -7,18 +7,19 @@
|
|||
|
||||
virtual report
|
||||
|
||||
@r@
|
||||
@r exists@
|
||||
identifier probe_fn;
|
||||
expression hdev, flags;
|
||||
identifier hdev;
|
||||
expression flags;
|
||||
position p1, p2;
|
||||
@@
|
||||
|
||||
probe_fn(struct hid_device *hdev, ...) {
|
||||
<...
|
||||
... when any
|
||||
hid_hw_start@p1(hdev, flags)
|
||||
...
|
||||
\(input_ff_create\|input_ff_create_memless\)@p2(...)
|
||||
...>
|
||||
\(input_ff_create@p2\|input_ff_create_memless@p2\)(...)
|
||||
... when any
|
||||
}
|
||||
|
||||
@script:python depends on report@
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include <bpf/bpf.h>
|
||||
|
||||
struct hid_hw_request_syscall_args {
|
||||
__u8 data[10];
|
||||
__u8 data[MAX_BUF_SIZE];
|
||||
unsigned int hid;
|
||||
int retval;
|
||||
size_t size;
|
||||
|
|
@ -54,11 +54,27 @@ FIXTURE_TEARDOWN(hid_bpf) {
|
|||
hid_bpf_teardown(_metadata, self, variant); \
|
||||
} while (0)
|
||||
|
||||
FIXTURE_VARIANT(hid_bpf) {
|
||||
__u8 *rdesc;
|
||||
size_t rdesc_size;
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(hid_bpf, numbered) {
|
||||
.rdesc = rdesc,
|
||||
.rdesc_size = sizeof(rdesc),
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(hid_bpf, unnumbered) {
|
||||
.rdesc = fido2_rdesc,
|
||||
.rdesc_size = sizeof(fido2_rdesc),
|
||||
};
|
||||
|
||||
FIXTURE_SETUP(hid_bpf)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36, rdesc, sizeof(rdesc));
|
||||
err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36,
|
||||
variant->rdesc, variant->rdesc_size);
|
||||
ASSERT_OK(err);
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +191,7 @@ TEST_F(hid_bpf, raw_event)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_first_event" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -226,7 +242,7 @@ TEST_F(hid_bpf, subprog_raw_event)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_subprog_first_event" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -284,7 +300,7 @@ TEST_F(hid_bpf, test_attach_detach)
|
|||
{ .name = "hid_second_event" },
|
||||
};
|
||||
struct bpf_link *link;
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err, link_fd;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -369,7 +385,7 @@ TEST_F(hid_bpf, test_hid_change_report)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_change_report_id" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -396,21 +412,24 @@ TEST_F(hid_bpf, test_hid_user_input_report_call)
|
|||
{
|
||||
struct hid_hw_request_syscall_args args = {
|
||||
.retval = -1,
|
||||
.size = 10,
|
||||
.size = MAX_BUF_SIZE,
|
||||
};
|
||||
DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattrs,
|
||||
.ctx_in = &args,
|
||||
.ctx_size_in = sizeof(args),
|
||||
);
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err, prog_fd;
|
||||
|
||||
LOAD_BPF;
|
||||
|
||||
args.hid = self->hid.hid_id;
|
||||
args.data[0] = 1; /* report ID */
|
||||
args.data[1] = 2; /* report ID */
|
||||
args.data[2] = 42; /* report ID */
|
||||
args.data[1] = 2;
|
||||
args.data[2] = 42;
|
||||
|
||||
if (variant->rdesc == fido2_rdesc)
|
||||
args.data[0] = 0;
|
||||
|
||||
prog_fd = bpf_program__fd(self->skel->progs.hid_user_input_report);
|
||||
|
||||
|
|
@ -428,8 +447,13 @@ TEST_F(hid_bpf, test_hid_user_input_report_call)
|
|||
/* read the data from hidraw */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
err = read(self->hidraw_fd, buf, sizeof(buf));
|
||||
ASSERT_EQ(err, 6) TH_LOG("read_hidraw");
|
||||
ASSERT_EQ(buf[0], 1);
|
||||
if (variant->rdesc == rdesc) {
|
||||
ASSERT_EQ(err, 6) TH_LOG("read_hidraw");
|
||||
} else {
|
||||
ASSERT_EQ(err, 64)
|
||||
TH_LOG("read_hidraw");
|
||||
}
|
||||
ASSERT_EQ(buf[0], args.data[0]);
|
||||
ASSERT_EQ(buf[1], 2);
|
||||
ASSERT_EQ(buf[2], 42);
|
||||
}
|
||||
|
|
@ -442,7 +466,7 @@ TEST_F(hid_bpf, test_hid_user_output_report_call)
|
|||
{
|
||||
struct hid_hw_request_syscall_args args = {
|
||||
.retval = -1,
|
||||
.size = 10,
|
||||
.size = MAX_BUF_SIZE,
|
||||
};
|
||||
DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattrs,
|
||||
.ctx_in = &args,
|
||||
|
|
@ -455,8 +479,11 @@ TEST_F(hid_bpf, test_hid_user_output_report_call)
|
|||
|
||||
args.hid = self->hid.hid_id;
|
||||
args.data[0] = 1; /* report ID */
|
||||
args.data[1] = 2; /* report ID */
|
||||
args.data[2] = 42; /* report ID */
|
||||
args.data[1] = 2;
|
||||
args.data[2] = 42;
|
||||
|
||||
if (variant->rdesc == fido2_rdesc)
|
||||
args.data[0] = 0;
|
||||
|
||||
prog_fd = bpf_program__fd(self->skel->progs.hid_user_output_report);
|
||||
|
||||
|
|
@ -472,9 +499,14 @@ TEST_F(hid_bpf, test_hid_user_output_report_call)
|
|||
ASSERT_OK(err) TH_LOG("error while calling bpf_prog_test_run_opts");
|
||||
ASSERT_OK(cond_err) TH_LOG("error while calling waiting for the condition");
|
||||
|
||||
ASSERT_EQ(args.retval, 3);
|
||||
if (variant->rdesc == rdesc) {
|
||||
ASSERT_EQ(args.retval, 3);
|
||||
} else if (variant->rdesc == fido2_rdesc) {
|
||||
ASSERT_EQ(args.retval, 65)
|
||||
TH_LOG("report size error, should have 64 + 1 extra byte for the report ID 0");
|
||||
}
|
||||
|
||||
ASSERT_EQ(output_report[0], 1);
|
||||
ASSERT_EQ(output_report[0], args.data[0]);
|
||||
ASSERT_EQ(output_report[1], 2);
|
||||
ASSERT_EQ(output_report[2], 42);
|
||||
|
||||
|
|
@ -491,7 +523,7 @@ TEST_F(hid_bpf, test_hid_user_raw_request_call)
|
|||
.retval = -1,
|
||||
.type = HID_FEATURE_REPORT,
|
||||
.request_type = HID_REQ_GET_REPORT,
|
||||
.size = 10,
|
||||
.size = MAX_BUF_SIZE,
|
||||
};
|
||||
DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattrs,
|
||||
.ctx_in = &args,
|
||||
|
|
@ -524,7 +556,7 @@ TEST_F(hid_bpf, test_hid_filter_raw_request_call)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_test_filter_raw_request" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -577,7 +609,7 @@ TEST_F(hid_bpf, test_hid_change_raw_request_call)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_test_hidraw_raw_request" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -603,7 +635,7 @@ TEST_F(hid_bpf, test_hid_infinite_loop_raw_request_call)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_test_infinite_loop_raw_request" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -626,7 +658,7 @@ TEST_F(hid_bpf, test_hid_filter_output_report_call)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_test_filter_output_report" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -679,7 +711,7 @@ TEST_F(hid_bpf, test_hid_change_output_report_call)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_test_hidraw_output_report" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -703,7 +735,7 @@ TEST_F(hid_bpf, test_hid_infinite_loop_output_report_call)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_test_infinite_loop_output_report" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -729,7 +761,7 @@ TEST_F(hid_bpf, test_multiply_events_wq)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_test_multiply_events_wq" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -767,7 +799,7 @@ TEST_F(hid_bpf, test_multiply_events)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_test_multiply_events" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -801,7 +833,7 @@ TEST_F(hid_bpf, test_hid_infinite_loop_input_report_call)
|
|||
const struct test_program progs[] = {
|
||||
{ .name = "hid_test_infinite_loop_input_report" },
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -855,7 +887,7 @@ TEST_F(hid_bpf, test_hid_attach_flags)
|
|||
.insert_head = 0,
|
||||
},
|
||||
};
|
||||
__u8 buf[10] = {0};
|
||||
__u8 buf[MAX_BUF_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
|
@ -886,6 +918,9 @@ TEST_F(hid_bpf, test_rdesc_fixup)
|
|||
};
|
||||
int err, desc_size;
|
||||
|
||||
if (variant->rdesc != rdesc)
|
||||
SKIP(return, "not compatible report descriptor");
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
||||
/* check that hid_rdesc_fixup() was executed */
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/uhid.h>
|
||||
|
||||
#define SHOW_UHID_DEBUG 0
|
||||
#define MAX_BUF_SIZE 128
|
||||
|
||||
#define min(a, b) \
|
||||
({ __typeof__(a) _a = (a); \
|
||||
|
|
@ -97,6 +98,28 @@ static unsigned char rdesc[] = {
|
|||
|
||||
static __u8 feature_data[] = { 1, 2 };
|
||||
|
||||
static __maybe_unused unsigned char fido2_rdesc[] = {
|
||||
0x06, 0xd0, 0xf1, /* Usage Page (FIDO Alliance) */
|
||||
0x09, 0x01, /* Usage (U2F Authenticator Device) */
|
||||
0xa1, 0x01, /* Collection (Application) */
|
||||
0x09, 0x20, /* Usage (Input Report Data) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x26, 0xff, 0x00, /* Logical Maximum (255) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, 0x40, /* Report Count (64) */
|
||||
0x81, 0x02, /* Input (Data,Var,Abs) */
|
||||
0x09, 0x21, /* Usage (Output Report Data) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x26, 0xff, 0x00, /* Logical Maximum (255) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, 0x40, /* Report Count (64) */
|
||||
0x91, 0x02, /* Output (Data,Var,Abs) */
|
||||
0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */
|
||||
0x09, 0x22, /* Usage (Vendor Usage 0x22) */
|
||||
0xb1, 0x02, /* Feature (Data,Var,Abs) */
|
||||
0xc0, /* End Collection */
|
||||
};
|
||||
|
||||
#define ASSERT_OK(data) ASSERT_FALSE(data)
|
||||
#define ASSERT_OK_PTR(ptr) ASSERT_NE(NULL, ptr)
|
||||
|
||||
|
|
@ -110,7 +133,7 @@ static pthread_cond_t uhid_started = PTHREAD_COND_INITIALIZER;
|
|||
|
||||
static pthread_mutex_t uhid_output_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t uhid_output_cond = PTHREAD_COND_INITIALIZER;
|
||||
static unsigned char output_report[10];
|
||||
static unsigned char output_report[MAX_BUF_SIZE];
|
||||
|
||||
/* no need to protect uhid_stopped, only one thread accesses it */
|
||||
static bool uhid_stopped;
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ struct hid_bpf_ops change_report_id = {
|
|||
|
||||
struct hid_hw_request_syscall_args {
|
||||
/* data needs to come at offset 0 so we can use it in calls */
|
||||
__u8 data[10];
|
||||
__u8 data[128];
|
||||
unsigned int hid;
|
||||
int retval;
|
||||
size_t size;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user