From a65b1b8b315ec1a6989f16cd7525269be9407d0f Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Thu, 2 Nov 2023 00:09:56 -0700 Subject: [PATCH] Add deactivation report fields to GameCardErrorReportInfo --- src/LibHac/Fs/GameCard.cs | 6 +- .../FsSystem/CardDeviceDetectionEvent.cs | 1 - src/LibHac/GcSrv/GameCardManager.cs | 58 ++++++++++++++----- .../SdmmcSrv/SdCardDetectionEventManager.cs | 6 +- tests/LibHac.Tests/Fs/TypeLayoutTests.cs | 6 +- 5 files changed, 54 insertions(+), 23 deletions(-) diff --git a/src/LibHac/Fs/GameCard.cs b/src/LibHac/Fs/GameCard.cs index 3383904d..2a5c7023 100644 --- a/src/LibHac/Fs/GameCard.cs +++ b/src/LibHac/Fs/GameCard.cs @@ -85,7 +85,8 @@ public struct GameCardErrorInfo public struct GameCardErrorReportInfo { public ushort GameCardCrcErrorNum; - public ushort Reserved2; + public byte LastDeactivateReason; + public byte Reserved3; public ushort AsicCrcErrorNum; public ushort Reserved6; public ushort RefreshNum; @@ -106,7 +107,8 @@ public struct GameCardErrorReportInfo public uint AwakenCount; public uint ReadCountFromInsert; public uint ReadCountFromAwaken; - public Array8 Reserved38; + public uint LastDeactivateReasonResult; + public Array4 Reserved3C; } public struct GameCardUpdatePartitionInfo diff --git a/src/LibHac/FsSystem/CardDeviceDetectionEvent.cs b/src/LibHac/FsSystem/CardDeviceDetectionEvent.cs index 3d210443..4d18ba0f 100644 --- a/src/LibHac/FsSystem/CardDeviceDetectionEvent.cs +++ b/src/LibHac/FsSystem/CardDeviceDetectionEvent.cs @@ -23,7 +23,6 @@ internal class CardDeviceDetectionEventManager : IDisposable { public CardDeviceDetectionEventManager EventManager; public SdkMutex Mutex; - public Sdmmc.Port Port; } public CardDeviceDetectionEventManager() diff --git a/src/LibHac/GcSrv/GameCardManager.cs b/src/LibHac/GcSrv/GameCardManager.cs index 789dd4f3..8e346ee1 100644 --- a/src/LibHac/GcSrv/GameCardManager.cs +++ b/src/LibHac/GcSrv/GameCardManager.cs @@ -40,12 +40,28 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG Write = 3 } + private enum DeactivateReason : byte + { + Reason0 = 0, + Reason1 = 1, + Reason2 = 2, + Reason3 = 3, + Reason4 = 4, + Reason5 = 5, + Reason6 = 6, + Reason7 = 7, + Reason8 = 8, + Reason9 = 9, + } + private ReaderWriterLock _rwLock; private bool _isInitialized; private bool _isFinalized; private CardState _state; + private DeactivateReason _lastDeactivateReason; private GameCardHandle _currentHandle; private GameCardDetectionEventManager _detectionEventManager; + private Result _lastDeactivateReasonResult; // LibHac additions private WeakRef _selfReference; @@ -81,18 +97,19 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG _selfReference.Destroy(); } - private void DeactivateAndChangeState() + private void DeactivateAndChangeState(DeactivateReason reason) { _gc.Deactivate(); _currentHandle++; _state = CardState.Initial; + _lastDeactivateReason = reason; } - private void CheckGameCardAndDeactivate() + private void CheckGameCardAndDeactivate(DeactivateReason reason) { if (_state != CardState.Initial && !_gc.IsCardActivationValid()) { - DeactivateAndChangeState(); + DeactivateAndChangeState(reason); } } @@ -162,7 +179,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG UnsafeHelpers.SkipParamInit(out outNewHandle); if (_state == CardState.Normal) - CheckGameCardAndDeactivate(); + CheckGameCardAndDeactivate(DeactivateReason.Reason6); switch (_state) { @@ -183,7 +200,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG case CardState.Secure: { // Secure -> Initial -> Normal - DeactivateAndChangeState(); + DeactivateAndChangeState(DeactivateReason.Reason7); Result res = ActivateGameCard(); if (res.IsFailure()) return res.Miss(); @@ -194,7 +211,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG case CardState.Write: { // Write -> Initial -> Normal - DeactivateAndChangeState(); + DeactivateAndChangeState(DeactivateReason.Reason9); _gc.Writer.ChangeMode(AsicMode.Read); Result res = ActivateGameCard(); @@ -217,7 +234,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG UnsafeHelpers.SkipParamInit(out outNewHandle); if (_state == CardState.Secure) - CheckGameCardAndDeactivate(); + CheckGameCardAndDeactivate(DeactivateReason.Reason8); switch (_state) { @@ -251,7 +268,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG case CardState.Write: { // Write -> Initial -> Normal -> Secure - DeactivateAndChangeState(); + DeactivateAndChangeState(DeactivateReason.Reason9); _gc.Writer.ChangeMode(AsicMode.Read); Result res = ActivateGameCard(); @@ -293,7 +310,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG case CardState.Secure: { // Normal/Secure -> Initial -> Write - DeactivateAndChangeState(); + DeactivateAndChangeState(DeactivateReason.Reason9); _gc.Writer.ChangeMode(AsicMode.Write); Result res = ActivateGameCardForWriter(); @@ -623,12 +640,17 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG public Result Invalidate() { - using var writeLock = new UniqueLock(_rwLock); - DeactivateAndChangeState(); + InvalidateImpl(DeactivateReason.Reason1); return Result.Success; } + private void InvalidateImpl(DeactivateReason reason) + { + using var writeLock = new UniqueLock(_rwLock); + DeactivateAndChangeState(reason); + } + public Result Operate(int operationId) { var operation = (GameCardManagerOperationIdValue)operationId; @@ -879,6 +901,9 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG Result res = _gc.GetErrorInfo(out outErrorInfo); if (res.IsFailure()) return res.Miss(); + outErrorInfo.LastDeactivateReasonResult = _lastDeactivateReasonResult.Value; + outErrorInfo.LastDeactivateReason = (byte)_lastDeactivateReason; + return Result.Success; } @@ -1033,7 +1058,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG } } - Invalidate().IgnoreResult(); + InvalidateImpl(DeactivateReason.Reason2); return ResultFs.GameCardFsCheckHandleInAcquireReadLock.Log(); } @@ -1051,7 +1076,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG if (_state != CardState.Initial && !_gc.IsCardActivationValid()) { readLock.Unlock(); - Invalidate().IgnoreResult(); + InvalidateImpl(DeactivateReason.Reason3); } else if (_currentHandle == inOutHandle) { @@ -1115,7 +1140,8 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG if (result.IsFailure()) { - DeactivateAndChangeState(); + DeactivateAndChangeState(DeactivateReason.Reason4); + _lastDeactivateReasonResult = result; } return result; @@ -1127,7 +1153,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG if (_state == CardState.Normal || _state == CardState.Secure) { - CheckGameCardAndDeactivate(); + CheckGameCardAndDeactivate(DeactivateReason.Reason5); } switch (_state) @@ -1144,7 +1170,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG break; case CardState.Write: { - DeactivateAndChangeState(); + DeactivateAndChangeState(DeactivateReason.Reason9); _gc.Writer.ChangeMode(AsicMode.Read); Result res = ActivateGameCard(); diff --git a/src/LibHac/SdmmcSrv/SdCardDetectionEventManager.cs b/src/LibHac/SdmmcSrv/SdCardDetectionEventManager.cs index e8cc1c7f..746fbfeb 100644 --- a/src/LibHac/SdmmcSrv/SdCardDetectionEventManager.cs +++ b/src/LibHac/SdmmcSrv/SdCardDetectionEventManager.cs @@ -9,12 +9,14 @@ namespace LibHac.SdmmcSrv; /// Based on nnSdk 16.2.0 (FS 16.0.0) internal class SdCardDetectionEventManager : CardDeviceDetectionEventManager { + public Port Port; + // LibHac addition private readonly SdmmcApi _sdmmc; public SdCardDetectionEventManager(Port port, SdmmcApi sdmmc) { - CallbackArgs.Port = port; + Port = port; _sdmmc = sdmmc; _sdmmc.RegisterSdCardDetectionEventCallback(port, DetectionEventCallback, CallbackArgs); @@ -22,7 +24,7 @@ internal class SdCardDetectionEventManager : CardDeviceDetectionEventManager public override void Dispose() { - _sdmmc.UnregisterSdCardDetectionEventCallback(CallbackArgs.Port); + _sdmmc.UnregisterSdCardDetectionEventCallback(Port); base.Dispose(); } diff --git a/tests/LibHac.Tests/Fs/TypeLayoutTests.cs b/tests/LibHac.Tests/Fs/TypeLayoutTests.cs index 0f3b1f5c..54b2008c 100644 --- a/tests/LibHac.Tests/Fs/TypeLayoutTests.cs +++ b/tests/LibHac.Tests/Fs/TypeLayoutTests.cs @@ -520,7 +520,8 @@ public class TypeLayoutTests Assert.Equal(0x40, Unsafe.SizeOf()); Assert.Equal(0x00, GetOffset(in s, in s.GameCardCrcErrorNum)); - Assert.Equal(0x02, GetOffset(in s, in s.Reserved2)); + Assert.Equal(0x02, GetOffset(in s, in s.LastDeactivateReason)); + Assert.Equal(0x03, GetOffset(in s, in s.Reserved3)); Assert.Equal(0x04, GetOffset(in s, in s.AsicCrcErrorNum)); Assert.Equal(0x06, GetOffset(in s, in s.Reserved6)); Assert.Equal(0x08, GetOffset(in s, in s.RefreshNum)); @@ -541,7 +542,8 @@ public class TypeLayoutTests Assert.Equal(0x2C, GetOffset(in s, in s.AwakenCount)); Assert.Equal(0x30, GetOffset(in s, in s.ReadCountFromInsert)); Assert.Equal(0x34, GetOffset(in s, in s.ReadCountFromAwaken)); - Assert.Equal(0x38, GetOffset(in s, in s.Reserved38)); + Assert.Equal(0x38, GetOffset(in s, in s.LastDeactivateReasonResult)); + Assert.Equal(0x3C, GetOffset(in s, in s.Reserved3C)); } [Fact]