USB: Fixed G27 crash during reinitialization

This commit is contained in:
Florin9doi
2026-01-05 16:52:26 +02:00
committed by Megamouse
parent 8f26c01ae5
commit 9b256d71a9
3 changed files with 29 additions and 21 deletions
+1 -1
View File
@@ -51,7 +51,7 @@ These are the essentials tools to build RPCS3 on Linux. Some of them can be inst
#### Debian & Ubuntu #### Debian & Ubuntu
sudo apt-get install build-essential ninja-build libasound2-dev libpulse-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git libevdev-dev libsdl3-3.2 libsdl3-dev libjack-dev libsndio-dev sudo apt-get install build-essential ninja-build libasound2-dev libpulse-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git libevdev-dev libsdl3-dev libjack-dev libsndio-dev libcurl4-openssl-dev qt6-base-dev qt6-base-private-dev qt6-multimedia-dev qt6-svg-dev libxkbcommon-dev
Ubuntu is usually horrendously out of date, and some packages need to be downloaded by hand. This part is for Qt, GCC, Vulkan, and CMake Ubuntu is usually horrendously out of date, and some packages need to be downloaded by hand. This part is for Qt, GCC, Vulkan, and CMake
+23 -15
View File
@@ -137,6 +137,7 @@ public:
const std::array<u8, 7>& get_new_location(); const std::array<u8, 7>& get_new_location();
void connect_usb_device(std::shared_ptr<usb_device> dev, bool update_usb_devices = false); void connect_usb_device(std::shared_ptr<usb_device> dev, bool update_usb_devices = false);
void disconnect_usb_device(std::shared_ptr<usb_device> dev, bool update_usb_devices = false); void disconnect_usb_device(std::shared_ptr<usb_device> dev, bool update_usb_devices = false);
void reconnect_usb_device(u32 assigned_number);
// Map of devices actively handled by the ps3(device_id, device) // Map of devices actively handled by the ps3(device_id, device)
std::map<u32, std::pair<UsbInternalDevice, std::shared_ptr<usb_device>>> handled_devices; std::map<u32, std::pair<UsbInternalDevice, std::shared_ptr<usb_device>>> handled_devices;
@@ -205,19 +206,23 @@ private:
{0x1BAD, 0x3430, 0x343F, "Harmonix Button Guitar - Wii", nullptr, nullptr}, {0x1BAD, 0x3430, 0x343F, "Harmonix Button Guitar - Wii", nullptr, nullptr},
{0x1BAD, 0x3530, 0x353F, "Harmonix Real Guitar - Wii", nullptr, nullptr}, {0x1BAD, 0x3530, 0x353F, "Harmonix Real Guitar - Wii", nullptr, nullptr},
//Top Shot Elite controllers // Top Shot Elite controllers
{0x12BA, 0x04A0, 0x04A0, "Top Shot Elite", nullptr, nullptr}, {0x12BA, 0x04A0, 0x04A0, "Top Shot Elite", nullptr, nullptr},
{0x12BA, 0x04A1, 0x04A1, "Top Shot Fearmaster", nullptr, nullptr}, {0x12BA, 0x04A1, 0x04A1, "Top Shot Fearmaster", nullptr, nullptr},
{0x12BA, 0x04B0, 0x04B0, "Rapala Fishing Rod", nullptr, nullptr}, {0x12BA, 0x04B0, 0x04B0, "Rapala Fishing Rod", nullptr, nullptr},
// GT5 Wheels&co // Wheels
#ifdef HAVE_SDL3 #ifdef HAVE_SDL3
{0x046D, 0xC283, 0xC29B, "lgFF_c283_c29b", &usb_device_logitech_g27::get_num_emu_devices, &usb_device_logitech_g27::make_instance}, {0x046D, 0xC283, 0xC29B, "lgFF_c283_c29b", &usb_device_logitech_g27::get_num_emu_devices, &usb_device_logitech_g27::make_instance},
#else #else
{0x046D, 0xC283, 0xC29B, "lgFF_c283_c29b", nullptr, nullptr}, {0x046D, 0xC283, 0xC29B, "lgFF_c283_c29b", nullptr, nullptr},
#endif #endif
{0x046D, 0xCA03, 0xCA03, "lgFF_ca03_ca03", nullptr, nullptr},
{0x044F, 0xB652, 0xB652, "Thrustmaster FGT FFB old", nullptr, nullptr},
{0x044F, 0xB653, 0xB653, "Thrustmaster RGT FFB Pro", nullptr, nullptr}, {0x044F, 0xB653, 0xB653, "Thrustmaster RGT FFB Pro", nullptr, nullptr},
{0x044F, 0xB654, 0xB654, "Thrustmaster FGT FFB", nullptr, nullptr},
{0x044F, 0xb655, 0xb655, "Thrustmaster FGT Rumble 3-in-1", nullptr, nullptr},
{0x044F, 0xB65A, 0xB65A, "Thrustmaster F430", nullptr, nullptr}, {0x044F, 0xB65A, 0xB65A, "Thrustmaster F430", nullptr, nullptr},
{0x044F, 0xB65D, 0xB65D, "Thrustmaster FFB", nullptr, nullptr}, {0x044F, 0xB65D, 0xB65D, "Thrustmaster FFB", nullptr, nullptr},
{0x044F, 0xB65E, 0xB65E, "Thrustmaster TRS", nullptr, nullptr}, {0x044F, 0xB65E, 0xB65E, "Thrustmaster TRS", nullptr, nullptr},
@@ -225,7 +230,6 @@ private:
// GT6 // GT6
{0x2833, 0x0001, 0x0001, "Oculus", nullptr, nullptr}, {0x2833, 0x0001, 0x0001, "Oculus", nullptr, nullptr},
{0x046D, 0xCA03, 0xCA03, "lgFF_ca03_ca03", nullptr, nullptr},
// Buzz controllers // Buzz controllers
{0x054C, 0x1000, 0x1040, "buzzer0", &usb_device_buzz::get_num_emu_devices, &usb_device_buzz::make_instance}, {0x054C, 0x1000, 0x1040, "buzzer0", &usb_device_buzz::get_num_emu_devices, &usb_device_buzz::make_instance},
@@ -968,6 +972,21 @@ void usb_handler_thread::disconnect_usb_device(std::shared_ptr<usb_device> dev,
} }
} }
void usb_handler_thread::reconnect_usb_device(u32 assigned_number)
{
std::lock_guard lock(mutex);
ensure(assigned_number != 0);
for (const auto& dev : usb_devices)
{
if (dev->assigned_number == assigned_number)
{
disconnect_usb_device(dev, false);
connect_usb_device(dev, false);
break;
}
}
}
void connect_usb_controller(u8 index, input::product_type type) void connect_usb_controller(u8 index, input::product_type type)
{ {
auto usbh = g_fxo->try_get<named_thread<usb_handler_thread>>(); auto usbh = g_fxo->try_get<named_thread<usb_handler_thread>>();
@@ -1061,18 +1080,7 @@ void reconnect_usb(u32 assigned_number)
{ {
return; return;
} }
usbh->reconnect_usb_device(assigned_number);
std::lock_guard lock(usbh->mutex);
for (auto& [nr, pair] : usbh->handled_devices)
{
auto& [internal_dev, dev] = pair;
if (nr == assigned_number)
{
usbh->disconnect_usb_device(dev, false);
usbh->connect_usb_device(dev, false);
break;
}
}
} }
void handle_hotplug_event(bool connected) void handle_hotplug_event(bool connected)
+5 -5
View File
@@ -1752,7 +1752,7 @@ void usb_device_logitech_g27::interrupt_transfer(u32 buf_size, u8* buf, u32 endp
{ {
if (!SDL_RunHapticEffect(m_haptic_handle, m_effect_slots[i].effect_id, 1)) if (!SDL_RunHapticEffect(m_haptic_handle, m_effect_slots[i].effect_id, 1))
{ {
logitech_g27_log.error("Failed playing sdl effect %d on slot %d, %s\n", m_effect_slots[i].last_effect.type, i, SDL_GetError()); logitech_g27_log.error("Failed playing sdl effect %d on slot %d, %s", m_effect_slots[i].last_effect.type, i, SDL_GetError());
} }
} }
else else
@@ -1796,14 +1796,14 @@ void usb_device_logitech_g27::interrupt_transfer(u32 buf_size, u8* buf, u32 endp
{ {
if (!SDL_RunHapticEffect(m_haptic_handle, m_effect_slots[i].effect_id, 1)) if (!SDL_RunHapticEffect(m_haptic_handle, m_effect_slots[i].effect_id, 1))
{ {
logitech_g27_log.error("Failed playing sdl effect %d on slot %d, %s\n", m_effect_slots[i].last_effect.type, i, SDL_GetError()); logitech_g27_log.error("Failed playing sdl effect %d on slot %d, %s", m_effect_slots[i].last_effect.type, i, SDL_GetError());
} }
} }
else else
{ {
if (!SDL_StopHapticEffect(m_haptic_handle, m_effect_slots[i].effect_id)) if (!SDL_StopHapticEffect(m_haptic_handle, m_effect_slots[i].effect_id))
{ {
logitech_g27_log.error("Failed stopping sdl effect %d on slot %d, %s\n", m_effect_slots[i].last_effect.type, i, SDL_GetError()); logitech_g27_log.error("Failed stopping sdl effect %d on slot %d, %s", m_effect_slots[i].last_effect.type, i, SDL_GetError());
} }
} }
} }
@@ -1824,11 +1824,11 @@ void usb_device_logitech_g27::interrupt_transfer(u32 buf_size, u8* buf, u32 endp
{ {
if (cmd == 0x02) if (cmd == 0x02)
{ {
logitech_g27_log.error("Tried to play effect slot %d but it was never uploaded\n", i); logitech_g27_log.error("Tried to play effect slot %d but it was never uploaded", i);
} }
else else
{ {
logitech_g27_log.error("Tried to stop effect slot %d but it was never uploaded\n", i); logitech_g27_log.error("Tried to stop effect slot %d but it was never uploaded", i);
} }
} }
} }