From 340f15d1fa79594dbe12a6e19140ba012751b533 Mon Sep 17 00:00:00 2001
From: german77 <juangerman-13@hotmail.com>
Date: Fri, 13 Jan 2023 23:29:05 -0600
Subject: [PATCH] input_common: Address byte review

---
 src/input_common/drivers/joycon.cpp           |  50 ++---
 src/input_common/drivers/joycon.h             |   1 -
 src/input_common/drivers/sdl_driver.cpp       |   2 +-
 src/input_common/helpers/joycon_driver.cpp    |   8 +-
 src/input_common/helpers/joycon_driver.h      |   3 +-
 .../helpers/joycon_protocol/calibration.cpp   |   9 +-
 .../joycon_protocol/common_protocol.cpp       |  24 +--
 .../helpers/joycon_protocol/common_protocol.h |  22 +-
 .../joycon_protocol/generic_functions.cpp     |  54 ++---
 .../helpers/joycon_protocol/irs.cpp           |  18 +-
 .../helpers/joycon_protocol/joycon_types.h    |  12 ++
 .../helpers/joycon_protocol/nfc.cpp           | 191 ++++++++----------
 .../helpers/joycon_protocol/nfc.h             |   4 +-
 .../helpers/joycon_protocol/poller.cpp        |  18 +-
 .../helpers/joycon_protocol/ringcon.cpp       |  36 ++--
 .../helpers/joycon_protocol/rumble.cpp        |  19 +-
 16 files changed, 224 insertions(+), 247 deletions(-)

diff --git a/src/input_common/drivers/joycon.cpp b/src/input_common/drivers/joycon.cpp
index fff886ca8a..1582def13c 100644
--- a/src/input_common/drivers/joycon.cpp
+++ b/src/input_common/drivers/joycon.cpp
@@ -60,15 +60,12 @@ void Joycons::Setup() {
         device = std::make_shared<Joycon::JoyconDriver>(port++);
     }
 
-    if (!scan_thread_running) {
-        scan_thread = std::jthread([this](std::stop_token stop_token) { ScanThread(stop_token); });
-    }
+    scan_thread = std::jthread([this](std::stop_token stop_token) { ScanThread(stop_token); });
 }
 
 void Joycons::ScanThread(std::stop_token stop_token) {
     constexpr u16 nintendo_vendor_id = 0x057e;
-    Common::SetCurrentThreadName("yuzu:input:JoyconScanThread");
-    scan_thread_running = true;
+    Common::SetCurrentThreadName("JoyconScanThread");
     while (!stop_token.stop_requested()) {
         SDL_hid_device_info* devs = SDL_hid_enumerate(nintendo_vendor_id, 0x0);
         SDL_hid_device_info* cur_dev = devs;
@@ -82,9 +79,9 @@ void Joycons::ScanThread(std::stop_token stop_token) {
             cur_dev = cur_dev->next;
         }
 
+        SDL_hid_free_enumeration(devs);
         std::this_thread::sleep_for(std::chrono::seconds(5));
     }
-    scan_thread_running = false;
 }
 
 bool Joycons::IsDeviceNew(SDL_hid_device_info* device_info) const {
@@ -185,19 +182,19 @@ void Joycons::RegisterNewDevice(SDL_hid_device_info* device_info) {
 
 std::shared_ptr<Joycon::JoyconDriver> Joycons::GetNextFreeHandle(
     Joycon::ControllerType type) const {
-
     if (type == Joycon::ControllerType::Left) {
-        for (const auto& device : left_joycons) {
-            if (!device->IsConnected()) {
-                return device;
-            }
+        const auto unconnected_device =
+            std::ranges::find_if(left_joycons, [](auto& device) { return !device->IsConnected(); });
+        if (unconnected_device != left_joycons.end()) {
+            return *unconnected_device;
         }
     }
     if (type == Joycon::ControllerType::Right) {
-        for (const auto& device : right_joycons) {
-            if (!device->IsConnected()) {
-                return device;
-            }
+        const auto unconnected_device = std::ranges::find_if(
+            right_joycons, [](auto& device) { return !device->IsConnected(); });
+
+        if (unconnected_device != right_joycons.end()) {
+            return *unconnected_device;
         }
     }
     return nullptr;
@@ -391,20 +388,25 @@ std::shared_ptr<Joycon::JoyconDriver> Joycons::GetHandle(PadIdentifier identifie
         return false;
     };
     const auto type = static_cast<Joycon::ControllerType>(identifier.pad);
+
     if (type == Joycon::ControllerType::Left) {
-        for (const auto& device : left_joycons) {
-            if (is_handle_active(device)) {
-                return device;
-            }
+        const auto matching_device = std::ranges::find_if(
+            left_joycons, [is_handle_active](auto& device) { return is_handle_active(device); });
+
+        if (matching_device != left_joycons.end()) {
+            return *matching_device;
         }
     }
+
     if (type == Joycon::ControllerType::Right) {
-        for (const auto& device : right_joycons) {
-            if (is_handle_active(device)) {
-                return device;
-            }
+        const auto matching_device = std::ranges::find_if(
+            right_joycons, [is_handle_active](auto& device) { return is_handle_active(device); });
+
+        if (matching_device != right_joycons.end()) {
+            return *matching_device;
         }
     }
+
     return nullptr;
 }
 
@@ -676,7 +678,7 @@ std::string Joycons::JoyconName(Joycon::ControllerType type) const {
     case Joycon::ControllerType::Dual:
         return "Dual Joycon";
     default:
-        return "Unknow Joycon";
+        return "Unknown Joycon";
     }
 }
 } // namespace InputCommon
diff --git a/src/input_common/drivers/joycon.h b/src/input_common/drivers/joycon.h
index f5cc787db0..6d2e2ec786 100644
--- a/src/input_common/drivers/joycon.h
+++ b/src/input_common/drivers/joycon.h
@@ -99,7 +99,6 @@ private:
     std::string JoyconName(Joycon::ControllerType type) const;
 
     std::jthread scan_thread;
-    bool scan_thread_running{};
 
     // Joycon types are split by type to ease supporting dualjoycon configurations
     std::array<std::shared_ptr<Joycon::JoyconDriver>, MaxSupportedControllers> left_joycons{};
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp
index e915ec0908..a0103edde2 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -321,7 +321,7 @@ void SDLDriver::InitJoystick(int joystick_index) {
     if (Settings::values.enable_joycon_driver) {
         if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e &&
             (guid.uuid[8] == 0x06 || guid.uuid[8] == 0x07)) {
-            LOG_ERROR(Input, "Device black listed {}", joystick_index);
+            LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index);
             SDL_JoystickClose(sdl_joystick);
             return;
         }
diff --git a/src/input_common/helpers/joycon_driver.cpp b/src/input_common/helpers/joycon_driver.cpp
index 5525723435..4159e5717a 100644
--- a/src/input_common/helpers/joycon_driver.cpp
+++ b/src/input_common/helpers/joycon_driver.cpp
@@ -123,7 +123,7 @@ DriverResult JoyconDriver::InitializeDevice() {
 }
 
 void JoyconDriver::InputThread(std::stop_token stop_token) {
-    LOG_INFO(Input, "JC Adapter input thread started");
+    LOG_INFO(Input, "Joycon Adapter input thread started");
     Common::SetCurrentThreadName("JoyconInput");
     input_thread_running = true;
 
@@ -157,7 +157,7 @@ void JoyconDriver::InputThread(std::stop_token stop_token) {
 
     is_connected = false;
     input_thread_running = false;
-    LOG_INFO(Input, "JC Adapter input thread stopped");
+    LOG_INFO(Input, "Joycon Adapter input thread stopped");
 }
 
 void JoyconDriver::OnNewData(std::span<u8> buffer) {
@@ -349,7 +349,7 @@ JoyconDriver::SupportedFeatures JoyconDriver::GetSupportedFeatures() {
 }
 
 bool JoyconDriver::IsInputThreadValid() const {
-    if (!is_connected) {
+    if (!is_connected.load()) {
         return false;
     }
     if (hidapi_handle->handle == nullptr) {
@@ -491,7 +491,7 @@ DriverResult JoyconDriver::SetRingConMode() {
 
 bool JoyconDriver::IsConnected() const {
     std::scoped_lock lock{mutex};
-    return is_connected;
+    return is_connected.load();
 }
 
 bool JoyconDriver::IsVibrationEnabled() const {
diff --git a/src/input_common/helpers/joycon_driver.h b/src/input_common/helpers/joycon_driver.h
index e8e65e1331..c1e189fa52 100644
--- a/src/input_common/helpers/joycon_driver.h
+++ b/src/input_common/helpers/joycon_driver.h
@@ -3,6 +3,7 @@
 
 #pragma once
 
+#include <atomic>
 #include <functional>
 #include <mutex>
 #include <span>
@@ -97,7 +98,7 @@ private:
     std::unique_ptr<RumbleProtocol> rumble_protocol;
 
     // Connection status
-    bool is_connected{};
+    std::atomic<bool> is_connected{};
     u64 delta_time;
     std::size_t error_counter{};
     std::shared_ptr<JoyconHandle> hidapi_handle;
diff --git a/src/input_common/helpers/joycon_protocol/calibration.cpp b/src/input_common/helpers/joycon_protocol/calibration.cpp
index cd30ab8698..f6e7e97d59 100644
--- a/src/input_common/helpers/joycon_protocol/calibration.cpp
+++ b/src/input_common/helpers/joycon_protocol/calibration.cpp
@@ -12,10 +12,10 @@ CalibrationProtocol::CalibrationProtocol(std::shared_ptr<JoyconHandle> handle)
     : JoyconCommonProtocol(std::move(handle)) {}
 
 DriverResult CalibrationProtocol::GetLeftJoyStickCalibration(JoyStickCalibration& calibration) {
+    ScopedSetBlocking sb(this);
     std::vector<u8> buffer;
     DriverResult result{DriverResult::Success};
     calibration = {};
-    SetBlocking();
 
     result = ReadSPI(CalAddr::USER_LEFT_MAGIC, sizeof(u16), buffer);
 
@@ -44,15 +44,14 @@ DriverResult CalibrationProtocol::GetLeftJoyStickCalibration(JoyStickCalibration
     // Set a valid default calibration if data is missing
     ValidateCalibration(calibration);
 
-    SetNonBlocking();
     return result;
 }
 
 DriverResult CalibrationProtocol::GetRightJoyStickCalibration(JoyStickCalibration& calibration) {
+    ScopedSetBlocking sb(this);
     std::vector<u8> buffer;
     DriverResult result{DriverResult::Success};
     calibration = {};
-    SetBlocking();
 
     result = ReadSPI(CalAddr::USER_RIGHT_MAGIC, sizeof(u16), buffer);
 
@@ -81,15 +80,14 @@ DriverResult CalibrationProtocol::GetRightJoyStickCalibration(JoyStickCalibratio
     // Set a valid default calibration if data is missing
     ValidateCalibration(calibration);
 
-    SetNonBlocking();
     return result;
 }
 
 DriverResult CalibrationProtocol::GetImuCalibration(MotionCalibration& calibration) {
+    ScopedSetBlocking sb(this);
     std::vector<u8> buffer;
     DriverResult result{DriverResult::Success};
     calibration = {};
-    SetBlocking();
 
     result = ReadSPI(CalAddr::USER_IMU_MAGIC, sizeof(u16), buffer);
 
@@ -124,7 +122,6 @@ DriverResult CalibrationProtocol::GetImuCalibration(MotionCalibration& calibrati
 
     ValidateCalibration(calibration);
 
-    SetNonBlocking();
     return result;
 }
 
diff --git a/src/input_common/helpers/joycon_protocol/common_protocol.cpp b/src/input_common/helpers/joycon_protocol/common_protocol.cpp
index 153a3908c6..417d0dcc50 100644
--- a/src/input_common/helpers/joycon_protocol/common_protocol.cpp
+++ b/src/input_common/helpers/joycon_protocol/common_protocol.cpp
@@ -58,9 +58,8 @@ DriverResult JoyconCommonProtocol::CheckDeviceAccess(SDL_hid_device_info* device
 }
 
 DriverResult JoyconCommonProtocol::SetReportMode(ReportMode report_mode) {
-    const std::vector<u8> buffer{static_cast<u8>(report_mode)};
-    std::vector<u8> output;
-    return SendSubCommand(SubCommand::SET_REPORT_MODE, buffer, output);
+    const std::array<u8, 1> buffer{static_cast<u8>(report_mode)};
+    return SendSubCommand(SubCommand::SET_REPORT_MODE, buffer);
 }
 
 DriverResult JoyconCommonProtocol::SendData(std::span<const u8> buffer) {
@@ -120,7 +119,12 @@ DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const
     return DriverResult::Success;
 }
 
-DriverResult JoyconCommonProtocol::SendMcuCommand(SubCommand sc, std::span<const u8> buffer) {
+DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const u8> buffer) {
+    std::vector<u8> output;
+    return SendSubCommand(sc, buffer, output);
+}
+
+DriverResult JoyconCommonProtocol::SendMCUCommand(SubCommand sc, std::span<const u8> buffer) {
     std::vector<u8> local_buffer(MaxResponseSize);
 
     local_buffer[0] = static_cast<u8>(OutputReport::MCU_DATA);
@@ -147,7 +151,7 @@ DriverResult JoyconCommonProtocol::SendVibrationReport(std::span<const u8> buffe
 DriverResult JoyconCommonProtocol::ReadSPI(CalAddr addr, u8 size, std::vector<u8>& output) {
     constexpr std::size_t MaxTries = 10;
     std::size_t tries = 0;
-    std::vector<u8> buffer = {0x00, 0x00, 0x00, 0x00, size};
+    std::array<u8, 5> buffer = {0x00, 0x00, 0x00, 0x00, size};
     std::vector<u8> local_buffer(size + 20);
 
     buffer[0] = static_cast<u8>(static_cast<u16>(addr) & 0x00FF);
@@ -169,10 +173,8 @@ DriverResult JoyconCommonProtocol::ReadSPI(CalAddr addr, u8 size, std::vector<u8
 }
 
 DriverResult JoyconCommonProtocol::EnableMCU(bool enable) {
-    std::vector<u8> output;
-
-    const std::vector<u8> mcu_state{static_cast<u8>(enable ? 1 : 0)};
-    const auto result = SendSubCommand(SubCommand::SET_MCU_STATE, mcu_state, output);
+    const std::array<u8, 1> mcu_state{static_cast<u8>(enable ? 1 : 0)};
+    const auto result = SendSubCommand(SubCommand::SET_MCU_STATE, mcu_state);
 
     if (result != DriverResult::Success) {
         LOG_ERROR(Input, "SendMCUData failed with error {}", result);
@@ -183,13 +185,11 @@ DriverResult JoyconCommonProtocol::EnableMCU(bool enable) {
 
 DriverResult JoyconCommonProtocol::ConfigureMCU(const MCUConfig& config) {
     LOG_DEBUG(Input, "ConfigureMCU");
-    std::vector<u8> output;
-
     std::array<u8, sizeof(MCUConfig)> config_buffer;
     memcpy(config_buffer.data(), &config, sizeof(MCUConfig));
     config_buffer[37] = CalculateMCU_CRC8(config_buffer.data() + 1, 36);
 
-    const auto result = SendSubCommand(SubCommand::SET_MCU_CONFIG, config_buffer, output);
+    const auto result = SendSubCommand(SubCommand::SET_MCU_CONFIG, config_buffer);
 
     if (result != DriverResult::Success) {
         LOG_ERROR(Input, "Set MCU config failed with error {}", result);
diff --git a/src/input_common/helpers/joycon_protocol/common_protocol.h b/src/input_common/helpers/joycon_protocol/common_protocol.h
index 2a3feaf598..903bcf4025 100644
--- a/src/input_common/helpers/joycon_protocol/common_protocol.h
+++ b/src/input_common/helpers/joycon_protocol/common_protocol.h
@@ -74,12 +74,19 @@ public:
      */
     DriverResult SendSubCommand(SubCommand sc, std::span<const u8> buffer, std::vector<u8>& output);
 
+    /**
+     * Sends a sub command to the device and waits for it's reply and ignores the output
+     * @param sc sub command to be send
+     * @param buffer data to be send
+     */
+    DriverResult SendSubCommand(SubCommand sc, std::span<const u8> buffer);
+
     /**
      * Sends a mcu command to the device
      * @param sc sub command to be send
      * @param buffer data to be send
      */
-    DriverResult SendMcuCommand(SubCommand sc, std::span<const u8> buffer);
+    DriverResult SendMCUCommand(SubCommand sc, std::span<const u8> buffer);
 
     /**
      * Sends vibration data to the joycon
@@ -150,4 +157,17 @@ private:
     std::shared_ptr<JoyconHandle> hidapi_handle;
 };
 
+class ScopedSetBlocking {
+public:
+    explicit ScopedSetBlocking(JoyconCommonProtocol* self) : m_self{self} {
+        m_self->SetBlocking();
+    }
+
+    ~ScopedSetBlocking() {
+        m_self->SetNonBlocking();
+    }
+
+private:
+    JoyconCommonProtocol* m_self{};
+};
 } // namespace InputCommon::Joycon
diff --git a/src/input_common/helpers/joycon_protocol/generic_functions.cpp b/src/input_common/helpers/joycon_protocol/generic_functions.cpp
index cbd9ff4f8b..52bb8b61aa 100644
--- a/src/input_common/helpers/joycon_protocol/generic_functions.cpp
+++ b/src/input_common/helpers/joycon_protocol/generic_functions.cpp
@@ -10,22 +10,18 @@ GenericProtocol::GenericProtocol(std::shared_ptr<JoyconHandle> handle)
     : JoyconCommonProtocol(std::move(handle)) {}
 
 DriverResult GenericProtocol::EnablePassiveMode() {
-    SetBlocking();
-    const auto result = SetReportMode(ReportMode::SIMPLE_HID_MODE);
-    SetNonBlocking();
-    return result;
+    ScopedSetBlocking sb(this);
+    return SetReportMode(ReportMode::SIMPLE_HID_MODE);
 }
 
 DriverResult GenericProtocol::EnableActiveMode() {
-    SetBlocking();
-    const auto result = SetReportMode(ReportMode::STANDARD_FULL_60HZ);
-    SetNonBlocking();
-    return result;
+    ScopedSetBlocking sb(this);
+    return SetReportMode(ReportMode::STANDARD_FULL_60HZ);
 }
 
 DriverResult GenericProtocol::GetDeviceInfo(DeviceInfo& device_info) {
+    ScopedSetBlocking sb(this);
     std::vector<u8> output;
-    SetBlocking();
 
     const auto result = SendSubCommand(SubCommand::REQ_DEV_INFO, {}, output);
 
@@ -34,7 +30,6 @@ DriverResult GenericProtocol::GetDeviceInfo(DeviceInfo& device_info) {
         memcpy(&device_info, output.data(), sizeof(DeviceInfo));
     }
 
-    SetNonBlocking();
     return result;
 }
 
@@ -43,36 +38,30 @@ DriverResult GenericProtocol::GetControllerType(ControllerType& controller_type)
 }
 
 DriverResult GenericProtocol::EnableImu(bool enable) {
+    ScopedSetBlocking sb(this);
     const std::array<u8, 1> buffer{static_cast<u8>(enable ? 1 : 0)};
-    std::vector<u8> output;
-    SetBlocking();
-    const auto result = SendSubCommand(SubCommand::ENABLE_IMU, buffer, output);
-    SetNonBlocking();
-    return result;
+    return SendSubCommand(SubCommand::ENABLE_IMU, buffer);
 }
 
 DriverResult GenericProtocol::SetImuConfig(GyroSensitivity gsen, GyroPerformance gfrec,
                                            AccelerometerSensitivity asen,
                                            AccelerometerPerformance afrec) {
+    ScopedSetBlocking sb(this);
     const std::array<u8, 4> buffer{static_cast<u8>(gsen), static_cast<u8>(asen),
                                    static_cast<u8>(gfrec), static_cast<u8>(afrec)};
-    std::vector<u8> output;
-    SetBlocking();
-    const auto result = SendSubCommand(SubCommand::SET_IMU_SENSITIVITY, buffer, output);
-    SetNonBlocking();
-    return result;
+    return SendSubCommand(SubCommand::SET_IMU_SENSITIVITY, buffer);
 }
 
 DriverResult GenericProtocol::GetBattery(u32& battery_level) {
+    // This function is meant to request the high resolution battery status
     battery_level = 0;
     return DriverResult::NotSupported;
 }
 
 DriverResult GenericProtocol::GetColor(Color& color) {
+    ScopedSetBlocking sb(this);
     std::vector<u8> buffer;
-    SetBlocking();
     const auto result = ReadSPI(CalAddr::COLOR_DATA, 12, buffer);
-    SetNonBlocking();
 
     color = {};
     if (result == DriverResult::Success) {
@@ -86,10 +75,9 @@ DriverResult GenericProtocol::GetColor(Color& color) {
 }
 
 DriverResult GenericProtocol::GetSerialNumber(SerialNumber& serial_number) {
+    ScopedSetBlocking sb(this);
     std::vector<u8> buffer;
-    SetBlocking();
     const auto result = ReadSPI(CalAddr::SERIAL_NUMBER, 16, buffer);
-    SetNonBlocking();
 
     serial_number = {};
     if (result == DriverResult::Success) {
@@ -115,14 +103,9 @@ DriverResult GenericProtocol::GetVersionNumber(FirmwareVersion& version) {
 }
 
 DriverResult GenericProtocol::SetHomeLight() {
+    ScopedSetBlocking sb(this);
     static constexpr std::array<u8, 3> buffer{0x0f, 0xf0, 0x00};
-    std::vector<u8> output;
-    SetBlocking();
-
-    const auto result = SendSubCommand(SubCommand::SET_HOME_LIGHT, buffer, output);
-
-    SetNonBlocking();
-    return result;
+    return SendSubCommand(SubCommand::SET_HOME_LIGHT, buffer);
 }
 
 DriverResult GenericProtocol::SetLedBusy() {
@@ -130,14 +113,9 @@ DriverResult GenericProtocol::SetLedBusy() {
 }
 
 DriverResult GenericProtocol::SetLedPattern(u8 leds) {
+    ScopedSetBlocking sb(this);
     const std::array<u8, 1> buffer{leds};
-    std::vector<u8> output;
-    SetBlocking();
-
-    const auto result = SendSubCommand(SubCommand::SET_PLAYER_LIGHTS, buffer, output);
-
-    SetNonBlocking();
-    return result;
+    return SendSubCommand(SubCommand::SET_PLAYER_LIGHTS, buffer);
 }
 
 DriverResult GenericProtocol::SetLedBlinkPattern(u8 leds) {
diff --git a/src/input_common/helpers/joycon_protocol/irs.cpp b/src/input_common/helpers/joycon_protocol/irs.cpp
index 9dfa503c23..09e17bc5b6 100644
--- a/src/input_common/helpers/joycon_protocol/irs.cpp
+++ b/src/input_common/helpers/joycon_protocol/irs.cpp
@@ -12,8 +12,8 @@ IrsProtocol::IrsProtocol(std::shared_ptr<JoyconHandle> handle)
 
 DriverResult IrsProtocol::EnableIrs() {
     LOG_INFO(Input, "Enable IRS");
+    ScopedSetBlocking sb(this);
     DriverResult result{DriverResult::Success};
-    SetBlocking();
 
     if (result == DriverResult::Success) {
         result = SetReportMode(ReportMode::NFC_IR_MODE_60HZ);
@@ -49,14 +49,13 @@ DriverResult IrsProtocol::EnableIrs() {
 
     is_enabled = true;
 
-    SetNonBlocking();
     return result;
 }
 
 DriverResult IrsProtocol::DisableIrs() {
     LOG_DEBUG(Input, "Disable IRS");
+    ScopedSetBlocking sb(this);
     DriverResult result{DriverResult::Success};
-    SetBlocking();
 
     if (result == DriverResult::Success) {
         result = EnableMCU(false);
@@ -64,7 +63,6 @@ DriverResult IrsProtocol::DisableIrs() {
 
     is_enabled = false;
 
-    SetNonBlocking();
     return result;
 }
 
@@ -148,7 +146,7 @@ DriverResult IrsProtocol::ConfigureIrs() {
     };
     buf_image.resize((static_cast<u8>(fragments) + 1) * 300);
 
-    std::vector<u8> request_data(sizeof(IrsConfigure));
+    std::array<u8, sizeof(IrsConfigure)> request_data{};
     memcpy(request_data.data(), &irs_configuration, sizeof(IrsConfigure));
     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
     do {
@@ -191,7 +189,7 @@ DriverResult IrsProtocol::WriteRegistersStep1() {
         .crc = {},
     };
 
-    std::vector<u8> request_data(sizeof(IrsWriteRegisters));
+    std::array<u8, sizeof(IrsWriteRegisters)> request_data{};
     memcpy(request_data.data(), &irs_registers, sizeof(IrsWriteRegisters));
     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
 
@@ -208,7 +206,7 @@ DriverResult IrsProtocol::WriteRegistersStep1() {
 
         // First time we need to set the report mode
         if (result == DriverResult::Success && tries == 0) {
-            result = SendMcuCommand(SubCommand::SET_REPORT_MODE, mcu_request);
+            result = SendMCUCommand(SubCommand::SET_REPORT_MODE, mcu_request);
         }
         if (result == DriverResult::Success && tries == 0) {
             GetSubCommandResponse(SubCommand::SET_MCU_CONFIG, output);
@@ -250,7 +248,7 @@ DriverResult IrsProtocol::WriteRegistersStep2() {
         .crc = {},
     };
 
-    std::vector<u8> request_data(sizeof(IrsWriteRegisters));
+    std::array<u8, sizeof(IrsWriteRegisters)> request_data{};
     memcpy(request_data.data(), &irs_registers, sizeof(IrsWriteRegisters));
     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
     do {
@@ -272,7 +270,7 @@ DriverResult IrsProtocol::RequestFrame(u8 frame) {
     mcu_request[3] = frame;
     mcu_request[36] = CalculateMCU_CRC8(mcu_request.data(), 36);
     mcu_request[37] = 0xFF;
-    return SendMcuCommand(SubCommand::SET_REPORT_MODE, mcu_request);
+    return SendMCUCommand(SubCommand::SET_REPORT_MODE, mcu_request);
 }
 
 DriverResult IrsProtocol::ResendFrame(u8 frame) {
@@ -282,7 +280,7 @@ DriverResult IrsProtocol::ResendFrame(u8 frame) {
     mcu_request[3] = 0x0;
     mcu_request[36] = CalculateMCU_CRC8(mcu_request.data(), 36);
     mcu_request[37] = 0xFF;
-    return SendMcuCommand(SubCommand::SET_REPORT_MODE, mcu_request);
+    return SendMCUCommand(SubCommand::SET_REPORT_MODE, mcu_request);
 }
 
 std::vector<u8> IrsProtocol::GetImage() const {
diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h
index 273c8d07d3..e2d47349f0 100644
--- a/src/input_common/helpers/joycon_protocol/joycon_types.h
+++ b/src/input_common/helpers/joycon_protocol/joycon_types.h
@@ -273,6 +273,18 @@ enum class NFCTagType : u8 {
     Ntag215 = 0x01,
 };
 
+enum class NFCPages {
+    Block0 = 0,
+    Block45 = 45,
+    Block135 = 135,
+    Block231 = 231,
+};
+
+enum class NFCStatus : u8 {
+    LastPackage = 0x04,
+    TagLost = 0x07,
+};
+
 enum class IrsMode : u8 {
     None = 0x02,
     Moment = 0x03,
diff --git a/src/input_common/helpers/joycon_protocol/nfc.cpp b/src/input_common/helpers/joycon_protocol/nfc.cpp
index 8755e310b8..5c0f717228 100644
--- a/src/input_common/helpers/joycon_protocol/nfc.cpp
+++ b/src/input_common/helpers/joycon_protocol/nfc.cpp
@@ -12,8 +12,8 @@ NfcProtocol::NfcProtocol(std::shared_ptr<JoyconHandle> handle)
 
 DriverResult NfcProtocol::EnableNfc() {
     LOG_INFO(Input, "Enable NFC");
+    ScopedSetBlocking sb(this);
     DriverResult result{DriverResult::Success};
-    SetBlocking();
 
     if (result == DriverResult::Success) {
         result = SetReportMode(ReportMode::NFC_IR_MODE_60HZ);
@@ -35,14 +35,13 @@ DriverResult NfcProtocol::EnableNfc() {
         result = ConfigureMCU(config);
     }
 
-    SetNonBlocking();
     return result;
 }
 
 DriverResult NfcProtocol::DisableNfc() {
     LOG_DEBUG(Input, "Disable NFC");
+    ScopedSetBlocking sb(this);
     DriverResult result{DriverResult::Success};
-    SetBlocking();
 
     if (result == DriverResult::Success) {
         result = EnableMCU(false);
@@ -50,15 +49,14 @@ DriverResult NfcProtocol::DisableNfc() {
 
     is_enabled = false;
 
-    SetNonBlocking();
     return result;
 }
 
 DriverResult NfcProtocol::StartNFCPollingMode() {
     LOG_DEBUG(Input, "Start NFC pooling Mode");
+    ScopedSetBlocking sb(this);
     DriverResult result{DriverResult::Success};
     TagFoundData tag_data{};
-    SetBlocking();
 
     if (result == DriverResult::Success) {
         result = WaitSetMCUMode(ReportMode::NFC_IR_MODE_60HZ, MCUMode::NFC);
@@ -70,15 +68,14 @@ DriverResult NfcProtocol::StartNFCPollingMode() {
         is_enabled = true;
     }
 
-    SetNonBlocking();
     return result;
 }
 
 DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) {
     LOG_DEBUG(Input, "Start NFC pooling Mode");
+    ScopedSetBlocking sb(this);
     DriverResult result{DriverResult::Success};
     TagFoundData tag_data{};
-    SetBlocking();
 
     if (result == DriverResult::Success) {
         result = StartPolling(tag_data);
@@ -96,20 +93,18 @@ DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) {
         result = GetAmiiboData(data);
     }
 
-    SetNonBlocking();
     return result;
 }
 
 bool NfcProtocol::HasAmiibo() {
+    ScopedSetBlocking sb(this);
     DriverResult result{DriverResult::Success};
     TagFoundData tag_data{};
-    SetBlocking();
 
     if (result == DriverResult::Success) {
         result = StartPolling(tag_data);
     }
 
-    SetNonBlocking();
     return result == DriverResult::Success;
 }
 
@@ -169,55 +164,53 @@ DriverResult NfcProtocol::ReadTag(const TagFoundData& data) {
     LOG_INFO(Input, "Tag detected, type={}, uuid={}", data.type, uuid_string);
 
     tries = 0;
-    std::size_t ntag_pages = 0;
+    NFCPages ntag_pages = NFCPages::Block0;
     // Read Tag data
-loop1:
     while (true) {
         auto result = SendReadAmiiboRequest(output, ntag_pages);
-
-        int attempt = 0;
-        while (1) {
-            if (attempt != 0) {
-                result = GetMCUDataResponse(ReportMode::NFC_IR_MODE_60HZ, output);
-            }
-            if ((output[49] == 0x3a || output[49] == 0x2a) && output[56] == 0x07) {
-                return DriverResult::ErrorReadingData;
-            }
-            if (output[49] == 0x3a && output[51] == 0x07 && output[52] == 0x01) {
-                if (data.type != 2) {
-                    goto loop1;
-                }
-                switch (output[74]) {
-                case 0:
-                    ntag_pages = 135;
-                    break;
-                case 3:
-                    ntag_pages = 45;
-                    break;
-                case 4:
-                    ntag_pages = 231;
-                    break;
-                default:
-                    return DriverResult::ErrorReadingData;
-                }
-                goto loop1;
-            }
-            if (output[49] == 0x2a && output[56] == 0x04) {
-                // finished
-                SendStopPollingRequest(output);
-                return DriverResult::Success;
-            }
-            if (output[49] == 0x2a) {
-                goto loop1;
-            }
-            if (attempt++ > 6) {
-                goto loop1;
-            }
-        }
+        const auto mcu_report = static_cast<MCUReport>(output[49]);
+        const auto nfc_status = static_cast<NFCStatus>(output[56]);
 
         if (result != DriverResult::Success) {
             return result;
         }
+
+        if ((mcu_report == MCUReport::NFCReadData || mcu_report == MCUReport::NFCState) &&
+            nfc_status == NFCStatus::TagLost) {
+            return DriverResult::ErrorReadingData;
+        }
+
+        if (mcu_report == MCUReport::NFCReadData && output[51] == 0x07 && output[52] == 0x01) {
+            if (data.type != 2) {
+                continue;
+            }
+            switch (output[74]) {
+            case 0:
+                ntag_pages = NFCPages::Block135;
+                break;
+            case 3:
+                ntag_pages = NFCPages::Block45;
+                break;
+            case 4:
+                ntag_pages = NFCPages::Block231;
+                break;
+            default:
+                return DriverResult::ErrorReadingData;
+            }
+            continue;
+        }
+
+        if (mcu_report == MCUReport::NFCState && nfc_status == NFCStatus::LastPackage) {
+            // finished
+            SendStopPollingRequest(output);
+            return DriverResult::Success;
+        }
+
+        // Ignore other state reports
+        if (mcu_report == MCUReport::NFCState) {
+            continue;
+        }
+
         if (tries++ > timeout_limit) {
             return DriverResult::Timeout;
         }
@@ -231,47 +224,44 @@ DriverResult NfcProtocol::GetAmiiboData(std::vector<u8>& ntag_data) {
     std::vector<u8> output;
     std::size_t tries = 0;
 
-    std::size_t ntag_pages = 135;
+    NFCPages ntag_pages = NFCPages::Block135;
     std::size_t ntag_buffer_pos = 0;
     // Read Tag data
-loop1:
     while (true) {
         auto result = SendReadAmiiboRequest(output, ntag_pages);
-
-        int attempt = 0;
-        while (1) {
-            if (attempt != 0) {
-                result = GetMCUDataResponse(ReportMode::NFC_IR_MODE_60HZ, output);
-            }
-            if ((output[49] == 0x3a || output[49] == 0x2a) && output[56] == 0x07) {
-                return DriverResult::ErrorReadingData;
-            }
-            if (output[49] == 0x3a && output[51] == 0x07) {
-                std::size_t payload_size = (output[54] << 8 | output[55]) & 0x7FF;
-                if (output[52] == 0x01) {
-                    memcpy(ntag_data.data() + ntag_buffer_pos, output.data() + 116,
-                           payload_size - 60);
-                    ntag_buffer_pos += payload_size - 60;
-                } else {
-                    memcpy(ntag_data.data() + ntag_buffer_pos, output.data() + 56, payload_size);
-                }
-                goto loop1;
-            }
-            if (output[49] == 0x2a && output[56] == 0x04) {
-                LOG_INFO(Input, "Finished reading amiibo");
-                return DriverResult::Success;
-            }
-            if (output[49] == 0x2a) {
-                goto loop1;
-            }
-            if (attempt++ > 4) {
-                goto loop1;
-            }
-        }
+        const auto mcu_report = static_cast<MCUReport>(output[49]);
+        const auto nfc_status = static_cast<NFCStatus>(output[56]);
 
         if (result != DriverResult::Success) {
             return result;
         }
+
+        if ((mcu_report == MCUReport::NFCReadData || mcu_report == MCUReport::NFCState) &&
+            nfc_status == NFCStatus::TagLost) {
+            return DriverResult::ErrorReadingData;
+        }
+
+        if (mcu_report == MCUReport::NFCReadData && output[51] == 0x07) {
+            std::size_t payload_size = (output[54] << 8 | output[55]) & 0x7FF;
+            if (output[52] == 0x01) {
+                memcpy(ntag_data.data() + ntag_buffer_pos, output.data() + 116, payload_size - 60);
+                ntag_buffer_pos += payload_size - 60;
+            } else {
+                memcpy(ntag_data.data() + ntag_buffer_pos, output.data() + 56, payload_size);
+            }
+            continue;
+        }
+
+        if (mcu_report == MCUReport::NFCState && nfc_status == NFCStatus::LastPackage) {
+            LOG_INFO(Input, "Finished reading amiibo");
+            return DriverResult::Success;
+        }
+
+        // Ignore other state reports
+        if (mcu_report == MCUReport::NFCState) {
+            continue;
+        }
+
         if (tries++ > timeout_limit) {
             return DriverResult::Timeout;
         }
@@ -298,7 +288,7 @@ DriverResult NfcProtocol::SendStartPollingRequest(std::vector<u8>& output) {
         .crc = {},
     };
 
-    std::vector<u8> request_data(sizeof(NFCRequestState));
+    std::array<u8, sizeof(NFCRequestState)> request_data{};
     memcpy(request_data.data(), &request, sizeof(NFCRequestState));
     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
@@ -315,7 +305,7 @@ DriverResult NfcProtocol::SendStopPollingRequest(std::vector<u8>& output) {
         .crc = {},
     };
 
-    std::vector<u8> request_data(sizeof(NFCRequestState));
+    std::array<u8, sizeof(NFCRequestState)> request_data{};
     memcpy(request_data.data(), &request, sizeof(NFCRequestState));
     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
@@ -338,7 +328,7 @@ DriverResult NfcProtocol::SendStartWaitingRecieveRequest(std::vector<u8>& output
     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
 }
 
-DriverResult NfcProtocol::SendReadAmiiboRequest(std::vector<u8>& output, std::size_t ntag_pages) {
+DriverResult NfcProtocol::SendReadAmiiboRequest(std::vector<u8>& output, NFCPages ntag_pages) {
     NFCRequestState request{
         .sub_command = MCUSubCommand::ReadDeviceMode,
         .command_argument = NFCReadCommand::Ntag,
@@ -357,20 +347,19 @@ DriverResult NfcProtocol::SendReadAmiiboRequest(std::vector<u8>& output, std::si
         .crc = {},
     };
 
-    std::vector<u8> request_data(sizeof(NFCRequestState));
+    std::array<u8, sizeof(NFCRequestState)> request_data{};
     memcpy(request_data.data(), &request, sizeof(NFCRequestState));
     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
 }
 
-NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(std::size_t pages) const {
-    if (pages == 0) {
+NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(NFCPages pages) const {
+    switch (pages) {
+    case NFCPages::Block0:
         return {
             .block_count = 1,
         };
-    }
-
-    if (pages == 45) {
+    case NFCPages::Block45:
         return {
             .block_count = 1,
             .blocks =
@@ -378,9 +367,7 @@ NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(std::size_t pages) const {
                     NFCReadBlock{0x00, 0x2C},
                 },
         };
-    }
-
-    if (pages == 135) {
+    case NFCPages::Block135:
         return {
             .block_count = 3,
             .blocks =
@@ -390,9 +377,7 @@ NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(std::size_t pages) const {
                     {0x78, 0x86},
                 },
         };
-    }
-
-    if (pages == 231) {
+    case NFCPages::Block231:
         return {
             .block_count = 4,
             .blocks =
@@ -403,9 +388,9 @@ NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(std::size_t pages) const {
                     {0xb4, 0xe6},
                 },
         };
-    }
-
-    return {};
+    default:
+        return {};
+    };
 }
 
 bool NfcProtocol::IsEnabled() const {
diff --git a/src/input_common/helpers/joycon_protocol/nfc.h b/src/input_common/helpers/joycon_protocol/nfc.h
index 5cb0e5a652..e63665aa97 100644
--- a/src/input_common/helpers/joycon_protocol/nfc.h
+++ b/src/input_common/helpers/joycon_protocol/nfc.h
@@ -51,9 +51,9 @@ private:
 
     DriverResult SendStartWaitingRecieveRequest(std::vector<u8>& output);
 
-    DriverResult SendReadAmiiboRequest(std::vector<u8>& output, std::size_t ntag_pages);
+    DriverResult SendReadAmiiboRequest(std::vector<u8>& output, NFCPages ntag_pages);
 
-    NFCReadBlockCommand GetReadBlockCommand(std::size_t pages) const;
+    NFCReadBlockCommand GetReadBlockCommand(NFCPages pages) const;
 
     bool is_enabled{};
 };
diff --git a/src/input_common/helpers/joycon_protocol/poller.cpp b/src/input_common/helpers/joycon_protocol/poller.cpp
index 940b20b7f0..7f8e093faf 100644
--- a/src/input_common/helpers/joycon_protocol/poller.cpp
+++ b/src/input_common/helpers/joycon_protocol/poller.cpp
@@ -224,9 +224,9 @@ void JoyconPoller::UpdatePasiveLeftPadInput(const InputReportPassive& input) {
         Joycon::PasivePadButton::StickL,
     };
 
-    for (std::size_t i = 0; i < left_buttons.size(); ++i) {
-        const bool button_status = (input.button_input & static_cast<u32>(left_buttons[i])) != 0;
-        const int button = static_cast<int>(left_buttons[i]);
+    for (auto left_button : left_buttons) {
+        const bool button_status = (input.button_input & static_cast<u32>(left_button)) != 0;
+        const int button = static_cast<int>(left_button);
         callbacks.on_button_data(button, button_status);
     }
 }
@@ -241,9 +241,9 @@ void JoyconPoller::UpdatePasiveRightPadInput(const InputReportPassive& input) {
         Joycon::PasivePadButton::StickR,
     };
 
-    for (std::size_t i = 0; i < right_buttons.size(); ++i) {
-        const bool button_status = (input.button_input & static_cast<u32>(right_buttons[i])) != 0;
-        const int button = static_cast<int>(right_buttons[i]);
+    for (auto right_button : right_buttons) {
+        const bool button_status = (input.button_input & static_cast<u32>(right_button)) != 0;
+        const int button = static_cast<int>(right_button);
         callbacks.on_button_data(button, button_status);
     }
 }
@@ -259,9 +259,9 @@ void JoyconPoller::UpdatePasiveProPadInput(const InputReportPassive& input) {
         Joycon::PasivePadButton::StickL,  Joycon::PasivePadButton::StickR,
     };
 
-    for (std::size_t i = 0; i < pro_buttons.size(); ++i) {
-        const bool button_status = (input.button_input & static_cast<u32>(pro_buttons[i])) != 0;
-        const int button = static_cast<int>(pro_buttons[i]);
+    for (auto pro_button : pro_buttons) {
+        const bool button_status = (input.button_input & static_cast<u32>(pro_button)) != 0;
+        const int button = static_cast<int>(pro_button);
         callbacks.on_button_data(button, button_status);
     }
 }
diff --git a/src/input_common/helpers/joycon_protocol/ringcon.cpp b/src/input_common/helpers/joycon_protocol/ringcon.cpp
index 8adad57dd6..12f81309e1 100644
--- a/src/input_common/helpers/joycon_protocol/ringcon.cpp
+++ b/src/input_common/helpers/joycon_protocol/ringcon.cpp
@@ -11,8 +11,8 @@ RingConProtocol::RingConProtocol(std::shared_ptr<JoyconHandle> handle)
 
 DriverResult RingConProtocol::EnableRingCon() {
     LOG_DEBUG(Input, "Enable Ringcon");
+    ScopedSetBlocking sb(this);
     DriverResult result{DriverResult::Success};
-    SetBlocking();
 
     if (result == DriverResult::Success) {
         result = SetReportMode(ReportMode::STANDARD_FULL_60HZ);
@@ -30,14 +30,13 @@ DriverResult RingConProtocol::EnableRingCon() {
         result = ConfigureMCU(config);
     }
 
-    SetNonBlocking();
     return result;
 }
 
 DriverResult RingConProtocol::DisableRingCon() {
     LOG_DEBUG(Input, "Disable RingCon");
+    ScopedSetBlocking sb(this);
     DriverResult result{DriverResult::Success};
-    SetBlocking();
 
     if (result == DriverResult::Success) {
         result = EnableMCU(false);
@@ -45,15 +44,14 @@ DriverResult RingConProtocol::DisableRingCon() {
 
     is_enabled = false;
 
-    SetNonBlocking();
     return result;
 }
 
 DriverResult RingConProtocol::StartRingconPolling() {
     LOG_DEBUG(Input, "Enable Ringcon");
-    bool is_connected = false;
+    ScopedSetBlocking sb(this);
     DriverResult result{DriverResult::Success};
-    SetBlocking();
+    bool is_connected = false;
 
     if (result == DriverResult::Success) {
         result = IsRingConnected(is_connected);
@@ -66,13 +64,13 @@ DriverResult RingConProtocol::StartRingconPolling() {
         is_enabled = true;
     }
 
-    SetNonBlocking();
     return result;
 }
 
 DriverResult RingConProtocol::IsRingConnected(bool& is_connected) {
     LOG_DEBUG(Input, "IsRingConnected");
     constexpr std::size_t max_tries = 28;
+    constexpr u8 ring_controller_id = 0x20;
     std::vector<u8> output;
     std::size_t tries = 0;
     is_connected = false;
@@ -88,7 +86,7 @@ DriverResult RingConProtocol::IsRingConnected(bool& is_connected) {
         if (tries++ >= max_tries) {
             return DriverResult::NoDeviceDetected;
         }
-    } while (output[14] != 0x59 || output[16] != 0x20);
+    } while (output[16] != ring_controller_id);
 
     is_connected = true;
     return DriverResult::Success;
@@ -96,30 +94,20 @@ DriverResult RingConProtocol::IsRingConnected(bool& is_connected) {
 
 DriverResult RingConProtocol::ConfigureRing() {
     LOG_DEBUG(Input, "ConfigureRing");
-    constexpr std::size_t max_tries = 28;
-    DriverResult result{DriverResult::Success};
-    std::vector<u8> output;
-    std::size_t tries = 0;
 
     static constexpr std::array<u8, 37> ring_config{
         0x06, 0x03, 0x25, 0x06, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x16, 0xED, 0x34, 0x36,
         0x00, 0x00, 0x00, 0x0A, 0x64, 0x0B, 0xE6, 0xA9, 0x22, 0x00, 0x00, 0x04, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xA8, 0xE1, 0x34, 0x36};
-    do {
-        result = SendSubCommand(SubCommand::UNKNOWN_RINGCON3, ring_config, output);
 
-        if (result != DriverResult::Success) {
-            return result;
-        }
-        if (tries++ >= max_tries) {
-            return DriverResult::NoDeviceDetected;
-        }
-    } while (output[14] != 0x5C);
+    const DriverResult result = SendSubCommand(SubCommand::UNKNOWN_RINGCON3, ring_config);
+
+    if (result != DriverResult::Success) {
+        return result;
+    }
 
     static constexpr std::array<u8, 4> ringcon_data{0x04, 0x01, 0x01, 0x02};
-    result = SendSubCommand(SubCommand::UNKNOWN_RINGCON2, ringcon_data, output);
-
-    return result;
+    return SendSubCommand(SubCommand::UNKNOWN_RINGCON2, ringcon_data);
 }
 
 bool RingConProtocol::IsEnabled() const {
diff --git a/src/input_common/helpers/joycon_protocol/rumble.cpp b/src/input_common/helpers/joycon_protocol/rumble.cpp
index fad67a94ba..63b60c9468 100644
--- a/src/input_common/helpers/joycon_protocol/rumble.cpp
+++ b/src/input_common/helpers/joycon_protocol/rumble.cpp
@@ -14,12 +14,9 @@ RumbleProtocol::RumbleProtocol(std::shared_ptr<JoyconHandle> handle)
 
 DriverResult RumbleProtocol::EnableRumble(bool is_enabled) {
     LOG_DEBUG(Input, "Enable Rumble");
+    ScopedSetBlocking sb(this);
     const std::array<u8, 1> buffer{static_cast<u8>(is_enabled ? 1 : 0)};
-    std::vector<u8> output;
-    SetBlocking();
-    const auto result = SendSubCommand(SubCommand::ENABLE_VIBRATION, buffer, output);
-    SetNonBlocking();
-    return result;
+    return SendSubCommand(SubCommand::ENABLE_VIBRATION, buffer);
 }
 
 DriverResult RumbleProtocol::SendVibration(const VibrationValue& vibration) {
@@ -66,9 +63,9 @@ u8 RumbleProtocol::EncodeLowFrequency(f32 frequency) const {
 }
 
 u8 RumbleProtocol::EncodeHighAmplitude(f32 amplitude) const {
-    /* More information about these values can be found here:
-     * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md
-     */
+    // More information about these values can be found here:
+    // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md
+
     static constexpr std::array<std::pair<f32, int>, 101> high_fequency_amplitude{
         std::pair<f32, int>{0.0f, 0x0},
         {0.01f, 0x2},
@@ -183,9 +180,9 @@ u8 RumbleProtocol::EncodeHighAmplitude(f32 amplitude) const {
 }
 
 u16 RumbleProtocol::EncodeLowAmplitude(f32 amplitude) const {
-    /* More information about these values can be found here:
-     * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md
-     */
+    // More information about these values can be found here:
+    // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md
+
     static constexpr std::array<std::pair<f32, int>, 101> high_fequency_amplitude{
         std::pair<f32, int>{0.0f, 0x0040},
         {0.01f, 0x8040},