diff --git a/libraries/libstratosphere/include/stratosphere/os/os_io_region_api.hpp b/libraries/libstratosphere/include/stratosphere/os/os_io_region_api.hpp index d2a4f781d..838228a5e 100644 --- a/libraries/libstratosphere/include/stratosphere/os/os_io_region_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/os/os_io_region_api.hpp @@ -26,6 +26,7 @@ namespace ams::os { Result CreateIoRegion(IoRegionType *io_region, NativeHandle io_pool_handle, uintptr_t address, size_t size, MemoryMapping mapping, MemoryPermission permission); void AttachIoRegionHandle(IoRegionType *io_region, size_t size, NativeHandle handle, bool managed); + os::NativeHandle DetachIoRegionHandle(IoRegionType *io_region); void DestroyIoRegion(IoRegionType *io_region); diff --git a/libraries/libstratosphere/include/stratosphere/os/os_io_region_types.hpp b/libraries/libstratosphere/include/stratosphere/os/os_io_region_types.hpp index 172f5e14f..387541afa 100644 --- a/libraries/libstratosphere/include/stratosphere/os/os_io_region_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/os/os_io_region_types.hpp @@ -26,6 +26,7 @@ namespace ams::os { State_NotInitialized = 0, State_Initialized = 1, State_Mapped = 2, + State_Detached = 3, }; NativeHandle handle; diff --git a/libraries/libstratosphere/source/os/os_io_region.cpp b/libraries/libstratosphere/source/os/os_io_region.cpp index 368abfca1..04eab10ce 100644 --- a/libraries/libstratosphere/source/os/os_io_region.cpp +++ b/libraries/libstratosphere/source/os/os_io_region.cpp @@ -69,6 +69,28 @@ namespace ams::os { InitializeIoRegion(io_region, handle, size, managed); } + os::NativeHandle DetachIoRegionHandle(IoRegionType *io_region) { + /* Check pre-conditions. */ + AMS_ASSERT(io_region->state != IoRegionType::State_NotInitialized); + + /* Acquire exclusive access to the io region. */ + std::scoped_lock lk(util::GetReference(io_region->cs_io_region)); + + /* Check that we can detach. */ + AMS_ASSERT(io_region->state == IoRegionType::State_Initialized); + + /* Set state as detached. */ + io_region->state = IoRegionType::State_Detached; + + /* Detach the handle. */ + const auto handle = io_region->handle; + + io_region->handle = os::InvalidNativeHandle; + io_region->handle_managed = false; + + return handle; + } + void DestroyIoRegion(IoRegionType *io_region) { /* Check pre-conditions. */ AMS_ASSERT(io_region->state != IoRegionType::State_NotInitialized);