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.
This commit is contained in:
Sam Lantinga 2022-11-03 12:37:54 -07:00
parent 084fa4c3fa
commit c70e675900
2 changed files with 10 additions and 10 deletions

View File

@ -368,26 +368,22 @@ HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device, SDL_bool *removed)
* *
* See https://github.com/libsdl-org/SDL/issues/6347 for details * See https://github.com/libsdl-org/SDL/issues/6347 for details
*/ */
const int MAX_ATTEMPTS = 3;
int attempt;
int lock_count = 0; int lock_count = 0;
SDL_HIDAPI_Device *curr; SDL_HIDAPI_Device *curr;
SDL_hid_device *dev; SDL_hid_device *dev;
char *path = SDL_strdup(device->path); char *path = SDL_strdup(device->path);
/* Wait a little bit for the device to initialize */
SDL_Delay(10);
SDL_AssertJoysticksLocked(); SDL_AssertJoysticksLocked();
while (SDL_JoysticksLocked()) { while (SDL_JoysticksLocked()) {
++lock_count; ++lock_count;
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
} }
for (attempt = 0; attempt < MAX_ATTEMPTS; ++attempt) {
dev = SDL_hid_open_path(path, 0); dev = SDL_hid_open_path(path, 0);
if (dev != NULL) {
break;
}
/* Wait a bit and try again */
SDL_Delay(30);
}
while (lock_count > 0) { while (lock_count > 0) {
--lock_count; --lock_count;
SDL_LockJoysticks(); SDL_LockJoysticks();

View File

@ -267,6 +267,10 @@ static void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_clas
return; return;
} }
} }
/* Wait a bit for the hidraw udev node to initialize */
SDL_Delay(10);
MaybeAddDevice(devpath); MaybeAddDevice(devpath);
break; break;