Browse Source

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.
Sam Lantinga 2 years ago
parent
commit
c70e675900
2 changed files with 10 additions and 10 deletions
  1. 6 10
      src/joystick/hidapi/SDL_hidapijoystick.c
  2. 4 0
      src/joystick/linux/SDL_sysjoystick.c

+ 6 - 10
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();

+ 4 - 0
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;