From c70e67590049380875d018b1f29f181837594dbf Mon Sep 17 00:00:00 2001 From: Sam Lantinga <slouken@libsdl.org> 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 aab90ed7e..2ed4aee86 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 4e3da5dde..5d3a994f5 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;