From c70e67590049380875d018b1f29f181837594dbf Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 3 Nov 2022 12:37:54 -0700
Subject: [PATCH] Wait a bit for devices to initialize before trying to
enumerate and open them.
This works around udev event nodes arriving before hidraw nodes and the controller being opened twice - once using the Linux driver and once by the HIDAPI driver.
This also fixes a kernel panic on Steam Link hardware due to trying to open the hidraw device node too early.
A delay of 10 ms seems to be a good value, tested on Steam Link hardware.
---
src/joystick/hidapi/SDL_hidapijoystick.c | 16 ++++++----------
src/joystick/linux/SDL_sysjoystick.c | 4 ++++
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c
index aab90ed7e99e..2ed4aee863cf 100644
--- a/src/joystick/hidapi/SDL_hidapijoystick.c
+++ b/src/joystick/hidapi/SDL_hidapijoystick.c
@@ -368,26 +368,22 @@ HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device, SDL_bool *removed)
*
* See https://github.com/libsdl-org/SDL/issues/6347 for details
*/
- const int MAX_ATTEMPTS = 3;
- int attempt;
int lock_count = 0;
SDL_HIDAPI_Device *curr;
SDL_hid_device *dev;
char *path = SDL_strdup(device->path);
+ /* Wait a little bit for the device to initialize */
+ SDL_Delay(10);
+
SDL_AssertJoysticksLocked();
while (SDL_JoysticksLocked()) {
++lock_count;
SDL_UnlockJoysticks();
}
- for (attempt = 0; attempt < MAX_ATTEMPTS; ++attempt) {
- dev = SDL_hid_open_path(path, 0);
- if (dev != NULL) {
- break;
- }
- /* Wait a bit and try again */
- SDL_Delay(30);
- }
+
+ dev = SDL_hid_open_path(path, 0);
+
while (lock_count > 0) {
--lock_count;
SDL_LockJoysticks();
diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c
index 4e3da5dde66e..5d3a994f5b16 100644
--- a/src/joystick/linux/SDL_sysjoystick.c
+++ b/src/joystick/linux/SDL_sysjoystick.c
@@ -267,6 +267,10 @@ static void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_clas
return;
}
}
+
+ /* Wait a bit for the hidraw udev node to initialize */
+ SDL_Delay(10);
+
MaybeAddDevice(devpath);
break;