From 83f406b5cb0bf1c5a1b6eff4982c94d0e105d443 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Sat, 14 Mar 2020 12:05:01 -0400 Subject: [PATCH 1/6] Added hidbus. --- nx/include/switch.h | 1 + nx/include/switch/services/hidbus.h | 219 +++++++++++ nx/source/services/hidbus.c | 571 ++++++++++++++++++++++++++++ 3 files changed, 791 insertions(+) create mode 100644 nx/include/switch/services/hidbus.h create mode 100644 nx/source/services/hidbus.c diff --git a/nx/include/switch.h b/nx/include/switch.h index 5b06c4fd..d1089ab2 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -75,6 +75,7 @@ extern "C" { #include "switch/services/usbds.h" #include "switch/services/usbhs.h" #include "switch/services/hid.h" +#include "switch/services/hidbus.h" #include "switch/services/hiddbg.h" #include "switch/services/hidsys.h" #include "switch/services/irs.h" diff --git a/nx/include/switch/services/hidbus.h b/nx/include/switch/services/hidbus.h new file mode 100644 index 00000000..892ed0eb --- /dev/null +++ b/nx/include/switch/services/hidbus.h @@ -0,0 +1,219 @@ +/** + * @file hidbus.h + * @brief hidbus service IPC wrapper, for using external devices attached to HID controllers. See also: https://switchbrew.org/wiki/HID_services#hidbus + * @note Only available on [5.0.0+]. + * @author yellows8 + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/hid.h" +#include "../sf/service.h" + +/// BusType +typedef enum { + HidbusBusType_Unknown0 = 0, ///< Unknown. + HidbusBusType_Unknown1 = 1, ///< Unknown. + HidbusBusType_Unknown2 = 2, ///< [6.0.0+] Unknown. +} HidbusBusType; + +/// JoyPollingMode +typedef enum { + HidbusJoyPollingMode_JoyDisableSixAxisPollingData = 0, ///< JoyDisableSixAxisPollingData + HidbusJoyPollingMode_JoyEnableSixAxisPollingData = 1, ///< JoyEnableSixAxisPollingData + HidbusJoyPollingMode_JoyButtonOnlyPollingData = 2, ///< [6.0.0+] JoyButtonOnlyPollingData +} HidbusJoyPollingMode; + +/// BusHandle +typedef struct { + u32 abstracted_pad_id; ///< AbstractedPadId + u8 internal_index; ///< InternalIndex + u8 player_number; ///< PlayerNumber + u8 bus_type_id; ///< BusTypeId + u8 is_valid; ///< IsValid +} HidbusBusHandle; + +/// JoyPollingReceivedData +typedef struct { + u8 data[0x30]; ///< Data. + u64 size; ///< Size of data. + u64 timestamp; ///< Timestamp. +} HidbusJoyPollingReceivedData; + +/// HidbusDataAccessorHeader +typedef struct { + Result res; ///< Result. + u32 pad; ///< Padding. + u8 unused[0x18]; ///< Initialized sysmodule-side, not used by sdknso. + u64 latest_entry; ///< Latest entry. + u64 total_entries; ///< Total entries. +} HidbusDataAccessorHeader; + +/// HidbusJoyDisableSixAxisPollingDataAccessorEntryData +typedef struct { + u8 data[0x26]; ///< Data. + u8 size; ///< Size of data. + u8 pad; ///< Padding. + u64 timestamp; ///< Timestamp. +} HidbusJoyDisableSixAxisPollingDataAccessorEntryData; + +/// HidbusJoyDisableSixAxisPollingDataAccessorEntry +typedef struct { + u64 timestamp; ///< Timestamp. + HidbusJoyDisableSixAxisPollingDataAccessorEntryData data; ///< \ref HidbusJoyDisableSixAxisPollingDataAccessorEntryData +} HidbusJoyDisableSixAxisPollingDataAccessorEntry; + +/// HidbusJoyEnableSixAxisPollingDataAccessorEntryData +typedef struct { + u8 data[0x8]; ///< Data. + u8 size; ///< Size of data. + u8 pad[7]; ///< Padding. + u64 timestamp; ///< Timestamp. +} HidbusJoyEnableSixAxisPollingDataAccessorEntryData; + +/// HidbusJoyEnableSixAxisPollingDataAccessorEntry +typedef struct { + u64 timestamp; ///< Timestamp. + HidbusJoyEnableSixAxisPollingDataAccessorEntryData data; ///< \ref HidbusJoyEnableSixAxisPollingDataAccessorEntryData +} HidbusJoyEnableSixAxisPollingDataAccessorEntry; + +/// HidbusJoyButtonOnlyPollingDataAccessorEntryData +typedef struct { + u8 data[0x2c]; ///< Data. + u8 size; ///< Size of data. + u8 pad[3]; ///< Padding. + u64 timestamp; ///< Timestamp. +} HidbusJoyButtonOnlyPollingDataAccessorEntryData; + +/// HidbusJoyButtonOnlyPollingDataAccessorEntry +typedef struct { + u64 timestamp; ///< Timestamp. + HidbusJoyButtonOnlyPollingDataAccessorEntryData data; ///< \ref HidbusJoyEnableSixAxisPollingDataAccessorEntryData +} HidbusJoyButtonOnlyPollingDataAccessorEntry; + +/// HidbusJoyDisableSixAxisPollingDataAccessor +typedef struct { + HidbusDataAccessorHeader hdr; ///< \ref HidbusDataAccessorHeader + HidbusJoyDisableSixAxisPollingDataAccessorEntry entries[0xb]; ///< \ref HidbusJoyDisableSixAxisPollingDataAccessorEntry +} HidbusJoyDisableSixAxisPollingDataAccessor; + +/// HidbusJoyEnableSixAxisPollingDataAccessor +typedef struct { + HidbusDataAccessorHeader hdr; ///< \ref HidbusDataAccessorHeader + HidbusJoyEnableSixAxisPollingDataAccessorEntry entries[0xb]; ///< \ref HidbusJoyEnableSixAxisPollingDataAccessorEntry +} HidbusJoyEnableSixAxisPollingDataAccessor; + +/// HidbusJoyButtonOnlyPollingDataAccessor +typedef struct { + HidbusDataAccessorHeader hdr; ///< \ref HidbusDataAccessorHeader + HidbusJoyButtonOnlyPollingDataAccessorEntry entries[0xb]; ///< \ref HidbusJoyButtonOnlyPollingDataAccessorEntry +} HidbusJoyButtonOnlyPollingDataAccessor; + +/// Common data for HidbusStatusManagerEntry*. +typedef struct { + u8 flag_x0; ///< Flag. + u8 pad[3]; ///< Padding. + Result res; ///< Result. + u8 device_enabled; ///< Flag indicating whether a device is enabled (\ref hidbusEnableExternalDevice). + u8 is_valid; ///< Flag indicating whether this entry is valid. + u8 polling_enabled; ///< Flag indicating whether polling is enabled (\ref hidbusEnableJoyPollingReceiveMode). + u8 unk_xb; ///< Unknown / padding? + u32 polling_mode; ///< \ref HidbusJoyPollingMode +} HidbusStatusManagerEntryCommon; + +/// HidbusStatusManagerEntry on 5.x. +typedef struct { + HidbusStatusManagerEntryCommon common; ///< \ref HidbusStatusManagerEntryCommon + u8 unk_x10[0xf0]; ///< Ignored by official sw. +} HidbusStatusManagerEntryV5; + +/// HidbusStatusManagerEntry +typedef struct { + HidbusStatusManagerEntryCommon common; ///< \ref HidbusStatusManagerEntryCommon + u8 unk_x10[0x70]; ///< Ignored by official sw. +} HidbusStatusManagerEntry; + +/// StatusManager on 5.x. +typedef struct { + HidbusStatusManagerEntryV5 entries[0x10]; ///< \ref HidbusStatusManagerEntryV5 +} HidbusStatusManagerV5; + +/// StatusManager +typedef struct { + HidbusStatusManagerEntry entries[0x13]; ///< \ref HidbusStatusManagerEntry + u8 unused[0x680]; ///< Unused. +} HidbusStatusManager; + +/// Gets the Service object for the actual hidbus service session. This object must be closed by the user once finished using cmds with this. +Result hidbusGetServiceSession(Service* srv_out); + +/// Gets the SharedMemory addr (\ref HidbusStatusManagerV5 on 5.x, otherwise \ref HidbusStatusManager). Only valid when at least one BusHandle is currently initialized (\ref hidbusInitialize). +void* hidbusGetSharedmemAddr(void); + +/** + * @brief GetBusHandle + * @param[out] handle \ref HidbusBusHandle + * @param[out] flag Output flag indicating whether the handle is valid. + * @param[in] id \ref HidControllerID + * @param[in] bus_type \ref HidbusBusType + */ +Result hidbusGetBusHandle(HidbusBusHandle *handle, bool *flag, HidControllerID id, HidbusBusType bus_type); + +/** + * @brief Initialize + * @param[in] handle \ref HidbusBusHandle + */ +Result hidbusInitialize(HidbusBusHandle handle); + +/** + * @brief Finalize + * @param[in] handle \ref HidbusBusHandle + */ +Result hidbusFinalize(HidbusBusHandle handle); + +/** + * @brief EnableExternalDevice + * @note This uses \ref hidLaShowControllerFirmwareUpdate if needed. + * @param[in] handle \ref HidbusBusHandle + * @param[in] flag Whether to enable the device (true = enable, false = disable). When false, this will internally use \ref hidbusDisableJoyPollingReceiveMode if needed. + * @param[in] device_id ExternalDeviceId which must match the connected device. Only used when flag is set. + */ +Result hidbusEnableExternalDevice(HidbusBusHandle handle, bool flag, u32 device_id); + +/** + * @brief SendAndReceive + * @param[in] handle \ref HidbusBusHandle + * @param[in] inbuf Input buffer, containing the command data. + * @param[in] inbuf_size Input buffer size, must be <0x26. + * @param[out] outbuf Output buffer, containing the command reply data. + * @param[in] outbuf_size Output buffer max size. + * @param[out] out_size Actual output size. + */ +Result hidbusSendAndReceive(HidbusBusHandle handle, const void* inbuf, size_t inbuf_size, void* outbuf, size_t outbuf_size, u64 *out_size); + +/** + * @brief EnableJoyPollingReceiveMode + * @param[in] handle \ref HidbusBusHandle + * @param[in] inbuf Input buffer, containing the command data. + * @param[in] inbuf_size Input buffer size, must be <0x26. + * @param[out] workbuf TransferMemory buffer, must be 0x1000-byte aligned. This buffer must not be written to until after \ref hidbusDisableJoyPollingReceiveMode is used. + * @param[in] workbuf_size TransferMemory buffer size, must be 0x1000-byte aligned. + * @param[in] polling_mode \ref HidbusJoyPollingMode + */ +Result hidbusEnableJoyPollingReceiveMode(HidbusBusHandle handle, const void* inbuf, size_t inbuf_size, void* workbuf, size_t workbuf_size, HidbusJoyPollingMode polling_mode); + +/** + * @brief DisableJoyPollingReceiveMode + * @note This can also be used via \ref hidbusEnableExternalDevice with flag=false. + * @param[in] handle \ref HidbusBusHandle + */ +Result hidbusDisableJoyPollingReceiveMode(HidbusBusHandle handle); + +/** + * @brief GetJoyPollingReceivedData + * @param[in] handle \ref HidbusBusHandle + * @param[out] recv_data Output array of \ref HidbusJoyPollingReceivedData. + * @param[in] count Total entries for the recv_data array. The maximum is 0xa. Official apps use range 0x1-0x9. + */ +Result hidbusGetJoyPollingReceivedData(HidbusBusHandle handle, HidbusJoyPollingReceivedData *recv_data, s32 count); + diff --git a/nx/source/services/hidbus.c b/nx/source/services/hidbus.c new file mode 100644 index 00000000..1f5614c0 --- /dev/null +++ b/nx/source/services/hidbus.c @@ -0,0 +1,571 @@ +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include +#include +#include "service_guard.h" +#include "runtime/hosversion.h" +#include "kernel/shmem.h" +#include "services/hidbus.h" +#include "services/applet.h" +#include "applets/hid_la.h" + +typedef struct { + Mutex mutex; + Event event; + HidbusBusHandle handle; + void* workbuf; +} HidBusDeviceEntry; + +static HidBusDeviceEntry g_hidbusDevices[0x13]; + +static Mutex g_hidbusSharedmemMutex, g_hidbusUpdateMutex; +static bool g_hidbusUpdateFlag; +static u32 g_hidbusSharedmemRefCount; +static SharedMemory g_hidbusSharedmem; + +Result hidbusGetServiceSession(Service* srv_out) { + if (hosversionBefore(5,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return smGetService(srv_out, "hidbus"); +} + +static Result _hidBusVerifyBusHandle(HidbusBusHandle handle) { + u8 max_count = hosversionBefore(6,0,0) ? 0x10 : 0x13; // sdknso uses value 0x11 on 5.x, but that's off-by-one with sharedmem because 0x10*sizeof(HidbusStatusManagerEntryV5) == sizeof(sharedmem). Hence, we check for 0x10 instead. + + return handle.internal_index < max_count ? 0 : MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); +} + +static Result _hidbusCmdGetHandle(Service* srv, Handle* handle_out, u32 cmd_id) { + return serviceDispatch(srv, cmd_id, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = handle_out, + ); +} + +static Result _hidbusGetBusHandle(Service* srv, u32 id, u64 bus_type, bool *flag, HidbusBusHandle *handle) { + const struct { + u32 id; + u32 pad; + u64 bus_type; + u64 appletResourceUserId; + } in = { id, 0, bus_type, appletGetAppletResourceUserId() }; + + struct { + u8 flag; + u8 pad[7]; + HidbusBusHandle handle; + } out; + + Result rc = serviceDispatchInOut(srv, 1, in, out); + if (R_SUCCEEDED(rc)) { + if (flag) *flag = out.flag & 1; + if (handle) *handle = out.handle; + } + return rc; +} + +static Result _hidbusInBusHandleResIdNoOut(Service* srv, HidbusBusHandle handle, u32 cmd_id) { + const struct { + HidbusBusHandle handle; + u64 appletResourceUserId; + } in = { handle, appletGetAppletResourceUserId() }; + + return serviceDispatchIn(srv, cmd_id, in); +} + +static Result _hidbusEnableExternalDevice(Service* srv, HidbusBusHandle handle, bool flag, u64 inval) { + const struct { + u8 flag; + u8 pad[7]; + HidbusBusHandle handle; + u64 inval; + u64 appletResourceUserId; + } in = { flag!=0, {0}, handle, inval, appletGetAppletResourceUserId() }; + + return serviceDispatchIn(srv, 5, in); +} + +static Result _hidbusGetExternalDeviceId(Service* srv, HidbusBusHandle handle, u32 *out) { + return serviceDispatchInOut(srv, 6, handle, *out); +} + +static Result _hidbusSendCommandAsync(Service* srv, HidbusBusHandle handle, const void* buffer, size_t size) { + return serviceDispatchIn(srv, 7, handle, + .buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_In }, + .buffers = { { buffer, size } }, + ); +} + +static Result _hidbusGetSendCommandAsynceResult(Service* srv, HidbusBusHandle handle, void* buffer, size_t size, u32 *out_size) { + return serviceDispatchInOut(srv, 8, handle, *out_size, + .buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out }, + .buffers = { { buffer, size } }, + ); +} + +static Result _hidbusSetEventForSendCommandAsycResult(Service* srv, HidbusBusHandle handle, Event* out_event) { + Handle event = INVALID_HANDLE; + Result rc = serviceDispatchIn(srv, 9, handle, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = &event, + ); + + if (R_SUCCEEDED(rc)) + eventLoadRemote(out_event, event, false); + + return rc; +} + +static Result _hidbusEnableJoyPollingReceiveMode(Service* srv, HidbusBusHandle handle, u32 polling_mode, const void* inbuf, size_t inbuf_size, TransferMemory *tmem) { // [8.0.0+] + const struct { + u32 size; + u32 polling_mode; + HidbusBusHandle handle; + } in = { tmem->size, polling_mode, handle }; + + Result rc = serviceDispatchIn(srv, 11, in, + .buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_In }, + .buffers = { { inbuf, inbuf_size } }, + .in_num_handles = 1, + .in_handles = { tmem->handle }, + ); + + return rc; +} + +static Result _hidbusDisableJoyPollingReceiveMode(Service* srv, HidbusBusHandle handle) { + return serviceDispatchIn(srv, 12, handle); +} + +static Result _hidbusSetStatusManagerType(Service* srv, u32 inval) { // [6.0.0+] + return serviceDispatchIn(srv, 14, inval); +} + +// Official sw just checks whether a global flag is set, and runs initialization if not set. The code for cleanup is not used. Since we want to actually handle cleanup, use refcounting for sharedmem. +static Result _hidbusSharedmemInitialize(Service* srv) { + Result rc=0; + Handle sharedmem_handle; + mutexLock(&g_hidbusSharedmemMutex); + if ((g_hidbusSharedmemRefCount++) == 0) { + rc = _hidbusCmdGetHandle(srv, &sharedmem_handle, 10); // GetSharedMemoryHandle + if (R_SUCCEEDED(rc)) { + shmemLoadRemote(&g_hidbusSharedmem, sharedmem_handle, 0x1000, Perm_R); + rc = shmemMap(&g_hidbusSharedmem); + if (R_FAILED(rc)) shmemClose(&g_hidbusSharedmem); + } + if (R_FAILED(rc)) g_hidbusSharedmemRefCount--; + _hidbusSetStatusManagerType(srv, 0x2); // Official sw ignores errors from this. + } + mutexUnlock(&g_hidbusSharedmemMutex); + + return rc; +} + +static void _hidbusSharedmemExit(void) { + mutexLock(&g_hidbusSharedmemMutex); + if (g_hidbusSharedmemRefCount && (--g_hidbusSharedmemRefCount) == 0) { + shmemClose(&g_hidbusSharedmem); + } + mutexUnlock(&g_hidbusSharedmemMutex); +} + +void* hidbusGetSharedmemAddr(void) { + return shmemGetAddr(&g_hidbusSharedmem); +} + +static HidbusStatusManagerEntryCommon* _hidbusGetStatusManagerEntryCommon(u8 internal_index) { + if (hosversionBefore(6,0,0)) + return &((HidbusStatusManagerV5*)hidbusGetSharedmemAddr())->entries[internal_index].common; + else + return &((HidbusStatusManager*)hidbusGetSharedmemAddr())->entries[internal_index].common; +} + +static bool _hidbusGetStatusManagerEntryFlag_x0(u8 internal_index) { + return atomic_load_explicit(&_hidbusGetStatusManagerEntryCommon(internal_index)->flag_x0, memory_order_acquire) & 1; +} + +static Result _hidbusGetStatusManagerEntryRes(u8 internal_index) { + return _hidbusGetStatusManagerEntryCommon(internal_index)->res; +} + +static bool _hidbusGetStatusManagerEntryDeviceEnabled(u8 internal_index) { + return atomic_load_explicit(&_hidbusGetStatusManagerEntryCommon(internal_index)->device_enabled, memory_order_acquire) & 1; +} + +static bool _hidbusGetStatusManagerEntryIsValid(u8 internal_index) { + return atomic_load_explicit(&_hidbusGetStatusManagerEntryCommon(internal_index)->is_valid, memory_order_acquire) & 1; +} + +static bool _hidbusGetStatusManagerEntryPollingEnabled(u8 internal_index) { + return atomic_load_explicit(&_hidbusGetStatusManagerEntryCommon(internal_index)->polling_enabled, memory_order_acquire) & 1; +} + +static HidbusJoyPollingMode _hidbusGetStatusManagerEntryPollingMode(u8 internal_index) { + return atomic_load_explicit(&_hidbusGetStatusManagerEntryCommon(internal_index)->polling_mode, memory_order_acquire); +} + +Result hidbusGetBusHandle(HidbusBusHandle *handle, bool *flag, HidControllerID id, HidbusBusType bus_type) { + Service srv={0}; + Result rc = hidbusGetServiceSession(&srv); + *flag = 0; + if (R_FAILED(rc)) return rc; + + HidbusBusHandle tmphandle={0}; + bool tmpflag=0; + rc = _hidbusGetBusHandle(&srv, hidControllerIDToOfficial(id), bus_type, &tmpflag, &tmphandle); + if (R_SUCCEEDED(rc)) { + if (!tmpflag) *flag = tmpflag; + else { + rc = _hidBusVerifyBusHandle(tmphandle); + if (R_SUCCEEDED(rc)) { + *flag = tmpflag; + *handle = tmphandle; + + g_hidbusDevices[tmphandle.internal_index].handle = tmphandle; + } + } + } + + serviceClose(&srv); + return rc; +} + +Result hidbusInitialize(HidbusBusHandle handle) { + Service srv={0}; + bool setup_event=1; + bool sharedmem_init=0; + Result rc = _hidBusVerifyBusHandle(handle); + if (R_FAILED(rc)) return rc; + HidBusDeviceEntry *entry = &g_hidbusDevices[handle.internal_index]; + mutexLock(&entry->mutex); + if (memcmp(&entry->handle, &handle, sizeof(handle))!=0) rc = MAKERESULT(218, 4); + + if (R_SUCCEEDED(rc)) rc = hidbusGetServiceSession(&srv); + + if (R_SUCCEEDED(rc)) { + rc = _hidbusSharedmemInitialize(&srv); + if (R_SUCCEEDED(rc)) sharedmem_init = 1; + } + + if (R_SUCCEEDED(rc)) { + rc = _hidbusInBusHandleResIdNoOut(&srv, handle, 3); // Initialize + if (R_VALUE(rc) == MAKERESULT(218, 10)) { + rc = 0; + setup_event = 0; + } + } + + if (R_SUCCEEDED(rc) && setup_event) { + eventClose(&entry->event); + rc = _hidbusSetEventForSendCommandAsycResult(&srv, handle, &entry->event); + } + + if ((R_FAILED(rc) || !setup_event) && sharedmem_init) _hidbusSharedmemExit(); + + mutexUnlock(&entry->mutex); + serviceClose(&srv); + return rc; +} + +Result hidbusFinalize(HidbusBusHandle handle) { + Service srv={0}; + Result rc = _hidBusVerifyBusHandle(handle); + if (R_FAILED(rc)) return rc; + HidBusDeviceEntry *entry = &g_hidbusDevices[handle.internal_index]; + mutexLock(&entry->mutex); + + if (memcmp(&entry->handle, &handle, sizeof(handle))==0) { + rc = hidbusGetServiceSession(&srv); + + if (R_SUCCEEDED(rc)) rc = _hidbusInBusHandleResIdNoOut(&srv, handle, 4); // Finalize + eventClose(&entry->event); + + _hidbusSharedmemExit(); + } + + mutexUnlock(&entry->mutex); + serviceClose(&srv); + return rc; +} + +Result hidbusEnableExternalDevice(HidbusBusHandle handle, bool flag, u32 device_id) { + Service srv={0}; + Result rc = _hidBusVerifyBusHandle(handle); + if (R_FAILED(rc)) return rc; + u64 inval = hosversionBefore(7,0,0) ? 0x38900050018 : 0x3A600050018; + u32 index = handle.internal_index; + HidBusDeviceEntry *entry = &g_hidbusDevices[index]; + mutexLock(&entry->mutex); + if (memcmp(&entry->handle, &handle, sizeof(handle))!=0) rc = MAKERESULT(218, 4); + + if (R_SUCCEEDED(rc) && !_hidbusGetStatusManagerEntryIsValid(index)) rc = MAKERESULT(218, 2); + if (R_SUCCEEDED(rc)) rc = _hidbusGetStatusManagerEntryRes(index); + if (R_SUCCEEDED(rc)) { + if (!_hidbusGetStatusManagerEntryFlag_x0(index) && !flag) rc = MAKERESULT(218, 5); + } + + if (R_SUCCEEDED(rc)) rc = hidbusGetServiceSession(&srv); + + if (R_SUCCEEDED(rc)) { + rc = _hidbusEnableExternalDevice(&srv, handle, flag, inval); + if (R_FAILED(rc)) { + // sdknso asserts when rc is MAKERESULT(218, 12), we won't do an equivalent. + if (R_VALUE(rc) == MAKERESULT(202, 547) || R_VALUE(rc) == MAKERESULT(108, 426)) { + mutexLock(&g_hidbusUpdateMutex); + bool updateflag = g_hidbusUpdateFlag; + if (!updateflag) g_hidbusUpdateFlag = true; + mutexUnlock(&g_hidbusUpdateMutex); + if (updateflag) rc = MAKERESULT(218, 2); + else { + HidLaControllerFirmwareUpdateArg arg; + hidLaCreateControllerFirmwareUpdateArg(&arg); + arg.enable_force_update = 1; + rc = hidLaShowControllerFirmwareUpdate(&arg); + + if (R_FAILED(rc)) rc = R_VALUE(rc) == MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit) ? MAKERESULT(218, 3) : rc; + else rc = _hidbusEnableExternalDevice(&srv, handle, flag, inval); + + mutexLock(&g_hidbusUpdateMutex); + g_hidbusUpdateFlag = false; + mutexUnlock(&g_hidbusUpdateMutex); + } + } + } + if (R_SUCCEEDED(rc) && flag) { + u32 tmpout=0; + rc = _hidbusGetExternalDeviceId(&srv, handle, &tmpout); + if (R_SUCCEEDED(rc) && tmpout!=device_id) { + rc = hidbusEnableExternalDevice(handle, false, device_id); + rc = R_SUCCEEDED(rc) ? MAKERESULT(218, 9) : rc; + } + } + } + + mutexUnlock(&entry->mutex); + serviceClose(&srv); + return rc; +} + +Result hidbusSendAndReceive(HidbusBusHandle handle, const void* inbuf, size_t inbuf_size, void* outbuf, size_t outbuf_size, u64 *out_size) { + Service srv={0}; + Result rc = _hidBusVerifyBusHandle(handle); + if (R_FAILED(rc)) return rc; + if (inbuf_size >= 0x26) return MAKERESULT(Module_Libnx, LibnxError_BadInput); + u32 index = handle.internal_index; + HidBusDeviceEntry *entry = &g_hidbusDevices[index]; + mutexLock(&entry->mutex); + if (memcmp(&entry->handle, &handle, sizeof(handle))!=0) rc = MAKERESULT(218, 4); + + if (R_SUCCEEDED(rc) && !_hidbusGetStatusManagerEntryDeviceEnabled(index)) rc = MAKERESULT(218, 8); + + if (R_SUCCEEDED(rc)) rc = hidbusGetServiceSession(&srv); + + if (R_SUCCEEDED(rc)) { + eventClear(&entry->event); // This was added with sdknso 6.x+, but we'll do it on 5.x regardless. + rc = _hidbusSendCommandAsync(&srv, handle, inbuf, inbuf_size); + } + if (R_SUCCEEDED(rc)) { + eventWait(&entry->event, U64_MAX); + eventClear(&entry->event); + u32 tmpout=0; + rc = _hidbusGetSendCommandAsynceResult(&srv, handle, outbuf, outbuf_size, &tmpout); + if (R_SUCCEEDED(rc) && out_size) *out_size = tmpout; + } + + mutexUnlock(&entry->mutex); + serviceClose(&srv); + return rc; +} + +Result hidbusEnableJoyPollingReceiveMode(HidbusBusHandle handle, const void* inbuf, size_t inbuf_size, void* workbuf, size_t workbuf_size, HidbusJoyPollingMode polling_mode) { + Service srv={0}; + Result rc = _hidBusVerifyBusHandle(handle); + if (R_FAILED(rc)) return rc; + if (inbuf_size >= 0x26) return MAKERESULT(Module_Libnx, LibnxError_BadInput); + u32 index = handle.internal_index; + HidBusDeviceEntry *entry = &g_hidbusDevices[index]; + mutexLock(&entry->mutex); + if (memcmp(&entry->handle, &handle, sizeof(handle))!=0) rc = MAKERESULT(218, 4); + + if (R_SUCCEEDED(rc) && !_hidbusGetStatusManagerEntryDeviceEnabled(index)) rc = MAKERESULT(218, 8); + + if (R_SUCCEEDED(rc) && !_hidbusGetStatusManagerEntryPollingEnabled(index)) { + rc = hidbusGetServiceSession(&srv); + + if (R_SUCCEEDED(rc)) { + TransferMemory tmem={0}; + rc = tmemCreateFromMemory(&tmem, workbuf, workbuf_size, Perm_R); + if (R_SUCCEEDED(rc)) rc = _hidbusEnableJoyPollingReceiveMode(&srv, handle, polling_mode, inbuf, inbuf_size, &tmem); + if (R_SUCCEEDED(rc)) entry->workbuf = workbuf; // sdknso does this before using the cmd. + tmemClose(&tmem); + } + } + + mutexUnlock(&entry->mutex); + serviceClose(&srv); + return rc; +} + +Result hidbusDisableJoyPollingReceiveMode(HidbusBusHandle handle) { + Service srv={0}; + Result rc = _hidBusVerifyBusHandle(handle); + if (R_FAILED(rc)) return rc; + u32 index = handle.internal_index; + HidBusDeviceEntry *entry = &g_hidbusDevices[index]; + mutexLock(&entry->mutex); + if (memcmp(&entry->handle, &handle, sizeof(handle))!=0) rc = MAKERESULT(218, 4); + + if (R_SUCCEEDED(rc) && !_hidbusGetStatusManagerEntryDeviceEnabled(index)) rc = MAKERESULT(218, 8); + + if (R_SUCCEEDED(rc)) rc = hidbusGetServiceSession(&srv); + + if (R_SUCCEEDED(rc)) rc = _hidbusDisableJoyPollingReceiveMode(&srv, handle); + + mutexUnlock(&entry->mutex); + serviceClose(&srv); + return rc; +} + +Result hidbusGetJoyPollingReceivedData(HidbusBusHandle handle, HidbusJoyPollingReceivedData *recv_data, s32 count) { + Result rc = _hidBusVerifyBusHandle(handle); + if (R_FAILED(rc)) return rc; + u32 index = handle.internal_index; + HidBusDeviceEntry *entry = &g_hidbusDevices[index]; + if (memcmp(&entry->handle, &handle, sizeof(handle))!=0) rc = MAKERESULT(218, 4); + + if (R_SUCCEEDED(rc) && !_hidbusGetStatusManagerEntryDeviceEnabled(index)) rc = MAKERESULT(218, 8); + + if (R_SUCCEEDED(rc)) rc = _hidbusGetStatusManagerEntryRes(index); + if (R_SUCCEEDED(rc) && !_hidbusGetStatusManagerEntryFlag_x0(index)) rc = MAKERESULT(218, 8); + + if (R_SUCCEEDED(rc) && count >= 1) memset(recv_data, 0, sizeof(HidbusJoyPollingReceivedData)*count); + if (R_SUCCEEDED(rc) && !_hidbusGetStatusManagerEntryPollingEnabled(index)) { + return 0; + } + if (R_FAILED(rc)) return rc; + + if (count > 0xa) count = 0xa; + + HidbusJoyDisableSixAxisPollingDataAccessor *joydisable_accessor = entry->workbuf; + HidbusJoyEnableSixAxisPollingDataAccessor *joyenable_accessor = entry->workbuf; + HidbusJoyButtonOnlyPollingDataAccessor *joybutton_accessor = entry->workbuf; + HidbusDataAccessorHeader *accessor_header; + + HidbusJoyPollingMode polling_mode = _hidbusGetStatusManagerEntryPollingMode(index); + if (polling_mode == HidbusJoyPollingMode_JoyDisableSixAxisPollingData) { + accessor_header = &joydisable_accessor->hdr; + } + else if (polling_mode == HidbusJoyPollingMode_JoyEnableSixAxisPollingData) { + accessor_header = &joyenable_accessor->hdr; + } + else if (hosversionAtLeast(6,0,0) && polling_mode == HidbusJoyPollingMode_JoyButtonOnlyPollingData) { + accessor_header = &joybutton_accessor->hdr; + } + else { + return MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); + } + + s32 total_entries = (s32)atomic_load_explicit(&accessor_header->total_entries, memory_order_acquire); + if (total_entries < 0) total_entries = 0; + s32 newcount = count < total_entries ? count : total_entries; + s32 latest_entry = (s32)atomic_load_explicit(&accessor_header->latest_entry, memory_order_acquire); + + union { + HidbusJoyDisableSixAxisPollingDataAccessorEntryData joydisable[0xa]; + HidbusJoyEnableSixAxisPollingDataAccessorEntryData joyenable[0xa]; + HidbusJoyButtonOnlyPollingDataAccessorEntryData joybutton[0xa]; + } tmp_entries; + + if (polling_mode == HidbusJoyPollingMode_JoyDisableSixAxisPollingData) { + memset(tmp_entries.joydisable, 0, sizeof(tmp_entries.joydisable)); + } + else if (polling_mode == HidbusJoyPollingMode_JoyEnableSixAxisPollingData) { + memset(tmp_entries.joyenable, 0, sizeof(tmp_entries.joyenable)); + } + else if (hosversionAtLeast(6,0,0) && polling_mode == HidbusJoyPollingMode_JoyButtonOnlyPollingData) { + memset(tmp_entries.joybutton, 0, sizeof(tmp_entries.joybutton)); + } + + for (s32 i=0; ientries[entrypos].timestamp, memory_order_acquire); + memcpy(&tmp_entries.joydisable[newcount-i-1], &joydisable_accessor->entries[entrypos].data, sizeof(HidbusJoyDisableSixAxisPollingDataAccessorEntryData)); + timestamp1 = atomic_load_explicit(&joydisable_accessor->entries[entrypos].timestamp, memory_order_acquire); + + if (timestamp0 != timestamp1 || (i>0 && joydisable_accessor->entries[entrypos].data.timestamp - tmp_entries.joydisable[newcount-i].timestamp != 1)) + retry=true; + } + else if (polling_mode == HidbusJoyPollingMode_JoyEnableSixAxisPollingData) { + timestamp0 = atomic_load_explicit(&joyenable_accessor->entries[entrypos].timestamp, memory_order_acquire); + memcpy(&tmp_entries.joyenable[newcount-i-1], &joyenable_accessor->entries[entrypos].data, sizeof(HidbusJoyEnableSixAxisPollingDataAccessorEntryData)); + timestamp1 = atomic_load_explicit(&joyenable_accessor->entries[entrypos].timestamp, memory_order_acquire); + + if (timestamp0 != timestamp1 || (i>0 && joyenable_accessor->entries[entrypos].data.timestamp - tmp_entries.joyenable[newcount-i].timestamp != 1)) + retry=true; + } + else if (hosversionAtLeast(6,0,0) && polling_mode == HidbusJoyPollingMode_JoyButtonOnlyPollingData) { + timestamp0 = atomic_load_explicit(&joybutton_accessor->entries[entrypos].timestamp, memory_order_acquire); + memcpy(&tmp_entries.joybutton[newcount-i-1], &joybutton_accessor->entries[entrypos].data, sizeof(HidbusJoyButtonOnlyPollingDataAccessorEntryData)); + timestamp1 = atomic_load_explicit(&joybutton_accessor->entries[entrypos].timestamp, memory_order_acquire); + + if (timestamp0 != timestamp1 || (i>0 && joybutton_accessor->entries[entrypos].data.timestamp - tmp_entries.joybutton[newcount-i].timestamp != 1)) + retry=true; + } + + if (retry) { + total_entries = (s32)atomic_load_explicit(&accessor_header->total_entries, memory_order_acquire); + s32 tmpcount = newcount < total_entries ? total_entries : newcount; + newcount = tmpcount < count ? tmpcount : count; + latest_entry = (s32)atomic_load_explicit(&accessor_header->latest_entry, memory_order_acquire); + + i=-1; + } + } + + bool dataready=false; + if (polling_mode == HidbusJoyPollingMode_JoyDisableSixAxisPollingData) { + dataready = tmp_entries.joydisable[count-1].timestamp != 0; + } + else if (polling_mode == HidbusJoyPollingMode_JoyEnableSixAxisPollingData) { + dataready = tmp_entries.joyenable[count-1].timestamp != 0; + } + else if (hosversionAtLeast(6,0,0) && polling_mode == HidbusJoyPollingMode_JoyButtonOnlyPollingData) { + dataready = tmp_entries.joybutton[count-1].timestamp != 0; + } + if (!dataready) rc = MAKERESULT(218, 7); + if (R_SUCCEEDED(rc)) rc = accessor_header->res; + if (R_FAILED(rc)) return rc; + + for (s32 i=0; i sizeof(tmp_entries.joydisable[i].data)) return MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); + memcpy(recv_data[i].data, tmp_entries.joydisable[i].data, size); + recv_data[i].size = size; + recv_data[i].timestamp = tmp_entries.joydisable[i].timestamp; + } + else if (polling_mode == HidbusJoyPollingMode_JoyEnableSixAxisPollingData) { + size = tmp_entries.joyenable[i].size; + if (size > sizeof(tmp_entries.joyenable[i].data)) return MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); + memcpy(recv_data[i].data, tmp_entries.joyenable[i].data, size); + recv_data[i].size = size; + recv_data[i].timestamp = tmp_entries.joyenable[i].timestamp; + } + else if (hosversionAtLeast(6,0,0) && polling_mode == HidbusJoyPollingMode_JoyButtonOnlyPollingData) { + size = tmp_entries.joybutton[i].size; + if (size > sizeof(tmp_entries.joybutton[i].data)) return MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); + memcpy(recv_data[i].data, tmp_entries.joybutton[i].data, size); + recv_data[i].size = size; + recv_data[i].timestamp = tmp_entries.joybutton[i].timestamp; + } + } + + return rc; +} + From 91b4efb6f550a69d6c5a92a9a094a86df5603730 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Sat, 14 Mar 2020 16:24:29 -0400 Subject: [PATCH 2/6] hidbus: Updated HidbusBusType. --- nx/include/switch/services/hidbus.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nx/include/switch/services/hidbus.h b/nx/include/switch/services/hidbus.h index 892ed0eb..790c8295 100644 --- a/nx/include/switch/services/hidbus.h +++ b/nx/include/switch/services/hidbus.h @@ -12,9 +12,9 @@ /// BusType typedef enum { - HidbusBusType_Unknown0 = 0, ///< Unknown. - HidbusBusType_Unknown1 = 1, ///< Unknown. - HidbusBusType_Unknown2 = 2, ///< [6.0.0+] Unknown. + HidbusBusType_JoyLeftRail = 0, ///< JoyLeftRail + HidbusBusType_JoyRightRail = 1, ///< JoyRightRail + HidbusBusType_LarkRightRail = 2, ///< [6.0.0+] LarkRightRail (for microphone). } HidbusBusType; /// JoyPollingMode From 2c19f13f74b11b6604d8a7766c2990435643ed08 Mon Sep 17 00:00:00 2001 From: fincs Date: Mon, 16 Mar 2020 12:48:08 +0100 Subject: [PATCH 3/6] nvFence/nvGpu/nvMap: use service guard instead of unsafe atomic refcnt --- nx/source/nvidia/fence.c | 34 ++++++++++++---------------------- nx/source/nvidia/gpu.c | 27 ++++++++------------------- nx/source/nvidia/map.c | 31 +++++++++---------------------- 3 files changed, 29 insertions(+), 63 deletions(-) diff --git a/nx/source/nvidia/fence.c b/nx/source/nvidia/fence.c index 1847a6ef..6fe9bfe7 100644 --- a/nx/source/nvidia/fence.c +++ b/nx/source/nvidia/fence.c @@ -1,6 +1,4 @@ -#include "types.h" -#include "result.h" -#include "arm/atomics.h" +#include "../services/service_guard.h" #include "kernel/svc.h" #include "kernel/event.h" #include "runtime/hosversion.h" @@ -8,11 +6,13 @@ #include "nvidia/fence.h" static u32 g_ctrl_fd = -1; -static u64 g_refCnt; static u64 g_NvEventUsedMask; static Event g_NvEvents[64]; +#define nvFenceInitialize nvFenceInit +NX_GENERATE_SERVICE_GUARD(nvFence); + static int _nvGetEventSlot(void) { int slot; @@ -66,28 +66,18 @@ static void _nvFreeEvent(int event_id) nvioctlNvhostCtrl_EventUnregister(g_ctrl_fd, event_id); } -Result nvFenceInit(void) +Result _nvFenceInitialize(void) { - Result rc; - - if (atomicIncrement64(&g_refCnt) > 0) - return 0; - - rc = nvOpen(&g_ctrl_fd, "/dev/nvhost-ctrl"); - - if (R_FAILED(rc)) - g_ctrl_fd = -1; - - return rc; + return nvOpen(&g_ctrl_fd, "/dev/nvhost-ctrl"); } -void nvFenceExit(void) +void _nvFenceCleanup(void) { - if (atomicDecrement64(&g_refCnt) == 0) { - for (int i = 0; i < 64; i ++) - _nvFreeEvent(i); - if (g_ctrl_fd != -1) - nvClose(g_ctrl_fd); + for (int i = 0; i < 64; i ++) + _nvFreeEvent(i); + + if (g_ctrl_fd != -1) { + nvClose(g_ctrl_fd); g_ctrl_fd = -1; } } diff --git a/nx/source/nvidia/gpu.c b/nx/source/nvidia/gpu.c index 534ebed1..8b153d76 100644 --- a/nx/source/nvidia/gpu.c +++ b/nx/source/nvidia/gpu.c @@ -1,7 +1,5 @@ #include -#include "types.h" -#include "result.h" -#include "arm/atomics.h" +#include "../services/service_guard.h" #include "kernel/svc.h" #include "services/nv.h" #include "nvidia/ioctl.h" @@ -11,25 +9,21 @@ #define NUM_TPC_MASKS 1 static u32 g_ctrlgpu_fd = -1; -static u64 g_refCnt; static nvioctl_gpu_characteristics g_gpu_characteristics; static u32 g_zcull_ctx_size; static nvioctl_zcull_info g_zcull_info; static u32 g_tpc_masks[NUM_TPC_MASKS]; -Result nvGpuInit(void) +#define nvGpuInitialize nvGpuInit +NX_GENERATE_SERVICE_GUARD(nvGpu); + +Result _nvGpuInitialize(void) { Result rc; - if (atomicIncrement64(&g_refCnt) > 0) - return 0; - rc = nvOpen(&g_ctrlgpu_fd, "/dev/nvhost-ctrl-gpu"); - if (R_FAILED(rc)) - g_ctrlgpu_fd = -1; - if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_GetCharacteristics(g_ctrlgpu_fd, &g_gpu_characteristics); @@ -42,18 +36,13 @@ Result nvGpuInit(void) if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_GetTpcMasks(g_ctrlgpu_fd, g_tpc_masks, sizeof(g_tpc_masks)); - if (R_FAILED(rc)) - nvGpuExit(); - return rc; } -void nvGpuExit(void) +void _nvGpuCleanup(void) { - if (atomicDecrement64(&g_refCnt) == 0) { - if (g_ctrlgpu_fd != -1) - nvClose(g_ctrlgpu_fd); - + if (g_ctrlgpu_fd != -1) { + nvClose(g_ctrlgpu_fd); g_ctrlgpu_fd = -1; } } diff --git a/nx/source/nvidia/map.c b/nx/source/nvidia/map.c index fc137d32..9ba23751 100644 --- a/nx/source/nvidia/map.c +++ b/nx/source/nvidia/map.c @@ -1,7 +1,5 @@ #include -#include "types.h" -#include "result.h" -#include "arm/atomics.h" +#include "../services/service_guard.h" #include "arm/cache.h" #include "kernel/svc.h" #include "services/nv.h" @@ -9,30 +7,19 @@ #include "nvidia/map.h" static u32 g_nvmap_fd = -1; -static u64 g_refCnt; -Result nvMapInit(void) +#define nvMapInitialize nvMapInit +NX_GENERATE_SERVICE_GUARD(nvMap); + +Result _nvMapInitialize(void) { - Result rc; - - if (atomicIncrement64(&g_refCnt) > 0) - return 0; - - rc = nvOpen(&g_nvmap_fd, "/dev/nvmap"); - - if (R_FAILED(rc)) - atomicDecrement64(&g_refCnt); - - return rc; + return nvOpen(&g_nvmap_fd, "/dev/nvmap"); } -void nvMapExit(void) +void _nvMapCleanup(void) { - if (atomicDecrement64(&g_refCnt) == 0) - { - if (g_nvmap_fd != -1) - nvClose(g_nvmap_fd); - + if (g_nvmap_fd != -1) { + nvClose(g_nvmap_fd); g_nvmap_fd = -1; } } From cacf8615a8cb2c5c51c06144b1137b923ea82082 Mon Sep 17 00:00:00 2001 From: fincs Date: Mon, 16 Mar 2020 12:51:07 +0100 Subject: [PATCH 4/6] Remove arm/atomics.h (use C or C++ instead) --- nx/include/switch.h | 1 - nx/include/switch/arm/atomics.h | 28 ---------------------------- nx/source/audio/driver_internal.h | 1 - nx/source/nvidia/address_space.c | 1 - nx/source/nvidia/channel.c | 1 - nx/source/nvidia/gpu_channel.c | 1 - 6 files changed, 33 deletions(-) delete mode 100644 nx/include/switch/arm/atomics.h diff --git a/nx/include/switch.h b/nx/include/switch.h index d1089ab2..5d263d8b 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -17,7 +17,6 @@ extern "C" { #include "switch/arm/tls.h" #include "switch/arm/cache.h" -#include "switch/arm/atomics.h" #include "switch/arm/counter.h" #include "switch/kernel/svc.h" diff --git a/nx/include/switch/arm/atomics.h b/nx/include/switch/arm/atomics.h deleted file mode 100644 index b60b9dd1..00000000 --- a/nx/include/switch/arm/atomics.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @file atomics.h - * @brief AArch64 atomic operations. - * @author plutoo - * @copyright libnx Authors - */ -#pragma once -#include "../types.h" - -/// Atomically increments a 32-bit value. -static inline u32 atomicIncrement32(u32* p) { - return __atomic_fetch_add(p, 1, __ATOMIC_SEQ_CST); -} - -/// Atomically decrements a 32-bit value. -static inline u32 atomicDecrement32(u32* p) { - return __atomic_sub_fetch(p, 1, __ATOMIC_SEQ_CST); -} - -/// Atomically increments a 64-bit value. -static inline u64 atomicIncrement64(u64* p) { - return __atomic_fetch_add(p, 1, __ATOMIC_SEQ_CST); -} - -/// Atomically decrements a 64-bit value. -static inline u64 atomicDecrement64(u64* p) { - return __atomic_sub_fetch(p, 1, __ATOMIC_SEQ_CST); -} diff --git a/nx/source/audio/driver_internal.h b/nx/source/audio/driver_internal.h index b6435ca7..116fe1a4 100644 --- a/nx/source/audio/driver_internal.h +++ b/nx/source/audio/driver_internal.h @@ -3,7 +3,6 @@ #include #include "types.h" #include "result.h" -#include "arm/atomics.h" #include "services/audren.h" #include "audio/driver.h" diff --git a/nx/source/nvidia/address_space.c b/nx/source/nvidia/address_space.c index 7ae8fde2..051c9aaa 100644 --- a/nx/source/nvidia/address_space.c +++ b/nx/source/nvidia/address_space.c @@ -1,7 +1,6 @@ #include #include "types.h" #include "result.h" -#include "arm/atomics.h" #include "kernel/svc.h" #include "services/nv.h" #include "nvidia/ioctl.h" diff --git a/nx/source/nvidia/channel.c b/nx/source/nvidia/channel.c index c8099c41..9485a8e5 100644 --- a/nx/source/nvidia/channel.c +++ b/nx/source/nvidia/channel.c @@ -1,7 +1,6 @@ #include #include "types.h" #include "result.h" -#include "arm/atomics.h" #include "kernel/svc.h" #include "services/nv.h" #include "nvidia/ioctl.h" diff --git a/nx/source/nvidia/gpu_channel.c b/nx/source/nvidia/gpu_channel.c index 31f3d9fd..d180ba85 100644 --- a/nx/source/nvidia/gpu_channel.c +++ b/nx/source/nvidia/gpu_channel.c @@ -1,7 +1,6 @@ #include #include "types.h" #include "result.h" -#include "arm/atomics.h" #include "kernel/svc.h" #include "runtime/hosversion.h" #include "services/nv.h" From 6535d6f8713bfe727a3aba8b6eecd450f1f53d15 Mon Sep 17 00:00:00 2001 From: fincs Date: Mon, 16 Mar 2020 16:21:33 +0100 Subject: [PATCH 5/6] Remove U64_MAX in favor of using UINT64_MAX --- nx/include/switch/kernel/condvar.h | 2 +- nx/include/switch/kernel/svc.h | 2 +- nx/include/switch/services/applet.h | 6 +++--- nx/include/switch/services/async.h | 12 ++++++------ nx/include/switch/services/audin.h | 2 +- nx/include/switch/services/audout.h | 2 +- nx/include/switch/services/ns.h | 8 ++++---- nx/include/switch/types.h | 3 --- nx/source/display/native_window.c | 2 +- nx/source/nvidia/fence.c | 2 +- nx/source/runtime/devices/usb_comms.c | 8 ++++---- nx/source/services/applet.c | 14 +++++++------- nx/source/services/async.c | 8 ++++---- nx/source/services/audin.c | 20 ++++++++++---------- nx/source/services/audout.c | 18 +++++++++--------- nx/source/services/audren.c | 2 +- nx/source/services/grc.c | 6 +++--- nx/source/services/hidbus.c | 2 +- nx/source/services/hiddbg.c | 4 ++-- nx/source/services/ns.c | 4 ++-- nx/source/services/usbhs.c | 4 ++-- 21 files changed, 64 insertions(+), 67 deletions(-) diff --git a/nx/include/switch/kernel/condvar.h b/nx/include/switch/kernel/condvar.h index 6ff11d28..563a6627 100644 --- a/nx/include/switch/kernel/condvar.h +++ b/nx/include/switch/kernel/condvar.h @@ -40,7 +40,7 @@ Result condvarWaitTimeout(CondVar* c, Mutex* m, u64 timeout); */ static inline Result condvarWait(CondVar* c, Mutex* m) { - return condvarWaitTimeout(c, m, U64_MAX); + return condvarWaitTimeout(c, m, UINT64_MAX); } /** diff --git a/nx/include/switch/kernel/svc.h b/nx/include/switch/kernel/svc.h index 21a8cc92..6838daee 100644 --- a/nx/include/switch/kernel/svc.h +++ b/nx/include/switch/kernel/svc.h @@ -188,7 +188,7 @@ typedef enum { TickCountInfo_Core2 = 2, ///< Tick count on core 2. TickCountInfo_Core3 = 3, ///< Tick count on core 3. - TickCountInfo_Total = U64_MAX, ///< Tick count on all cores. + TickCountInfo_Total = UINT64_MAX, ///< Tick count on all cores. } TickCountInfo; /// GetInfo InitialProcessIdRange Sub IDs. diff --git a/nx/include/switch/services/applet.h b/nx/include/switch/services/applet.h index 2fc56b32..a6a082cd 100644 --- a/nx/include/switch/services/applet.h +++ b/nx/include/switch/services/applet.h @@ -1003,7 +1003,7 @@ Result appletLockAccessorTryLock(AppletLockAccessor *a, bool *flag); /** * @brief Lock a LockAccessor. - * @note Similar to \ref appletLockAccessorTryLock, except this uses timeout U64_MAX with the eventWait call, and this uses TryLock repeatedly until the output flag value is true. + * @note Similar to \ref appletLockAccessorTryLock, except this uses timeout UINT64_MAX with the eventWait call, and this uses TryLock repeatedly until the output flag value is true. * @param a LockAccessor object. */ Result appletLockAccessorLock(AppletLockAccessor *a); @@ -1095,7 +1095,7 @@ Result appletHolderTerminate(AppletHolder *h); /** * @brief Uses cmds GetAppletStateChangedEvent and RequestExit, then waits for the LibraryApplet to exit with the specified timeout. If a timeout occurs, the Terminate cmd is used. * @param h AppletHolder object. - * @param[in] timeout Timeout in nanoseconds. U64_MAX for no timeout. + * @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. */ Result appletHolderRequestExitOrTerminate(AppletHolder *h, u64 timeout); @@ -1792,7 +1792,7 @@ Result appletApplicationAreAnyLibraryAppletsLeft(AppletApplication *a, bool *out /** * @brief Calls the same func as \ref appletHolderRequestExitOrTerminate with the output IAppletAccessor from the GetCurrentLibraryApplet cmd. * @param a \ref AppletApplication - * @param[in] timeout Timeout in nanoseconds. U64_MAX for no timeout. + * @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. */ Result appletApplicationRequestExitLibraryAppletOrTerminate(AppletApplication *a, u64 timeout); diff --git a/nx/include/switch/services/async.h b/nx/include/switch/services/async.h index ae441f44..c4181d34 100644 --- a/nx/include/switch/services/async.h +++ b/nx/include/switch/services/async.h @@ -27,7 +27,7 @@ typedef struct { /** * @brief Close a \ref AsyncValue. - * @note When the object is initialized, this uses \ref asyncValueCancel then \ref asyncValueWait with timeout=U64_MAX. + * @note When the object is initialized, this uses \ref asyncValueCancel then \ref asyncValueWait with timeout=UINT64_MAX. * @param a \ref AsyncValue */ void asyncValueClose(AsyncValue *a); @@ -35,7 +35,7 @@ void asyncValueClose(AsyncValue *a); /** * @brief Waits for the async operation to finish using the specified timeout. * @param a \ref AsyncValue - * @param[in] timeout Timeout in nanoseconds. U64_MAX for no timeout. + * @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. */ Result asyncValueWait(AsyncValue *a, u64 timeout); @@ -48,7 +48,7 @@ Result asyncValueGetSize(AsyncValue *a, u64 *size); /** * @brief Gets the value. - * @note Prior to using the cmd, this uses \ref asyncResultWait with timeout=U64_MAX. + * @note Prior to using the cmd, this uses \ref asyncResultWait with timeout=UINT64_MAX. * @param a \ref AsyncValue * @param[out] buffer Output buffer. * @param[in] size Output buffer size. @@ -77,7 +77,7 @@ Result asyncValueGetErrorContext(AsyncValue *a, ErrorContext *context); /** * @brief Close a \ref AsyncResult. - * @note When the object is initialized, this uses \ref asyncResultCancel then \ref asyncResultWait with timeout=U64_MAX. + * @note When the object is initialized, this uses \ref asyncResultCancel then \ref asyncResultWait with timeout=UINT64_MAX. * @param a \ref AsyncResult */ void asyncResultClose(AsyncResult *a); @@ -85,13 +85,13 @@ void asyncResultClose(AsyncResult *a); /** * @brief Waits for the async operation to finish using the specified timeout. * @param a \ref AsyncResult - * @param[in] timeout Timeout in nanoseconds. U64_MAX for no timeout. + * @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. */ Result asyncResultWait(AsyncResult *a, u64 timeout); /** * @brief Gets the Result. - * @note Prior to using the cmd, this uses \ref asyncResultWait with timeout=U64_MAX. + * @note Prior to using the cmd, this uses \ref asyncResultWait with timeout=UINT64_MAX. * @param a \ref AsyncResult */ Result asyncResultGet(AsyncResult *a); diff --git a/nx/include/switch/services/audin.h b/nx/include/switch/services/audin.h index bd54c3ac..fbc245a5 100644 --- a/nx/include/switch/services/audin.h +++ b/nx/include/switch/services/audin.h @@ -63,7 +63,7 @@ Result audinCaptureBuffer(AudioInBuffer *source, AudioInBuffer **released); * @brief Waits for audio capture to finish. * @param released AudioInBuffer to receive the first captured buffer after being released. * @param released_count Pointer to receive the number of captured buffers. - * @param timeout Timeout value, use U64_MAX to wait until all finished. + * @param timeout Timeout value, use UINT64_MAX to wait until all finished. */ Result audinWaitCaptureFinish(AudioInBuffer **released, u32* released_count, u64 timeout); diff --git a/nx/include/switch/services/audout.h b/nx/include/switch/services/audout.h index 443e9014..2f18f676 100644 --- a/nx/include/switch/services/audout.h +++ b/nx/include/switch/services/audout.h @@ -63,7 +63,7 @@ Result audoutPlayBuffer(AudioOutBuffer *source, AudioOutBuffer **released); * @brief Waits for audio playback to finish. * @param released AudioOutBuffer to receive the first played buffer after being released. * @param released_count Pointer to receive the number of played buffers. - * @param timeout Timeout value, use U64_MAX to wait until all finished. + * @param timeout Timeout value, use UINT64_MAX to wait until all finished. */ Result audoutWaitPlayFinish(AudioOutBuffer **released, u32* released_count, u64 timeout); diff --git a/nx/include/switch/services/ns.h b/nx/include/switch/services/ns.h index c4383481..6067a26f 100644 --- a/nx/include/switch/services/ns.h +++ b/nx/include/switch/services/ns.h @@ -906,7 +906,7 @@ Result nsCanDeliverApplication(const NsApplicationDeliveryInfo *info0, s32 count Result nsListContentMetaKeyToDeliverApplication(NcmContentMetaKey *meta, s32 meta_count, s32 meta_index, const NsApplicationDeliveryInfo *info, s32 info_count, s32 *total_out); /** - * @brief After validation etc, this sets the output bool by comparing system-version fields in the \ref NsSystemDeliveryInfo / info-array and with a state field. + * @brief After validation etc, this sets the output bool by comparing system-version fields in the \ref NsSystemDeliveryInfo / info-array and with a state field. * @note Only available on [4.0.0+]. * @param[in] info Input array of \ref NsApplicationDeliveryInfo. * @param[in] count Size of the info array in entries. Must be value 1. @@ -1239,7 +1239,7 @@ Result nsProgressMonitorForDeleteUserSaveDataAllGetProgress(NsProgressMonitorFor /** * @brief Close a \ref NsProgressAsyncResult. - * @note When the object is initialized, this uses \ref nsProgressAsyncResultCancel then \ref nsProgressAsyncResultWait with timeout=U64_MAX. + * @note When the object is initialized, this uses \ref nsProgressAsyncResultCancel then \ref nsProgressAsyncResultWait with timeout=UINT64_MAX. * @param a \ref NsProgressAsyncResult */ void nsProgressAsyncResultClose(NsProgressAsyncResult *a); @@ -1247,13 +1247,13 @@ void nsProgressAsyncResultClose(NsProgressAsyncResult *a); /** * @brief Waits for the async operation to finish using the specified timeout. * @param a \ref NsProgressAsyncResult - * @param[in] timeout Timeout in nanoseconds. U64_MAX for no timeout. + * @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. */ Result nsProgressAsyncResultWait(NsProgressAsyncResult *a, u64 timeout); /** * @brief Gets the Result. - * @note Prior to using the cmd, this uses \ref nsProgressAsyncResultWait with timeout=U64_MAX. + * @note Prior to using the cmd, this uses \ref nsProgressAsyncResultWait with timeout=UINT64_MAX. * @param a \ref NsProgressAsyncResult */ Result nsProgressAsyncResultGet(NsProgressAsyncResult *a); diff --git a/nx/include/switch/types.h b/nx/include/switch/types.h index 12138829..4941fe2c 100644 --- a/nx/include/switch/types.h +++ b/nx/include/switch/types.h @@ -10,9 +10,6 @@ #include #include -/// The maximum value of a u64. -#define U64_MAX UINT64_MAX - #ifndef SSIZE_MAX #ifdef SIZE_MAX #define SSIZE_MAX ((SIZE_MAX) >> 1) diff --git a/nx/source/display/native_window.c b/nx/source/display/native_window.c index 47081ced..4fde09f0 100644 --- a/nx/source/display/native_window.c +++ b/nx/source/display/native_window.c @@ -222,7 +222,7 @@ Result nwindowDequeueBuffer(NWindow* nw, s32* out_slot, NvMultiFence* out_fence) if (eventActive(&nw->event)) { do { - eventWait(&nw->event, U64_MAX); + eventWait(&nw->event, UINT64_MAX); rc = bqDequeueBuffer(&nw->bq, true, nw->width, nw->height, nw->format, nw->usage, &slot, &fence); } while (rc == MAKERESULT(Module_LibnxBinder, LibnxBinderError_WouldBlock)); } diff --git a/nx/source/nvidia/fence.c b/nx/source/nvidia/fence.c index 6fe9bfe7..73733ff1 100644 --- a/nx/source/nvidia/fence.c +++ b/nx/source/nvidia/fence.c @@ -84,7 +84,7 @@ void _nvFenceCleanup(void) static Result _nvFenceEventWaitCommon(Event* event, u32 event_id, s32 timeout_us) { - u64 timeout_ns = U64_MAX; + u64 timeout_ns = UINT64_MAX; if (timeout_us >= 0) timeout_ns = (u64)1000*timeout_us; Result rc = eventWait(event, timeout_ns); diff --git a/nx/source/runtime/devices/usb_comms.c b/nx/source/runtime/devices/usb_comms.c index 59faf628..fd22cfc5 100644 --- a/nx/source/runtime/devices/usb_comms.c +++ b/nx/source/runtime/devices/usb_comms.c @@ -409,7 +409,7 @@ static Result _usbCommsRead(usbCommsInterface *interface, void* buffer, size_t s UsbDsReportData reportdata; //Makes sure endpoints are ready for data-transfer / wait for init if needed. - rc = usbDsWaitReady(U64_MAX); + rc = usbDsWaitReady(UINT64_MAX); if (R_FAILED(rc)) return rc; while(size) @@ -438,7 +438,7 @@ static Result _usbCommsRead(usbCommsInterface *interface, void* buffer, size_t s if (R_FAILED(rc)) return rc; //Wait for the transfer to finish. - eventWait(&interface->endpoint_out->CompletionEvent, U64_MAX); + eventWait(&interface->endpoint_out->CompletionEvent, UINT64_MAX); eventClear(&interface->endpoint_out->CompletionEvent); rc = usbDsEndpoint_GetReportData(interface->endpoint_out, &reportdata); @@ -474,7 +474,7 @@ static Result _usbCommsWrite(usbCommsInterface *interface, const void* buffer, s UsbDsReportData reportdata; //Makes sure endpoints are ready for data-transfer / wait for init if needed. - rc = usbDsWaitReady(U64_MAX); + rc = usbDsWaitReady(UINT64_MAX); if (R_FAILED(rc)) return rc; while(size) @@ -501,7 +501,7 @@ static Result _usbCommsWrite(usbCommsInterface *interface, const void* buffer, s if(R_FAILED(rc))return rc; //Wait for the transfer to finish. - eventWait(&interface->endpoint_in->CompletionEvent, U64_MAX); + eventWait(&interface->endpoint_in->CompletionEvent, UINT64_MAX); eventClear(&interface->endpoint_in->CompletionEvent); rc = usbDsEndpoint_GetReportData(interface->endpoint_in, &reportdata); diff --git a/nx/source/services/applet.c b/nx/source/services/applet.c index f83ed9f0..dbb21b01 100644 --- a/nx/source/services/applet.c +++ b/nx/source/services/applet.c @@ -254,7 +254,7 @@ Result _appletInitialize(void) { //Don't enter this msg-loop when g_appletFocusState is already 1, it will hang when applet was previously initialized in the context of the current process for AppletType_Application. if (R_SUCCEEDED(rc) && g_appletFocusState != AppletFocusState_Focused) { do { - eventWait(&g_appletMessageEvent, U64_MAX); + eventWait(&g_appletMessageEvent, UINT64_MAX); u32 msg; rc = _appletReceiveMessage(&msg); @@ -873,7 +873,7 @@ static Result _appletWaitAcquiredSleepLockEvent(void) { Event tmpevent={0}; rc = _appletGetAcquiredSleepLockEvent(&tmpevent); - if (R_SUCCEEDED(rc)) rc = eventWait(&tmpevent, U64_MAX); + if (R_SUCCEEDED(rc)) rc = eventWait(&tmpevent, UINT64_MAX); eventClose(&tmpevent); return rc; } @@ -1027,7 +1027,7 @@ static Result _appletWaitLibraryAppletLaunchableEvent(void) { if (!eventActive(&g_appletLibraryAppletLaunchableEvent)) rc = _appletCmdGetEvent(&g_appletISelfController, &g_appletLibraryAppletLaunchableEvent, false, 9); - if (R_SUCCEEDED(rc)) rc = eventWait(&g_appletLibraryAppletLaunchableEvent, U64_MAX); + if (R_SUCCEEDED(rc)) rc = eventWait(&g_appletLibraryAppletLaunchableEvent, UINT64_MAX); return rc; } @@ -1404,7 +1404,7 @@ Result appletLockAccessorLock(AppletLockAccessor *a) { return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); do { - rc = eventWait(&a->event, U64_MAX); + rc = eventWait(&a->event, UINT64_MAX); if (R_SUCCEEDED(rc)) rc = _appletLockAccessorTryLock(a, false, NULL, &flag); if (R_FAILED(rc)) break; } while(!flag); @@ -1602,7 +1602,7 @@ void appletHolderJoin(AppletHolder *h) { LibAppletExitReason res = LibAppletExitReason_Normal; u32 desc=0; - eventWait(&h->StateChangedEvent, U64_MAX); + eventWait(&h->StateChangedEvent, UINT64_MAX); rc = _appletCmdNoIO(&h->s, 30);//GetResult if (R_FAILED(rc)) { @@ -1642,7 +1642,7 @@ bool appletHolderWaitInteractiveOut(AppletHolder *h) { rc = _appletHolderGetPopInteractiveOutDataEvent(h); if (R_FAILED(rc)) return false; - rc = waitMulti(&idx, U64_MAX, waiterForEvent(&h->PopInteractiveOutDataEvent), waiterForEvent(&h->StateChangedEvent)); + rc = waitMulti(&idx, UINT64_MAX, waiterForEvent(&h->PopInteractiveOutDataEvent), waiterForEvent(&h->StateChangedEvent)); if (R_FAILED(rc)) return false; return idx==0; @@ -2387,7 +2387,7 @@ void appletApplicationJoin(AppletApplication *a) { AppletApplicationExitReason res = AppletApplicationExitReason_Normal; u32 desc=0; - eventWait(&a->StateChangedEvent, U64_MAX); + eventWait(&a->StateChangedEvent, UINT64_MAX); rc = _appletCmdNoIO(&a->s, 30);//GetResult if (R_FAILED(rc)) { diff --git a/nx/source/services/async.c b/nx/source/services/async.c index c0807d78..9c637112 100644 --- a/nx/source/services/async.c +++ b/nx/source/services/async.c @@ -22,7 +22,7 @@ static Result _asyncCmdNoInOutBuf(Service* srv, void* buffer, size_t size, u32 c void asyncValueClose(AsyncValue *a) { if (serviceIsActive(&a->s)) { asyncValueCancel(a); // Official sw ignores rc from this prior to waiting on the event. - asyncValueWait(a, U64_MAX); + asyncValueWait(a, UINT64_MAX); } serviceClose(&a->s); @@ -47,7 +47,7 @@ Result asyncValueGet(AsyncValue *a, void* buffer, size_t size) { if (!serviceIsActive(&a->s)) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); - Result rc = asyncValueWait(a, U64_MAX); + Result rc = asyncValueWait(a, UINT64_MAX); if (R_SUCCEEDED(rc)) rc = _asyncCmdNoInOutBuf(&a->s, buffer, size, 1); return rc; } @@ -73,7 +73,7 @@ Result asyncValueGetErrorContext(AsyncValue *a, ErrorContext *context) { void asyncResultClose(AsyncResult *a) { if (serviceIsActive(&a->s)) { asyncResultCancel(a); // Official sw ignores rc from this prior to waiting on the event. - asyncResultWait(a, U64_MAX); + asyncResultWait(a, UINT64_MAX); } serviceClose(&a->s); @@ -91,7 +91,7 @@ Result asyncResultGet(AsyncResult *a) { if (!serviceIsActive(&a->s)) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); - Result rc = asyncResultWait(a, U64_MAX); + Result rc = asyncResultWait(a, UINT64_MAX); if (R_SUCCEEDED(rc)) rc = _asyncCmdNoIO(&a->s, 0); return rc; } diff --git a/nx/source/services/audin.c b/nx/source/services/audin.c index d14c50e8..5b2c96b1 100644 --- a/nx/source/services/audin.c +++ b/nx/source/services/audin.c @@ -25,21 +25,21 @@ NX_GENERATE_SERVICE_GUARD(audin); Result _audinInitialize(void) { Result rc = 0; rc = smGetService(&g_audinSrv, "audin:u"); - + // Setup the default device if (R_SUCCEEDED(rc)) { // Passing an empty device name will open the default "BuiltInHeadset" char DeviceNameIn[DEVICE_NAME_LENGTH] = {0}; char DeviceNameOut[DEVICE_NAME_LENGTH] = {0}; - + // Open audio input device rc = audinOpenAudioIn(DeviceNameIn, DeviceNameOut, DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_COUNT, &g_sampleRate, &g_channelCount, &g_pcmFormat, &g_deviceState); } - + // Register global handle for buffer events if (R_SUCCEEDED(rc)) rc = _audinRegisterBufferEvent(&g_audinBufferEvent); - + return rc; } @@ -106,25 +106,25 @@ static Result _audinCmdNoInOutU32(Service* srv, u32 *out, u32 cmd_id) { Result audinWaitCaptureFinish(AudioInBuffer **released, u32* released_count, u64 timeout) { // Wait on the buffer event handle Result rc = eventWait(&g_audinBufferEvent, timeout); - + if (R_SUCCEEDED(rc)) { // Grab the released buffer rc = audinGetReleasedAudioInBuffer(released, released_count); } - + return rc; } Result audinCaptureBuffer(AudioInBuffer *source, AudioInBuffer **released) { Result rc = 0; u32 released_count = 0; - + // Try to push the supplied buffer to the audio input device rc = audinAppendAudioInBuffer(source); - + if (R_SUCCEEDED(rc)) - rc = audinWaitCaptureFinish(released, &released_count, U64_MAX); - + rc = audinWaitCaptureFinish(released, &released_count, UINT64_MAX); + return rc; } diff --git a/nx/source/services/audout.c b/nx/source/services/audout.c index b04351c3..607b7ee1 100644 --- a/nx/source/services/audout.c +++ b/nx/source/services/audout.c @@ -25,17 +25,17 @@ NX_GENERATE_SERVICE_GUARD(audout); Result _audoutInitialize(void) { Result rc = 0; rc = smGetService(&g_audoutSrv, "audout:u"); - + // Setup the default device if (R_SUCCEEDED(rc)) { // Passing an empty device name will open the default "DeviceOut" char DeviceNameIn[DEVICE_NAME_LENGTH] = {0}; char DeviceNameOut[DEVICE_NAME_LENGTH] = {0}; - + // Open audio output device rc = audoutOpenAudioOut(DeviceNameIn, DeviceNameOut, DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_COUNT, &g_sampleRate, &g_channelCount, &g_pcmFormat, &g_deviceState); } - + // Register global handle for buffer events if (R_SUCCEEDED(rc)) rc = _audoutRegisterBufferEvent(&g_audoutBufferEvent); @@ -106,25 +106,25 @@ static Result _audoutCmdNoInOutU32(Service* srv, u32 *out, u32 cmd_id) { Result audoutWaitPlayFinish(AudioOutBuffer **released, u32* released_count, u64 timeout) { // Wait on the buffer event handle Result rc = eventWait(&g_audoutBufferEvent, timeout); - + if (R_SUCCEEDED(rc)) { // Grab the released buffer rc = audoutGetReleasedAudioOutBuffer(released, released_count); } - + return rc; } Result audoutPlayBuffer(AudioOutBuffer *source, AudioOutBuffer **released) { Result rc = 0; u32 released_count = 0; - + // Try to push the supplied buffer to the audio output device rc = audoutAppendAudioOutBuffer(source); - + if (R_SUCCEEDED(rc)) - rc = audoutWaitPlayFinish(released, &released_count, U64_MAX); - + rc = audoutWaitPlayFinish(released, &released_count, UINT64_MAX); + return rc; } diff --git a/nx/source/services/audren.c b/nx/source/services/audren.c index 663b03e0..07dda7e2 100644 --- a/nx/source/services/audren.c +++ b/nx/source/services/audren.c @@ -136,7 +136,7 @@ static Result _audrenCmdNoInOutU32(Service* srv, u32 *out, u32 cmd_id) { } void audrenWaitFrame(void) { - eventWait(&g_audrenEvent, U64_MAX); + eventWait(&g_audrenEvent, UINT64_MAX); } Result _audrenOpenAudioRenderer(Service* srv, Service* srv_out, const AudioRendererParameter* param) { diff --git a/nx/source/services/grc.c b/nx/source/services/grc.c index 9b579e22..717fab56 100644 --- a/nx/source/services/grc.c +++ b/nx/source/services/grc.c @@ -142,7 +142,7 @@ Result grcTrimGameMovie(GrcGameMovieId *dst_movieid, const GrcGameMovieId *src_m if (R_SUCCEEDED(rc)) rc = _grcGameMovieTrimmerBeginTrim(&trimmer, src_movieid, start, end); - if (R_SUCCEEDED(rc)) rc = eventWait(&trimevent, U64_MAX); + if (R_SUCCEEDED(rc)) rc = eventWait(&trimevent, UINT64_MAX); if (R_SUCCEEDED(rc)) rc = _grcGameMovieTrimmerEndTrim(&trimmer, dst_movieid); @@ -308,7 +308,7 @@ Result grcMovieMakerFinish(GrcMovieMaker *m, s32 width, s32 height, const void* rc = _grcCmdInU64NoOut(&m->s, m->layer_handle, 22); // RequestOffscreenRecordingFinishReady - if (R_SUCCEEDED(rc)) rc = eventWait(&m->recording_event, U64_MAX); + if (R_SUCCEEDED(rc)) rc = eventWait(&m->recording_event, UINT64_MAX); if (hosversionAtLeast(7,0,0)) rc = _grcMovieMakerCompleteOffscreenRecordingFinishEx1(m, width, height, userdata, userdata_size, thumbnail, thumbnail_size, entry); @@ -342,7 +342,7 @@ Result grcMovieMakerEncodeAudioSample(GrcMovieMaker *m, const void* buffer, size return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); for (u64 pos=0; size!=0; pos+=out_size, size-=out_size) { - rc = eventWait(&m->audio_event, U64_MAX); + rc = eventWait(&m->audio_event, UINT64_MAX); if (R_FAILED(rc)) break; rc = _grcMovieMakerEncodeOffscreenLayerAudioSample(m, &bufptr[pos], size, &out_size); diff --git a/nx/source/services/hidbus.c b/nx/source/services/hidbus.c index 1f5614c0..c74bb568 100644 --- a/nx/source/services/hidbus.c +++ b/nx/source/services/hidbus.c @@ -365,7 +365,7 @@ Result hidbusSendAndReceive(HidbusBusHandle handle, const void* inbuf, size_t in rc = _hidbusSendCommandAsync(&srv, handle, inbuf, inbuf_size); } if (R_SUCCEEDED(rc)) { - eventWait(&entry->event, U64_MAX); + eventWait(&entry->event, UINT64_MAX); eventClear(&entry->event); u32 tmpout=0; rc = _hidbusGetSendCommandAsynceResult(&srv, handle, outbuf, outbuf_size, &tmpout); diff --git a/nx/source/services/hiddbg.c b/nx/source/services/hiddbg.c index abc9611d..5fc97664 100644 --- a/nx/source/services/hiddbg.c +++ b/nx/source/services/hiddbg.c @@ -165,7 +165,7 @@ Result hiddbgReadSerialFlash(u32 offset, void* buffer, size_t size, u64 UniquePa rc = hiddbgAcquireOperationEventHandle(&tmpevent, true, UniquePadId); // *Must* be used before _hiddbgReadSerialFlash. if (R_SUCCEEDED(rc)) rc = _hiddbgReadSerialFlash(&tmem, offset, size, UniquePadId); - if (R_SUCCEEDED(rc)) rc = eventWait(&tmpevent, U64_MAX); + if (R_SUCCEEDED(rc)) rc = eventWait(&tmpevent, UINT64_MAX); if (R_SUCCEEDED(rc)) rc = hiddbgGetOperationResult(UniquePadId); if (R_SUCCEEDED(rc)) memcpy(buffer, tmem.src_addr, size); eventClose(&tmpevent); @@ -186,7 +186,7 @@ Result hiddbgWriteSerialFlash(u32 offset, void* buffer, size_t tmem_size, size_t rc = hiddbgAcquireOperationEventHandle(&tmpevent, true, UniquePadId); // *Must* be used before _hiddbgWriteSerialFlash. if (R_SUCCEEDED(rc)) rc = _hiddbgWriteSerialFlash(&tmem, offset, tmem_size, size, UniquePadId); - if (R_SUCCEEDED(rc)) rc = eventWait(&tmpevent, U64_MAX); + if (R_SUCCEEDED(rc)) rc = eventWait(&tmpevent, UINT64_MAX); if (R_SUCCEEDED(rc)) rc = hiddbgGetOperationResult(UniquePadId); eventClose(&tmpevent); tmemClose(&tmem); diff --git a/nx/source/services/ns.c b/nx/source/services/ns.c index c2716ecf..c8c4ddf9 100644 --- a/nx/source/services/ns.c +++ b/nx/source/services/ns.c @@ -2150,7 +2150,7 @@ Result nsProgressMonitorForDeleteUserSaveDataAllGetProgress(NsProgressMonitorFor void nsProgressAsyncResultClose(NsProgressAsyncResult *a) { if (serviceIsActive(&a->s)) { nsProgressAsyncResultCancel(a); // Official sw ignores rc from this prior to waiting on the event. - nsProgressAsyncResultWait(a, U64_MAX); + nsProgressAsyncResultWait(a, UINT64_MAX); } serviceClose(&a->s); @@ -2168,7 +2168,7 @@ Result nsProgressAsyncResultGet(NsProgressAsyncResult *a) { if (!serviceIsActive(&a->s)) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); - Result rc = nsProgressAsyncResultWait(a, U64_MAX); + Result rc = nsProgressAsyncResultWait(a, UINT64_MAX); if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(&a->s, 0); return rc; } diff --git a/nx/source/services/usbhs.c b/nx/source/services/usbhs.c index dbe2a3de..6b821619 100644 --- a/nx/source/services/usbhs.c +++ b/nx/source/services/usbhs.c @@ -307,7 +307,7 @@ Result usbHsIfCtrlXfer(UsbHsClientIfSession* s, u8 bmRequestType, u8 bRequest, u rc = _usbHsIfCtrlXferAsync(s, bmRequestType, bRequest, wValue, wIndex, wLength, buffer); if (R_FAILED(rc)) return rc; - rc = eventWait(&s->eventCtrlXfer, U64_MAX); + rc = eventWait(&s->eventCtrlXfer, UINT64_MAX); if (R_FAILED(rc)) return rc; eventClear(&s->eventCtrlXfer); @@ -429,7 +429,7 @@ Result usbHsEpPostBuffer(UsbHsClientEpSession* s, void* buffer, u32 size, u32* t rc = _usbHsEpPostBufferAsync(s, buffer, size, 0, &xferId); if (R_FAILED(rc)) return rc; - rc = eventWait(&s->eventXfer, U64_MAX); + rc = eventWait(&s->eventXfer, UINT64_MAX); if (R_FAILED(rc)) return rc; eventClear(&s->eventXfer); From 31f871a74f89d6c179d7be8da2aedbdf56711612 Mon Sep 17 00:00:00 2001 From: cathery Date: Mon, 16 Mar 2020 22:45:07 +0300 Subject: [PATCH 6/6] hid: Update the value for JOYSTICK_MIN --- nx/include/switch/services/hid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index 71eb5ac3..0c8beaa6 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -431,7 +431,7 @@ typedef struct SixAxisSensorValues { } SixAxisSensorValues; #define JOYSTICK_MAX (0x7FFF) -#define JOYSTICK_MIN (-0x8000) +#define JOYSTICK_MIN (-0x7FFF) // End enums and output structs