SDL: Fixed locking up the Logitech F310 with the PlayStation controller detection (da134)

From da134a30396e12786c14fe8d1190ab05c67d9dba Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 28 Feb 2023 08:36:31 -0800
Subject: [PATCH] Fixed locking up the Logitech F310 with the PlayStation
 controller detection

---
 src/joystick/hidapi/SDL_hidapi_ps3.c       |  2 +-
 src/joystick/hidapi/SDL_hidapi_ps4.c       |  2 +-
 src/joystick/hidapi/SDL_hidapi_ps5.c       |  2 +-
 src/joystick/hidapi/SDL_hidapijoystick.c   | 50 ++++++++++++++++++++++
 src/joystick/hidapi/SDL_hidapijoystick_c.h |  2 +
 src/joystick/usb_ids.h                     | 22 +---------
 6 files changed, 56 insertions(+), 24 deletions(-)

diff --git a/src/joystick/hidapi/SDL_hidapi_ps3.c b/src/joystick/hidapi/SDL_hidapi_ps3.c
index 8dc34d13d6aa..e26596ccd739 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps3.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps3.c
@@ -581,7 +581,7 @@ static SDL_bool HIDAPI_DriverPS3ThirdParty_IsSupportedDevice(SDL_HIDAPI_Device *
     Uint8 data[USB_PACKET_LENGTH];
     int size;
 
-    if (SONY_THIRDPARTY_VENDOR(vendor_id)) {
+    if (HIDAPI_SupportsPlaystationDetection(vendor_id, product_id)) {
         if (device && device->dev) {
             size = ReadFeatureReport(device->dev, 0x03, data, sizeof data);
             if (size == 8 && data[2] == 0x26) {
diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c
index 527496a81aa3..03f60c279f13 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps4.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps4.c
@@ -183,7 +183,7 @@ static SDL_bool HIDAPI_DriverPS4_IsSupportedDevice(SDL_HIDAPI_Device *device, co
         return SDL_TRUE;
     }
 
-    if (SONY_THIRDPARTY_VENDOR(vendor_id)) {
+    if (HIDAPI_SupportsPlaystationDetection(vendor_id, product_id)) {
         if (device && device->dev) {
             size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdCapabilities, data, sizeof data);
             if (size == 48 && data[2] == 0x27) {
diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c
index 83f47328eb8e..56c92c669d5f 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps5.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps5.c
@@ -278,7 +278,7 @@ static SDL_bool HIDAPI_DriverPS5_IsSupportedDevice(SDL_HIDAPI_Device *device, co
         return SDL_TRUE;
     }
 
-    if (SONY_THIRDPARTY_VENDOR(vendor_id)) {
+    if (HIDAPI_SupportsPlaystationDetection(vendor_id, product_id)) {
         if (device && device->dev) {
             size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCapabilities, data, sizeof data);
             if (size == 48 && data[2] == 0x28) {
diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c
index 157d5d80afee..5bfdc312af92 100644
--- a/src/joystick/hidapi/SDL_hidapijoystick.c
+++ b/src/joystick/hidapi/SDL_hidapijoystick.c
@@ -133,6 +133,56 @@ void HIDAPI_DumpPacket(const char *prefix, const Uint8 *data, int size)
     SDL_free(buffer);
 }
 
+SDL_bool HIDAPI_SupportsPlaystationDetection(Uint16 vendor, Uint16 product)
+{
+    switch (vendor) {
+    case USB_VENDOR_DRAGONRISE:
+        return SDL_TRUE;
+    case USB_VENDOR_HORI:
+        return SDL_TRUE;
+    case USB_VENDOR_LOGITECH:
+        /* Most Logitech devices are fine with this, but the F310 will lock up */
+        if (product == USB_PRODUCT_LOGITECH_F310) {
+            return SDL_FALSE;
+        }
+        return SDL_TRUE;
+    case USB_VENDOR_MADCATZ:
+        return SDL_TRUE;
+    case USB_VENDOR_NACON:
+        return SDL_TRUE;
+    case USB_VENDOR_PDP:
+        return SDL_TRUE;
+    case USB_VENDOR_POWERA:
+        return SDL_TRUE;
+    case USB_VENDOR_POWERA_ALT:
+        return SDL_TRUE;
+    case USB_VENDOR_QANBA:
+        return SDL_TRUE;
+    case USB_VENDOR_RAZER:
+        /* Most Razer devices are not game controllers, and some of them lock up
+         * or reset when we send them the Sony third-party query feature report,
+         * so don't include that vendor here. Instead add devices as appropriate
+         * to controller_type.c
+         *
+         * Reference: https://github.com/libsdl-org/SDL/issues/6733
+         *            https://github.com/libsdl-org/SDL/issues/6799
+         */
+        return SDL_FALSE;
+    case USB_VENDOR_SHANWAN:
+        return SDL_TRUE;
+    case USB_VENDOR_SHANWAN_ALT:
+        return SDL_TRUE;
+    case USB_VENDOR_THRUSTMASTER:
+        return SDL_TRUE;
+    case USB_VENDOR_ZEROPLUS:
+        return SDL_TRUE;
+    case 0x7545 /* SZ-MYPOWER */:
+        return SDL_TRUE;
+    default:
+        return SDL_FALSE;
+    }
+}
+
 float HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float output_max)
 {
     return output_min + (output_max - output_min) * (val - val_min) / (val_max - val_min);
diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h
index 10e2eb40c6b5..e5c59c58adc2 100644
--- a/src/joystick/hidapi/SDL_hidapijoystick_c.h
+++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h
@@ -154,6 +154,8 @@ extern void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickI
 
 extern void HIDAPI_DumpPacket(const char *prefix, const Uint8 *data, int size);
 
+extern SDL_bool HIDAPI_SupportsPlaystationDetection(Uint16 vendor, Uint16 product);
+
 extern float HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float output_max);
 
 #endif /* SDL_JOYSTICK_HIDAPI_H */
diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h
index f9b66d9c9ed9..8336ff0ce1d2 100644
--- a/src/joystick/usb_ids.h
+++ b/src/joystick/usb_ids.h
@@ -51,27 +51,6 @@
 #define USB_VENDOR_VALVE        0x28de
 #define USB_VENDOR_ZEROPLUS     0x0c12
 
-// Most Razer devices are not game controllers, and some of them lock up or reset
-// when we send them the Sony third-party query feature report, so don't include that
-// vendor here. Instead add devices as appropriate to controller_type.c
-// Reference: https://github.com/libsdl-org/SDL/issues/6733
-//            https://github.com/libsdl-org/SDL/issues/6799
-#define SONY_THIRDPARTY_VENDOR(X)    \
-    (X == USB_VENDOR_DRAGONRISE ||   \
-     X == USB_VENDOR_HORI ||         \
-     X == USB_VENDOR_LOGITECH ||     \
-     X == USB_VENDOR_MADCATZ ||      \
-     X == USB_VENDOR_NACON ||        \
-     X == USB_VENDOR_PDP ||          \
-     X == USB_VENDOR_POWERA ||       \
-     X == USB_VENDOR_POWERA_ALT ||   \
-     X == USB_VENDOR_QANBA ||        \
-     X == USB_VENDOR_SHANWAN ||      \
-     X == USB_VENDOR_SHANWAN_ALT ||  \
-     X == USB_VENDOR_THRUSTMASTER || \
-     X == USB_VENDOR_ZEROPLUS ||     \
-     X == 0x7545 /* SZ-MYPOWER */)
-
 #define USB_PRODUCT_8BITDO_XBOX_CONTROLLER                0x2002
 #define USB_PRODUCT_AMAZON_LUNA_CONTROLLER                0x0419
 #define USB_PRODUCT_BACKBONE_ONE_IOS                      0x0103
@@ -82,6 +61,7 @@
 #define USB_PRODUCT_HORI_HORIPAD_PRO_SERIES_X             0x014f
 #define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS4         0x011c
 #define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS5         0x0184
+#define USB_PRODUCT_LOGITECH_F310                         0xc216
 #define USB_PRODUCT_LOGITECH_CHILLSTREAM                  0xcad1
 #define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER             0x0337
 #define USB_PRODUCT_NINTENDO_N64_CONTROLLER               0x2019