Add deactivation report fields to GameCardErrorReportInfo

This commit is contained in:
Alex Barney 2023-11-02 00:09:56 -07:00
parent 253c0cb011
commit a65b1b8b31
5 changed files with 54 additions and 23 deletions

View file

@ -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<byte> Reserved38;
public uint LastDeactivateReasonResult;
public Array4<byte> Reserved3C;
}
public struct GameCardUpdatePartitionInfo

View file

@ -23,7 +23,6 @@ internal class CardDeviceDetectionEventManager : IDisposable
{
public CardDeviceDetectionEventManager EventManager;
public SdkMutex Mutex;
public Sdmmc.Port Port;
}
public CardDeviceDetectionEventManager()

View file

@ -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<GameCardManager> _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<ReaderWriterLock>(_rwLock);
DeactivateAndChangeState();
InvalidateImpl(DeactivateReason.Reason1);
return Result.Success;
}
private void InvalidateImpl(DeactivateReason reason)
{
using var writeLock = new UniqueLock<ReaderWriterLock>(_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();

View file

@ -9,12 +9,14 @@ namespace LibHac.SdmmcSrv;
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
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();
}

View file

@ -520,7 +520,8 @@ public class TypeLayoutTests
Assert.Equal(0x40, Unsafe.SizeOf<GameCardErrorReportInfo>());
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]