summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/GCAdapter.cpp
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2020-07-04 20:03:20 -0500
committerJordan Woyak <jordan.woyak@gmail.com>2020-07-07 14:45:19 -0500
commitf2fd5c7f90932a0b66764a863900f408c172a6f2 (patch)
tree3a0cbdb94f8b8868e5d3fe175a809685bf411dca /Source/Core/InputCommon/GCAdapter.cpp
parent4f98653ec63fed64a4f69f5cdea53020661e6e70 (diff)
InputCommon/GCAdapter: Fix offbrand "GCAdapters" with a libusb_control_transfer call.
Diffstat (limited to 'Source/Core/InputCommon/GCAdapter.cpp')
-rw-r--r--Source/Core/InputCommon/GCAdapter.cpp32
1 files changed, 16 insertions, 16 deletions
diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp
index 5172000dda..3b8e823b24 100644
--- a/Source/Core/InputCommon/GCAdapter.cpp
+++ b/Source/Core/InputCommon/GCAdapter.cpp
@@ -38,7 +38,7 @@ enum
};
// Current adapter status: detected/not detected/in error (holds the error code)
-static int s_status = NO_ADAPTER_DETECTED;
+static std::atomic<int> s_status = NO_ADAPTER_DETECTED;
static libusb_device_handle* s_handle = nullptr;
static u8 s_controller_type[SerialInterface::MAX_SI_CHANNELS] = {
ControllerTypes::CONTROLLER_NONE, ControllerTypes::CONTROLLER_NONE,
@@ -60,6 +60,7 @@ static Common::Event s_rumble_data_available;
static std::mutex s_init_mutex;
static std::thread s_adapter_detect_thread;
static Common::Flag s_adapter_detect_thread_running;
+static Common::Event s_hotplug_event;
static std::function<void(void)> s_detect_callback;
@@ -125,15 +126,8 @@ static int HotplugCallback(libusb_context* ctx, libusb_device* dev, libusb_hotpl
{
if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)
{
- if (s_handle == nullptr && CheckDeviceAccess(dev))
- {
- std::lock_guard<std::mutex> lk(s_init_mutex);
- AddGCAdapter(dev);
- }
- else if (s_status < 0 && s_detect_callback != nullptr)
- {
- s_detect_callback();
- }
+ if (s_handle == nullptr)
+ s_hotplug_event.Set();
}
else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
{
@@ -175,9 +169,6 @@ static void ScanThreadFunc()
}
#endif
- if (s_libusb_hotplug_enabled)
- return;
-
while (s_adapter_detect_thread_running.IsSet())
{
if (s_handle == nullptr)
@@ -185,7 +176,11 @@ static void ScanThreadFunc()
std::lock_guard<std::mutex> lk(s_init_mutex);
Setup();
}
- Common::SleepCurrentThread(500);
+
+ if (s_libusb_hotplug_enabled)
+ s_hotplug_event.Wait();
+ else
+ Common::SleepCurrentThread(500);
}
NOTICE_LOG(SERIALINTERFACE, "GC Adapter scanning thread stopped");
}
@@ -228,6 +223,7 @@ void StopScanThread()
{
if (s_adapter_detect_thread_running.TestAndClear())
{
+ s_hotplug_event.Set();
s_adapter_detect_thread.join();
}
}
@@ -307,6 +303,10 @@ static bool CheckDeviceAccess(libusb_device* device)
ERROR_LOG(SERIALINTERFACE, "libusb_detach_kernel_driver failed with error: %d", ret);
}
+ ret = libusb_control_transfer(s_handle, 0x21, 11, 0x0001, 0, nullptr, 0, 10000);
+ if (ret < 0)
+ ERROR_LOG(SERIALINTERFACE, "libusb_control_transfer failed with error: %d", ret);
+
// this split is needed so that we don't avoid claiming the interface when
// detaching the kernel driver is successful
if (ret != 0 && ret != LIBUSB_ERROR_NOT_SUPPORTED)
@@ -431,9 +431,9 @@ GCPadStatus Input(int chan)
if (payload_size != sizeof(controller_payload_copy) ||
controller_payload_copy[0] != LIBUSB_DT_HID)
{
+ // This can occur for a few frames on initialization.
ERROR_LOG(SERIALINTERFACE, "error reading payload (size: %d, type: %02x)", payload_size,
controller_payload_copy[0]);
- Reset();
}
else
{
@@ -575,7 +575,7 @@ bool IsDetected(const char** error_message)
}
if (error_message)
- *error_message = libusb_strerror(static_cast<libusb_error>(s_status));
+ *error_message = libusb_strerror(static_cast<libusb_error>(s_status.load()));
return false;
}