using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Helper;
using System.ComponentModel;
namespace Scsi
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public abstract class ModePage : IMarshalable
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private const byte PAGE_CODE_MASK = 0x3F;
protected ModePage(ModePageCode pageCode) : base() { this.PageCode = pageCode; }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private BitVector8 byte0;
/// <summary>For a Mode Sense command, indicates whether the mode page may be saved by the target in a nonvolatile, vendor specific location. Reserved for the Mode Select command.</summary>
[System.ComponentModel.Browsable(false)]
public bool ParametersSavable { get { return this.byte0[7]; } set { this.byte0[7] = value; } }
[System.ComponentModel.Browsable(false)]
public ModePageCode PageCode { get { return (ModePageCode)Bits.GetValueMask((byte)this.byte0, 0, PAGE_CODE_MASK); } private set { this.byte0 = (BitVector8)Bits.PutValueMask((byte)this.byte0, (byte)value, 0, PAGE_CODE_MASK); } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private byte _PageLength;
[System.ComponentModel.Browsable(false)]
public byte PageLength { get { return this._PageLength; } protected set { this._PageLength = value; } }
protected virtual void MarshalFrom(BufferWithSize buffer) { Marshaler.DefaultPtrToStructure(buffer, this); }
protected virtual void MarshalTo(BufferWithSize buffer) { this.PageLength = (byte)(Marshaler.SizeOf(this) - Marshaler.DefaultSizeOf<ModePage>()); Marshaler.DefaultStructureToPtr((object)this, buffer); }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected virtual int MarshaledSize { get { return Marshal.SizeOf(this); } }
void IMarshalable.MarshalFrom(BufferWithSize buffer) { this.MarshalFrom(buffer); }
void IMarshalable.MarshalTo(BufferWithSize buffer) { this.MarshalTo(buffer); }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
int IMarshalable.MarshaledSize { get { var size = this.MarshaledSize; this.PageLength = (byte)(size - Marshaler.DefaultSizeOf<ModePage>()); return size; } }
//public override string ToString() { return Internal.GenericToString(this, true); }
public static ModePage TryCreateInstance(ModePageCode pageCode)
{
switch (pageCode)
{
case ModePageCode.ReadWriteErrorRecoveryParameters:
return new ReadWriteErrorRecoveryParametersPage();
case ModePageCode.WriteParameters:
return new Multimedia.WriteParametersPage();
case ModePageCode.Caching:
return new CachingModePage();
case ModePageCode.CDDeviceParameters:
return new Multimedia.CDParametersPage();
case ModePageCode.CapabilitiesAndMechanicalStatus:
return new Multimedia.CapabilitiesMechanicalStatusPage();
default:
return null;
}
}
public static ModePage CreateInstance(ModePageCode pageCode) { var result = TryCreateInstance(pageCode); if (result == null) { throw new ArgumentOutOfRangeException("pageCode", pageCode, "Invalid mode page."); } return result; }
internal static ModePageCode ReadPageCode(IntPtr pBuffer) { unsafe { return (ModePageCode)Bits.GetValueMask(*(byte*)pBuffer, 0, PAGE_CODE_MASK); } }
public static ModePage FromBuffer(IntPtr pBuffer, int bufferLength) { var mp = CreateInstance(ReadPageCode(pBuffer)); Marshaler.PtrToStructure(new BufferWithSize(pBuffer, bufferLength), ref mp); return mp; }
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class ReadWriteErrorRecoveryParametersPage : ModePage
{
public ReadWriteErrorRecoveryParametersPage() : base(ModePageCode.ReadWriteErrorRecoveryParameters) { }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private BitVector8 errorRecoveryParameter;
public bool AutomaticWriteReallocationEnabled { get { return this.errorRecoveryParameter[7]; } set { this.errorRecoveryParameter[7] = value; } }
public bool AutomaticReadReallocationEnabled { get { return this.errorRecoveryParameter[6]; } set { this.errorRecoveryParameter[6] = value; } }
public bool TransferBlock { get { return this.errorRecoveryParameter[5]; } set { this.errorRecoveryParameter[5] = value; } }
public bool ReadContinuous { get { return this.errorRecoveryParameter[4]; } set { this.errorRecoveryParameter[4] = value; } }
public bool PostError { get { return this.errorRecoveryParameter[2]; } set { this.errorRecoveryParameter[2] = value; } }
public bool DisableTransferOnError { get { return this.errorRecoveryParameter[1]; } set { this.errorRecoveryParameter[1] = value; } }
public bool DisableCorrection { get { return this.errorRecoveryParameter[0]; } set { this.errorRecoveryParameter[0] = value; } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private byte _ReadRetryCount;
public byte ReadRetryCount { get { return this._ReadRetryCount; } set { this._ReadRetryCount = value; } }
private byte _CorrectionSpan;
private byte _HeadOffsetCount;
private byte _DataStrobeOffsetCount;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private byte byte7;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private byte _WriteRetryCount;
public byte WriteRetryCount { get { return this._WriteRetryCount; } set { this._WriteRetryCount = value; } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private byte byte9;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private ushort _RecoveryTimeLimit;
/// <summary>Should be zero.</summary>
public ushort RecoveryTimeLimit { get { return Bits.BigEndian(this._RecoveryTimeLimit); } set { this._RecoveryTimeLimit = Bits.BigEndian(value); } }
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class CachingModePage : ModePage
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private const byte DEMAND_READ_RETENTION_PRIORITY_MASK = 0xF0;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private const byte DEMAND_WRITE_RETENTION_PRIORITY_MASK = 0x0F;
public CachingModePage() : base(ModePageCode.Caching) { }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private BitVector8 byte2;
public bool InitiatorControl { get { return this.byte2[7]; } set { this.byte2[7] = value; } }
public bool AbortPrefetch { get { return this.byte2[6]; } set { this.byte2[6] = value; } }
public bool CacheAnalysisPermitted { get { return this.byte2[5]; } set { this.byte2[5] = value; } }
public bool Discontinuity { get { return this.byte2[4]; } set { this.byte2[4] = value; } }
public bool SizeEnable { get { return this.byte2[3]; } set { this.byte2[3] = value; } }
public bool WritebackCacheEnable { get { return this.byte2[2]; } set { this.byte2[2] = value; } }
public bool MultiplicationFactor { get { return this.byte2[1]; } set { this.byte2[1] = value; } }
public bool ReadCacheDisable { get { return this.byte2[0]; } set { this.byte2[0] = value; } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private byte byte3;
public DemandReadRetentionPriority DemandReadRetentionPriority
{
get { return (DemandReadRetentionPriority)Bits.GetValueMask((byte)this.byte3, 4, DEMAND_READ_RETENTION_PRIORITY_MASK); }
set { this.byte3 = Bits.PutValueMask(this.byte3, (byte)value, 4, DEMAND_READ_RETENTION_PRIORITY_MASK); }
}
public DemandWriteRetentionPriority DemandWriteRetentionPriority
{
get { return (DemandWriteRetentionPriority)Bits.GetValueMask((byte)this.byte3, 4, DEMAND_WRITE_RETENTION_PRIORITY_MASK); }
set { this.byte3 = Bits.PutValueMask(this.byte3, (byte)value, 4, DEMAND_WRITE_RETENTION_PRIORITY_MASK); }
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private ushort _DisablePrefetchTransferLength;
public ushort DisablePrefetchTransferLength { get { return Bits.BigEndian(this._DisablePrefetchTransferLength); } set { this._DisablePrefetchTransferLength = Bits.BigEndian(value); } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private ushort _MinimumPrefetch;
public ushort MinimumPrefetch { get { return Bits.BigEndian(this._MinimumPrefetch); } set { this._MinimumPrefetch = Bits.BigEndian(value); } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private ushort _MaximumPrefetch;
public ushort MaximumPrefetch { get { return Bits.BigEndian(this._MaximumPrefetch); } set { this._MaximumPrefetch = Bits.BigEndian(value); } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private ushort _MaximumPrefetchCeiling;
public ushort MaximumPrefetchCeiling { get { return Bits.BigEndian(this._MaximumPrefetchCeiling); } set { this._MaximumPrefetchCeiling = Bits.BigEndian(value); } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private BitVector8 byte12;
public bool ForceSequentialWrite { get { return this.byte12[7]; } set { this.byte12[7] = value; } }
public bool LogicalBlockCacheSegmentSize { get { return this.byte12[6]; } set { this.byte12[6] = value; } }
public bool DisableReadAhead { get { return this.byte12[5]; } set { this.byte12[5] = value; } }
public bool NonvolatileCacheDisabled { get { return this.byte12[0]; } set { this.byte12[0] = value; } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private byte _NumberOfCacheSegments;
public byte NumberOfCacheSegments { get { return this._NumberOfCacheSegments; } set { this._NumberOfCacheSegments = value; } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private ushort _CacheSegmentSize;
public ushort CacheSegmentSize { get { return Bits.BigEndian(this._CacheSegmentSize); } set { this._CacheSegmentSize = Bits.BigEndian(value); } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
#pragma warning disable 0169
private byte byte16;
#pragma warning restore 0169
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private byte _byte17; //MSB
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private byte _byte18;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private byte _byte19; //LSB
[Obsolete]
public uint NonCacheSegmentSize
{
get { unchecked { return (uint)this._byte19 | ((uint)this._byte18 << 8) | ((uint)this._byte17 << 16); } }
set { unchecked { this._byte19 = (byte)(value >> 0); this._byte18 = (byte)(value >> 8); this._byte17 = (byte)(value >> 16); } }
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class PowerConditionsModePage : ModePage
{
public PowerConditionsModePage() : base(ModePageCode.PowerConditions) { }
[DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
private byte byte2;
[DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
private BitVector8 byte3;
[DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
private bool IdleTimerActive { get { return this.byte3[1]; } set { this.byte3[1] = value; } }
[DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
private bool StandbyTimerActive { get { return this.byte3[0]; } set { this.byte3[0] = value; } }
[DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
private uint _IdleConditionTimer;
/// <summary>The inactivity time in 100 millisecond increments that the logical unit waits before transitioning to the idle power condition.</summary>
public uint? IdleConditionTimer { get { return this.IdleTimerActive ? Bits.BigEndian(this._IdleConditionTimer) : (uint?)null; } set { this.IdleTimerActive = value != null; this._IdleConditionTimer = Bits.BigEndian(value.GetValueOrDefault()); } }
public TimeSpan? IdleCondition { get { var timer = this.IdleConditionTimer; return TimeSpan.FromMilliseconds(timer.GetValueOrDefault() * 100); } set { this.IdleConditionTimer = value != null ? (uint)(value.Value.TotalMilliseconds / 100) : (uint?)0; } }
[DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
private uint _StandbyConditionTimer;
/// <summary>The inactivity time in 100 millisecond increments that the logical unit waits before transitioning to the standby power condition.</summary>
public uint? StandbyConditionTimer { get { return this.StandbyTimerActive ? Bits.BigEndian(this._StandbyConditionTimer) : (uint?)null; } set { this.StandbyTimerActive = value != null; this._StandbyConditionTimer = Bits.BigEndian(value.GetValueOrDefault()); } }
public TimeSpan? StandbyCondition { get { var timer = this.StandbyConditionTimer; return TimeSpan.FromMilliseconds(timer.GetValueOrDefault() * 100); } set { this.StandbyConditionTimer = value != null ? (uint)(value.Value.TotalMilliseconds / 100) : (uint?)0; } }
}
}