From 6a2ad0a0aa17c994ae95f492bfd27a2a2b3c2b0f Mon Sep 17 00:00:00 2001 From: Megamouse Date: Mon, 18 May 2026 18:50:26 +0200 Subject: [PATCH] sys_usbd: enable windows hotplug --- buildfiles/msvc/common_default.props | 3 ++ buildfiles/msvc/rpcs3_release.props | 1 - rpcs3/Emu/Cell/lv2/sys_usbd.cpp | 43 +++++++++++++++------------- rpcs3/Emu/Cell/lv2/sys_usbd.h | 2 +- rpcs3/rpcs3qt/gui_application.cpp | 2 +- 5 files changed, 28 insertions(+), 23 deletions(-) diff --git a/buildfiles/msvc/common_default.props b/buildfiles/msvc/common_default.props index bfddbb5465..742cc0637b 100644 --- a/buildfiles/msvc/common_default.props +++ b/buildfiles/msvc/common_default.props @@ -3,6 +3,9 @@ + + true + 10.0 diff --git a/buildfiles/msvc/rpcs3_release.props b/buildfiles/msvc/rpcs3_release.props index 378ba797d6..85cc17a8af 100644 --- a/buildfiles/msvc/rpcs3_release.props +++ b/buildfiles/msvc/rpcs3_release.props @@ -2,7 +2,6 @@ - Full diff --git a/rpcs3/Emu/Cell/lv2/sys_usbd.cpp b/rpcs3/Emu/Cell/lv2/sys_usbd.cpp index 031acd607b..d200b6608d 100644 --- a/rpcs3/Emu/Cell/lv2/sys_usbd.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_usbd.cpp @@ -46,6 +46,14 @@ #include +#ifdef _WIN32 +#if LIBUSB_WINDOWS_HOTPLUG && LIBUSB_API_VERSION >= 0x0100010C +#define SYS_USBD_HOTPLUG_SUPPORTED 1 +#endif +#elif LIBUSB_API_VERSION >= 0x01000102 +#define SYS_USBD_HOTPLUG_SUPPORTED 1 +#endif + LOG_CHANNEL(sys_usbd); cfg_buzz g_cfg_buzz; @@ -154,6 +162,7 @@ public: ppu_thread* sq{}; atomic_t usb_hotplug_timeout = umax; + atomic_t hotplug_supported = false; static constexpr auto thread_name = "Usb Manager Thread"sv; @@ -217,7 +226,6 @@ private: {0x12BA, 0x04A1, 0x04A1, "Top Shot Fearmaster", nullptr, nullptr}, {0x12BA, 0x04B0, 0x04B0, "Rapala Fishing Rod", nullptr, nullptr}, - // Wheels #ifdef HAVE_SDL3 {0x046D, 0xC283, 0xC29B, "lgFF_c283_c29b", &usb_device_logitech_g27::get_num_emu_devices, &usb_device_logitech_g27::make_instance}, @@ -294,13 +302,9 @@ private: libusb_context* ctx = nullptr; -#ifndef _WIN32 -#if LIBUSB_API_VERSION >= 0x01000102 +#if SYS_USBD_HOTPLUG_SUPPORTED libusb_hotplug_callback_handle callback_handle {}; #endif -#endif - - bool hotplug_supported = false; }; void LIBUSB_CALL callback_transfer(struct libusb_transfer* transfer) @@ -313,15 +317,13 @@ void LIBUSB_CALL callback_transfer(struct libusb_transfer* transfer) usbh.transfer_complete(transfer); } -#ifndef _WIN32 -#if LIBUSB_API_VERSION >= 0x01000102 -static int LIBUSB_CALL hotplug_callback(libusb_context* /*ctx*/, libusb_device * /*dev*/, libusb_hotplug_event event, void * /*user_data*/) +#if SYS_USBD_HOTPLUG_SUPPORTED +static int LIBUSB_CALL hotplug_callback(libusb_context* /*ctx*/, libusb_device* /*dev*/, libusb_hotplug_event event, void* /*user_data*/) { - handle_hotplug_event(event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED); + handle_hotplug_event(event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, true); return 0; } #endif -#endif #if LIBUSB_API_VERSION >= 0x0100010A static void LIBUSB_CALL log_cb(libusb_context* /*ctx*/, enum libusb_log_level level, const char* str) @@ -463,9 +465,7 @@ usb_handler_thread::usb_handler_thread() return; } -#ifdef _WIN32 - hotplug_supported = true; -#elif LIBUSB_API_VERSION >= 0x01000102 +#if SYS_USBD_HOTPLUG_SUPPORTED if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { if (int res = libusb_hotplug_register_callback(ctx, static_cast(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | @@ -480,6 +480,8 @@ usb_handler_thread::usb_handler_thread() hotplug_supported = true; } } +#elif defined(_WIN32) + hotplug_supported = true; #endif for (u32 index = 0; index < MAX_SYS_USBD_TRANSFERS; index++) @@ -627,11 +629,9 @@ usb_handler_thread::~usb_handler_thread() libusb_free_transfer(transfers[index].transfer); } -#ifndef _WIN32 -#if LIBUSB_API_VERSION >= 0x01000102 +#if SYS_USBD_HOTPLUG_SUPPORTED if (ctx && hotplug_supported) libusb_hotplug_deregister_callback(ctx, callback_handle); -#endif #endif if (ctx) @@ -654,7 +654,7 @@ void usb_handler_thread::operator()() // every 4 seconds. // On systems where hotplug is native, we wait a little bit for devices to settle before we start the scan perform_scan(); - usb_hotplug_timeout = hotplug_supported ? umax : get_system_time() + 4'000'000ull; + usb_hotplug_timeout = hotplug_supported ? umax : (get_system_time() + 4'000'000ull); } // Process asynchronous requests that are pending @@ -1106,15 +1106,18 @@ void reconnect_usb(u32 assigned_number) usbh->reconnect_usb_device(assigned_number); } -void handle_hotplug_event(bool connected) +void handle_hotplug_event(bool connected, bool source_is_libusb) { if (auto usbh = g_fxo->try_get>()) { + if (usbh->hotplug_supported && !source_is_libusb) return; + + sys_usbd.notice("handle_hotplug_event: connected=%d", connected); + usbh->usb_hotplug_timeout = get_system_time() + (connected ? 1'000'000ull : 0); } } - error_code sys_usbd_initialize(ppu_thread& ppu, vm::ptr handle) { ppu.state += cpu_flag::wait; diff --git a/rpcs3/Emu/Cell/lv2/sys_usbd.h b/rpcs3/Emu/Cell/lv2/sys_usbd.h index 45e9214e82..01a7891bbc 100644 --- a/rpcs3/Emu/Cell/lv2/sys_usbd.h +++ b/rpcs3/Emu/Cell/lv2/sys_usbd.h @@ -90,4 +90,4 @@ error_code sys_usbd_unregister_extra_ldd(ppu_thread& ppu, u32 handle, vm::cptrwParam == DBT_DEVICEARRIVAL); + handle_hotplug_event(msg->wParam == DBT_DEVICEARRIVAL, false); } return false; }