diff --git a/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_upper_layer_api.hpp b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_upper_layer_api.hpp index 48ec04f2b..acc6bedaa 100644 --- a/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_upper_layer_api.hpp +++ b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_upper_layer_api.hpp @@ -23,6 +23,7 @@ namespace ams::prfile2::pdm { namespace part { pdm::Error CheckDataEraseRequest(HandleType part_handle, bool *out); + pdm::Error CheckMediaDetect(HandleType part_handle, bool *out); pdm::Error CheckMediaInsert(HandleType part_handle, bool *out); } @@ -30,6 +31,7 @@ namespace ams::prfile2::pdm { namespace disk { pdm::Error CheckDataEraseRequest(HandleType disk_handle, bool *out); + pdm::Error CheckMediaDetect(HandleType disk_handle, bool *out); pdm::Error CheckMediaInsert(HandleType disk_handle, bool *out); } diff --git a/libraries/libvapours/include/vapours/prfile2/prfile2_drv.hpp b/libraries/libvapours/include/vapours/prfile2/prfile2_drv.hpp index 2130d4bf4..37fbdb399 100644 --- a/libraries/libvapours/include/vapours/prfile2/prfile2_drv.hpp +++ b/libraries/libvapours/include/vapours/prfile2/prfile2_drv.hpp @@ -26,6 +26,7 @@ namespace ams::prfile2::drv { pf::Error Initialize(Volume *volume); + bool IsDetected(Volume *volume); bool IsInserted(Volume *volume); } diff --git a/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_upper_layer_disk_api.cpp b/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_upper_layer_disk_api.cpp index 75c666089..f150107d8 100644 --- a/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_upper_layer_disk_api.cpp +++ b/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_upper_layer_disk_api.cpp @@ -38,6 +38,31 @@ namespace ams::prfile2::pdm::disk { return pdm::Error_Ok; } + pdm::Error CheckMediaDetect(HandleType disk_handle, bool *out) { + /* Check parameters. */ + Disk *disk = GetDisk(disk_handle); + if (out == nullptr || disk == nullptr) { + return pdm::Error_InvalidParameter; + } + + /* Default to no status change detected. */ + *out = false; + + /* Detect status change via disk nbc detect. */ + volatile NonBlockingProtocolType nbc; + do { + do { + nbc = disk->nbc; + } while ((nbc & 1) != 0); + if (nbc != disk->nbc_detect) { + *out = true; + } + } while (nbc != disk->nbc); + + return pdm::Error_Ok; + } + + pdm::Error CheckMediaInsert(HandleType disk_handle, bool *out) { /* Check parameters. */ Disk *disk = GetDisk(disk_handle); diff --git a/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_upper_layer_part_api.cpp b/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_upper_layer_part_api.cpp index 7e0a95f08..83be80f30 100644 --- a/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_upper_layer_part_api.cpp +++ b/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_upper_layer_part_api.cpp @@ -37,6 +37,33 @@ namespace ams::prfile2::pdm::part { return pdm::disk::CheckDataEraseRequest(part->disk_handle, out); } + pdm::Error CheckMediaDetect(HandleType part_handle, bool *out) { + /* Check parameters. */ + Partition *part = GetPartition(part_handle); + if (out == nullptr || part == nullptr) { + return pdm::Error_InvalidParameter; + } + + /* Get the disk (unsafe/not checked). */ + Disk *disk = GetDiskUnsafe(part->disk_handle); + + /* Default to no status change detected. */ + *out = false; + + /* Detect status change via partition nbc detect. */ + volatile NonBlockingProtocolType nbc; + do { + do { + nbc = disk->nbc; + } while ((nbc & 1) != 0); + if (nbc != part->nbc_detect) { + *out = true; + } + } while (nbc != disk->nbc); + + return pdm::Error_Ok; + } + pdm::Error CheckMediaInsert(HandleType part_handle, bool *out) { /* Check parameters. */ Partition *part = GetPartition(part_handle); diff --git a/libraries/libvapours/source/prfile2/prfile2_drv.cpp b/libraries/libvapours/source/prfile2/prfile2_drv.cpp index 7d00a2c2a..298c2069c 100644 --- a/libraries/libvapours/source/prfile2/prfile2_drv.cpp +++ b/libraries/libvapours/source/prfile2/prfile2_drv.cpp @@ -42,6 +42,14 @@ namespace ams::prfile2::drv { return pf::Error_Ok; } + bool IsDetected(Volume *volume) { + /* Check detect status changed. */ + /* NOTE: Error is not checked here. */ + bool detected = false; + pdm::part::CheckMediaDetect(volume->partition_handle, std::addressof(detected)); + return detected; + } + bool IsInserted(Volume *volume) { /* Check inserted. */ /* NOTE: Error is not checked here. */