From nobody Fri Apr 3 16:08:33 2026 Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80E252F6918 for ; Tue, 24 Mar 2026 01:38:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774316333; cv=none; b=eJakkwIBreIfyjgr3WaA8wW3a62LE12wWM5Mx8Qr0lXf//z43NFP4msWshXAL0ttnL0U/XTGtKtPDg4bdmLp6UWvte12eR0M63FuOLtQgRdVz8rUuqBrlL27hXCFKWxLWhv87bbZmUq161jM5tlbEcv+jOiCQIJMphj5c4mVAJU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774316333; c=relaxed/simple; bh=aO58map7MrL43NnKddrvuhuVBw1toClw63XP3wkk6yw=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=Y35OgrKG/aM8b2Sxh0S8ZlcgDMwD0iJU34GejA7JVHcWiaTk786Qlg28eo72rALZRh0aXeFIuswxoqw+AS/+xEe1y5LepIAV/yeXTD0BGdZLZLk+l1gRu6joLN8/RjbDZW1cldlOFUogYSy1VtqgZeN/DZ3iIkYKFQyYoLW8AOo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=CeE59je3; arc=none smtp.client-ip=209.85.214.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CeE59je3" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-2ab46931cf1so48335625ad.0 for ; Mon, 23 Mar 2026 18:38:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774316332; x=1774921132; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=+sMcB8vCZ+ft7voGK1GkvjNRLPcoujwUB0WOFLw7EZM=; b=CeE59je3VsLvGnSsleky5buKqJrdGlsZO/B3m3Y088AvE3atdj0iTTR6RKeMMEM45+ f8m6vXFGq5kvqNYK6tjeOs3e9piQaVvzYrFBWgrhD6pCpzAR3OyicI3W2ZrmWp39ne9s W64cyuiDPpBC1wCxp7EisCuds/+zcvt/c/V0c02S8d08tmWojXXQaibPo2+ew43B5OFX 04Wt4BGr4YGLVZvRW3fpYhgKHXl4KeLd8IzRy1Wh40u5dyhTJimI2UmhhutT5JCGEAV5 h0utdtOFwREjumC0Bsbfs5TOoXtHkxvEejaU8Ry6syDFbkQE4eiO0s4CvC+vosFmoCgB 7Nng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774316332; x=1774921132; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=+sMcB8vCZ+ft7voGK1GkvjNRLPcoujwUB0WOFLw7EZM=; b=K1p61e2gU0netm+a76GtHOibzXtFl6UvAou6hX3CmEj1a7XzbyBHXSbmpZcfNMGAlT eekL7tRRLAiBDsh/ZPkGAUjd+XXcMCkVXHtqDulwM8127Zp86lrFhsEVyBY9wyppZVW1 K5fh7Mv+igNB6WcIheSbGlLJFvz1VSdaKZXY0mRmNyV9l4bA1rTfUla5anca9ar8YhAl AZcSDOFLHJ4UAMrb0TM3cun2/P4fOSuyOcA6ZF5WREUw34hGyp9XBPmfCYddRKtrph4s kED3QmVi93Uy6/E8ZNUDunt+ANx2mwhcn9ZYpzgYYufxScyfhr4550SGymAvbQmQlG8z hucA== X-Forwarded-Encrypted: i=1; AJvYcCVc+5A2fMb05rS0zfvbeWhuznFHAjBfRoTvFsBGncRxEmujaxH3b5u4kIJgk9iB4HzSqdlM/Go+8sgdcfY=@vger.kernel.org X-Gm-Message-State: AOJu0YwoPScIb3T7gLWN926BYrbYpmxTS9Y/3htX1uGNQM6AOln4kMhh srmn+lrj0S+7mW0xP43SsbLwmNGW/eexrOoux9+41Wf3nKvRn0OibnUs X-Gm-Gg: ATEYQzwaM68hD3Abnqu6wVwmgapbKsDPqd4sX70r5xOVnFsfZ+lar/cJXs+BxDzuMJm FYF+YznynK1yEo8EIFDIGeR3T3EeaoqdkveJcNUnQ7PCDaXLX3Ab5PXDYdqxu3Q7Vrbx891NcgI 0TEkErpV3TqPOq8Ms2nrN/6wqZu4AmlAeqmWobKjz9ELKKi7womYbL9oEL6Q4OCR15+rb04MPgL xwhkFdA8RwPKKeJezw6f0wYhbm+N/AHxIgjtOYGyk0mwiewuuU0umtd3gUEkoXctspZ+SD2vxSd lxkilCV8QK9gFfw71JlrTkN4zd+A5gFevqLDrK58SpxbpDqhHpOR3++hfkmhhSDqdoaIB5cHtMz qQWKE8jJ+RC6Hu+4hIDz3dyD9HxbT1P2+4uA4hPW6R0mR4CCSHoaI8pl76YeHnR32NI11bEbhZA vlrgVGouN1DNocBgMnkde2UAQCvGxC2+KUBg== X-Received: by 2002:a17:903:388d:b0:2b0:51be:f9d7 with SMTP id d9443c01a7336-2b0a4e05583mr13848315ad.18.1774316331697; Mon, 23 Mar 2026 18:38:51 -0700 (PDT) Received: from localhost.localdomain ([212.107.28.57]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2b0836556desm164963475ad.47.2026.03.23.18.38.49 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Mon, 23 Mar 2026 18:38:51 -0700 (PDT) From: honjow To: Jiri Kosina , Benjamin Tissoires Cc: denis.benato@linux.dev, honjow311@gmail.com, linux-kernel@vger.kernel.org, linux-input@vger.kernel.org Subject: [PATCH] HID: gpd: fix report descriptor on GPD Win handheld (2f24:0137) Date: Tue, 24 Mar 2026 09:38:45 +0800 Message-ID: <20260324013847.68024-1-honjow311@gmail.com> X-Mailer: git-send-email 2.51.2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The OEM USB HID interface found on GPD Win handhelds (VID 2f24, registered to ShenZhen HuiJiaZhi / GameSir, PID 0137) declares 63-byte Input and Feature reports for Report ID 1, but the firmware only transfers 11 data bytes per interrupt. Since commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()"), the HID core rejects undersized reports instead of zero- padding them. This breaks the device entirely on kernels >=3D v7.0-rc5. Fix it by patching the report descriptor in report_fixup(), reducing Report Count from 63 to 11 for both Input and Feature. Closes: https://bugzilla.kernel.org/show_bug.cgi?id=3D221271 Signed-off-by: honjow --- drivers/hid/Kconfig | 10 +++++++++ drivers/hid/Makefile | 1 + drivers/hid/hid-gpd.c | 52 +++++++++++++++++++++++++++++++++++++++++++ drivers/hid/hid-ids.h | 3 +++ 4 files changed, 66 insertions(+) create mode 100644 drivers/hid/hid-gpd.c diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 10c12d8e65579..20c60f5aca4c5 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -419,6 +419,16 @@ config HID_GLORIOUS Support for Glorious PC Gaming Race mice such as the Glorious Model O, O- and D. =20 +config HID_GPD + tristate "GPD Win handheld OEM HID support" + depends on USB_HID + help + Report descriptor fix for the OEM USB HID interface (GameSir + 2f24:0137) found on GPD Win handhelds. The firmware declares 63-byte + reports but only sends 11 bytes, which the HID core rejects. + + Say Y or M here if you use a GPD Win handheld with this interface. + config HID_HOLTEK tristate "Holtek HID devices" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 07dfdb6a49c59..03ef72ec4499f 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -53,6 +53,7 @@ obj-$(CONFIG_HID_ELO) +=3D hid-elo.o obj-$(CONFIG_HID_EVISION) +=3D hid-evision.o obj-$(CONFIG_HID_EZKEY) +=3D hid-ezkey.o obj-$(CONFIG_HID_FT260) +=3D hid-ft260.o +obj-$(CONFIG_HID_GPD) +=3D hid-gpd.o obj-$(CONFIG_HID_GEMBIRD) +=3D hid-gembird.o obj-$(CONFIG_HID_GFRM) +=3D hid-gfrm.o obj-$(CONFIG_HID_GLORIOUS) +=3D hid-glorious.o diff --git a/drivers/hid/hid-gpd.c b/drivers/hid/hid-gpd.c new file mode 100644 index 0000000000000..5b4d203e24995 --- /dev/null +++ b/drivers/hid/hid-gpd.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * HID report descriptor fixup for GPD Win handhelds. + * + * The OEM HID interface (VID 2f24 / GameSir, PID 0137) declares Report I= D 1 + * with Report Count 63 (8-bit fields) for both Input and Feature, but the + * firmware only sends 11 bytes of payload after the report ID. + */ + +#include +#include + +#include "hid-ids.h" + +#define RDESC_LEN 38 +#define RPT_COUNT_INPUT_OFF 21 +#define RPT_COUNT_FEATURE_OFF 34 + +static const __u8 *gpd_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) +{ + if (*rsize !=3D RDESC_LEN) + return rdesc; + + if (rdesc[RPT_COUNT_INPUT_OFF - 1] =3D=3D 0x95 && + rdesc[RPT_COUNT_INPUT_OFF] =3D=3D 0x3f && + rdesc[RPT_COUNT_FEATURE_OFF - 1] =3D=3D 0x95 && + rdesc[RPT_COUNT_FEATURE_OFF] =3D=3D 0x3f) { + hid_info(hdev, "fixing report counts (63 -> 11 bytes)\n"); + rdesc[RPT_COUNT_INPUT_OFF] =3D 11; + rdesc[RPT_COUNT_FEATURE_OFF] =3D 11; + } + + return rdesc; +} + +static const struct hid_device_id gpd_devices[] =3D { + { HID_USB_DEVICE(USB_VENDOR_ID_GAMESIR, USB_DEVICE_ID_GAMESIR_0137) }, + { } +}; +MODULE_DEVICE_TABLE(hid, gpd_devices); + +static struct hid_driver gpd_driver =3D { + .name =3D "gpd", + .id_table =3D gpd_devices, + .report_fixup =3D gpd_report_fixup, +}; + +module_hid_driver(gpd_driver); + +MODULE_DESCRIPTION("HID report descriptor fix for GPD Win handheld (GameSi= r 2f24:0137)"); +MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 933b7943bdb50..d0a6c19baa660 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -533,6 +533,9 @@ #define USB_VENDOR_ID_FRUCTEL 0x25B6 #define USB_DEVICE_ID_GAMETEL_MT_MODE 0x0002 =20 +#define USB_VENDOR_ID_GAMESIR 0x2f24 +#define USB_DEVICE_ID_GAMESIR_0137 0x0137 + #define USB_VENDOR_ID_GAMEVICE 0x27F8 #define USB_DEVICE_ID_GAMEVICE_GV186 0x0BBE #define USB_DEVICE_ID_GAMEVICE_KISHI 0x0BBF --=20 2.51.2