* [PATCH] Input: xpad - add support for GameSir G7 Pro dongle in Xbox mode
@ 2026-11-15 13:58 Alexander Gollings
2026-11-15 14:06 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: Alexander Gollings @ 2026-11-15 13:58 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, Alexander Gollings
The GameSir G7 Pro 2.4GHz dongle enumerates as 3537:1004 in its Xbox
mode, the same VID/PID as the GameSir T4 Kaleid, which was added as an
Xbox 360 controller in commit 854d2233de0a ("Input: xpad - add GameSir
T4 Kaleid Controller support"). Unlike the T4 Kaleid, the dongle exposes
GIP interfaces (class 0xff, subclass 0x47, protocol 0xd0) and speaks the
Xbox One protocol.
xpad binds to the dongle through the vendor-wide GIP match, but the
device table lookup then forces XTYPE_XBOX360. The GIP power-on packet
is never sent, so the dongle reports no input at all and rumble requests
are ignored.
Make the device table lookup skip XTYPE_XBOX360 entries for interfaces
using the GIP protocol, and add an Xbox One entry for the G7 Pro. Its
36-byte input report carries the Share button in the same place as the
Xbox Series controllers, so enable MAP_SHARE_BUTTON. The T4 Kaleid uses
the Xbox 360 interface protocol and still matches its existing entry.
Tested with two G7 Pro controllers, each paired to its own dongle
(firmware 1.55): sticks, triggers, D-pad, all face, shoulder and stick
buttons, View, Menu, Guide and Share register, and both rumble motors
work, including through Steam Input. The back buttons send nothing in
this mode unless they are remapped on the controller.
This patch was developed with an AI coding assistant (Claude Code,
Claude Opus 5.5). It found the cause from the USB descriptors and the
xpad source, wrote the patch and this changelog, and helped capture raw
GIP reports to locate the Share button. I reviewed the change and tested
it on the hardware described above.
Signed-off-by: Alexander Gollings <levirootsmanuva2@gmail.com>
---
drivers/input/joystick/xpad.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index d2eb48d..f0ceb78 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -406,6 +406,7 @@ static const struct xpad_device {
{ 0x3285, 0x0663, "Nacon Evol-X", 0, XTYPE_XBOXONE },
{ 0x3507, 0x000b, "ZENAIM LEVERLESS", 0, XTYPE_XBOX360 },
{ 0x3537, 0x1004, "GameSir T4 Kaleid", 0, XTYPE_XBOX360 },
+ { 0x3537, 0x1004, "GameSir G7 Pro", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
{ 0x3537, 0x100f, "GameSir Nova 2 Lite", 0, XTYPE_XBOX360 },
{ 0x3537, 0x1010, "GameSir G7 SE", 0, XTYPE_XBOXONE },
{ 0x3537, 0x1040, "GameSir Nova Lite", 0, XTYPE_XBOX360 },
@@ -2054,6 +2055,30 @@ err_free_input:
return error;
}
+/*
+ * Some vendors reuse the VID/PID of an Xbox 360 protocol controller for a
+ * device speaking GIP: GameSir 3537:1004 is the T4 Kaleid, but also the
+ * G7 Pro 2.4GHz dongle in Xbox mode. Never apply an Xbox 360 entry to a GIP
+ * interface.
+ */
+static bool xpad_device_match(const struct xpad_device *xdev,
+ struct usb_device *udev,
+ struct usb_interface *intf)
+{
+ const struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
+
+ if (le16_to_cpu(udev->descriptor.idVendor) != xdev->idVendor ||
+ le16_to_cpu(udev->descriptor.idProduct) != xdev->idProduct)
+ return false;
+
+ if (xdev->xtype == XTYPE_XBOX360 &&
+ desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
+ desc->bInterfaceProtocol == 208)
+ return false;
+
+ return true;
+}
+
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
@@ -2065,8 +2090,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
return -ENODEV;
for (i = 0; xpad_device[i].idVendor; i++) {
- if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
- (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
+ if (xpad_device_match(&xpad_device[i], udev, intf))
break;
}
--
2.56.1
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] Input: xpad - add support for GameSir G7 Pro dongle in Xbox mode
2026-11-15 13:58 [PATCH] Input: xpad - add support for GameSir G7 Pro dongle in Xbox mode Alexander Gollings
@ 2026-11-15 14:06 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-11-15 14:06 UTC (permalink / raw)
To: Alexander Gollings; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found no new issues
in this patch, but noticed 1 related pre-existing issue it does not
introduce:
- [Critical] Input: xpad - use-after-free in xpad_probe() [1]
--
commit 9da1d473121c33d6a51bd41a4411539bd2d0fc9a
Author: Alexander Gollings <levirootsmanuva2@gmail.com>
Input: xpad - add support for GameSir G7 Pro dongle in Xbox mode
This commit adds an Xbox One device entry for the GameSir G7 Pro 2.4GHz
dongle and skips Xbox 360 entries in xpad_probe() when the USB interface
uses the GIP protocol.
> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
> index d2eb48d98fead..f0ceb78e40a36 100644
> --- a/drivers/input/joystick/xpad.c
> +++ b/drivers/input/joystick/xpad.c
[ ... ]
> @@ -2065,8 +2090,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
> return -ENODEV;
>
> for (i = 0; xpad_device[i].idVendor; i++) {
> - if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
> - (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
> + if (xpad_device_match(&xpad_device[i], udev, intf))
> break;
> }
[Severity: Critical]
This problem wasn't introduced by this patch, but can xpad_probe() cause a
use-after-free on xpad [1] if xpad360w_start_input() fails after
submitting xpad->irq_in?
When probing an XTYPE_XBOX360W device, xpad360w_start_input() submits
xpad->irq_in before calling xpad_inquiry_pad_presence():
drivers/input/joystick/xpad.c:xpad360w_start_input() {
error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
if (error)
return -EIO;
/*
* Send presence packet.
* This will force the controller to resend connection packets.
* This is useful in case we have connected a controller before
* the module was loaded.
*/
error = xpad_inquiry_pad_presence(xpad);
if (error) {
usb_kill_urb(xpad->irq_in);
return error;
}
}
If a packet arrives before xpad_inquiry_pad_presence() fails, xpad_irq_in()
schedules xpad->work, and the error path in xpad_probe() frees xpad without
canceling the work:
CPU0 CPU1
xpad_probe()
INIT_WORK(&xpad->work, ...)
xpad360w_start_input()
usb_submit_urb(xpad->irq_in)
xpad_irq_in()
xpad360w_process_packet()
schedule_work(&xpad->work)
xpad_inquiry_pad_presence()
/* fails */
usb_kill_urb(xpad->irq_in)
goto err_deinit_output;
...
kfree(xpad)
xpad_presence_work()
/* dereferences freed xpad */
<-- use-after-free
Calling cancel_work_sync(&xpad->work) after usb_kill_urb(xpad->irq_in) in
xpad360w_start_input() (matching xpad360w_stop_input()) would prevent the
work item from running after xpad is freed.
[1] https://sashiko.dev/#/bug/linux-0c0def42-a340-45bb-860d-c99ba757f43b
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261115135814.34031-1-levirootsmanuva2@gmail.com?part=1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-15 14:06 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-15 13:58 [PATCH] Input: xpad - add support for GameSir G7 Pro dongle in Xbox mode Alexander Gollings
2026-11-15 14:06 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox