mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add deactivation report fields to GameCardErrorReportInfo
This commit is contained in:
parent
253c0cb011
commit
a65b1b8b31
5 changed files with 54 additions and 23 deletions
|
@ -85,7 +85,8 @@ public struct GameCardErrorInfo
|
||||||
public struct GameCardErrorReportInfo
|
public struct GameCardErrorReportInfo
|
||||||
{
|
{
|
||||||
public ushort GameCardCrcErrorNum;
|
public ushort GameCardCrcErrorNum;
|
||||||
public ushort Reserved2;
|
public byte LastDeactivateReason;
|
||||||
|
public byte Reserved3;
|
||||||
public ushort AsicCrcErrorNum;
|
public ushort AsicCrcErrorNum;
|
||||||
public ushort Reserved6;
|
public ushort Reserved6;
|
||||||
public ushort RefreshNum;
|
public ushort RefreshNum;
|
||||||
|
@ -106,7 +107,8 @@ public struct GameCardErrorReportInfo
|
||||||
public uint AwakenCount;
|
public uint AwakenCount;
|
||||||
public uint ReadCountFromInsert;
|
public uint ReadCountFromInsert;
|
||||||
public uint ReadCountFromAwaken;
|
public uint ReadCountFromAwaken;
|
||||||
public Array8<byte> Reserved38;
|
public uint LastDeactivateReasonResult;
|
||||||
|
public Array4<byte> Reserved3C;
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct GameCardUpdatePartitionInfo
|
public struct GameCardUpdatePartitionInfo
|
||||||
|
|
|
@ -23,7 +23,6 @@ internal class CardDeviceDetectionEventManager : IDisposable
|
||||||
{
|
{
|
||||||
public CardDeviceDetectionEventManager EventManager;
|
public CardDeviceDetectionEventManager EventManager;
|
||||||
public SdkMutex Mutex;
|
public SdkMutex Mutex;
|
||||||
public Sdmmc.Port Port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CardDeviceDetectionEventManager()
|
public CardDeviceDetectionEventManager()
|
||||||
|
|
|
@ -40,12 +40,28 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
Write = 3
|
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 ReaderWriterLock _rwLock;
|
||||||
private bool _isInitialized;
|
private bool _isInitialized;
|
||||||
private bool _isFinalized;
|
private bool _isFinalized;
|
||||||
private CardState _state;
|
private CardState _state;
|
||||||
|
private DeactivateReason _lastDeactivateReason;
|
||||||
private GameCardHandle _currentHandle;
|
private GameCardHandle _currentHandle;
|
||||||
private GameCardDetectionEventManager _detectionEventManager;
|
private GameCardDetectionEventManager _detectionEventManager;
|
||||||
|
private Result _lastDeactivateReasonResult;
|
||||||
|
|
||||||
// LibHac additions
|
// LibHac additions
|
||||||
private WeakRef<GameCardManager> _selfReference;
|
private WeakRef<GameCardManager> _selfReference;
|
||||||
|
@ -81,18 +97,19 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
_selfReference.Destroy();
|
_selfReference.Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeactivateAndChangeState()
|
private void DeactivateAndChangeState(DeactivateReason reason)
|
||||||
{
|
{
|
||||||
_gc.Deactivate();
|
_gc.Deactivate();
|
||||||
_currentHandle++;
|
_currentHandle++;
|
||||||
_state = CardState.Initial;
|
_state = CardState.Initial;
|
||||||
|
_lastDeactivateReason = reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckGameCardAndDeactivate()
|
private void CheckGameCardAndDeactivate(DeactivateReason reason)
|
||||||
{
|
{
|
||||||
if (_state != CardState.Initial && !_gc.IsCardActivationValid())
|
if (_state != CardState.Initial && !_gc.IsCardActivationValid())
|
||||||
{
|
{
|
||||||
DeactivateAndChangeState();
|
DeactivateAndChangeState(reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +179,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
UnsafeHelpers.SkipParamInit(out outNewHandle);
|
UnsafeHelpers.SkipParamInit(out outNewHandle);
|
||||||
|
|
||||||
if (_state == CardState.Normal)
|
if (_state == CardState.Normal)
|
||||||
CheckGameCardAndDeactivate();
|
CheckGameCardAndDeactivate(DeactivateReason.Reason6);
|
||||||
|
|
||||||
switch (_state)
|
switch (_state)
|
||||||
{
|
{
|
||||||
|
@ -183,7 +200,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
case CardState.Secure:
|
case CardState.Secure:
|
||||||
{
|
{
|
||||||
// Secure -> Initial -> Normal
|
// Secure -> Initial -> Normal
|
||||||
DeactivateAndChangeState();
|
DeactivateAndChangeState(DeactivateReason.Reason7);
|
||||||
|
|
||||||
Result res = ActivateGameCard();
|
Result res = ActivateGameCard();
|
||||||
if (res.IsFailure()) return res.Miss();
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
@ -194,7 +211,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
case CardState.Write:
|
case CardState.Write:
|
||||||
{
|
{
|
||||||
// Write -> Initial -> Normal
|
// Write -> Initial -> Normal
|
||||||
DeactivateAndChangeState();
|
DeactivateAndChangeState(DeactivateReason.Reason9);
|
||||||
_gc.Writer.ChangeMode(AsicMode.Read);
|
_gc.Writer.ChangeMode(AsicMode.Read);
|
||||||
|
|
||||||
Result res = ActivateGameCard();
|
Result res = ActivateGameCard();
|
||||||
|
@ -217,7 +234,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
UnsafeHelpers.SkipParamInit(out outNewHandle);
|
UnsafeHelpers.SkipParamInit(out outNewHandle);
|
||||||
|
|
||||||
if (_state == CardState.Secure)
|
if (_state == CardState.Secure)
|
||||||
CheckGameCardAndDeactivate();
|
CheckGameCardAndDeactivate(DeactivateReason.Reason8);
|
||||||
|
|
||||||
switch (_state)
|
switch (_state)
|
||||||
{
|
{
|
||||||
|
@ -251,7 +268,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
case CardState.Write:
|
case CardState.Write:
|
||||||
{
|
{
|
||||||
// Write -> Initial -> Normal -> Secure
|
// Write -> Initial -> Normal -> Secure
|
||||||
DeactivateAndChangeState();
|
DeactivateAndChangeState(DeactivateReason.Reason9);
|
||||||
_gc.Writer.ChangeMode(AsicMode.Read);
|
_gc.Writer.ChangeMode(AsicMode.Read);
|
||||||
|
|
||||||
Result res = ActivateGameCard();
|
Result res = ActivateGameCard();
|
||||||
|
@ -293,7 +310,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
case CardState.Secure:
|
case CardState.Secure:
|
||||||
{
|
{
|
||||||
// Normal/Secure -> Initial -> Write
|
// Normal/Secure -> Initial -> Write
|
||||||
DeactivateAndChangeState();
|
DeactivateAndChangeState(DeactivateReason.Reason9);
|
||||||
|
|
||||||
_gc.Writer.ChangeMode(AsicMode.Write);
|
_gc.Writer.ChangeMode(AsicMode.Write);
|
||||||
Result res = ActivateGameCardForWriter();
|
Result res = ActivateGameCardForWriter();
|
||||||
|
@ -623,12 +640,17 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
|
|
||||||
public Result Invalidate()
|
public Result Invalidate()
|
||||||
{
|
{
|
||||||
using var writeLock = new UniqueLock<ReaderWriterLock>(_rwLock);
|
InvalidateImpl(DeactivateReason.Reason1);
|
||||||
DeactivateAndChangeState();
|
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InvalidateImpl(DeactivateReason reason)
|
||||||
|
{
|
||||||
|
using var writeLock = new UniqueLock<ReaderWriterLock>(_rwLock);
|
||||||
|
DeactivateAndChangeState(reason);
|
||||||
|
}
|
||||||
|
|
||||||
public Result Operate(int operationId)
|
public Result Operate(int operationId)
|
||||||
{
|
{
|
||||||
var operation = (GameCardManagerOperationIdValue)operationId;
|
var operation = (GameCardManagerOperationIdValue)operationId;
|
||||||
|
@ -879,6 +901,9 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
Result res = _gc.GetErrorInfo(out outErrorInfo);
|
Result res = _gc.GetErrorInfo(out outErrorInfo);
|
||||||
if (res.IsFailure()) return res.Miss();
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
outErrorInfo.LastDeactivateReasonResult = _lastDeactivateReasonResult.Value;
|
||||||
|
outErrorInfo.LastDeactivateReason = (byte)_lastDeactivateReason;
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1033,7 +1058,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Invalidate().IgnoreResult();
|
InvalidateImpl(DeactivateReason.Reason2);
|
||||||
|
|
||||||
return ResultFs.GameCardFsCheckHandleInAcquireReadLock.Log();
|
return ResultFs.GameCardFsCheckHandleInAcquireReadLock.Log();
|
||||||
}
|
}
|
||||||
|
@ -1051,7 +1076,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
if (_state != CardState.Initial && !_gc.IsCardActivationValid())
|
if (_state != CardState.Initial && !_gc.IsCardActivationValid())
|
||||||
{
|
{
|
||||||
readLock.Unlock();
|
readLock.Unlock();
|
||||||
Invalidate().IgnoreResult();
|
InvalidateImpl(DeactivateReason.Reason3);
|
||||||
}
|
}
|
||||||
else if (_currentHandle == inOutHandle)
|
else if (_currentHandle == inOutHandle)
|
||||||
{
|
{
|
||||||
|
@ -1115,7 +1140,8 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
|
|
||||||
if (result.IsFailure())
|
if (result.IsFailure())
|
||||||
{
|
{
|
||||||
DeactivateAndChangeState();
|
DeactivateAndChangeState(DeactivateReason.Reason4);
|
||||||
|
_lastDeactivateReasonResult = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -1127,7 +1153,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
|
|
||||||
if (_state == CardState.Normal || _state == CardState.Secure)
|
if (_state == CardState.Normal || _state == CardState.Secure)
|
||||||
{
|
{
|
||||||
CheckGameCardAndDeactivate();
|
CheckGameCardAndDeactivate(DeactivateReason.Reason5);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (_state)
|
switch (_state)
|
||||||
|
@ -1144,7 +1170,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
break;
|
break;
|
||||||
case CardState.Write:
|
case CardState.Write:
|
||||||
{
|
{
|
||||||
DeactivateAndChangeState();
|
DeactivateAndChangeState(DeactivateReason.Reason9);
|
||||||
_gc.Writer.ChangeMode(AsicMode.Read);
|
_gc.Writer.ChangeMode(AsicMode.Read);
|
||||||
|
|
||||||
Result res = ActivateGameCard();
|
Result res = ActivateGameCard();
|
||||||
|
|
|
@ -9,12 +9,14 @@ namespace LibHac.SdmmcSrv;
|
||||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||||
internal class SdCardDetectionEventManager : CardDeviceDetectionEventManager
|
internal class SdCardDetectionEventManager : CardDeviceDetectionEventManager
|
||||||
{
|
{
|
||||||
|
public Port Port;
|
||||||
|
|
||||||
// LibHac addition
|
// LibHac addition
|
||||||
private readonly SdmmcApi _sdmmc;
|
private readonly SdmmcApi _sdmmc;
|
||||||
|
|
||||||
public SdCardDetectionEventManager(Port port, SdmmcApi sdmmc)
|
public SdCardDetectionEventManager(Port port, SdmmcApi sdmmc)
|
||||||
{
|
{
|
||||||
CallbackArgs.Port = port;
|
Port = port;
|
||||||
_sdmmc = sdmmc;
|
_sdmmc = sdmmc;
|
||||||
|
|
||||||
_sdmmc.RegisterSdCardDetectionEventCallback(port, DetectionEventCallback, CallbackArgs);
|
_sdmmc.RegisterSdCardDetectionEventCallback(port, DetectionEventCallback, CallbackArgs);
|
||||||
|
@ -22,7 +24,7 @@ internal class SdCardDetectionEventManager : CardDeviceDetectionEventManager
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
_sdmmc.UnregisterSdCardDetectionEventCallback(CallbackArgs.Port);
|
_sdmmc.UnregisterSdCardDetectionEventCallback(Port);
|
||||||
|
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -520,7 +520,8 @@ public class TypeLayoutTests
|
||||||
Assert.Equal(0x40, Unsafe.SizeOf<GameCardErrorReportInfo>());
|
Assert.Equal(0x40, Unsafe.SizeOf<GameCardErrorReportInfo>());
|
||||||
|
|
||||||
Assert.Equal(0x00, GetOffset(in s, in s.GameCardCrcErrorNum));
|
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(0x04, GetOffset(in s, in s.AsicCrcErrorNum));
|
||||||
Assert.Equal(0x06, GetOffset(in s, in s.Reserved6));
|
Assert.Equal(0x06, GetOffset(in s, in s.Reserved6));
|
||||||
Assert.Equal(0x08, GetOffset(in s, in s.RefreshNum));
|
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(0x2C, GetOffset(in s, in s.AwakenCount));
|
||||||
Assert.Equal(0x30, GetOffset(in s, in s.ReadCountFromInsert));
|
Assert.Equal(0x30, GetOffset(in s, in s.ReadCountFromInsert));
|
||||||
Assert.Equal(0x34, GetOffset(in s, in s.ReadCountFromAwaken));
|
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]
|
[Fact]
|
||||||
|
|
Loading…
Reference in a new issue