diff options
| author | Admiral H. Curtiss <pikachu025@gmail.com> | 2023-07-22 03:38:45 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-22 03:38:45 +0200 |
| commit | fb2b3753b59a5c9f0fe390a452e2b8a857b60066 (patch) | |
| tree | c5b954d67616b0f0e4b3af9f340b6fb4c8c20326 /Source/Core/InputCommon | |
| parent | 2764978bebce9cedf0e329c320951ff0508f7139 (diff) | |
| parent | c8df26554bc5433bff13aaff934d1539226577d7 (diff) | |
Merge pull request #12015 from nyanpasu64/gc-adapter-sleep-detach
Fix GC Adapter breaking and burning a full CPU core after sleep-wake on Linux
Diffstat (limited to 'Source/Core/InputCommon')
| -rw-r--r-- | Source/Core/InputCommon/GCAdapter.cpp | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp index a3853e9e6c..ec3c3a1fb3 100644 --- a/Source/Core/InputCommon/GCAdapter.cpp +++ b/Source/Core/InputCommon/GCAdapter.cpp @@ -203,14 +203,25 @@ static void ReadThreadFunc() std::array<u8, CONTROLER_INPUT_PAYLOAD_EXPECTED_SIZE> input_buffer; int payload_size = 0; - const int error = - libusb_interrupt_transfer(s_handle, s_endpoint_in, input_buffer.data(), - int(input_buffer.size()), &payload_size, USB_TIMEOUT_MS); + int error = libusb_interrupt_transfer(s_handle, s_endpoint_in, input_buffer.data(), + int(input_buffer.size()), &payload_size, USB_TIMEOUT_MS); if (error != LIBUSB_SUCCESS) { ERROR_LOG_FMT(CONTROLLERINTERFACE, "Read: libusb_interrupt_transfer failed: {}", LibusbUtils::ErrorWrap(error)); } + if (error == LIBUSB_ERROR_IO) + { + // s_read_adapter_thread_running is cleared by the joiner, not the stopper. + + // Reset the device, which may trigger a replug. + error = libusb_reset_device(s_handle); + ERROR_LOG_FMT(CONTROLLERINTERFACE, "Read: libusb_reset_device: {}", + LibusbUtils::ErrorWrap(error)); + + // If error is nonzero, try fixing it next loop iteration. We can't easily return + // and cleanup program state without getting another thread to call Reset(). + } ProcessInputPayload(input_buffer.data(), payload_size); @@ -614,8 +625,8 @@ static bool CheckDeviceAccess(libusb_device* device) static void AddGCAdapter(libusb_device* device) { - libusb_config_descriptor* config = nullptr; - if (const int error = libusb_get_config_descriptor(device, 0, &config); error != LIBUSB_SUCCESS) + auto [error, config] = LibusbUtils::MakeConfigDescriptor(device); + if (error != LIBUSB_SUCCESS) { WARN_LOG_FMT(CONTROLLERINTERFACE, "libusb_get_config_descriptor failed: {}", LibusbUtils::ErrorWrap(error)); @@ -636,12 +647,12 @@ static void AddGCAdapter(libusb_device* device) } } } + config.reset(); int size = 0; std::array<u8, CONTROLER_OUTPUT_INIT_PAYLOAD_SIZE> payload = {0x13}; - const int error = - libusb_interrupt_transfer(s_handle, s_endpoint_out, payload.data(), - CONTROLER_OUTPUT_INIT_PAYLOAD_SIZE, &size, USB_TIMEOUT_MS); + error = libusb_interrupt_transfer(s_handle, s_endpoint_out, payload.data(), + CONTROLER_OUTPUT_INIT_PAYLOAD_SIZE, &size, USB_TIMEOUT_MS); if (error != LIBUSB_SUCCESS) { WARN_LOG_FMT(CONTROLLERINTERFACE, "AddGCAdapter: libusb_interrupt_transfer failed: {}", |
