summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2023-07-22 03:38:45 +0200
committerGitHub <noreply@github.com>2023-07-22 03:38:45 +0200
commitfb2b3753b59a5c9f0fe390a452e2b8a857b60066 (patch)
treec5b954d67616b0f0e4b3af9f340b6fb4c8c20326 /Source/Core/InputCommon
parent2764978bebce9cedf0e329c320951ff0508f7139 (diff)
parentc8df26554bc5433bff13aaff934d1539226577d7 (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.cpp27
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: {}",