Allocate SENSE buffer only once.

This commit is contained in:
2025-08-22 19:57:09 +01:00
parent 8e2fdd91a6
commit e4f55d3b3c
73 changed files with 1892 additions and 2565 deletions

View File

@@ -43,7 +43,6 @@ public partial class Device
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="cdb">SCSI CDB</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="senseBuffer">Buffer with the SCSI sense</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="direction">SCSI command transfer direction</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
@@ -51,12 +50,12 @@ public partial class Device
/// <c>True</c> if SCSI command returned non-OK status and <paramref name="senseBuffer" /> contains
/// SCSI sense
/// </param>
public virtual int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
public virtual int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, uint timeout, ScsiDirection direction,
out double duration, out bool sense)
{
duration = 0;
sense = true;
senseBuffer = null;
duration = 0;
sense = true;
buffer = null;
return -1;
}

View File

@@ -53,18 +53,22 @@ public partial class Device : IDisposable
{
// Pointer to send CDB to device
protected unsafe void* CdbPtr;
protected unsafe void* SensePtr;
protected Device()
{
unsafe
{
CdbPtr = NativeMemory.AlignedAlloc(16, 64);
NativeMemory.Clear(CdbPtr, 16);
CdbPtr = NativeMemory.AlignedAlloc(16, 64);
SensePtr = NativeMemory.AlignedAlloc(64, 64);
NativeMemory.Clear(CdbPtr, 16);
NativeMemory.Clear(SensePtr, 64);
}
}
// Span to make pointer usable as data. Fixed size CDB is maximum 16 bytes. Variable size CDB is another problem.
public unsafe Span<byte> CdbBuffer => new(CdbPtr, 16);
public unsafe Span<byte> CdbBuffer => new(CdbPtr, 16);
public unsafe Span<byte> SenseBuffer => new(SensePtr, 64);
#region IDisposable Members
@@ -211,9 +215,8 @@ public partial class Device : IDisposable
if(string.IsNullOrEmpty(dev.Serial))
dev.Serial = dev.UsbSerialString;
else
{
foreach(char c in dev.Serial.Where(c => !char.IsControl(c))) dev.Serial = $"{dev.Serial}{c:X2}";
}
foreach(char c in dev.Serial.Where(c => !char.IsControl(c)))
dev.Serial = $"{dev.Serial}{c:X2}";
}
if(dev.IsFireWire)
@@ -225,9 +228,8 @@ public partial class Device : IDisposable
if(string.IsNullOrEmpty(dev.Serial))
dev.Serial = $"{dev.FirewireGuid:X16}";
else
{
foreach(char c in dev.Serial.Where(c => !char.IsControl(c))) dev.Serial = $"{dev.Serial}{c:X2}";
}
foreach(char c in dev.Serial.Where(c => !char.IsControl(c)))
dev.Serial = $"{dev.Serial}{c:X2}";
}
// Some optical drives are not getting the correct serial, and IDENTIFY PACKET DEVICE is blocked without

View File

@@ -46,7 +46,7 @@ public partial class Device
/// <param name="lba">SCSI Logical Block Address.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool AdaptecTranslate(out byte[] buffer, out byte[] senseBuffer, uint lba, uint timeout,
public bool AdaptecTranslate(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint timeout,
out double duration) =>
AdaptecTranslate(out buffer, out senseBuffer, false, lba, timeout, out duration);
@@ -57,13 +57,13 @@ public partial class Device
/// <param name="lba">SCSI Logical Block Address.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool AdaptecTranslate(out byte[] buffer, out byte[] senseBuffer, bool drive1, uint lba, uint timeout,
out double duration)
public bool AdaptecTranslate(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool drive1, uint lba,
uint timeout, out double duration)
{
buffer = new byte[8];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.AdaptecTranslate;
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
@@ -72,13 +72,7 @@ public partial class Device
if(drive1) cdb[1] += 0x20;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -93,7 +87,8 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool AdaptecSetErrorThreshold(byte threshold, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool AdaptecSetErrorThreshold(byte threshold, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration) =>
AdaptecSetErrorThreshold(threshold, out senseBuffer, false, timeout, out duration);
/// <summary>Sets the error threshold</summary>
@@ -103,14 +98,14 @@ public partial class Device
/// <param name="drive1">If set to <c>true</c> set the threshold from drive 1.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool AdaptecSetErrorThreshold(byte threshold, out byte[] senseBuffer, bool drive1, uint timeout,
public bool AdaptecSetErrorThreshold(byte threshold, out ReadOnlySpan<byte> senseBuffer, bool drive1, uint timeout,
out double duration)
{
byte[] buffer = new byte[1];
buffer[0] = threshold;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.AdaptecSetErrorThreshold;
@@ -118,13 +113,7 @@ public partial class Device
cdb[4] = 1;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.Out,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.Out, out duration, out bool sense);
Error = LastError != 0;
@@ -138,7 +127,8 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool AdaptecReadUsageCounter(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool AdaptecReadUsageCounter(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration) =>
AdaptecReadUsageCounter(out buffer, out senseBuffer, false, timeout, out duration);
/// <summary>Requests the usage, seek and error counters, and resets them</summary>
@@ -147,13 +137,13 @@ public partial class Device
/// <param name="drive1">If set to <c>true</c> get the counters from drive 1.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool AdaptecReadUsageCounter(out byte[] buffer, out byte[] senseBuffer, bool drive1, uint timeout,
out double duration)
public bool AdaptecReadUsageCounter(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool drive1,
uint timeout, out double duration)
{
buffer = new byte[9];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.AdaptecTranslate;
@@ -161,13 +151,7 @@ public partial class Device
cdb[4] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -181,24 +165,18 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool AdaptecWriteBuffer(byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool AdaptecWriteBuffer(byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration)
{
byte[] oneKBuffer = new byte[1024];
Array.Copy(buffer, 0, oneKBuffer, 0, buffer.Length < 1024 ? buffer.Length : 1024);
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.AdaptecWriteBuffer;
LastError = SendScsiCommand(cdb,
ref oneKBuffer,
out senseBuffer,
timeout,
ScsiDirection.Out,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref oneKBuffer, timeout, ScsiDirection.Out, out duration, out bool sense);
Error = LastError != 0;
@@ -212,22 +190,17 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool AdaptecReadBuffer(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool AdaptecReadBuffer(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
buffer = new byte[1024];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.AdaptecReadBuffer;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -45,13 +45,13 @@ public partial class Device
/// <param name="lba">Address.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ArchiveCorpRequestBlockAddress(out byte[] buffer, out byte[] senseBuffer, uint lba, uint timeout,
out double duration)
public bool ArchiveCorpRequestBlockAddress(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba,
uint timeout, out double duration)
{
buffer = new byte[3];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.ArchiveRequestBlockAddress;
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
@@ -59,13 +59,7 @@ public partial class Device
cdb[3] = (byte)(lba & 0xFF);
cdb[4] = 3;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -79,7 +73,7 @@ public partial class Device
/// <param name="lba">Logical Block Address, starting from 1.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ArchiveCorpSeekBlock(out byte[] senseBuffer, uint lba, uint timeout, out double duration) =>
public bool ArchiveCorpSeekBlock(out ReadOnlySpan<byte> senseBuffer, uint lba, uint timeout, out double duration) =>
ArchiveCorpSeekBlock(out senseBuffer, false, lba, timeout, out duration);
/// <summary>Positions the tape at the specified block address</summary>
@@ -88,13 +82,13 @@ public partial class Device
/// <param name="lba">Logical Block Address, starting from 1.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ArchiveCorpSeekBlock(out byte[] senseBuffer, bool immediate, uint lba, uint timeout,
out double duration)
public bool ArchiveCorpSeekBlock(out ReadOnlySpan<byte> senseBuffer, bool immediate, uint lba, uint timeout,
out double duration)
{
byte[] buffer = [];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.ArchiveSeekBlock;
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
@@ -103,13 +97,7 @@ public partial class Device
if(immediate) cdb[1] += 0x01;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -43,14 +43,14 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool CertancePark(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool CertancePark(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
CertanceParkUnpark(out senseBuffer, true, timeout, out duration);
/// <summary>Unparks the load arm prior to operation</summary>
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool CertanceUnpark(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool CertanceUnpark(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
CertanceParkUnpark(out senseBuffer, false, timeout, out duration);
/// <summary>Parks the load arm in preparation for transport or unparks it prior to operation</summary>
@@ -58,24 +58,18 @@ public partial class Device
/// <param name="park">If set to <c>true</c>, parks the load arm</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool CertanceParkUnpark(out byte[] senseBuffer, bool park, uint timeout, out double duration)
public bool CertanceParkUnpark(out ReadOnlySpan<byte> senseBuffer, bool park, uint timeout, out double duration)
{
byte[] buffer = [];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.CertanceParkUnpark;
if(park) cdb[4] = 1;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -48,8 +48,8 @@ public partial class Device
/// <param name="timeout">Timeout to wait for command execution</param>
/// <param name="duration">Time the device took to execute the command in milliseconds</param>
/// <returns><c>true</c> if the device set an error condition, <c>false</c> otherwise</returns>
public bool FujitsuDisplay(out byte[] senseBuffer, bool flash, FujitsuDisplayModes mode, string firstHalf,
string secondHalf, uint timeout, out double duration)
public bool FujitsuDisplay(out ReadOnlySpan<byte> senseBuffer, bool flash, FujitsuDisplayModes mode,
string firstHalf, string secondHalf, uint timeout, out double duration)
{
byte[] tmp;
byte[] firstHalfBytes = new byte[8];
@@ -58,6 +58,7 @@ public partial class Device
bool displayLen = false;
bool halfMsg = false;
Span<byte> cdb = CdbBuffer[..10];
senseBuffer = SenseBuffer;
cdb.Clear();
if(!string.IsNullOrWhiteSpace(firstHalf))
@@ -98,13 +99,7 @@ public partial class Device
cdb[0] = (byte)ScsiCommands.FujitsuDisplay;
cdb[6] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.Out,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.Out, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -53,14 +53,14 @@ public partial class Device
/// <param name="transferLength">How many blocks to read.</param>
/// <param name="layerbreak">The address in which the layerbreak occur</param>
/// <param name="otp">Set to <c>true</c> if disk is Opposite Track Path (OTP)</param>
public bool HlDtStReadRawDvd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength, uint timeout,
out double duration, uint layerbreak, bool otp)
public bool HlDtStReadRawDvd(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint transferLength,
uint timeout, out double duration, uint layerbreak, bool otp)
{
// We need to fill the buffer before reading it with the HL-DT-ST command. We don't care about sense,
// because the data can be wrong anyway, so we check the buffer data later instead.
Read12(out _, out _, 0, false, false, false, false, lba, 2048, 0, 16, false, timeout, out duration);
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
buffer = new byte[2064 * transferLength];
@@ -79,13 +79,7 @@ public partial class Device
cdb[10] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[11] = (byte)(buffer.Length & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -49,8 +49,8 @@ public partial class Device
/// <param name="pba">If set to <c>true</c> address contain physical block address.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool HpReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address, ushort blockBytes,
bool pba, uint timeout, out double duration) =>
public bool HpReadLong(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool relAddr, uint address,
ushort blockBytes, bool pba, uint timeout, out double duration) =>
HpReadLong(out buffer, out senseBuffer, relAddr, address, 0, blockBytes, pba, false, timeout, out duration);
/// <summary>Sends the HP READ LONG vendor command</summary>
@@ -68,10 +68,11 @@ public partial class Device
/// </param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool HpReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address, ushort transferLen,
ushort blockBytes, bool pba, bool sectorCount, uint timeout, out double duration)
public bool HpReadLong(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool relAddr, uint address,
ushort transferLen, ushort blockBytes, bool pba, bool sectorCount, uint timeout,
out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -92,13 +93,7 @@ public partial class Device
buffer = sectorCount ? new byte[blockBytes * transferLen] : new byte[transferLen];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -42,9 +42,9 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool KreonDeprecatedUnlock(out byte[] senseBuffer, uint timeout, out double duration)
public bool KreonDeprecatedUnlock(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = [];
@@ -54,13 +54,7 @@ public partial class Device
cdb[2] = 0x01;
cdb[3] = 0x01;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -74,7 +68,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool KreonLock(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool KreonLock(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
KreonSetLockState(out senseBuffer, KreonLockStates.Locked, timeout, out duration);
/// <summary>Sets the drive to the xtreme unlocked state</summary>
@@ -82,7 +76,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool KreonUnlockXtreme(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool KreonUnlockXtreme(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
KreonSetLockState(out senseBuffer, KreonLockStates.Xtreme, timeout, out duration);
/// <summary>Sets the drive to the wxripper unlocked state</summary>
@@ -90,7 +84,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool KreonUnlockWxripper(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool KreonUnlockWxripper(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
KreonSetLockState(out senseBuffer, KreonLockStates.Wxripper, timeout, out duration);
/// <summary>Sets the drive to the specified lock state</summary>
@@ -99,9 +93,10 @@ public partial class Device
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
/// <param name="state">Lock state</param>
public bool KreonSetLockState(out byte[] senseBuffer, KreonLockStates state, uint timeout, out double duration)
public bool KreonSetLockState(out ReadOnlySpan<byte> senseBuffer, KreonLockStates state, uint timeout,
out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = [];
@@ -112,13 +107,7 @@ public partial class Device
cdb[3] = 0x11;
cdb[4] = (byte)state;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -133,10 +122,10 @@ public partial class Device
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
/// <param name="features">Features supported by drive.</param>
public bool KreonGetFeatureList(out byte[] senseBuffer, out KreonFeatures features, uint timeout,
out double duration)
public bool KreonGetFeatureList(out ReadOnlySpan<byte> senseBuffer, out KreonFeatures features, uint timeout,
out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = new byte[26];
@@ -147,13 +136,7 @@ public partial class Device
cdb[2] = 0x01;
cdb[3] = 0x10;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -224,13 +207,13 @@ public partial class Device
/// <param name="duration">Duration.</param>
/// <param name="buffer">The SS sector.</param>
/// <param name="requestNumber">Request number.</param>
public bool KreonExtractSs(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration,
public bool KreonExtractSs(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration,
byte requestNumber = 0x00)
{
buffer = new byte[2048];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.KreonSsCommand;
cdb[1] = 0x00;
@@ -245,13 +228,7 @@ public partial class Device
cdb[10] = requestNumber;
cdb[11] = 0xC0;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -50,8 +50,8 @@ public partial class Device
/// <param name="transferLength">How many blocks to read.</param>
/// <param name="layerbreak">The address in which the layerbreak occur</param>
/// <param name="otp">Set to <c>true</c> if disk is Opposite Track Path (OTP)</param>
public bool LiteOnReadRawDvd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength, uint timeout,
out double duration, uint layerbreak, bool otp)
public bool LiteOnReadRawDvd(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint transferLength,
uint timeout, out double duration, uint layerbreak, bool otp)
{
_bufferOffset %= 714;
@@ -61,7 +61,7 @@ public partial class Device
{
buffer = new byte[transferLength * 2064];
duration = 0;
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
return true;
}
@@ -107,14 +107,14 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="lba">Start block address.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
private bool LiteOnReadBuffer(out byte[] buffer, out byte[] senseBuffer, uint bufferOffset, uint transferLength,
uint timeout, out double duration, uint lba)
private bool LiteOnReadBuffer(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint bufferOffset,
uint transferLength, uint timeout, out double duration, uint lba)
{
// We need to fill the buffer before reading it with the ReadBuffer command. We don't care about sense,
// because the data can be wrong anyway, so we check the buffer data later instead.
Read12(out _, out _, 0, false, false, false, false, lba, 2048, 0, 16, false, timeout, out duration);
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -130,13 +130,7 @@ public partial class Device
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
return sense;
}
@@ -153,8 +147,9 @@ public partial class Device
/// <param name="transferLength">How many blocks to read.</param>
/// <param name="layerbreak">The address in which the layerbreak occur</param>
/// <param name="otp">Set to <c>true</c> if disk is Opposite Track Path (OTP)</param>
private bool LiteOnReadSectorsFromBuffer(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength,
uint timeout, out double duration, uint layerbreak, bool otp)
private bool LiteOnReadSectorsFromBuffer(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba,
uint transferLength, uint timeout, out double duration, uint layerbreak,
bool otp)
{
bool sense = LiteOnReadBuffer(out buffer,
out senseBuffer,
@@ -210,15 +205,15 @@ public partial class Device
/// <param name="transferLength">How many blocks to read.</param>
/// <param name="layerbreak">The address in which the layerbreak occur</param>
/// <param name="otp">Set to <c>true</c> if disk is Opposite Track Path (OTP)</param>
private bool LiteOnReadSectorsAcrossBufferBorder(out byte[] buffer, out byte[] senseBuffer, uint lba,
uint transferLength, uint timeout, out double duration,
uint layerbreak, bool otp)
private bool LiteOnReadSectorsAcrossBufferBorder(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba,
uint transferLength, uint timeout, out double duration,
uint layerbreak, bool otp)
{
uint newTransferLength1 = 714 - _bufferOffset;
uint newTransferLength2 = transferLength - newTransferLength1;
bool sense1 = LiteOnReadBuffer(out byte[] buffer1,
out byte[] _,
out _,
_bufferOffset * 2384,
newTransferLength1 * 2384,
timeout,
@@ -226,14 +221,14 @@ public partial class Device
lba);
bool sense2 = LiteOnReadBuffer(out byte[] buffer2,
out byte[] _,
out _,
0,
newTransferLength2 * 2384,
timeout,
out double duration2,
lba);
senseBuffer = new byte[64]; // TODO
senseBuffer = SenseBuffer; // TODO
buffer = new byte[2384 * transferLength];
Array.Copy(buffer1, buffer, buffer1.Length);
@@ -267,7 +262,7 @@ public partial class Device
{
for(uint i = 0; i < 714; i++)
{
LiteOnReadBuffer(out byte[] buffer, out byte[] _, i * 2384, 2384, timeout, out double _, lba);
LiteOnReadBuffer(out byte[] buffer, out _, i * 2384, 2384, timeout, out double _, lba);
if(CheckSectorNumber(buffer, lba, 1, layerbreak, otp)) return (int)i;
}

View File

@@ -48,7 +48,8 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool GetConfiguration(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration) =>
GetConfiguration(out buffer, out senseBuffer, 0x0000, MmcGetConfigurationRt.All, timeout, out duration);
/// <summary>Sends the MMC GET CONFIGURATION command for all Features starting with specified one</summary>
@@ -58,8 +59,8 @@ public partial class Device
/// <param name="startingFeatureNumber">Feature number where the feature list should start from</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber, uint timeout,
out double duration) =>
public bool GetConfiguration(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ushort startingFeatureNumber,
uint timeout, out double duration) =>
GetConfiguration(out buffer,
out senseBuffer,
startingFeatureNumber,
@@ -75,10 +76,10 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="startingFeatureNumber">Starting Feature number.</param>
/// <param name="rt">Return type, <see cref="MmcGetConfigurationRt" />.</param>
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber,
MmcGetConfigurationRt rt, uint timeout, out double duration)
public bool GetConfiguration(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ushort startingFeatureNumber,
MmcGetConfigurationRt rt, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[8];
@@ -91,13 +92,7 @@ public partial class Device
cdb[8] = (byte)(buffer.Length & 0xFF);
cdb[9] = 0;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -107,15 +102,9 @@ public partial class Device
buffer = new byte[confLength];
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
Error = LastError != 0;
@@ -142,11 +131,11 @@ public partial class Device
/// <param name="format">Which disc structure are we requesting</param>
/// <param name="agid">AGID used in medium copy protection</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadDiscStructure(out byte[] buffer, out byte[] senseBuffer, MmcDiscStructureMediaType mediaType,
uint address, byte layerNumber, MmcDiscStructureFormat format, byte agid,
uint timeout, out double duration)
public bool ReadDiscStructure(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer,
MmcDiscStructureMediaType mediaType, uint address, byte layerNumber,
MmcDiscStructureFormat format, byte agid, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
buffer = new byte[8];
@@ -163,13 +152,7 @@ public partial class Device
cdb[9] = (byte)(buffer.Length & 0xFF);
cdb[10] = (byte)((agid & 0x03) << 6);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -195,15 +178,9 @@ public partial class Device
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[9] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
Error = LastError != 0;
@@ -229,7 +206,8 @@ public partial class Device
/// <param name="track">Start TOC from this track</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadToc(out byte[] buffer, out byte[] senseBuffer, byte track, uint timeout, out double duration) =>
public bool ReadToc(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte track, uint timeout,
out double duration) =>
ReadTocPmaAtip(out buffer, out senseBuffer, true, 0, track, timeout, out duration);
/// <summary>Sends the MMC READ TOC/PMA/ATIP command to get formatted TOC from disc</summary>
@@ -240,7 +218,7 @@ public partial class Device
/// <param name="track">Start TOC from this track</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadToc(out byte[] buffer, out byte[] senseBuffer, bool msf, byte track, uint timeout,
public bool ReadToc(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool msf, byte track, uint timeout,
out double duration) =>
ReadTocPmaAtip(out buffer, out senseBuffer, msf, 0, track, timeout, out duration);
@@ -250,7 +228,8 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadSessionInfo(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool ReadSessionInfo(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration) =>
ReadTocPmaAtip(out buffer, out senseBuffer, true, 1, 0, timeout, out duration);
/// <summary>Sends the MMC READ TOC/PMA/ATIP command to get multi-session information</summary>
@@ -260,7 +239,7 @@ public partial class Device
/// <param name="msf">If <c>true</c>, request data in MM:SS:FF units, otherwise, in blocks</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadSessionInfo(out byte[] buffer, out byte[] senseBuffer, bool msf, uint timeout,
public bool ReadSessionInfo(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool msf, uint timeout,
out double duration) =>
ReadTocPmaAtip(out buffer, out senseBuffer, msf, 1, 0, timeout, out duration);
@@ -271,7 +250,7 @@ public partial class Device
/// <param name="sessionNumber">Session which TOC to get</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadRawToc(out byte[] buffer, out byte[] senseBuffer, byte sessionNumber, uint timeout,
public bool ReadRawToc(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte sessionNumber, uint timeout,
out double duration) =>
ReadTocPmaAtip(out buffer, out senseBuffer, true, 2, sessionNumber, timeout, out duration);
@@ -281,7 +260,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadPma(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool ReadPma(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
ReadTocPmaAtip(out buffer, out senseBuffer, true, 3, 0, timeout, out duration);
/// <summary>Sends the MMC READ TOC/PMA/ATIP command to get ATIP</summary>
@@ -290,7 +269,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadAtip(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool ReadAtip(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
ReadTocPmaAtip(out buffer, out senseBuffer, true, 4, 0, timeout, out duration);
/// <summary>Sends the MMC READ TOC/PMA/ATIP command to get Lead-In CD-TEXT</summary>
@@ -299,7 +278,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadCdText(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool ReadCdText(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
ReadTocPmaAtip(out buffer, out senseBuffer, true, 5, 0, timeout, out duration);
/// <summary>Sends the MMC READ TOC/PMA/ATIP command</summary>
@@ -311,10 +290,10 @@ public partial class Device
/// <param name="trackSessionNumber">Track/Session number</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadTocPmaAtip(out byte[] buffer, out byte[] senseBuffer, bool msf, byte format,
byte trackSessionNumber, uint timeout, out double duration)
public bool ReadTocPmaAtip(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool msf, byte format,
byte trackSessionNumber, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -329,13 +308,7 @@ public partial class Device
cdb[7] = (byte)((tmpBuffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(tmpBuffer.Length & 0xFF);
LastError = SendScsiCommand(cdb,
ref tmpBuffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref tmpBuffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -361,13 +334,7 @@ public partial class Device
double tmpDuration = duration;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
Error = LastError != 0;
@@ -392,7 +359,8 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadDiscInformation(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool ReadDiscInformation(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration) =>
ReadDiscInformation(out buffer,
out senseBuffer,
MmcDiscInformationDataTypes.DiscInformation,
@@ -406,10 +374,10 @@ public partial class Device
/// <param name="dataType">Which disc information to read</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadDiscInformation(out byte[] buffer, out byte[] senseBuffer, MmcDiscInformationDataTypes dataType,
uint timeout, out double duration)
public bool ReadDiscInformation(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer,
MmcDiscInformationDataTypes dataType, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] tmpBuffer = new byte[804];
@@ -419,13 +387,7 @@ public partial class Device
cdb[7] = (byte)((tmpBuffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(tmpBuffer.Length & 0xFF);
LastError = SendScsiCommand(cdb,
ref tmpBuffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref tmpBuffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -464,12 +426,12 @@ public partial class Device
/// <param name="edcEcc">If set to <c>true</c> we request the EDC/ECC fields for data sectors.</param>
/// <param name="c2Error">C2 error options.</param>
/// <param name="subchannel">Subchannel selection.</param>
public bool ReadCd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint transferLength,
MmcSectorTypes expectedSectorType, bool dap, bool relAddr, bool sync, MmcHeaderCodes headerCodes,
bool userData, bool edcEcc, MmcErrorField c2Error, MmcSubchannel subchannel, uint timeout,
out double duration)
public bool ReadCd(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint blockSize,
uint transferLength, MmcSectorTypes expectedSectorType, bool dap, bool relAddr, bool sync,
MmcHeaderCodes headerCodes, bool userData, bool edcEcc, MmcErrorField c2Error,
MmcSubchannel subchannel, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -500,13 +462,7 @@ public partial class Device
buffer = new byte[blockSize * transferLength];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -549,12 +505,12 @@ public partial class Device
/// <param name="edcEcc">If set to <c>true</c> we request the EDC/ECC fields for data sectors.</param>
/// <param name="c2Error">C2 error options.</param>
/// <param name="subchannel">Subchannel selection.</param>
public bool ReadCdMsf(out byte[] buffer, out byte[] senseBuffer, uint startMsf, uint endMsf, uint blockSize,
MmcSectorTypes expectedSectorType, bool dap, bool sync, MmcHeaderCodes headerCodes,
bool userData, bool edcEcc, MmcErrorField c2Error, MmcSubchannel subchannel, uint timeout,
out double duration)
public bool ReadCdMsf(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint startMsf, uint endMsf,
uint blockSize, MmcSectorTypes expectedSectorType, bool dap, bool sync,
MmcHeaderCodes headerCodes, bool userData, bool edcEcc, MmcErrorField c2Error,
MmcSubchannel subchannel, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -584,13 +540,7 @@ public partial class Device
buffer = new byte[blockSize * transferLength];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -620,7 +570,7 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool PreventMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool PreventMediumRemoval(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
PreventAllowMediumRemoval(out senseBuffer, false, true, timeout, out duration);
/// <summary>Allows ejection of the media inserted in the drive</summary>
@@ -628,7 +578,7 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool AllowMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool AllowMediumRemoval(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
PreventAllowMediumRemoval(out senseBuffer, false, false, timeout, out duration);
/// <summary>Prevents or allows ejection of the media inserted in the drive</summary>
@@ -638,10 +588,10 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool PreventAllowMediumRemoval(out byte[] senseBuffer, bool persistent, bool prevent, uint timeout,
out double duration)
public bool PreventAllowMediumRemoval(out ReadOnlySpan<byte> senseBuffer, bool persistent, bool prevent,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
@@ -652,13 +602,7 @@ public partial class Device
if(persistent) cdb[4] += 0x02;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -679,7 +623,7 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool LoadTray(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool LoadTray(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
StartStopUnit(out senseBuffer, false, 0, 0, false, true, true, timeout, out duration);
/// <summary>Ejects the media or its tray</summary>
@@ -687,7 +631,7 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool EjectTray(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool EjectTray(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
StartStopUnit(out senseBuffer, false, 0, 0, false, true, false, timeout, out duration);
/// <summary>Starts the drive's reading mechanism</summary>
@@ -695,7 +639,7 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool StartUnit(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool StartUnit(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
StartStopUnit(out senseBuffer, false, 0, 0, false, false, true, timeout, out duration);
/// <summary>Stops the drive's reading mechanism</summary>
@@ -703,7 +647,7 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool StopUnit(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool StopUnit(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
StartStopUnit(out senseBuffer, false, 0, 0, false, false, false, timeout, out duration);
/// <summary>Starts or stops the drive's reading mechanism or tray</summary>
@@ -717,10 +661,11 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool StartStopUnit(out byte[] senseBuffer, bool immediate, byte formatLayer, byte powerConditions,
bool changeFormatLayer, bool loadEject, bool start, uint timeout, out double duration)
public bool StartStopUnit(out ReadOnlySpan<byte> senseBuffer, bool immediate, byte formatLayer,
byte powerConditions, bool changeFormatLayer, bool loadEject, bool start, uint timeout,
out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
@@ -743,13 +688,7 @@ public partial class Device
cdb[4] += (byte)((powerConditions & 0x0F) << 4);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -777,9 +716,10 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
[SuppressMessage("ReSharper", "ShiftExpressionZeroLeftOperand")]
public bool ReadMcn(out string mcn, out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool ReadMcn(out string mcn, out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
mcn = null;
@@ -793,13 +733,7 @@ public partial class Device
buffer = new byte[23];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -823,10 +757,10 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
[SuppressMessage("ReSharper", "ShiftExpressionZeroLeftOperand")]
public bool ReadIsrc(byte trackNumber, out string isrc, out byte[] buffer, out byte[] senseBuffer, uint timeout,
out double duration)
public bool ReadIsrc(byte trackNumber, out string isrc, out byte[] buffer, out ReadOnlySpan<byte> senseBuffer,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
isrc = null;
@@ -841,13 +775,7 @@ public partial class Device
buffer = new byte[23];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -871,10 +799,10 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool SetCdSpeed(out byte[] senseBuffer, RotationalControl rotationalControl, ushort readSpeed,
ushort writeSpeed, uint timeout, out double duration)
public bool SetCdSpeed(out ReadOnlySpan<byte> senseBuffer, RotationalControl rotationalControl, ushort readSpeed,
ushort writeSpeed, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
byte[] buffer = [];
@@ -886,13 +814,7 @@ public partial class Device
cdb[4] = (byte)((writeSpeed & 0xFF00) >> 8);
cdb[5] = (byte)(writeSpeed & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -918,10 +840,10 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="open">Report information of non-closed tracks</param>
/// <param name="type">Type of information to retrieve</param>
public bool ReadTrackInformation(out byte[] buffer, out byte[] senseBuffer, bool open, TrackInformationType type,
uint address, uint timeout, out double duration)
public bool ReadTrackInformation(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool open,
TrackInformationType type, uint address, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[48];
@@ -937,13 +859,7 @@ public partial class Device
if(open) cdb[1] += 4;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -45,10 +45,10 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="offset">Starting offset in DRAM memory.</param>
/// <param name="length">How much data to retrieve from DRAM.</param>
public bool MediaTekReadDram(out byte[] buffer, out byte[] senseBuffer, uint offset, uint length, uint timeout,
out double duration)
public bool MediaTekReadDram(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint offset, uint length,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[length];
@@ -64,13 +64,7 @@ public partial class Device
cdb[8] = (byte)((length & 0xFF00) >> 8);
cdb[9] = (byte)(length & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -47,10 +47,11 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool MiniDiscReadDataTOC(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool MiniDiscReadDataTOC(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
const ushort transferLength = 2336;
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -61,13 +62,7 @@ public partial class Device
buffer = new byte[transferLength];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -83,11 +78,11 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool MiniDiscReadUserTOC(out byte[] buffer, out byte[] senseBuffer, uint sector, uint timeout,
public bool MiniDiscReadUserTOC(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint sector, uint timeout,
out double duration)
{
const ushort transferLength = 2336;
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -102,13 +97,7 @@ public partial class Device
buffer = new byte[transferLength];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -123,10 +112,10 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool MiniDiscD5(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool MiniDiscD5(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration)
{
const ushort transferLength = 4;
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -137,13 +126,7 @@ public partial class Device
buffer = new byte[transferLength];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -158,9 +141,10 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool MiniDiscStopPlaying(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool MiniDiscStopPlaying(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -168,13 +152,7 @@ public partial class Device
buffer = [];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -189,10 +167,11 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool MiniDiscReadPosition(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool MiniDiscReadPosition(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
const ushort transferLength = 4;
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -203,13 +182,7 @@ public partial class Device
buffer = new byte[transferLength];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -224,10 +197,11 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
public bool MiniDiscGetType(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool MiniDiscGetType(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
const ushort transferLength = 8;
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -238,13 +212,7 @@ public partial class Device
buffer = new byte[transferLength];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -45,10 +45,10 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="lba">Start block address.</param>
/// <param name="transferLength">How many blocks to read.</param>
public bool NecReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength, uint timeout,
out double duration)
public bool NecReadCdDa(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint transferLength,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -62,13 +62,7 @@ public partial class Device
buffer = new byte[2352 * transferLength];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -58,11 +58,11 @@ public partial class Device
/// </param>
/// <param name="requested">Number of contiguous blocks to find</param>
/// <param name="foundLba">First LBA found</param>
public bool MediumScan(out byte[] senseBuffer, bool written, bool advancedScan, bool reverse, bool partial,
bool relAddr, uint lba, uint requested, uint scanLength, out uint foundLba,
out uint foundBlocks, uint timeout, out double duration)
public bool MediumScan(out ReadOnlySpan<byte> senseBuffer, bool written, bool advancedScan, bool reverse,
bool partial, bool relAddr, uint lba, uint requested, uint scanLength, out uint foundLba,
out uint foundBlocks, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = [];
@@ -102,7 +102,6 @@ public partial class Device
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
buffer.Length == 0 ? ScsiDirection.None : ScsiDirection.Out,
out duration,
@@ -114,7 +113,7 @@ public partial class Device
if(Error) return sense;
DecodedSense? decodedSense = Sense.Decode(senseBuffer);
DecodedSense? decodedSense = Sense.Decode(senseBuffer.ToArray());
switch(decodedSense?.SenseKey)
{

View File

@@ -47,10 +47,10 @@ public partial class Device
/// <param name="transferLength">How many blocks to read.</param>
/// <param name="blockSize">Block size.</param>
/// <param name="subchannel">Subchannel selection.</param>
public bool PioneerReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize,
public bool PioneerReadCdDa(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint blockSize,
uint transferLength, PioneerSubchannel subchannel, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -66,13 +66,7 @@ public partial class Device
buffer = new byte[blockSize * transferLength];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -91,10 +85,10 @@ public partial class Device
/// <param name="endMsf">End MM:SS:FF of read encoded as 0x00MMSSFF.</param>
/// <param name="blockSize">Block size.</param>
/// <param name="subchannel">Subchannel selection.</param>
public bool PioneerReadCdDaMsf(out byte[] buffer, out byte[] senseBuffer, uint startMsf, uint endMsf,
public bool PioneerReadCdDaMsf(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint startMsf, uint endMsf,
uint blockSize, PioneerSubchannel subchannel, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -110,13 +104,7 @@ public partial class Device
uint transferLength = (uint)((cdb[7] - cdb[3]) * 60 * 75 + (cdb[8] - cdb[4]) * 75 + (cdb[9] - cdb[5]));
buffer = new byte[blockSize * transferLength];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -138,10 +126,10 @@ public partial class Device
/// <param name="wholeSector">If set to <c>true</c>, returns all 2352 bytes of sector data.</param>
/// <param name="lba">Start block address.</param>
/// <param name="transferLength">How many blocks to read.</param>
public bool PioneerReadCdXa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength,
bool errorFlags, bool wholeSector, uint timeout, out double duration)
public bool PioneerReadCdXa(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint transferLength,
bool errorFlags, bool wholeSector, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -170,13 +158,7 @@ public partial class Device
cdb[6] = 0x00;
}
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -49,8 +49,8 @@ public partial class Device
/// <param name="pba">If set to <c>true</c> address contain physical block address.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool PlasmonReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address,
ushort blockBytes, bool pba, uint timeout, out double duration) =>
public bool PlasmonReadLong(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool relAddr, uint address,
ushort blockBytes, bool pba, uint timeout, out double duration) =>
HpReadLong(out buffer, out senseBuffer, relAddr, address, 0, blockBytes, pba, false, timeout, out duration);
/// <summary>Sends the Plasmon READ LONG vendor command</summary>
@@ -68,8 +68,8 @@ public partial class Device
/// </param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool PlasmonReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address,
ushort transferLen, ushort blockBytes, bool pba, bool sectorCount, uint timeout,
public bool PlasmonReadLong(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool relAddr, uint address,
ushort transferLen, ushort blockBytes, bool pba, bool sectorCount, uint timeout,
out double duration) => HpReadLong(out buffer,
out senseBuffer,
relAddr,
@@ -89,10 +89,10 @@ public partial class Device
/// <param name="pba">If set to <c>true</c> address contain a physical block address.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool PlasmonReadSectorLocation(out byte[] buffer, out byte[] senseBuffer, uint address, bool pba,
public bool PlasmonReadSectorLocation(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint address, bool pba,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -106,13 +106,7 @@ public partial class Device
buffer = new byte[8];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -48,10 +48,10 @@ public partial class Device
/// <param name="transferLength">How many blocks to read.</param>
/// <param name="blockSize">Block size.</param>
/// <param name="subchannel">Subchannel selection.</param>
public bool PlextorReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize,
public bool PlextorReadCdDa(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint blockSize,
uint transferLength, PlextorSubchannel subchannel, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -68,13 +68,7 @@ public partial class Device
buffer = new byte[blockSize * transferLength];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -100,10 +94,10 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="lba">Start block address.</param>
/// <param name="transferLength">How many blocks to read.</param>
public bool PlextorReadRawDvd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength,
uint timeout, out double duration)
public bool PlextorReadRawDvd(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint transferLength,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[2064 * transferLength];
@@ -117,13 +111,7 @@ public partial class Device
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -138,23 +126,18 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorReadEepromCdr(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool PlextorReadEepromCdr(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
buffer = new byte[256];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorReadEeprom;
cdb[8] = 1;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -169,23 +152,18 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorReadEeprom(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool PlextorReadEeprom(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
buffer = new byte[512];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorReadEeprom;
cdb[8] = 2;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -202,11 +180,11 @@ public partial class Device
/// <param name="blockSize">How many bytes are in the EEPROM block</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorReadEepromBlock(out byte[] buffer, out byte[] senseBuffer, byte block, ushort blockSize,
uint timeout, out double duration)
public bool PlextorReadEepromBlock(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte block,
ushort blockSize, uint timeout, out double duration)
{
buffer = new byte[blockSize];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -216,13 +194,7 @@ public partial class Device
cdb[8] = (byte)((blockSize & 0xFF00) >> 8);
cdb[9] = (byte)(blockSize & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -239,11 +211,11 @@ public partial class Device
/// <param name="last">Last actual speed.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorGetSpeeds(out byte[] senseBuffer, out ushort selected, out ushort max, out ushort last,
uint timeout, out double duration)
public bool PlextorGetSpeeds(out ReadOnlySpan<byte> senseBuffer, out ushort selected, out ushort max,
out ushort last, uint timeout, out double duration)
{
byte[] buf = new byte[10];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -254,13 +226,7 @@ public partial class Device
cdb[0] = (byte)ScsiCommands.PlextorPoweRec;
cdb[9] = (byte)buf.Length;
LastError = SendScsiCommand(cdb,
ref buf,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buf, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -282,11 +248,11 @@ public partial class Device
/// <param name="speed">PoweRec recommended speed.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorGetPoweRec(out byte[] senseBuffer, out bool enabled, out ushort speed, uint timeout,
out double duration)
public bool PlextorGetPoweRec(out ReadOnlySpan<byte> senseBuffer, out bool enabled, out ushort speed, uint timeout,
out double duration)
{
byte[] buf = new byte[8];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -297,13 +263,7 @@ public partial class Device
cdb[1] = (byte)PlextorSubCommands.GetMode;
cdb[9] = (byte)buf.Length;
LastError = SendScsiCommand(cdb,
ref buf,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buf, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -323,10 +283,11 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorGetSilentMode(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool PlextorGetSilentMode(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
buffer = new byte[8];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -336,13 +297,7 @@ public partial class Device
cdb[3] = 4;
cdb[10] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -357,10 +312,11 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorGetGigaRec(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool PlextorGetGigaRec(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
buffer = new byte[8];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -369,13 +325,7 @@ public partial class Device
cdb[2] = (byte)PlextorSubCommands.GigaRec;
cdb[10] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -391,11 +341,11 @@ public partial class Device
/// <param name="dvd">Set if request is for DVD.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorGetVariRec(out byte[] buffer, out byte[] senseBuffer, bool dvd, uint timeout,
public bool PlextorGetVariRec(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool dvd, uint timeout,
out double duration)
{
buffer = new byte[8];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -409,13 +359,7 @@ public partial class Device
else
cdb[3] = 0x02;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -430,10 +374,11 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorGetSecuRec(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool PlextorGetSecuRec(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
buffer = new byte[8];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -441,13 +386,7 @@ public partial class Device
cdb[2] = (byte)PlextorSubCommands.SecuRec;
cdb[10] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -462,10 +401,11 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorGetSpeedRead(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool PlextorGetSpeedRead(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
buffer = new byte[8];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -474,13 +414,7 @@ public partial class Device
cdb[2] = (byte)PlextorSubCommands.SpeedRead;
cdb[10] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -495,10 +429,11 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorGetHiding(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool PlextorGetHiding(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
buffer = new byte[8];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -507,13 +442,7 @@ public partial class Device
cdb[2] = (byte)PlextorSubCommands.SessionHide;
cdb[9] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -529,11 +458,11 @@ public partial class Device
/// <param name="dualLayer">Set if bitset is for dual layer discs.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorGetBitsetting(out byte[] buffer, out byte[] senseBuffer, bool dualLayer, uint timeout,
out double duration)
public bool PlextorGetBitsetting(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool dualLayer,
uint timeout, out double duration)
{
buffer = new byte[8];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -547,13 +476,7 @@ public partial class Device
else
cdb[3] = (byte)PlextorSubCommands.BitSetR;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -568,10 +491,11 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool PlextorGetTestWriteDvdPlus(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool PlextorGetTestWriteDvdPlus(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
buffer = new byte[8];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -580,13 +504,7 @@ public partial class Device
cdb[2] = (byte)PlextorSubCommands.TestWriteDvdPlus;
cdb[10] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -45,7 +45,7 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="lba">Starting block.</param>
/// <param name="blockSize">Block size in bytes.</param>
public bool Read6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout,
public bool Read6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint blockSize, uint timeout,
out double duration) =>
Read6(out buffer, out senseBuffer, lba, blockSize, 1, timeout, out duration);
@@ -58,10 +58,10 @@ public partial class Device
/// <param name="lba">Starting block.</param>
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="transferLength">How many blocks to read.</param>
public bool Read6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, byte transferLength,
uint timeout, out double duration)
public bool Read6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint blockSize,
byte transferLength, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
@@ -73,13 +73,7 @@ public partial class Device
buffer = transferLength == 0 ? new byte[256 * blockSize] : new byte[transferLength * blockSize];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -109,11 +103,11 @@ public partial class Device
/// <param name="groupNumber">Group number where attributes associated with this command should be collected.</param>
/// <param name="transferLength">How many blocks to read.</param>
/// <param name="relAddr">If set to <c>true</c> address is relative to current position.</param>
public bool Read10(out byte[] buffer, out byte[] senseBuffer, byte rdprotect, bool dpo, bool fua, bool fuaNv,
bool relAddr, uint lba, uint blockSize, byte groupNumber, ushort transferLength, uint timeout,
out double duration)
public bool Read10(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte rdprotect, bool dpo, bool fua,
bool fuaNv, bool relAddr, uint lba, uint blockSize, byte groupNumber, ushort transferLength,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -138,13 +132,7 @@ public partial class Device
buffer = new byte[transferLength * blockSize];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -175,11 +163,11 @@ public partial class Device
/// <param name="transferLength">How many blocks to read.</param>
/// <param name="streaming">If set to <c>true</c> the stream playback operation should be used (MMC only).</param>
/// <param name="relAddr">If set to <c>true</c> address is relative to current position.</param>
public bool Read12(out byte[] buffer, out byte[] senseBuffer, byte rdprotect, bool dpo, bool fua, bool fuaNv,
bool relAddr, uint lba, uint blockSize, byte groupNumber, uint transferLength, bool streaming,
uint timeout, out double duration)
public bool Read12(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte rdprotect, bool dpo, bool fua,
bool fuaNv, bool relAddr, uint lba, uint blockSize, byte groupNumber, uint transferLength,
bool streaming, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
@@ -208,13 +196,7 @@ public partial class Device
buffer = new byte[transferLength * blockSize];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -244,11 +226,11 @@ public partial class Device
/// <param name="groupNumber">Group number where attributes associated with this command should be collected.</param>
/// <param name="transferLength">How many blocks to read.</param>
/// <param name="streaming">If set to <c>true</c> the stream playback operation should be used (MMC only).</param>
public bool Read16(out byte[] buffer, out byte[] senseBuffer, byte rdprotect, bool dpo, bool fua, bool fuaNv,
ulong lba, uint blockSize, byte groupNumber, uint transferLength, bool streaming, uint timeout,
out double duration)
public bool Read16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte rdprotect, bool dpo, bool fua,
bool fuaNv, ulong lba, uint blockSize, byte groupNumber, uint transferLength, bool streaming,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..16];
cdb.Clear();
byte[] lbaBytes = BitConverter.GetBytes(lba);
@@ -280,13 +262,7 @@ public partial class Device
buffer = new byte[transferLength * blockSize];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -308,10 +284,10 @@ public partial class Device
/// How many bytes to read. If the number is not exactly the drive's size, the command will
/// fail and incidate a delta of the size in SENSE.
/// </param>
public bool ReadLong10(out byte[] buffer, out byte[] senseBuffer, bool correct, bool relAddr, uint lba,
ushort transferBytes, uint timeout, out double duration)
public bool ReadLong10(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool correct, bool relAddr, uint lba,
ushort transferBytes, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
@@ -330,13 +306,7 @@ public partial class Device
buffer = new byte[transferBytes];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -357,10 +327,10 @@ public partial class Device
/// How many bytes to read. If the number is not exactly the drive's size, the command will
/// fail and incidate a delta of the size in SENSE.
/// </param>
public bool ReadLong16(out byte[] buffer, out byte[] senseBuffer, bool correct, ulong lba, uint transferBytes,
uint timeout, out double duration)
public bool ReadLong16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool correct, ulong lba,
uint transferBytes, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..16];
cdb.Clear();
byte[] lbaBytes = BitConverter.GetBytes(lba);
@@ -382,13 +352,7 @@ public partial class Device
buffer = new byte[transferBytes];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -402,9 +366,9 @@ public partial class Device
/// <param name="lba">LBA.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Seek6(out byte[] senseBuffer, uint lba, uint timeout, out double duration)
public bool Seek6(out ReadOnlySpan<byte> senseBuffer, uint lba, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
@@ -414,13 +378,7 @@ public partial class Device
cdb[2] = (byte)((lba & 0xFF00) >> 8);
cdb[3] = (byte)(lba & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -434,9 +392,9 @@ public partial class Device
/// <param name="lba">LBA.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Seek10(out byte[] senseBuffer, uint lba, uint timeout, out double duration)
public bool Seek10(out ReadOnlySpan<byte> senseBuffer, uint lba, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = [];
@@ -447,13 +405,7 @@ public partial class Device
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -49,14 +49,14 @@ public partial class Device
/// <param name="cache">If set to <c>true</c> device can return cached data.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, ushort element,
byte elementType, byte volume, byte partition, ushort firstAttribute, bool cache,
uint timeout, out double duration)
public bool ReadAttribute(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ScsiAttributeAction action,
ushort element, byte elementType, byte volume, byte partition, ushort firstAttribute,
bool cache, uint timeout, out double duration)
{
buffer = new byte[256];
Span<byte> cdb = CdbBuffer[..16];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.ReadAttribute;
cdb[1] = (byte)((byte)action & 0x1F);
@@ -74,13 +74,7 @@ public partial class Device
if(cache) cdb[14] += 0x01;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -92,15 +86,9 @@ public partial class Device
cdb[11] = (byte)((buffer.Length & 0xFF0000) >> 16);
cdb[12] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[13] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
Error = LastError != 0;

View File

@@ -47,7 +47,7 @@ public partial class Device
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
/// <param name="buffer">Buffer where the SCSI INQUIRY response will be stored</param>
/// <param name="senseBuffer">Sense buffer.</param>
public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer) =>
public bool ScsiInquiry(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer) =>
ScsiInquiry(out buffer, out senseBuffer, Timeout);
/// <summary>Sends the SPC INQUIRY command to the device using default device timeout.</summary>
@@ -55,7 +55,7 @@ public partial class Device
/// <param name="buffer">Buffer where the SCSI INQUIRY response will be stored</param>
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, out double duration) =>
public bool ScsiInquiry(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, out double duration) =>
ScsiInquiry(out buffer, out senseBuffer, Timeout, out duration);
/// <summary>Sends the SPC INQUIRY command to the device.</summary>
@@ -63,7 +63,7 @@ public partial class Device
/// <param name="buffer">Buffer where the SCSI INQUIRY response will be stored</param>
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, uint timeout) =>
public bool ScsiInquiry(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout) =>
ScsiInquiry(out buffer, out senseBuffer, timeout, out _);
/// <summary>Sends the SPC INQUIRY command to the device.</summary>
@@ -72,10 +72,10 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool ScsiInquiry(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration)
{
buffer = new byte[36];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
@@ -87,13 +87,7 @@ public partial class Device
cdb[4] = 36;
cdb[5] = 0;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -109,15 +103,9 @@ public partial class Device
cdb[5] = 0;
buffer = new byte[pagesLength];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
Error = LastError != 0;
@@ -134,7 +122,7 @@ public partial class Device
/// <param name="buffer">Buffer where the SCSI INQUIRY response will be stored</param>
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="page">The Extended Vital Product Data</param>
public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, byte page) =>
public bool ScsiInquiry(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte page) =>
ScsiInquiry(out buffer, out senseBuffer, page, Timeout);
/// <summary>
@@ -146,7 +134,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="page">The Extended Vital Product Data</param>
public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, byte page, out double duration) =>
public bool ScsiInquiry(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte page, out double duration) =>
ScsiInquiry(out buffer, out senseBuffer, page, Timeout, out duration);
/// <summary>Sends the SPC INQUIRY command to the device with an Extended Vital Product Data page.</summary>
@@ -155,7 +143,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="page">The Extended Vital Product Data</param>
public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, byte page, uint timeout) =>
public bool ScsiInquiry(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte page, uint timeout) =>
ScsiInquiry(out buffer, out senseBuffer, page, timeout, out _);
/// <summary>Sends the SPC INQUIRY command to the device with an Extended Vital Product Data page.</summary>
@@ -165,10 +153,11 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="page">The Extended Vital Product Data</param>
public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, byte page, uint timeout, out double duration)
public bool ScsiInquiry(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte page, uint timeout,
out double duration)
{
buffer = new byte[36];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
@@ -179,13 +168,7 @@ public partial class Device
cdb[4] = 36;
cdb[5] = 0;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -204,15 +187,9 @@ public partial class Device
cdb[5] = 0;
buffer = new byte[pagesLength];
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
Error = LastError != 0;
@@ -226,9 +203,9 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ScsiTestUnitReady(out byte[] senseBuffer, uint timeout, out double duration)
public bool ScsiTestUnitReady(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
@@ -237,13 +214,7 @@ public partial class Device
byte[] buffer = [];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -258,7 +229,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ModeSense(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool ModeSense(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
ModeSense6(out buffer, out senseBuffer, false, ScsiModeSensePageControl.Current, 0, 0, timeout, out duration);
/// <summary>Sends the SPC MODE SENSE(6) command to the device as introduced in SCSI-2</summary>
@@ -270,8 +241,8 @@ public partial class Device
/// <param name="dbd">If set to <c>true</c> device MUST not return any block descriptor.</param>
/// <param name="pageControl">Page control.</param>
/// <param name="pageCode">Page code.</param>
public bool ModeSense6(out byte[] buffer, out byte[] senseBuffer, bool dbd, ScsiModeSensePageControl pageControl,
byte pageCode, uint timeout, out double duration) =>
public bool ModeSense6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool dbd,
ScsiModeSensePageControl pageControl, byte pageCode, uint timeout, out double duration) =>
ModeSense6(out buffer, out senseBuffer, dbd, pageControl, pageCode, 0, timeout, out duration);
/// <summary>Sends the SPC MODE SENSE(6) command to the device as introduced in SCSI-3 SPC-3</summary>
@@ -284,10 +255,11 @@ public partial class Device
/// <param name="pageControl">Page control.</param>
/// <param name="pageCode">Page code.</param>
/// <param name="subPageCode">Sub-page code.</param>
public bool ModeSense6(out byte[] buffer, out byte[] senseBuffer, bool dbd, ScsiModeSensePageControl pageControl,
byte pageCode, byte subPageCode, uint timeout, out double duration)
public bool ModeSense6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool dbd,
ScsiModeSensePageControl pageControl, byte pageCode, byte subPageCode, uint timeout,
out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
buffer = new byte[254];
@@ -303,13 +275,7 @@ public partial class Device
cdb[4] = (byte)buffer.Length;
cdb[5] = 0;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -320,15 +286,9 @@ public partial class Device
buffer = new byte[modeLength];
cdb[4] = (byte)buffer.Length;
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
Error = LastError != 0;
@@ -346,8 +306,8 @@ public partial class Device
/// <param name="dbd">If set to <c>true</c> device MUST not return any block descriptor.</param>
/// <param name="pageControl">Page control.</param>
/// <param name="pageCode">Page code.</param>
public bool ModeSense10(out byte[] buffer, out byte[] senseBuffer, bool dbd, ScsiModeSensePageControl pageControl,
byte pageCode, uint timeout, out double duration) =>
public bool ModeSense10(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool dbd,
ScsiModeSensePageControl pageControl, byte pageCode, uint timeout, out double duration) =>
ModeSense10(out buffer, out senseBuffer, false, dbd, pageControl, pageCode, 0, timeout, out duration);
/// <summary>Sends the SPC MODE SENSE(10) command to the device as introduced in SCSI-3 SPC-2</summary>
@@ -360,7 +320,7 @@ public partial class Device
/// <param name="pageControl">Page control.</param>
/// <param name="pageCode">Page code.</param>
/// <param name="llbaa">If set means 64-bit LBAs are accepted by the caller.</param>
public bool ModeSense10(out byte[] buffer, out byte[] senseBuffer, bool llbaa, bool dbd,
public bool ModeSense10(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool llbaa, bool dbd,
ScsiModeSensePageControl pageControl, byte pageCode, uint timeout, out double duration) =>
ModeSense10(out buffer, out senseBuffer, llbaa, dbd, pageControl, pageCode, 0, timeout, out duration);
@@ -375,11 +335,11 @@ public partial class Device
/// <param name="pageCode">Page code.</param>
/// <param name="subPageCode">Sub-page code.</param>
/// <param name="llbaa">If set means 64-bit LBAs are accepted by the caller.</param>
public bool ModeSense10(out byte[] buffer, out byte[] senseBuffer, bool llbaa, bool dbd,
ScsiModeSensePageControl pageControl, byte pageCode, byte subPageCode, uint timeout,
public bool ModeSense10(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool llbaa, bool dbd,
ScsiModeSensePageControl pageControl, byte pageCode, byte subPageCode, uint timeout,
out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[4096];
@@ -397,13 +357,7 @@ public partial class Device
cdb[8] = (byte)(buffer.Length & 0xFF);
cdb[9] = 0;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -415,15 +369,9 @@ public partial class Device
buffer = new byte[modeLength];
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
Error = LastError != 0;
@@ -437,7 +385,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool SpcPreventMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool SpcPreventMediumRemoval(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
SpcPreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Prevent, timeout, out duration);
/// <summary>Sends the SPC PREVENT ALLOW MEDIUM REMOVAL command to allow medium removal</summary>
@@ -445,7 +393,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool SpcAllowMediumRemoval(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool SpcAllowMediumRemoval(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
SpcPreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Allow, timeout, out duration);
/// <summary>Sends the SPC PREVENT ALLOW MEDIUM REMOVAL command</summary>
@@ -454,7 +402,8 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="prevent"><c>true</c> to prevent medium removal, <c>false</c> to allow it.</param>
public bool SpcPreventAllowMediumRemoval(out byte[] senseBuffer, bool prevent, uint timeout, out double duration) =>
public bool SpcPreventAllowMediumRemoval(out ReadOnlySpan<byte> senseBuffer, bool prevent, uint timeout,
out double duration) =>
prevent
? SpcPreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Prevent, timeout, out duration)
: SpcPreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Allow, timeout, out duration);
@@ -465,10 +414,10 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="preventMode">Prevention mode.</param>
public bool SpcPreventAllowMediumRemoval(out byte[] senseBuffer, ScsiPreventAllowMode preventMode, uint timeout,
out double duration)
public bool SpcPreventAllowMediumRemoval(out ReadOnlySpan<byte> senseBuffer, ScsiPreventAllowMode preventMode,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
@@ -476,13 +425,7 @@ public partial class Device
cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval;
cdb[4] = (byte)((byte)preventMode & 0x03);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -497,7 +440,8 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadCapacity(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool
ReadCapacity(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
ReadCapacity(out buffer, out senseBuffer, false, 0, false, timeout, out duration);
/// <summary>Sends the SPC READ CAPACITY command</summary>
@@ -509,10 +453,10 @@ public partial class Device
/// <param name="pmi">If set, it is requesting partial media capacity</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadCapacity(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address, bool pmi,
uint timeout, out double duration)
public bool ReadCapacity(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool relAddr, uint address,
bool pmi, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[8];
@@ -531,13 +475,7 @@ public partial class Device
cdb[5] = (byte)(address & 0xFF);
}
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -552,7 +490,8 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadCapacity16(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool
ReadCapacity16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
ReadCapacity16(out buffer, out senseBuffer, 0, false, timeout, out duration);
/// <summary>Sends the SPC READ CAPACITY(16) command</summary>
@@ -563,10 +502,10 @@ public partial class Device
/// <param name="pmi">If set, it is requesting partial media capacity</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadCapacity16(out byte[] buffer, out byte[] senseBuffer, ulong address, bool pmi, uint timeout,
out double duration)
public bool ReadCapacity16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ulong address, bool pmi,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..16];
cdb.Clear();
buffer = new byte[32];
@@ -593,13 +532,7 @@ public partial class Device
cdb[12] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[13] = (byte)(buffer.Length & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -614,9 +547,10 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ReadMediaSerialNumber(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool ReadMediaSerialNumber(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
buffer = new byte[4];
@@ -628,13 +562,7 @@ public partial class Device
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[9] = (byte)(buffer.Length & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -646,15 +574,9 @@ public partial class Device
cdb[7] = (byte)((buffer.Length & 0xFF0000) >> 16);
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[9] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
Error = LastError != 0;
@@ -672,8 +594,8 @@ public partial class Device
/// <param name="cache">If set to <c>true</c> device can return cached data.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte partition,
ushort firstAttribute, bool cache, uint timeout, out double duration) =>
public bool ReadAttribute(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ScsiAttributeAction action,
byte partition, ushort firstAttribute, bool cache, uint timeout, out double duration) =>
ReadAttribute(out buffer,
out senseBuffer,
action,
@@ -694,8 +616,8 @@ public partial class Device
/// <param name="cache">If set to <c>true</c> device can return cached data.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action,
ushort firstAttribute, bool cache, uint timeout, out double duration) =>
public bool ReadAttribute(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ScsiAttributeAction action,
ushort firstAttribute, bool cache, uint timeout, out double duration) =>
ReadAttribute(out buffer, out senseBuffer, action, 0, 0, 0, 0, firstAttribute, cache, timeout, out duration);
/// <summary>Reads an attribute from the medium auxiliary memory</summary>
@@ -706,8 +628,8 @@ public partial class Device
/// <param name="firstAttribute">First attribute identifier.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte partition,
ushort firstAttribute, uint timeout, out double duration) =>
public bool ReadAttribute(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ScsiAttributeAction action,
byte partition, ushort firstAttribute, uint timeout, out double duration) =>
ReadAttribute(out buffer,
out senseBuffer,
action,
@@ -727,8 +649,8 @@ public partial class Device
/// <param name="firstAttribute">First attribute identifier.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action,
ushort firstAttribute, uint timeout, out double duration) =>
public bool ReadAttribute(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ScsiAttributeAction action,
ushort firstAttribute, uint timeout, out double duration) =>
ReadAttribute(out buffer, out senseBuffer, action, 0, 0, 0, 0, firstAttribute, false, timeout, out duration);
/// <summary>Reads an attribute from the medium auxiliary memory</summary>
@@ -740,8 +662,8 @@ public partial class Device
/// <param name="firstAttribute">First attribute identifier.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte volume,
byte partition, ushort firstAttribute, uint timeout, out double duration) =>
public bool ReadAttribute(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ScsiAttributeAction action,
byte volume, byte partition, ushort firstAttribute, uint timeout, out double duration) =>
ReadAttribute(out buffer,
out senseBuffer,
action,
@@ -764,19 +686,19 @@ public partial class Device
/// <param name="cache">If set to <c>true</c> device can return cached data.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte volume,
byte partition, ushort firstAttribute, bool cache, uint timeout, out double duration) =>
ReadAttribute(out buffer,
out senseBuffer,
action,
0,
0,
volume,
partition,
firstAttribute,
cache,
timeout,
out duration);
public bool ReadAttribute(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ScsiAttributeAction action,
byte volume, byte partition, ushort firstAttribute, bool cache, uint timeout,
out double duration) => ReadAttribute(out buffer,
out senseBuffer,
action,
0,
0,
volume,
partition,
firstAttribute,
cache,
timeout,
out duration);
/// <summary>Sends the SPC MODE SELECT(6) command</summary>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
@@ -786,10 +708,10 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="pageFormat">Set if page is formatted.</param>
public bool ModeSelect(byte[] buffer, out byte[] senseBuffer, bool pageFormat, bool savePages, uint timeout,
out double duration)
public bool ModeSelect(byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool pageFormat, bool savePages,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
// Prevent overflows
if(buffer.Length > 255)
@@ -821,13 +743,7 @@ public partial class Device
cdb[4] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.Out,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.Out, out duration, out bool sense);
Error = LastError != 0;
@@ -844,10 +760,10 @@ public partial class Device
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="pageFormat">Set if page is formatted.</param>
public bool ModeSelect10(byte[] buffer, out byte[] senseBuffer, bool pageFormat, bool savePages, uint timeout,
out double duration)
public bool ModeSelect10(byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool pageFormat, bool savePages,
uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
// Prevent overflows
if(buffer.Length > 65535)
@@ -878,13 +794,7 @@ public partial class Device
cdb[7] = (byte)((buffer.Length & 0xFF00) << 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.Out,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.Out, out duration, out bool sense);
Error = LastError != 0;
@@ -922,7 +832,7 @@ public partial class Device
cdb[4] = (byte)buffer.Length;
cdb[5] = 0;
LastError = SendScsiCommand(cdb, ref buffer, out _, timeout, ScsiDirection.In, out duration, out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -46,7 +46,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Load(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool Load(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
LoadUnload(out senseBuffer, false, true, false, false, false, timeout, out duration);
/// <summary>Prepares the medium for ejection</summary>
@@ -54,7 +54,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Unload(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool Unload(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
LoadUnload(out senseBuffer, false, false, false, false, false, timeout, out duration);
/// <summary>Prepares the medium for reading or ejection</summary>
@@ -70,10 +70,10 @@ public partial class Device
/// </param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool LoadUnload(out byte[] senseBuffer, bool immediate, bool load, bool retense, bool endOfTape, bool hold,
uint timeout, out double duration)
public bool LoadUnload(out ReadOnlySpan<byte> senseBuffer, bool immediate, bool load, bool retense, bool endOfTape,
bool hold, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
@@ -90,13 +90,7 @@ public partial class Device
if(hold) cdb[4] += 0x08;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -110,7 +104,7 @@ public partial class Device
/// <param name="lba">Logical block address.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Locate(out byte[] senseBuffer, uint lba, uint timeout, out double duration) =>
public bool Locate(out ReadOnlySpan<byte> senseBuffer, uint lba, uint timeout, out double duration) =>
Locate(out senseBuffer, false, false, false, 0, lba, timeout, out duration);
/// <summary>Positions the medium to the specified block in the specified partition</summary>
@@ -119,7 +113,8 @@ public partial class Device
/// <param name="lba">Logical block address.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Locate(out byte[] senseBuffer, byte partition, uint lba, uint timeout, out double duration) =>
public bool
Locate(out ReadOnlySpan<byte> senseBuffer, byte partition, uint lba, uint timeout, out double duration) =>
Locate(out senseBuffer, false, false, false, partition, lba, timeout, out duration);
/// <summary>Positions the medium to the specified block in the current partition</summary>
@@ -128,7 +123,8 @@ public partial class Device
/// <param name="lba">Logical block address.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Locate(out byte[] senseBuffer, bool immediate, uint lba, uint timeout, out double duration) =>
public bool Locate(out ReadOnlySpan<byte> senseBuffer, bool immediate, uint lba, uint timeout,
out double duration) =>
Locate(out senseBuffer, immediate, false, false, 0, lba, timeout, out duration);
/// <summary>Positions the medium to the specified block in the specified partition</summary>
@@ -138,15 +134,15 @@ public partial class Device
/// <param name="lba">Logical block address.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Locate(out byte[] senseBuffer, bool immediate, byte partition, uint lba, uint timeout,
out double duration) => Locate(out senseBuffer,
immediate,
false,
false,
partition,
lba,
timeout,
out duration);
public bool Locate(out ReadOnlySpan<byte> senseBuffer, bool immediate, byte partition, uint lba, uint timeout,
out double duration) => Locate(out senseBuffer,
immediate,
false,
false,
partition,
lba,
timeout,
out duration);
/// <summary>Positions the medium to the specified object identifier</summary>
/// <param name="senseBuffer">Sense buffer.</param>
@@ -157,10 +153,10 @@ public partial class Device
/// <param name="objectId">Object identifier.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Locate(out byte[] senseBuffer, bool immediate, bool blockType, bool changePartition, byte partition,
uint objectId, uint timeout, out double duration)
public bool Locate(out ReadOnlySpan<byte> senseBuffer, bool immediate, bool blockType, bool changePartition,
byte partition, uint objectId, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = [];
@@ -179,13 +175,7 @@ public partial class Device
cdb[6] = (byte)(objectId & 0xFF);
cdb[8] = partition;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -199,7 +189,7 @@ public partial class Device
/// <param name="lba">Logical block address.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Locate16(out byte[] senseBuffer, ulong lba, uint timeout, out double duration) =>
public bool Locate16(out ReadOnlySpan<byte> senseBuffer, ulong lba, uint timeout, out double duration) =>
Locate16(out senseBuffer, false, false, SscLogicalIdTypes.ObjectId, false, 0, lba, timeout, out duration);
/// <summary>Positions the medium to the specified block in the specified partition</summary>
@@ -208,16 +198,16 @@ public partial class Device
/// <param name="lba">Logical block address.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Locate16(out byte[] senseBuffer, byte partition, ulong lba, uint timeout, out double duration) =>
Locate16(out senseBuffer,
false,
false,
SscLogicalIdTypes.ObjectId,
false,
partition,
lba,
timeout,
out duration);
public bool Locate16(out ReadOnlySpan<byte> senseBuffer, byte partition, ulong lba, uint timeout,
out double duration) => Locate16(out senseBuffer,
false,
false,
SscLogicalIdTypes.ObjectId,
false,
partition,
lba,
timeout,
out duration);
/// <summary>Positions the medium to the specified block in the current partition</summary>
/// <param name="senseBuffer">Sense buffer.</param>
@@ -225,8 +215,16 @@ public partial class Device
/// <param name="lba">Logical block address.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Locate16(out byte[] senseBuffer, bool immediate, ulong lba, uint timeout, out double duration) =>
Locate16(out senseBuffer, immediate, false, SscLogicalIdTypes.ObjectId, false, 0, lba, timeout, out duration);
public bool Locate16(out ReadOnlySpan<byte> senseBuffer, bool immediate, ulong lba, uint timeout,
out double duration) => Locate16(out senseBuffer,
immediate,
false,
SscLogicalIdTypes.ObjectId,
false,
0,
lba,
timeout,
out duration);
/// <summary>Positions the medium to the specified block in the specified partition</summary>
/// <param name="senseBuffer">Sense buffer.</param>
@@ -235,16 +233,16 @@ public partial class Device
/// <param name="lba">Logical block address.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Locate16(out byte[] senseBuffer, bool immediate, byte partition, ulong lba, uint timeout,
out double duration) => Locate16(out senseBuffer,
immediate,
false,
SscLogicalIdTypes.ObjectId,
false,
partition,
lba,
timeout,
out duration);
public bool Locate16(out ReadOnlySpan<byte> senseBuffer, bool immediate, byte partition, ulong lba, uint timeout,
out double duration) => Locate16(out senseBuffer,
immediate,
false,
SscLogicalIdTypes.ObjectId,
false,
partition,
lba,
timeout,
out duration);
/// <summary>Positions the medium to the specified object identifier</summary>
/// <param name="senseBuffer">Sense buffer.</param>
@@ -256,10 +254,11 @@ public partial class Device
/// <param name="identifier">Destination identifier.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Locate16(out byte[] senseBuffer, bool immediate, bool changePartition, SscLogicalIdTypes destType,
bool bam, byte partition, ulong identifier, uint timeout, out double duration)
public bool Locate16(out ReadOnlySpan<byte> senseBuffer, bool immediate, bool changePartition,
SscLogicalIdTypes destType, bool bam, byte partition, ulong identifier, uint timeout,
out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..16];
cdb.Clear();
byte[] buffer = [];
@@ -285,13 +284,7 @@ public partial class Device
cdb[10] = idBytes[1];
cdb[11] = idBytes[0];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -309,7 +302,7 @@ public partial class Device
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Read6(out byte[] buffer, out byte[] senseBuffer, uint blocks, uint blockSize, uint timeout, out double duration)
public bool Read6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint blocks, uint blockSize, uint timeout, out double duration)
{
return Read6(out buffer, out senseBuffer, false, true, blocks, blockSize, timeout, out duration);
}*/
@@ -322,15 +315,9 @@ public partial class Device
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Read6(out byte[] buffer, out byte[] senseBuffer, bool sili, uint transferLen, uint blockSize,
uint timeout, out double duration) => Read6(out buffer,
out senseBuffer,
sili,
false,
transferLen,
blockSize,
timeout,
out duration);
public bool Read6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool sili, uint transferLen,
uint blockSize, uint timeout, out double duration) =>
Read6(out buffer, out senseBuffer, sili, false, transferLen, blockSize, timeout, out duration);
/// <summary>Reads the specified number of bytes or of blocks from the medium</summary>
/// <param name="buffer">Buffer.</param>
@@ -347,13 +334,13 @@ public partial class Device
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Read6(out byte[] buffer, out byte[] senseBuffer, bool sili, bool fixedLen, uint transferLen,
uint blockSize, uint timeout, out double duration)
public bool Read6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool sili, bool fixedLen, uint transferLen,
uint blockSize, uint timeout, out double duration)
{
buffer = fixedLen ? new byte[blockSize * transferLen] : new byte[transferLen];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.Read6;
@@ -365,13 +352,7 @@ public partial class Device
cdb[3] = (byte)((transferLen & 0xFF00) >> 8);
cdb[4] = (byte)(transferLen & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -389,8 +370,8 @@ public partial class Device
/// <param name="blockSize">Object size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Read16(out byte[] buffer, out byte[] senseBuffer, bool sili, ulong objectId, uint blocks,
uint blockSize, uint timeout, out double duration) =>
public bool Read16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool sili, ulong objectId, uint blocks,
uint blockSize, uint timeout, out double duration) =>
Read16(out buffer, out senseBuffer, sili, false, 0, objectId, blocks, blockSize, timeout, out duration);
/// <summary>Reads a number of fixed-length blocks starting at specified block from the specified partition</summary>
@@ -403,8 +384,8 @@ public partial class Device
/// <param name="blockSize">Object size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Read16(out byte[] buffer, out byte[] senseBuffer, bool sili, byte partition, ulong objectId,
uint blocks, uint blockSize, uint timeout, out double duration) =>
public bool Read16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool sili, byte partition, ulong objectId,
uint blocks, uint blockSize, uint timeout, out double duration) =>
Read16(out buffer, out senseBuffer, sili, false, partition, objectId, blocks, blockSize, timeout, out duration);
/// <summary>Reads a number of fixed-length blocks starting at specified object</summary>
@@ -415,17 +396,9 @@ public partial class Device
/// <param name="blockSize">Object size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Read16(out byte[] buffer, out byte[] senseBuffer, ulong objectId, uint blocks, uint blockSize,
uint timeout, out double duration) => Read16(out buffer,
out senseBuffer,
false,
true,
0,
objectId,
blocks,
blockSize,
timeout,
out duration);
public bool Read16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ulong objectId, uint blocks,
uint blockSize, uint timeout, out double duration) =>
Read16(out buffer, out senseBuffer, false, true, 0, objectId, blocks, blockSize, timeout, out duration);
/// <summary>Reads a number of fixed-length blocks starting at specified block from the specified partition</summary>
/// <param name="buffer">Buffer.</param>
@@ -436,8 +409,8 @@ public partial class Device
/// <param name="blockSize">Object size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Read16(out byte[] buffer, out byte[] senseBuffer, byte partition, ulong objectId, uint blocks,
uint blockSize, uint timeout, out double duration) =>
public bool Read16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte partition, ulong objectId,
uint blocks, uint blockSize, uint timeout, out double duration) =>
Read16(out buffer, out senseBuffer, false, true, partition, objectId, blocks, blockSize, timeout, out duration);
/// <summary>Reads a number of bytes or objects starting at specified object from the specified partition</summary>
@@ -457,13 +430,13 @@ public partial class Device
/// <param name="objectSize">Object size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Read16(out byte[] buffer, out byte[] senseBuffer, bool sili, bool fixedLen, byte partition,
ulong objectId, uint transferLen, uint objectSize, uint timeout, out double duration)
public bool Read16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool sili, bool fixedLen, byte partition,
ulong objectId, uint transferLen, uint objectSize, uint timeout, out double duration)
{
buffer = fixedLen ? new byte[objectSize * transferLen] : new byte[transferLen];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
byte[] idBytes = BitConverter.GetBytes(objectId);
cdb[0] = (byte)ScsiCommands.Read16;
@@ -485,13 +458,7 @@ public partial class Device
cdb[13] = (byte)((transferLen & 0xFF00) >> 8);
cdb[14] = (byte)(transferLen & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -505,22 +472,17 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadBlockLimits(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
public bool ReadBlockLimits(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration)
{
buffer = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.ReadBlockLimits;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -534,7 +496,8 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadPosition(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool
ReadPosition(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
ReadPosition(out buffer, out senseBuffer, SscPositionForms.Short, timeout, out duration);
/// <summary>Reports current reading/writing elements position on the medium using 32 bytes response</summary>
@@ -542,7 +505,8 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadPositionLong(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool ReadPositionLong(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration) =>
ReadPosition(out buffer, out senseBuffer, SscPositionForms.Long, timeout, out duration);
/// <summary>Reports current reading/writing elements position on the medium</summary>
@@ -553,8 +517,8 @@ public partial class Device
/// <param name="totalPosition">Requests current logical position.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadPosition(out byte[] buffer, out byte[] senseBuffer, bool vendorType, bool longForm,
bool totalPosition, uint timeout, out double duration)
public bool ReadPosition(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool vendorType, bool longForm,
bool totalPosition, uint timeout, out double duration)
{
byte responseForm = 0;
@@ -573,8 +537,8 @@ public partial class Device
/// <param name="responseForm">Response form.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadPosition(out byte[] buffer, out byte[] senseBuffer, SscPositionForms responseForm, uint timeout,
out double duration)
public bool ReadPosition(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, SscPositionForms responseForm,
uint timeout, out double duration)
{
buffer = responseForm switch
{
@@ -592,7 +556,7 @@ public partial class Device
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.ReadPosition;
cdb[1] = (byte)((byte)responseForm & 0x1F);
@@ -603,13 +567,7 @@ public partial class Device
cdb[8] = (byte)(buffer.Length & 0xFF);
}
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -625,16 +583,9 @@ public partial class Device
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadReverse6(out byte[] buffer, out byte[] senseBuffer, uint blocks, uint blockSize, uint timeout,
out double duration) => ReadReverse6(out buffer,
out senseBuffer,
false,
false,
true,
blocks,
blockSize,
timeout,
out duration);
public bool ReadReverse6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint blocks, uint blockSize,
uint timeout, out double duration) =>
ReadReverse6(out buffer, out senseBuffer, false, false, true, blocks, blockSize, timeout, out duration);
/// <summary>Reads the specified number of bytes or of blocks from the medium, backwards</summary>
/// <param name="buffer">Buffer.</param>
@@ -644,8 +595,8 @@ public partial class Device
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadReverse6(out byte[] buffer, out byte[] senseBuffer, bool sili, uint transferLen, uint blockSize,
uint timeout, out double duration) =>
public bool ReadReverse6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool sili, uint transferLen,
uint blockSize, uint timeout, out double duration) =>
ReadReverse6(out buffer, out senseBuffer, false, sili, false, transferLen, blockSize, timeout, out duration);
/// <summary>Reads the specified number of bytes or of blocks from the medium, backwards</summary>
@@ -664,13 +615,13 @@ public partial class Device
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadReverse6(out byte[] buffer, out byte[] senseBuffer, bool byteOrder, bool sili, bool fixedLen,
uint transferLen, uint blockSize, uint timeout, out double duration)
public bool ReadReverse6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool byteOrder, bool sili,
bool fixedLen, uint transferLen, uint blockSize, uint timeout, out double duration)
{
buffer = fixedLen ? new byte[blockSize * transferLen] : new byte[transferLen];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.ReadReverse;
@@ -684,13 +635,7 @@ public partial class Device
cdb[3] = (byte)((transferLen & 0xFF00) >> 8);
cdb[4] = (byte)(transferLen & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -708,8 +653,8 @@ public partial class Device
/// <param name="blockSize">Object size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, bool sili, ulong objectId, uint blocks,
uint blockSize, uint timeout, out double duration) =>
public bool ReadReverse16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool sili, ulong objectId,
uint blocks, uint blockSize, uint timeout, out double duration) =>
ReadReverse16(out buffer,
out senseBuffer,
false,
@@ -732,8 +677,8 @@ public partial class Device
/// <param name="blockSize">Object size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, bool sili, byte partition, ulong objectId,
uint blocks, uint blockSize, uint timeout, out double duration) =>
public bool ReadReverse16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool sili, byte partition,
ulong objectId, uint blocks, uint blockSize, uint timeout, out double duration) =>
ReadReverse16(out buffer,
out senseBuffer,
false,
@@ -754,8 +699,8 @@ public partial class Device
/// <param name="blockSize">Object size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, ulong objectId, uint blocks, uint blockSize,
uint timeout, out double duration) =>
public bool ReadReverse16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, ulong objectId, uint blocks,
uint blockSize, uint timeout, out double duration) =>
ReadReverse16(out buffer,
out senseBuffer,
false,
@@ -777,8 +722,8 @@ public partial class Device
/// <param name="blockSize">Object size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, byte partition, ulong objectId, uint blocks,
uint blockSize, uint timeout, out double duration) =>
public bool ReadReverse16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, byte partition, ulong objectId,
uint blocks, uint blockSize, uint timeout, out double duration) =>
ReadReverse16(out buffer,
out senseBuffer,
false,
@@ -809,14 +754,14 @@ public partial class Device
/// <param name="objectSize">Object size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, bool byteOrder, bool sili, bool fixedLen,
byte partition, ulong objectId, uint transferLen, uint objectSize, uint timeout,
out double duration)
public bool ReadReverse16(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool byteOrder, bool sili,
bool fixedLen, byte partition, ulong objectId, uint transferLen, uint objectSize,
uint timeout, out double duration)
{
buffer = fixedLen ? new byte[objectSize * transferLen] : new byte[transferLen];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
byte[] idBytes = BitConverter.GetBytes(objectId);
cdb[0] = (byte)ScsiCommands.Read16;
@@ -840,13 +785,7 @@ public partial class Device
cdb[13] = (byte)((transferLen & 0xFF00) >> 8);
cdb[14] = (byte)(transferLen & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -862,8 +801,8 @@ public partial class Device
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool RecoverBufferedData(out byte[] buffer, out byte[] senseBuffer, uint blocks, uint blockSize,
uint timeout, out double duration) =>
public bool RecoverBufferedData(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint blocks, uint blockSize,
uint timeout, out double duration) =>
RecoverBufferedData(out buffer, out senseBuffer, false, true, blocks, blockSize, timeout, out duration);
/// <summary>Reads the specified number of bytes or of blocks from the device's buffer</summary>
@@ -874,8 +813,8 @@ public partial class Device
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool RecoverBufferedData(out byte[] buffer, out byte[] senseBuffer, bool sili, uint transferLen,
uint blockSize, uint timeout, out double duration) =>
public bool RecoverBufferedData(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool sili, uint transferLen,
uint blockSize, uint timeout, out double duration) =>
RecoverBufferedData(out buffer, out senseBuffer, sili, false, transferLen, blockSize, timeout, out duration);
/// <summary>Reads the specified number of bytes or of blocks from the device's buffer</summary>
@@ -893,13 +832,13 @@ public partial class Device
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool RecoverBufferedData(out byte[] buffer, out byte[] senseBuffer, bool sili, bool fixedLen,
uint transferLen, uint blockSize, uint timeout, out double duration)
public bool RecoverBufferedData(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool sili, bool fixedLen,
uint transferLen, uint blockSize, uint timeout, out double duration)
{
buffer = fixedLen ? new byte[blockSize * transferLen] : new byte[transferLen];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.RecoverBufferedData;
@@ -911,13 +850,7 @@ public partial class Device
cdb[3] = (byte)((transferLen & 0xFF00) >> 8);
cdb[4] = (byte)(transferLen & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -931,7 +864,8 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReportDensitySupport(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool ReportDensitySupport(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration) =>
ReportDensitySupport(out buffer, out senseBuffer, false, false, timeout, out duration);
/// <summary>Requests the device to return descriptors for supported densities or medium types</summary>
@@ -940,8 +874,8 @@ public partial class Device
/// <param name="currentMedia">If set to <c>true</c> descriptors should apply to currently inserted media.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReportDensitySupport(out byte[] buffer, out byte[] senseBuffer, bool currentMedia, uint timeout,
out double duration) =>
public bool ReportDensitySupport(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool currentMedia,
uint timeout, out double duration) =>
ReportDensitySupport(out buffer, out senseBuffer, false, currentMedia, timeout, out duration);
/// <summary>Requests the device to return descriptors for supported densities or medium types</summary>
@@ -951,13 +885,13 @@ public partial class Device
/// <param name="currentMedia">If set to <c>true</c> descriptors should apply to currently inserted media.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool ReportDensitySupport(out byte[] buffer, out byte[] senseBuffer, bool mediumType, bool currentMedia,
uint timeout, out double duration)
public bool ReportDensitySupport(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, bool mediumType,
bool currentMedia, uint timeout, out double duration)
{
buffer = new byte[256];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
cdb[0] = (byte)ScsiCommands.ReportDensitySupport;
@@ -968,13 +902,7 @@ public partial class Device
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
Error = LastError != 0;
@@ -984,15 +912,9 @@ public partial class Device
buffer = new byte[availableLength];
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
Error = LastError != 0;
@@ -1005,7 +927,7 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Rewind(out byte[] senseBuffer, uint timeout, out double duration) =>
public bool Rewind(out ReadOnlySpan<byte> senseBuffer, uint timeout, out double duration) =>
Rewind(out senseBuffer, false, timeout, out duration);
/// <summary>Positions the reading/writing element to the beginning of current partition</summary>
@@ -1013,9 +935,9 @@ public partial class Device
/// <param name="immediate">If set to <c>true</c> return from the command immediately.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool Rewind(out byte[] senseBuffer, bool immediate, uint timeout, out double duration)
public bool Rewind(out ReadOnlySpan<byte> senseBuffer, bool immediate, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
@@ -1024,13 +946,7 @@ public partial class Device
if(immediate) cdb[1] += 0x01;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -1045,9 +961,9 @@ public partial class Device
/// <param name="track">Track.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool TrackSelect(out byte[] senseBuffer, byte track, uint timeout, out double duration)
public bool TrackSelect(out ReadOnlySpan<byte> senseBuffer, byte track, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
@@ -1055,13 +971,7 @@ public partial class Device
cdb[0] = (byte)ScsiCommands.TrackSelect;
cdb[5] = track;
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;
@@ -1077,9 +987,10 @@ public partial class Device
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
/// <returns><c>true</c>, if select was tracked, <c>false</c> otherwise.</returns>
public bool Space(out byte[] senseBuffer, SscSpaceCodes code, int count, uint timeout, out double duration)
public bool Space(out ReadOnlySpan<byte> senseBuffer, SscSpaceCodes code, int count, uint timeout,
out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
@@ -1091,13 +1002,7 @@ public partial class Device
cdb[3] = countB[1];
cdb[4] = countB[0];
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out bool sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out bool sense);
Error = LastError != 0;

View File

@@ -47,16 +47,9 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="lba">Starting block.</param>
/// <param name="blockSize">Block size in bytes.</param>
public bool SyQuestRead6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout,
out double duration) => SyQuestRead6(out buffer,
out senseBuffer,
lba,
blockSize,
1,
false,
false,
timeout,
out duration);
public bool SyQuestRead6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint blockSize,
uint timeout, out double duration) =>
SyQuestRead6(out buffer, out senseBuffer, lba, blockSize, 1, false, false, timeout, out duration);
/// <summary>Sends the SyQuest READ LONG (6) command</summary>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
@@ -66,8 +59,8 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="lba">Starting block.</param>
/// <param name="blockSize">Block size in bytes.</param>
public bool SyQuestReadLong6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout,
out double duration) =>
public bool SyQuestReadLong6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint blockSize,
uint timeout, out double duration) =>
SyQuestRead6(out buffer, out senseBuffer, lba, blockSize, 1, false, true, timeout, out duration);
/// <summary>Sends the SyQuest READ (6) command</summary>
@@ -81,10 +74,10 @@ public partial class Device
/// <param name="readLong">If set to <c>true</c> drive will return ECC bytes and disable error detection.</param>
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="transferLength">How many blocks to read.</param>
public bool SyQuestRead6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, byte transferLength,
bool inhibitDma, bool readLong, uint timeout, out double duration)
public bool SyQuestRead6(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint blockSize,
byte transferLength, bool inhibitDma, bool readLong, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
bool sense;
@@ -111,23 +104,11 @@ public partial class Device
if(!inhibitDma)
{
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
}
else
{
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out sense);
}
Error = LastError != 0;
@@ -142,7 +123,8 @@ public partial class Device
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout.</param>
/// <param name="duration">Duration.</param>
public bool SyQuestReadUsageCounter(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) =>
public bool SyQuestReadUsageCounter(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint timeout,
out double duration) =>
AdaptecReadUsageCounter(out buffer, out senseBuffer, false, timeout, out duration);
/// <summary>Sends the SyQuest READ LONG (10) command</summary>
@@ -153,8 +135,8 @@ public partial class Device
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="lba">Starting block.</param>
/// <param name="blockSize">Block size in bytes.</param>
public bool SyQuestReadLong10(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout,
out double duration) =>
public bool SyQuestReadLong10(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint blockSize,
uint timeout, out double duration) =>
SyQuestRead10(out buffer, out senseBuffer, lba, blockSize, 1, false, true, timeout, out duration);
/// <summary>Sends the SyQuest READ (10) command</summary>
@@ -168,10 +150,10 @@ public partial class Device
/// <param name="readLong">If set to <c>true</c> drive will return ECC bytes and disable error detection.</param>
/// <param name="blockSize">Block size in bytes.</param>
/// <param name="transferLength">How many blocks to read.</param>
public bool SyQuestRead10(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize,
public bool SyQuestRead10(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint blockSize,
ushort transferLength, bool inhibitDma, bool readLong, uint timeout, out double duration)
{
senseBuffer = new byte[64];
senseBuffer = SenseBuffer;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
bool sense;
@@ -200,23 +182,11 @@ public partial class Device
if(!inhibitDma)
{
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.In,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out sense);
}
else
{
LastError = SendScsiCommand(cdb,
ref buffer,
out senseBuffer,
timeout,
ScsiDirection.None,
out duration,
out sense);
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.None, out duration, out sense);
}
Error = LastError != 0;

View File

@@ -43,15 +43,15 @@ namespace Aaru.Devices.Linux;
partial class Device
{
/// <inheritdoc />
public override unsafe int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
public override unsafe int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, uint timeout, ScsiDirection direction,
out double duration, out bool sense)
{
// We need a timeout
if(timeout == 0) timeout = Timeout > 0 ? Timeout : 15;
senseBuffer = null;
duration = 0;
sense = false;
duration = 0;
sense = false;
SenseBuffer.Clear();
if(buffer == null) return -1;
@@ -66,21 +66,18 @@ partial class Device
var ioHdr = new SgIoHdrT();
senseBuffer = new byte[64];
ioHdr.interface_id = 'S';
ioHdr.cmd_len = (byte)cdb.Length;
ioHdr.mx_sb_len = (byte)senseBuffer.Length;
ioHdr.mx_sb_len = (byte)SenseBuffer.Length;
ioHdr.dxfer_direction = dir;
ioHdr.dxfer_len = (uint)buffer.Length;
ioHdr.dxferp = Marshal.AllocHGlobal(buffer.Length);
ioHdr.cmdp = (IntPtr)CdbPtr;
ioHdr.sbp = Marshal.AllocHGlobal(senseBuffer.Length);
ioHdr.sbp = (IntPtr)SensePtr;
ioHdr.timeout = timeout * 1000;
ioHdr.flags = (uint)SgFlags.DirectIo;
Marshal.Copy(buffer, 0, ioHdr.dxferp, buffer.Length);
Marshal.Copy(senseBuffer, 0, ioHdr.sbp, senseBuffer.Length);
Marshal.Copy(buffer, 0, ioHdr.dxferp, buffer.Length);
var cmdStopWatch = new Stopwatch();
cmdStopWatch.Start();
@@ -89,15 +86,13 @@ partial class Device
if(error < 0) error = Marshal.GetLastWin32Error();
Marshal.Copy(ioHdr.dxferp, buffer, 0, buffer.Length);
Marshal.Copy(ioHdr.sbp, senseBuffer, 0, senseBuffer.Length);
Marshal.Copy(ioHdr.dxferp, buffer, 0, buffer.Length);
sense |= (ioHdr.info & SgInfo.OkMask) != SgInfo.Ok;
duration = ioHdr.duration > 0 ? ioHdr.duration : cmdStopWatch.Elapsed.TotalMilliseconds;
Marshal.FreeHGlobal(ioHdr.dxferp);
Marshal.FreeHGlobal(ioHdr.sbp);
return error;
}
@@ -165,22 +160,21 @@ partial class Device
int error = SendScsiCommand(cdb,
ref buffer,
out byte[] senseBuffer,
timeout,
AtaProtocolToScsiDirection(protocol),
out duration,
out sense);
if(senseBuffer.Length < 22 || senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C) return error;
if(SenseBuffer.Length < 22 || SenseBuffer[8] != 0x09 && SenseBuffer[9] != 0x0C) return error;
errorRegisters.Error = senseBuffer[11];
errorRegisters.Error = SenseBuffer[11];
errorRegisters.SectorCount = senseBuffer[13];
errorRegisters.Sector = senseBuffer[15];
errorRegisters.CylinderLow = senseBuffer[17];
errorRegisters.CylinderHigh = senseBuffer[19];
errorRegisters.DeviceHead = senseBuffer[20];
errorRegisters.Status = senseBuffer[21];
errorRegisters.SectorCount = SenseBuffer[13];
errorRegisters.Sector = SenseBuffer[15];
errorRegisters.CylinderLow = SenseBuffer[17];
errorRegisters.CylinderHigh = SenseBuffer[19];
errorRegisters.DeviceHead = SenseBuffer[20];
errorRegisters.Status = SenseBuffer[21];
sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0;
@@ -230,22 +224,21 @@ partial class Device
int error = SendScsiCommand(cdb,
ref buffer,
out byte[] senseBuffer,
timeout,
AtaProtocolToScsiDirection(protocol),
out duration,
out sense);
if(senseBuffer.Length < 22 || senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C) return error;
if(SenseBuffer.Length < 22 || SenseBuffer[8] != 0x09 && SenseBuffer[9] != 0x0C) return error;
errorRegisters.Error = senseBuffer[11];
errorRegisters.Error = SenseBuffer[11];
errorRegisters.SectorCount = senseBuffer[13];
errorRegisters.LbaLow = senseBuffer[15];
errorRegisters.LbaMid = senseBuffer[17];
errorRegisters.LbaHigh = senseBuffer[19];
errorRegisters.DeviceHead = senseBuffer[20];
errorRegisters.Status = senseBuffer[21];
errorRegisters.SectorCount = SenseBuffer[13];
errorRegisters.LbaLow = SenseBuffer[15];
errorRegisters.LbaMid = SenseBuffer[17];
errorRegisters.LbaHigh = SenseBuffer[19];
errorRegisters.DeviceHead = SenseBuffer[20];
errorRegisters.Status = SenseBuffer[21];
sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0;
@@ -301,25 +294,24 @@ partial class Device
int error = SendScsiCommand(cdb,
ref buffer,
out byte[] senseBuffer,
timeout,
AtaProtocolToScsiDirection(protocol),
out duration,
out sense);
if(senseBuffer.Length < 22 || senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C) return error;
if(SenseBuffer.Length < 22 || SenseBuffer[8] != 0x09 && SenseBuffer[9] != 0x0C) return error;
errorRegisters.Error = senseBuffer[11];
errorRegisters.Error = SenseBuffer[11];
errorRegisters.SectorCount = (ushort)((senseBuffer[12] << 8) + senseBuffer[13]);
errorRegisters.LbaLowPrevious = senseBuffer[14];
errorRegisters.LbaLowCurrent = senseBuffer[15];
errorRegisters.LbaMidPrevious = senseBuffer[16];
errorRegisters.LbaMidCurrent = senseBuffer[17];
errorRegisters.LbaHighPrevious = senseBuffer[18];
errorRegisters.LbaHighCurrent = senseBuffer[19];
errorRegisters.DeviceHead = senseBuffer[20];
errorRegisters.Status = senseBuffer[21];
errorRegisters.SectorCount = (ushort)((SenseBuffer[12] << 8) + SenseBuffer[13]);
errorRegisters.LbaLowPrevious = SenseBuffer[14];
errorRegisters.LbaLowCurrent = SenseBuffer[15];
errorRegisters.LbaMidPrevious = SenseBuffer[16];
errorRegisters.LbaMidCurrent = SenseBuffer[17];
errorRegisters.LbaHighPrevious = SenseBuffer[18];
errorRegisters.LbaHighCurrent = SenseBuffer[19];
errorRegisters.DeviceHead = SenseBuffer[20];
errorRegisters.Status = SenseBuffer[21];
sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0;

View File

@@ -41,13 +41,13 @@ namespace Aaru.Devices.Remote;
public partial class Device
{
/// <inheritdoc />
public override int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
public override int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, uint timeout, ScsiDirection direction,
out double duration, out bool sense)
{
// We need a timeout
if(timeout == 0) timeout = Timeout > 0 ? Timeout : 15;
return _remote.SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, direction, out duration, out sense);
return _remote.SendScsiCommand(cdb, ref buffer, SenseBuffer, timeout, direction, out duration, out sense);
}
/// <inheritdoc />

View File

@@ -522,7 +522,7 @@ public class Remote : IDisposable
/// <c>True</c> if SCSI command returned non-OK status and <paramref name="senseBuffer" /> contains
/// SCSI sense
/// </param>
public int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
public int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, Span<byte> senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
{
senseBuffer = null;
@@ -610,8 +610,7 @@ public class Remote : IDisposable
AaruPacketResScsi res = Marshal.ByteArrayToStructureLittleEndian<AaruPacketResScsi>(buf);
senseBuffer = new byte[res.sense_len];
Array.Copy(buf, Marshal.SizeOf<AaruPacketResScsi>(), senseBuffer, 0, res.sense_len);
buf.AsSpan(Marshal.SizeOf<AaruPacketResScsi>(), (int)res.sense_len).CopyTo(senseBuffer);
buffer = new byte[res.buf_len];
Array.Copy(buf, Marshal.SizeOf<AaruPacketResScsi>() + res.sense_len, buffer, 0, res.buf_len);
duration = res.duration;

View File

@@ -44,15 +44,14 @@ namespace Aaru.Devices.Windows;
partial class Device
{
/// <inheritdoc />
public override int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
public override int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, uint timeout, ScsiDirection direction,
out double duration, out bool sense)
{
// We need a timeout
if(timeout == 0) timeout = Timeout > 0 ? Timeout : 15;
senseBuffer = null;
duration = 0;
sense = false;
duration = 0;
sense = false;
if(buffer == null) return -1;
@@ -107,8 +106,7 @@ partial class Device
sense |= sptdSb.sptd.ScsiStatus != 0;
senseBuffer = new byte[64];
Array.Copy(sptdSb.SenseBuf, senseBuffer, 32);
sptdSb.SenseBuf.AsSpan().CopyTo(SenseBuffer);
duration = cmdStopwatch.Elapsed.TotalMilliseconds;