Decode fixed or descriptor SCSI sense in a single pass, use whichever was returned by drive.

This commit is contained in:
2021-03-26 00:37:54 +00:00
parent e4dbcdebc3
commit eda85862cd
16 changed files with 608 additions and 488 deletions

View File

@@ -198,8 +198,8 @@ namespace Aaru.Core.Devices.Dumping
} }
if(track.TrackSequence != 0 && if(track.TrackSequence != 0 &&
(i + blocksToRead) - (ulong)sectorsForOffset > track.TrackEndSector + 1) i + blocksToRead - (ulong)sectorsForOffset > track.TrackEndSector + 1)
blocksToRead = (uint)(((track.TrackEndSector + 1) - i) + (ulong)sectorsForOffset); blocksToRead = (uint)(track.TrackEndSector + 1 - i + (ulong)sectorsForOffset);
if(blocksToRead == 1 && if(blocksToRead == 1 &&
!inData) !inData)
@@ -495,7 +495,7 @@ namespace Aaru.Core.Devices.Dumping
if(elapsed < 1) if(elapsed < 1)
continue; continue;
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed); currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
} }
@@ -592,7 +592,7 @@ namespace Aaru.Core.Devices.Dumping
} }
else else
{ {
if(crossingLeadOut && Sense.DecodeFixed(senseBuf)?.ASC == 0x21) if(crossingLeadOut && Sense.Decode(senseBuf)?.ASC == 0x21)
{ {
if(failedCrossingLeadOut) if(failedCrossingLeadOut)
break; break;
@@ -661,7 +661,7 @@ namespace Aaru.Core.Devices.Dumping
if(elapsed < 1) if(elapsed < 1)
continue; continue;
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed); currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
} }

View File

@@ -276,7 +276,7 @@ namespace Aaru.Core.Devices.Dumping
if(!runningPersistent) if(!runningPersistent)
continue; continue;
FixedSense? decSense = Sense.DecodeFixed(senseBuf); DecodedSense? decSense = Sense.Decode(senseBuf);
// MEDIUM ERROR, retry with ignore error below // MEDIUM ERROR, retry with ignore error below
if(decSense.HasValue && if(decSense.HasValue &&

View File

@@ -56,7 +56,7 @@ namespace Aaru.Core.Devices.Dumping
if(sense) if(sense)
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuf); var decSense = Sense.Decode(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
{ {
@@ -88,7 +88,7 @@ namespace Aaru.Core.Devices.Dumping
if(!sense) if(!sense)
break; break;
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.Decode(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
{ {
@@ -124,7 +124,7 @@ namespace Aaru.Core.Devices.Dumping
if(!sense) if(!sense)
break; break;
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.Decode(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
{ {
@@ -174,7 +174,7 @@ namespace Aaru.Core.Devices.Dumping
if(!sense) if(!sense)
break; break;
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.Decode(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
{ {

View File

@@ -60,7 +60,7 @@ namespace Aaru.Core.Devices.Dumping
/// <summary>Dumps the tape from a SCSI Streaming device</summary> /// <summary>Dumps the tape from a SCSI Streaming device</summary>
void Ssc() void Ssc()
{ {
FixedSense? fxSense; DecodedSense? decSense;
bool sense; bool sense;
uint blockSize; uint blockSize;
ulong blocks = 0; ulong blocks = 0;
@@ -73,28 +73,27 @@ namespace Aaru.Core.Devices.Dumping
double minSpeed = double.MaxValue; double minSpeed = double.MaxValue;
_dev.RequestSense(out byte[] senseBuf, _dev.Timeout, out double duration); _dev.RequestSense(out byte[] senseBuf, _dev.Timeout, out double duration);
fxSense = Sense.DecodeFixed(senseBuf, out string strSense); decSense = Sense.Decode(senseBuf);
InitProgress?.Invoke(); InitProgress?.Invoke();
if(fxSense.HasValue && if(decSense.HasValue &&
fxSense.Value.SenseKey != SenseKeys.NoSense) decSense.Value.SenseKey != SenseKeys.NoSense)
{ {
_dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense.Value.SenseKey, _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", decSense.Value.SenseKey,
fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.ASC, decSense.Value.ASCQ);
StoppingErrorMessage?.Invoke("Drive has status error, please correct. Sense follows..." + StoppingErrorMessage?.Invoke("Drive has status error, please correct. Sense follows..." +
Environment.NewLine + strSense); Environment.NewLine + decSense.Value.Description);
return; return;
} }
// Not in BOM/P // Not in BOM/P
if(fxSense.HasValue && if(decSense is { ASC: 0x00 } &&
fxSense.Value.ASC == 0x00 && decSense.Value.ASCQ != 0x00 &&
fxSense.Value.ASCQ != 0x00 && decSense.Value.ASCQ != 0x04 &&
fxSense.Value.ASCQ != 0x04 && decSense.Value.SenseKey != SenseKeys.IllegalRequest)
fxSense.Value.SenseKey != SenseKeys.IllegalRequest)
{ {
_dumpLog.WriteLine("Rewinding, please wait..."); _dumpLog.WriteLine("Rewinding, please wait...");
PulseProgress?.Invoke("Rewinding, please wait..."); PulseProgress?.Invoke("Rewinding, please wait...");
@@ -108,26 +107,25 @@ namespace Aaru.Core.Devices.Dumping
{ {
PulseProgress?.Invoke("Rewinding, please wait..."); PulseProgress?.Invoke("Rewinding, please wait...");
_dev.RequestSense(out senseBuf, _dev.Timeout, out duration); _dev.RequestSense(out senseBuf, _dev.Timeout, out duration);
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
} while(fxSense.HasValue && } while(decSense is { ASC: 0x00 } &&
fxSense.Value.ASC == 0x00 && (decSense.Value.ASCQ == 0x1A || decSense.Value.ASCQ != 0x04 || decSense.Value.ASCQ != 0x00));
(fxSense.Value.ASCQ == 0x1A || fxSense.Value.ASCQ != 0x04 || fxSense.Value.ASCQ != 0x00));
_dev.RequestSense(out senseBuf, _dev.Timeout, out duration); _dev.RequestSense(out senseBuf, _dev.Timeout, out duration);
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
// And yet, did not rewind! // And yet, did not rewind!
if(fxSense.HasValue && if(decSense.HasValue &&
((fxSense.Value.ASC == 0x00 && fxSense.Value.ASCQ != 0x04 && fxSense.Value.ASCQ != 0x00) || ((decSense.Value.ASC == 0x00 && decSense.Value.ASCQ != 0x04 && decSense.Value.ASCQ != 0x00) ||
fxSense.Value.ASC != 0x00)) decSense.Value.ASC != 0x00))
{ {
StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." + StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." +
Environment.NewLine + strSense); Environment.NewLine + decSense.Value.Description);
_dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows..."); _dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense.Value.SenseKey, _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", decSense.Value.SenseKey,
fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.ASC, decSense.Value.ASCQ);
return; return;
} }
@@ -141,19 +139,19 @@ namespace Aaru.Core.Devices.Dumping
{ {
// READ POSITION is mandatory starting SCSI-2, so do not cry if the drive does not recognize the command (SCSI-1 or earlier) // READ POSITION is mandatory starting SCSI-2, so do not cry if the drive does not recognize the command (SCSI-1 or earlier)
// Anyway, <=SCSI-1 tapes do not support partitions // Anyway, <=SCSI-1 tapes do not support partitions
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
if(fxSense.HasValue && if(decSense.HasValue &&
((fxSense.Value.ASC == 0x20 && fxSense.Value.ASCQ != 0x00) || ((decSense.Value.ASC == 0x20 && decSense.Value.ASCQ != 0x00) ||
(fxSense.Value.ASC != 0x20 && fxSense.Value.SenseKey != SenseKeys.IllegalRequest))) (decSense.Value.ASC != 0x20 && decSense.Value.SenseKey != SenseKeys.IllegalRequest)))
{ {
StoppingErrorMessage?.Invoke("Could not get position. Sense follows..." + Environment.NewLine + StoppingErrorMessage?.Invoke("Could not get position. Sense follows..." + Environment.NewLine +
strSense); decSense.Value.Description);
_dumpLog.WriteLine("Could not get position. Sense follows..."); _dumpLog.WriteLine("Could not get position. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense.Value.SenseKey, _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", decSense.Value.SenseKey,
fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.ASC, decSense.Value.ASCQ);
return; return;
} }
@@ -172,12 +170,12 @@ namespace Aaru.Core.Devices.Dumping
if(sense) if(sense)
{ {
StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." + StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." +
Environment.NewLine + strSense); Environment.NewLine + decSense?.Description);
_dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows..."); _dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey, _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", decSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ); decSense?.ASC, decSense?.ASCQ);
return; return;
} }
@@ -189,23 +187,22 @@ namespace Aaru.Core.Devices.Dumping
Thread.Sleep(1000); Thread.Sleep(1000);
PulseProgress?.Invoke("Rewinding, please wait..."); PulseProgress?.Invoke("Rewinding, please wait...");
_dev.RequestSense(out senseBuf, _dev.Timeout, out duration); _dev.RequestSense(out senseBuf, _dev.Timeout, out duration);
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
} while(fxSense.HasValue && } while(decSense is { ASC: 0x00 } &&
fxSense.Value.ASC == 0x00 && (decSense.Value.ASCQ == 0x1A || decSense.Value.ASCQ == 0x19));
(fxSense.Value.ASCQ == 0x1A || fxSense.Value.ASCQ == 0x19));
// And yet, did not rewind! // And yet, did not rewind!
if(fxSense.HasValue && if(decSense.HasValue &&
((fxSense.Value.ASC == 0x00 && fxSense.Value.ASCQ != 0x04 && fxSense.Value.ASCQ != 0x00) || ((decSense.Value.ASC == 0x00 && decSense.Value.ASCQ != 0x04 && decSense.Value.ASCQ != 0x00) ||
fxSense.Value.ASC != 0x00)) decSense.Value.ASC != 0x00))
{ {
StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." + StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." +
Environment.NewLine + strSense); Environment.NewLine + decSense.Value.Description);
_dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows..."); _dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ);
return; return;
} }
@@ -215,15 +212,15 @@ namespace Aaru.Core.Devices.Dumping
if(sense) if(sense)
{ {
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." + StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." +
Environment.NewLine + strSense); Environment.NewLine + decSense?.Description);
_dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows..."); _dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense?.SenseKey, _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", decSense?.SenseKey,
fxSense?.ASC, fxSense?.ASCQ); decSense?.ASC, decSense?.ASCQ);
return; return;
} }
@@ -339,26 +336,32 @@ namespace Aaru.Core.Devices.Dumping
if(sense) if(sense)
{ {
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
if(fxSense.HasValue) if(decSense.HasValue)
if(fxSense.Value.SenseKey == SenseKeys.IllegalRequest) if(decSense.Value.SenseKey == SenseKeys.IllegalRequest)
{ {
sense = _dev.Space(out senseBuf, SscSpaceCodes.LogicalBlock, -1, _dev.Timeout, out duration); sense = _dev.Space(out senseBuf, SscSpaceCodes.LogicalBlock, -1, _dev.Timeout, out duration);
if(sense) if(sense)
{ {
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
if(fxSense?.EOM != true) bool eom = decSense?.Fixed?.EOM == true;
if(decSense?.Descriptor != null &&
decSense.Value.Descriptor.Value.Descriptors.TryGetValue(4, out byte[] sscDescriptor))
Sense.DecodeDescriptor04(sscDescriptor, out _, out eom, out _);
if(!eom)
{ {
StoppingErrorMessage?.Invoke("Drive could not return back. Sense follows..." + StoppingErrorMessage?.Invoke("Drive could not return back. Sense follows..." +
Environment.NewLine + strSense); Environment.NewLine + decSense.Value.Description);
_dumpLog.WriteLine("Drive could not return back. Sense follows..."); _dumpLog.WriteLine("Drive could not return back. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h", _dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ);
return; return;
} }
@@ -372,62 +375,89 @@ namespace Aaru.Core.Devices.Dumping
if(sense) if(sense)
{ {
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
StoppingErrorMessage?.Invoke("Drive could not read. Sense follows..." + StoppingErrorMessage?.Invoke("Drive could not read. Sense follows..." +
Environment.NewLine + strSense); Environment.NewLine + decSense.Value.Description);
_dumpLog.WriteLine("Drive could not read. Sense follows..."); _dumpLog.WriteLine("Drive could not read. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h", _dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ);
return; return;
} }
} }
else if(fxSense.Value.ASC == 0x00 && else if(decSense.Value.ASC == 0x00 &&
fxSense.Value.ASCQ == 0x00 && decSense.Value.ASCQ == 0x00)
fxSense.Value.ILI && {
fxSense.Value.InformationValid) bool ili = decSense.Value.Fixed?.ILI == true;
bool valid = decSense.Value.Fixed?.InformationValid == true;
uint information = decSense.Value.Fixed?.Information ?? 0;
if(decSense.Value.Descriptor.HasValue)
{
valid = decSense.Value.Descriptor.Value.Descriptors.TryGetValue(0, out byte[] desc00);
if(valid)
information = (uint)Sense.DecodeDescriptor00(desc00);
if(decSense.Value.Descriptor.Value.Descriptors.TryGetValue(4, out byte[] desc04))
Sense.DecodeDescriptor04(desc04, out _, out _, out ili);
}
if(ili && valid)
{ {
blockSize = (uint)((int)blockSize - blockSize = (uint)((int)blockSize -
BitConverter.ToInt32(BitConverter.GetBytes(fxSense.Value.Information), 0)); BitConverter.ToInt32(BitConverter.GetBytes(information), 0));
transferLen = blockSize; transferLen = blockSize;
UpdateStatus?.Invoke($"Blocksize changed to {blockSize} bytes at block {currentBlock}"); UpdateStatus?.Invoke($"Blocksize changed to {blockSize} bytes at block {currentBlock}");
_dumpLog.WriteLine("Blocksize changed to {0} bytes at block {1}", blockSize, currentBlock); _dumpLog.WriteLine("Blocksize changed to {0} bytes at block {1}", blockSize, currentBlock);
sense = _dev.Space(out senseBuf, SscSpaceCodes.LogicalBlock, -1, _dev.Timeout, out duration); sense = _dev.Space(out senseBuf, SscSpaceCodes.LogicalBlock, -1, _dev.Timeout,
out duration);
totalDuration += duration; totalDuration += duration;
if(sense) if(sense)
{ {
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
StoppingErrorMessage?.Invoke("Drive could not go back one block. Sense follows..." + StoppingErrorMessage?.Invoke("Drive could not go back one block. Sense follows..." +
Environment.NewLine + strSense); Environment.NewLine + decSense.Value.Description);
_dumpLog.WriteLine("Drive could not go back one block. Sense follows..."); _dumpLog.WriteLine("Drive could not go back one block. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ);
return; return;
} }
goto firstRead; goto firstRead;
} }
else
{
StoppingErrorMessage?.Invoke("Drive could not read. Sense follows..." + Environment.NewLine + StoppingErrorMessage?.Invoke("Drive could not read. Sense follows..." + Environment.NewLine +
strSense); decSense.Value.Description);
_dumpLog.WriteLine("Drive could not read. Sense follows..."); _dumpLog.WriteLine("Drive could not read. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h", _dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ);
return;
}
else
{
StoppingErrorMessage?.Invoke("Drive could not read. Sense follows..." + Environment.NewLine +
decSense.Value.Description);
_dumpLog.WriteLine("Drive could not read. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ);
return; return;
} }
@@ -444,17 +474,23 @@ namespace Aaru.Core.Devices.Dumping
if(sense) if(sense)
{ {
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
if(fxSense?.EOM != true) bool eom = decSense?.Fixed?.EOM == true;
if(decSense.Value.Descriptor.HasValue &&
decSense.Value.Descriptor.Value.Descriptors.TryGetValue(4, out byte[] desc04))
Sense.DecodeDescriptor04(desc04, out _, out eom, out _);
if(!eom)
{ {
StoppingErrorMessage?.Invoke("Drive could not return back. Sense follows..." + Environment.NewLine + StoppingErrorMessage?.Invoke("Drive could not return back. Sense follows..." + Environment.NewLine +
strSense); decSense.Value.Description);
_dumpLog.WriteLine("Drive could not return back. Sense follows..."); _dumpLog.WriteLine("Drive could not return back. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h", fxSense.Value.SenseKey, _dumpLog.WriteLine("Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h", decSense.Value.SenseKey,
fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.ASC, decSense.Value.ASCQ);
return; return;
} }
@@ -700,23 +736,22 @@ namespace Aaru.Core.Devices.Dumping
Thread.Sleep(1000); Thread.Sleep(1000);
PulseProgress?.Invoke("Rewinding, please wait..."); PulseProgress?.Invoke("Rewinding, please wait...");
_dev.RequestSense(out senseBuf, _dev.Timeout, out duration); _dev.RequestSense(out senseBuf, _dev.Timeout, out duration);
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
} while(fxSense.HasValue && } while(decSense is { ASC: 0x00 } &&
fxSense.Value.ASC == 0x00 && (decSense.Value.ASCQ == 0x1A || decSense.Value.ASCQ == 0x19));
(fxSense.Value.ASCQ == 0x1A || fxSense.Value.ASCQ == 0x19));
// And yet, did not rewind! // And yet, did not rewind!
if(fxSense.HasValue && if(decSense.HasValue &&
((fxSense.Value.ASC == 0x00 && fxSense.Value.ASCQ != 0x00 && fxSense.Value.ASCQ != 0x04) || ((decSense.Value.ASC == 0x00 && decSense.Value.ASCQ != 0x00 && decSense.Value.ASCQ != 0x04) ||
fxSense.Value.ASC != 0x00)) decSense.Value.ASC != 0x00))
{ {
StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." + StoppingErrorMessage?.Invoke("Drive could not rewind, please correct. Sense follows..." +
Environment.NewLine + strSense); Environment.NewLine + decSense.Value.Description);
_dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows..."); _dumpLog.WriteLine("Drive could not rewind, please correct. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", fxSense.Value.SenseKey, _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", decSense.Value.SenseKey,
fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.ASC, decSense.Value.ASCQ);
return; return;
} }
@@ -774,8 +809,9 @@ namespace Aaru.Core.Devices.Dumping
currentTapeFile = currentTapeFile =
(_outputPlugin as IWritableTapeImage).Files.FirstOrDefault(f => f.LastBlock == (_outputPlugin as IWritableTapeImage).Files.FirstOrDefault(f => f.LastBlock ==
(_outputPlugin as IWritableTapeImage (_outputPlugin as
)?.Files.Max(g => g.LastBlock)); IWritableTapeImage)?.
Files.Max(g => g.LastBlock));
currentTapePartition = currentTapePartition =
(_outputPlugin as IWritableTapeImage).TapePartitions.FirstOrDefault(p => p.LastBlock == (_outputPlugin as IWritableTapeImage).TapePartitions.FirstOrDefault(p => p.LastBlock ==
@@ -864,15 +900,33 @@ namespace Aaru.Core.Devices.Dumping
senseBuf?.Length != 0 && senseBuf?.Length != 0 &&
!ArrayHelpers.ArrayIsNullOrEmpty(senseBuf)) !ArrayHelpers.ArrayIsNullOrEmpty(senseBuf))
{ {
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
if(fxSense.Value.ASC == 0x00 && bool ili = decSense?.Fixed?.ILI == true;
fxSense.Value.ASCQ == 0x00 && bool valid = decSense?.Fixed?.InformationValid == true;
fxSense.Value.ILI && uint information = decSense?.Fixed?.Information ?? 0;
fxSense.Value.InformationValid) bool eom = decSense?.Fixed?.EOM == true;
bool filemark = decSense?.Fixed?.Filemark == true;
if(decSense?.Descriptor.HasValue == true)
{
if(decSense.Value.Descriptor.Value.Descriptors.TryGetValue(0, out byte[] desc00))
{
valid = true;
information = (uint)Sense.DecodeDescriptor00(desc00);
}
if(decSense.Value.Descriptor.Value.Descriptors.TryGetValue(4, out byte[] desc04))
Sense.DecodeDescriptor04(desc04, out filemark, out eom, out ili);
}
if(decSense.Value.ASC == 0x00 &&
decSense.Value.ASCQ == 0x00 &&
ili &&
valid)
{ {
blockSize = (uint)((int)blockSize - blockSize = (uint)((int)blockSize -
BitConverter.ToInt32(BitConverter.GetBytes(fxSense.Value.Information), 0)); BitConverter.ToInt32(BitConverter.GetBytes(information), 0));
if(!fixedLen) if(!fixedLen)
transferLen = blockSize; transferLen = blockSize;
@@ -886,16 +940,16 @@ namespace Aaru.Core.Devices.Dumping
if(sense) if(sense)
{ {
fxSense = Sense.DecodeFixed(senseBuf, out strSense); decSense = Sense.Decode(senseBuf);
StoppingErrorMessage?.Invoke("Drive could not go back one block. Sense follows..." + StoppingErrorMessage?.Invoke("Drive could not go back one block. Sense follows..." +
Environment.NewLine + strSense); Environment.NewLine + decSense.Value.Description);
_outputPlugin.Close(); _outputPlugin.Close();
_dumpLog.WriteLine("Drive could not go back one block. Sense follows..."); _dumpLog.WriteLine("Drive could not go back one block. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ);
return; return;
} }
@@ -903,7 +957,7 @@ namespace Aaru.Core.Devices.Dumping
continue; continue;
} }
switch(fxSense.Value.SenseKey) switch(decSense.Value.SenseKey)
{ {
case SenseKeys.BlankCheck when currentBlock == 0: case SenseKeys.BlankCheck when currentBlock == 0:
StoppingErrorMessage?.Invoke("Cannot dump a blank tape..."); StoppingErrorMessage?.Invoke("Cannot dump a blank tape...");
@@ -913,9 +967,9 @@ namespace Aaru.Core.Devices.Dumping
return; return;
// For sure this is an end-of-tape/partition // For sure this is an end-of-tape/partition
case SenseKeys.BlankCheck when fxSense.Value.ASC == 0x00 && case SenseKeys.BlankCheck when decSense.Value.ASC == 0x00 &&
(fxSense.Value.ASCQ == 0x02 || fxSense.Value.ASCQ == 0x05 || (decSense.Value.ASCQ == 0x02 || decSense.Value.ASCQ == 0x05 ||
fxSense.Value.EOM): eom):
// TODO: Detect end of partition // TODO: Detect end of partition
endOfMedia = true; endOfMedia = true;
UpdateStatus?.Invoke("Found end-of-tape/partition..."); UpdateStatus?.Invoke("Found end-of-tape/partition...");
@@ -930,9 +984,9 @@ namespace Aaru.Core.Devices.Dumping
continue; continue;
} }
if((fxSense.Value.SenseKey == SenseKeys.NoSense || if((decSense.Value.SenseKey == SenseKeys.NoSense ||
fxSense.Value.SenseKey == SenseKeys.RecoveredError) && decSense.Value.SenseKey == SenseKeys.RecoveredError) &&
(fxSense.Value.ASCQ == 0x02 || fxSense.Value.ASCQ == 0x05 || fxSense.Value.EOM)) (decSense.Value.ASCQ == 0x02 || decSense.Value.ASCQ == 0x05 || eom))
{ {
// TODO: Detect end of partition // TODO: Detect end of partition
endOfMedia = true; endOfMedia = true;
@@ -942,9 +996,9 @@ namespace Aaru.Core.Devices.Dumping
continue; continue;
} }
if((fxSense.Value.SenseKey == SenseKeys.NoSense || if((decSense.Value.SenseKey == SenseKeys.NoSense ||
fxSense.Value.SenseKey == SenseKeys.RecoveredError) && decSense.Value.SenseKey == SenseKeys.RecoveredError) &&
(fxSense.Value.ASCQ == 0x01 || fxSense.Value.Filemark)) (decSense.Value.ASCQ == 0x01 || filemark))
{ {
currentTapeFile.LastBlock = currentBlock - 1; currentTapeFile.LastBlock = currentBlock - 1;
(_outputPlugin as IWritableTapeImage).AddFile(currentTapeFile); (_outputPlugin as IWritableTapeImage).AddFile(currentTapeFile);
@@ -964,7 +1018,7 @@ namespace Aaru.Core.Devices.Dumping
continue; continue;
} }
if(fxSense is null) if(decSense is null)
{ {
StoppingErrorMessage?. StoppingErrorMessage?.
Invoke($"Drive could not read block ${currentBlock}. Sense cannot be decoded, look at log for dump..."); Invoke($"Drive could not read block ${currentBlock}. Sense cannot be decoded, look at log for dump...");
@@ -975,12 +1029,12 @@ namespace Aaru.Core.Devices.Dumping
else else
{ {
StoppingErrorMessage?. StoppingErrorMessage?.
Invoke($"Drive could not read block ${currentBlock}. Sense follows...\n{fxSense.Value.SenseKey} {strSense}"); Invoke($"Drive could not read block ${currentBlock}. Sense follows...\n{decSense.Value.SenseKey} {decSense.Value.Description}");
_dumpLog.WriteLine($"Drive could not read block ${currentBlock}. Sense follows..."); _dumpLog.WriteLine($"Drive could not read block ${currentBlock}. Sense follows...");
_dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", _dumpLog.WriteLine("Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
fxSense.Value.SenseKey, fxSense.Value.ASC, fxSense.Value.ASCQ); decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.ASCQ);
} }
// TODO: Reset device after X errors // TODO: Reset device after X errors
@@ -1043,18 +1097,18 @@ namespace Aaru.Core.Devices.Dumping
UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds.");
UpdateStatus?. UpdateStatus?.
Invoke($"Average dump speed {(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000):F3} KiB/sec."); Invoke($"Average dump speed {blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000):F3} KiB/sec.");
UpdateStatus?. UpdateStatus?.
Invoke($"Average write speed {(double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration:F3} KiB/sec."); Invoke($"Average write speed {blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration:F3} KiB/sec.");
_dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds); _dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);
_dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.", _dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000)); blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));
_dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.", _dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration); blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration);
#region Error handling #region Error handling
if(_resume.BadBlocks.Count > 0 && if(_resume.BadBlocks.Count > 0 &&
@@ -1285,12 +1339,12 @@ namespace Aaru.Core.Devices.Dumping
UpdateStatus?.Invoke($"Sidecar created in {(end - chkStart).TotalSeconds} seconds."); UpdateStatus?.Invoke($"Sidecar created in {(end - chkStart).TotalSeconds} seconds.");
UpdateStatus?. UpdateStatus?.
Invoke($"Average checksum speed {(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000):F3} KiB/sec."); Invoke($"Average checksum speed {blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000):F3} KiB/sec.");
_dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds); _dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds);
_dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", _dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000));
if(_preSidecar != null) if(_preSidecar != null)
{ {
@@ -1362,7 +1416,7 @@ namespace Aaru.Core.Devices.Dumping
Invoke($"Took a total of {(end - start).TotalSeconds:F3} seconds ({totalDuration / 1000:F3} processing commands, {totalChkDuration / 1000:F3} checksumming, {imageWriteDuration:F3} writing, {(closeEnd - closeStart).TotalSeconds:F3} closing)."); Invoke($"Took a total of {(end - start).TotalSeconds:F3} seconds ({totalDuration / 1000:F3} processing commands, {totalChkDuration / 1000:F3} checksumming, {imageWriteDuration:F3} writing, {(closeEnd - closeStart).TotalSeconds:F3} closing).");
UpdateStatus?. UpdateStatus?.
Invoke($"Average speed: {(double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000):F3} MiB/sec."); Invoke($"Average speed: {blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000):F3} MiB/sec.");
if(maxSpeed > 0) if(maxSpeed > 0)
UpdateStatus?.Invoke($"Fastest speed burst: {maxSpeed:F3} MiB/sec."); UpdateStatus?.Invoke($"Fastest speed burst: {maxSpeed:F3} MiB/sec.");

View File

@@ -62,7 +62,7 @@ namespace Aaru.Core.Devices.Dumping
written = _dev.MediumScan(out buffer, true, false, false, false, false, 0, 1, 1, out _, out _, written = _dev.MediumScan(out buffer, true, false, false, false, false, 0, 1, 1, out _, out _,
uint.MaxValue, out _); uint.MaxValue, out _);
FixedSense? decodedSense = Sense.DecodeFixed(buffer); DecodedSense? decodedSense = Sense.Decode(buffer);
if(_dev.LastError != 0 || if(_dev.LastError != 0 ||
decodedSense?.SenseKey == SenseKeys.IllegalRequest) decodedSense?.SenseKey == SenseKeys.IllegalRequest)
@@ -194,8 +194,8 @@ namespace Aaru.Core.Devices.Dumping
break; break;
} }
if((extent.Item2 + 1) - i < blocksToRead) if(extent.Item2 + 1 - i < blocksToRead)
blocksToRead = (uint)((extent.Item2 + 1) - i); blocksToRead = (uint)(extent.Item2 + 1 - i);
if(currentSpeed > maxSpeed && if(currentSpeed > maxSpeed &&
currentSpeed > 0) currentSpeed > 0)
@@ -228,7 +228,7 @@ namespace Aaru.Core.Devices.Dumping
return; // TODO: Return more cleanly return; // TODO: Return more cleanly
if(i + _skip > extent.Item2 + 1) if(i + _skip > extent.Item2 + 1)
_skip = (uint)((extent.Item2 + 1) - i); _skip = (uint)(extent.Item2 + 1 - i);
// Write empty data // Write empty data
DateTime writeStart = DateTime.Now; DateTime writeStart = DateTime.Now;
@@ -254,7 +254,7 @@ namespace Aaru.Core.Devices.Dumping
if(elapsed < 1) if(elapsed < 1)
continue; continue;
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed); currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
} }

View File

@@ -195,11 +195,11 @@ namespace Aaru.Core.Devices
}*/ }*/
testSense = _dev.ReadLong10(out _, out senseBuf, false, false, 0, 0xFFFF, _timeout, out _); testSense = _dev.ReadLong10(out _, out senseBuf, false, false, 0, 0xFFFF, _timeout, out _);
FixedSense? decSense; DecodedSense? decSense;
if(testSense && !_dev.Error) if(testSense && !_dev.Error)
{ {
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.Decode(senseBuf);
if(decSense?.SenseKey == SenseKeys.IllegalRequest && if(decSense?.SenseKey == SenseKeys.IllegalRequest &&
decSense.Value.ASC == 0x24 && decSense.Value.ASC == 0x24 &&
@@ -207,10 +207,24 @@ namespace Aaru.Core.Devices
{ {
CanReadRaw = true; CanReadRaw = true;
if(decSense.Value.InformationValid && bool valid = decSense?.Fixed?.InformationValid == true;
decSense.Value.ILI) bool ili = decSense?.Fixed?.ILI == true;
uint information = decSense?.Fixed?.Information ?? 0;
if(decSense.Value.Descriptor.HasValue &&
decSense.Value.Descriptor.Value.Descriptors.TryGetValue(0, out byte[] desc00))
{ {
LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); valid = true;
ili = true;
information = (uint)Sense.DecodeDescriptor00(desc00);
if(decSense.Value.Descriptor.Value.Descriptors.TryGetValue(4, out byte[] desc04))
Sense.DecodeDescriptor04(desc04, out _, out _, out ili);
}
if(valid && ili)
{
LongBlockSize = 0xFFFF - (information & 0xFFFF);
_readLong10 = !_dev.ReadLong10(out _, out senseBuf, false, false, 0, _readLong10 = !_dev.ReadLong10(out _, out senseBuf, false, false, 0,
(ushort)LongBlockSize, _timeout, out _); (ushort)LongBlockSize, _timeout, out _);
@@ -392,7 +406,7 @@ namespace Aaru.Core.Devices
if(testSense) if(testSense)
{ {
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.Decode(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && if(decSense.Value.SenseKey == SenseKeys.IllegalRequest &&
@@ -401,10 +415,25 @@ namespace Aaru.Core.Devices
{ {
CanReadRaw = true; CanReadRaw = true;
if(decSense.Value.InformationValid && bool valid = decSense?.Fixed?.InformationValid == true;
decSense.Value.ILI) bool ili = decSense?.Fixed?.ILI == true;
uint information = decSense?.Fixed?.Information ?? 0;
if(decSense.Value.Descriptor.HasValue &&
decSense.Value.Descriptor.Value.Descriptors.TryGetValue(0, out byte[] desc00))
{ {
LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); valid = true;
ili = true;
information = (uint)Sense.DecodeDescriptor00(desc00);
if(decSense.Value.Descriptor.Value.Descriptors.
TryGetValue(4, out byte[] desc04))
Sense.DecodeDescriptor04(desc04, out _, out _, out ili);
}
if(valid && ili)
{
LongBlockSize = 0xFFFF - (information & 0xFFFF);
_syqReadLong10 = _syqReadLong10 =
!_dev.SyQuestReadLong10(out _, out senseBuf, 0, LongBlockSize, _timeout, !_dev.SyQuestReadLong10(out _, out senseBuf, 0, LongBlockSize, _timeout,
@@ -417,7 +446,7 @@ namespace Aaru.Core.Devices
if(testSense) if(testSense)
{ {
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.Decode(senseBuf);
if(decSense?.SenseKey == SenseKeys.IllegalRequest && if(decSense?.SenseKey == SenseKeys.IllegalRequest &&
decSense.Value.ASC == 0x24 && decSense.Value.ASC == 0x24 &&
@@ -425,10 +454,26 @@ namespace Aaru.Core.Devices
{ {
CanReadRaw = true; CanReadRaw = true;
if(decSense.Value.InformationValid && bool valid = decSense?.Fixed?.InformationValid == true;
decSense.Value.ILI) bool ili = decSense?.Fixed?.ILI == true;
uint information = decSense?.Fixed?.Information ?? 0;
if(decSense.Value.Descriptor.HasValue &&
decSense.Value.Descriptor.Value.Descriptors.
TryGetValue(0, out byte[] desc00))
{ {
LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); valid = true;
ili = true;
information = (uint)Sense.DecodeDescriptor00(desc00);
if(decSense.Value.Descriptor.Value.Descriptors.
TryGetValue(4, out byte[] desc04))
Sense.DecodeDescriptor04(desc04, out _, out _, out ili);
}
if(valid && ili)
{
LongBlockSize = 0xFFFF - (information & 0xFFFF);
_syqReadLong6 = _syqReadLong6 =
!_dev.SyQuestReadLong6(out _, out senseBuf, 0, LongBlockSize, !_dev.SyQuestReadLong6(out _, out senseBuf, 0, LongBlockSize,
@@ -675,11 +720,9 @@ namespace Aaru.Core.Devices
!_dev.Error) !_dev.Error)
return false; return false;
recoveredError = Sense.DecodeFixed(senseBuf)?.SenseKey == SenseKeys.RecoveredError || recoveredError = Sense.Decode(senseBuf)?.SenseKey == SenseKeys.RecoveredError;
Sense.DecodeDescriptor(senseBuf)?.SenseKey == SenseKeys.RecoveredError;
blankCheck = Sense.DecodeFixed(senseBuf)?.SenseKey == SenseKeys.BlankCheck || blankCheck = Sense.Decode(senseBuf)?.SenseKey == SenseKeys.BlankCheck;
Sense.DecodeDescriptor(senseBuf)?.SenseKey == SenseKeys.BlankCheck;
AaruConsole.DebugWriteLine("SCSI Reader", "READ error:\n{0}", Sense.PrettifySense(senseBuf)); AaruConsole.DebugWriteLine("SCSI Reader", "READ error:\n{0}", Sense.PrettifySense(senseBuf));

View File

@@ -92,7 +92,7 @@ namespace Aaru.Core.Devices.Report
if(!sense) if(!sense)
break; break;
FixedSense? decodedSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decodedSense = Sense.Decode(senseBuffer);
if(decodedSense?.ASC != 0x04) if(decodedSense?.ASC != 0x04)
break; break;
@@ -172,7 +172,7 @@ namespace Aaru.Core.Devices.Report
frame = ((leadOutTrack.PFRAME >> 4) * 10) + (leadOutTrack.PFRAME & 0x0F); frame = ((leadOutTrack.PFRAME >> 4) * 10) + (leadOutTrack.PFRAME & 0x0F);
} }
int sectors = ((min * 60 * 75) + (sec * 75) + frame) - 150; int sectors = (min * 60 * 75) + (sec * 75) + frame - 150;
AaruConsole.WriteLine("Trap disc shows {0} sectors...", sectors); AaruConsole.WriteLine("Trap disc shows {0} sectors...", sectors);
@@ -211,7 +211,7 @@ namespace Aaru.Core.Devices.Report
if(!sense) if(!sense)
break; break;
FixedSense? decodedSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decodedSense = Sense.Decode(senseBuffer);
if(decodedSense?.ASC != 0x04) if(decodedSense?.ASC != 0x04)
break; break;
@@ -1568,7 +1568,7 @@ namespace Aaru.Core.Devices.Report
if(trackModeChange) if(trackModeChange)
break; break;
FixedSense? decoded = Sense.DecodeFixed(senseBuffer); DecodedSense? decoded = Sense.Decode(senseBuffer);
if(decoded?.ASC != 0x64) if(decoded?.ASC != 0x64)
break; break;
@@ -1596,7 +1596,7 @@ namespace Aaru.Core.Devices.Report
break; break;
} }
report.GdRomSwapDiscCapabilities.MaximumReadableSectorInHdArea = (lba + cluster) - 1; report.GdRomSwapDiscCapabilities.MaximumReadableSectorInHdArea = lba + cluster - 1;
} }
AaruConsole.WriteLine(); AaruConsole.WriteLine();

View File

@@ -1611,7 +1611,7 @@ namespace Aaru.Core.Devices.Report
if(sense && !_dev.Error) if(sense && !_dev.Error)
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decSense = Sense.Decode(senseBuffer);
if(decSense?.SenseKey == SenseKeys.IllegalRequest && if(decSense?.SenseKey == SenseKeys.IllegalRequest &&
decSense.Value.ASC == 0x24 && decSense.Value.ASC == 0x24 &&
@@ -1619,9 +1619,20 @@ namespace Aaru.Core.Devices.Report
{ {
mediaTest.SupportsReadLong = true; mediaTest.SupportsReadLong = true;
if(decSense.Value.InformationValid && bool valid = decSense?.Fixed?.InformationValid == true;
decSense.Value.ILI) bool ili = decSense?.Fixed?.ILI == true;
mediaTest.LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); uint information = decSense?.Fixed?.Information ?? 0;
if(decSense?.Descriptor.HasValue == true &&
decSense.Value.Descriptor.Value.Descriptors.TryGetValue(0, out byte[] desc00))
{
valid = true;
ili = true;
information = (uint)Sense.DecodeDescriptor00(desc00);
}
if(valid && ili)
mediaTest.LongBlockSize = 0xFFFF - (information & 0xFFFF);
} }
} }

View File

@@ -520,7 +520,7 @@ namespace Aaru.Core.Devices.Report
if(sense && !_dev.Error) if(sense && !_dev.Error)
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decSense = Sense.Decode(senseBuffer);
if(decSense?.SenseKey == SenseKeys.IllegalRequest && if(decSense?.SenseKey == SenseKeys.IllegalRequest &&
decSense.Value.ASC == 0x24 && decSense.Value.ASC == 0x24 &&
@@ -528,9 +528,20 @@ namespace Aaru.Core.Devices.Report
{ {
mediaTest.SupportsReadLong = true; mediaTest.SupportsReadLong = true;
if(decSense.Value.InformationValid && bool valid = decSense?.Fixed?.InformationValid == true;
decSense.Value.ILI) bool ili = decSense?.Fixed?.ILI == true;
mediaTest.LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); uint information = decSense?.Fixed?.Information ?? 0;
if(decSense?.Descriptor.HasValue == true &&
decSense.Value.Descriptor.Value.Descriptors.TryGetValue(0, out byte[] desc00))
{
valid = true;
ili = true;
information = (uint)Sense.DecodeDescriptor00(desc00);
}
if(valid && ili)
mediaTest.LongBlockSize = 0xFFFF - (information & 0xFFFF);
} }
} }
@@ -728,7 +739,7 @@ namespace Aaru.Core.Devices.Report
if(sense && !_dev.Error) if(sense && !_dev.Error)
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decSense = Sense.Decode(senseBuffer);
if(decSense?.SenseKey == SenseKeys.IllegalRequest && if(decSense?.SenseKey == SenseKeys.IllegalRequest &&
decSense.Value.ASC == 0x24 && decSense.Value.ASC == 0x24 &&
@@ -736,9 +747,20 @@ namespace Aaru.Core.Devices.Report
{ {
capabilities.SupportsReadLong = true; capabilities.SupportsReadLong = true;
if(decSense.Value.InformationValid && bool valid = decSense?.Fixed?.InformationValid == true;
decSense.Value.ILI) bool ili = decSense?.Fixed?.ILI == true;
capabilities.LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); uint information = decSense?.Fixed?.Information ?? 0;
if(decSense?.Descriptor.HasValue == true &&
decSense.Value.Descriptor.Value.Descriptors.TryGetValue(0, out byte[] desc00))
{
valid = true;
ili = true;
information = (uint)Sense.DecodeDescriptor00(desc00);
}
if(valid && ili)
capabilities.LongBlockSize = 0xFFFF - (information & 0xFFFF);
} }
} }

View File

@@ -65,7 +65,7 @@ namespace Aaru.Core.Devices.Scanning
if(sense) if(sense)
{ {
InitProgress?.Invoke(); InitProgress?.Invoke();
FixedSense? decSense = Sense.DecodeFixed(senseBuf); DecodedSense? decSense = Sense.Decode(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
if(decSense.Value.ASC == 0x3A) if(decSense.Value.ASC == 0x3A)
@@ -391,7 +391,7 @@ namespace Aaru.Core.Devices.Scanning
{ {
AaruConsole.DebugWriteLine("Media-Scan", "READ CD error:\n{0}", Sense.PrettifySense(senseBuf)); AaruConsole.DebugWriteLine("Media-Scan", "READ CD error:\n{0}", Sense.PrettifySense(senseBuf));
FixedSense? senseDecoded = Sense.DecodeFixed(senseBuf); DecodedSense? senseDecoded = Sense.Decode(senseBuf);
if(senseDecoded.HasValue) if(senseDecoded.HasValue)
{ {
@@ -435,7 +435,7 @@ namespace Aaru.Core.Devices.Scanning
if(elapsed < 1) if(elapsed < 1)
continue; continue;
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed); currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
ScanSpeed?.Invoke(i, currentSpeed * 1024); ScanSpeed?.Invoke(i, currentSpeed * 1024);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
@@ -446,7 +446,7 @@ namespace Aaru.Core.Devices.Scanning
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(_dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(_dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
(blockSize * (double)(results.Blocks + 1)) / 1024 / (results.ProcessingTime / 1000), blockSize * (double)(results.Blocks + 1) / 1024 / (results.ProcessingTime / 1000),
_devicePath); _devicePath);
} }
else else
@@ -526,7 +526,7 @@ namespace Aaru.Core.Devices.Scanning
if(elapsed < 1) if(elapsed < 1)
continue; continue;
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed); currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
ScanSpeed?.Invoke(i, currentSpeed * 1024); ScanSpeed?.Invoke(i, currentSpeed * 1024);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
@@ -537,7 +537,7 @@ namespace Aaru.Core.Devices.Scanning
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(_dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(_dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
(blockSize * (double)(results.Blocks + 1)) / 1024 / (results.ProcessingTime / 1000), blockSize * (double)(results.Blocks + 1) / 1024 / (results.ProcessingTime / 1000),
_devicePath); _devicePath);
} }
@@ -582,7 +582,7 @@ namespace Aaru.Core.Devices.Scanning
results.ProcessingTime /= 1000; results.ProcessingTime /= 1000;
results.TotalTime = (end - start).TotalSeconds; results.TotalTime = (end - start).TotalSeconds;
results.AvgSpeed = (blockSize * (double)(results.Blocks + 1)) / 1048576 / results.ProcessingTime; results.AvgSpeed = blockSize * (double)(results.Blocks + 1) / 1048576 / results.ProcessingTime;
results.SeekTimes = seekTimes; results.SeekTimes = seekTimes;
return results; return results;

View File

@@ -369,12 +369,11 @@ namespace Aaru.Core.Logging
return; return;
} }
FixedSense? decodedFixedSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decodedSense = Sense.Decode(senseBuffer);
DescriptorSense? decodedDescriptorSense = Sense.DecodeDescriptor(senseBuffer);
string prettySense = Sense.PrettifySense(senseBuffer); string prettySense = Sense.PrettifySense(senseBuffer);
string hexSense = string.Join(' ', senseBuffer.Select(b => $"{b:X2}")); string hexSense = string.Join(' ', senseBuffer.Select(b => $"{b:X2}"));
if(decodedFixedSense.HasValue) if(decodedSense.HasValue)
{ {
if(prettySense != null) if(prettySense != null)
{ {
@@ -387,37 +386,13 @@ namespace Aaru.Core.Logging
prettySense = prettySense.Replace("\n", " - "); prettySense = prettySense.Replace("\n", " - ");
_logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", command, _logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", command,
decodedFixedSense?.SenseKey, decodedFixedSense?.ASC, decodedFixedSense?.ASCQ, decodedSense?.SenseKey, decodedSense?.ASC, decodedSense?.ASCQ, hexSense,
hexSense, prettySense); prettySense);
} }
else else
{ {
_logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", command, _logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", command,
decodedFixedSense?.SenseKey, decodedFixedSense?.ASC, decodedFixedSense?.ASCQ, decodedSense?.SenseKey, decodedSense?.ASC, decodedSense?.ASCQ, hexSense);
hexSense);
}
}
else if(decodedDescriptorSense.HasValue)
{
if(prettySense != null)
{
if(prettySense.StartsWith("SCSI SENSE: ", StringComparison.Ordinal))
prettySense = prettySense.Substring(12);
if(prettySense.EndsWith('\n'))
prettySense = prettySense.Substring(0, prettySense.Length - 1);
prettySense = prettySense.Replace("\n", " - ");
_logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", command,
decodedDescriptorSense?.SenseKey, decodedDescriptorSense?.ASC,
decodedDescriptorSense?.ASCQ, hexSense, prettySense);
}
else
{
_logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", command,
decodedDescriptorSense?.SenseKey, decodedDescriptorSense?.ASC,
decodedDescriptorSense?.ASCQ, hexSense);
} }
} }
else else
@@ -461,12 +436,11 @@ namespace Aaru.Core.Logging
return; return;
} }
FixedSense? decodedFixedSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decodedSense = Sense.Decode(senseBuffer);
DescriptorSense? decodedDescriptorSense = Sense.DecodeDescriptor(senseBuffer);
string prettySense = Sense.PrettifySense(senseBuffer); string prettySense = Sense.PrettifySense(senseBuffer);
string hexSense = string.Join(' ', senseBuffer.Select(b => $"{b:X2}")); string hexSense = string.Join(' ', senseBuffer.Select(b => $"{b:X2}"));
if(decodedFixedSense.HasValue) if(decodedSense.HasValue)
{ {
if(prettySense != null) if(prettySense != null)
{ {
@@ -479,37 +453,13 @@ namespace Aaru.Core.Logging
prettySense = prettySense.Replace("\n", " - "); prettySense = prettySense.Replace("\n", " - ");
_logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", block, _logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", block,
decodedFixedSense?.SenseKey, decodedFixedSense?.ASC, decodedFixedSense?.ASCQ, decodedSense?.SenseKey, decodedSense?.ASC, decodedSense?.ASCQ, hexSense,
hexSense, prettySense); prettySense);
} }
else else
{ {
_logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", block, _logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", block,
decodedFixedSense?.SenseKey, decodedFixedSense?.ASC, decodedFixedSense?.ASCQ, decodedSense?.SenseKey, decodedSense?.ASC, decodedSense?.ASCQ, hexSense);
hexSense);
}
}
else if(decodedDescriptorSense.HasValue)
{
if(prettySense != null)
{
if(prettySense.StartsWith("SCSI SENSE: ", StringComparison.Ordinal))
prettySense = prettySense.Substring(12);
if(prettySense.EndsWith('\n'))
prettySense = prettySense.Substring(0, prettySense.Length - 1);
prettySense = prettySense.Replace("\n", " - ");
_logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", block,
decodedDescriptorSense?.SenseKey, decodedDescriptorSense?.ASC,
decodedDescriptorSense?.ASCQ, hexSense, prettySense);
}
else
{
_logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", block,
decodedDescriptorSense?.SenseKey, decodedDescriptorSense?.ASC,
decodedDescriptorSense?.ASCQ, hexSense);
} }
} }
else else

View File

@@ -78,7 +78,7 @@ namespace Aaru.Core.Media.Info
if(sense) if(sense)
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuf); DecodedSense? decSense = Sense.Decode(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
{ {
@@ -1300,7 +1300,7 @@ namespace Aaru.Core.Media.Info
{ {
AaruConsole.ErrorWriteLine("Cannot lock drive, not continuing."); AaruConsole.ErrorWriteLine("Cannot lock drive, not continuing.");
return; break;
} }
sense = dev.ReadCapacity(out cmdBuf, out senseBuf, dev.Timeout, out _); sense = dev.ReadCapacity(out cmdBuf, out senseBuf, dev.Timeout, out _);
@@ -1309,7 +1309,7 @@ namespace Aaru.Core.Media.Info
{ {
AaruConsole.ErrorWriteLine("Cannot get disc capacity."); AaruConsole.ErrorWriteLine("Cannot get disc capacity.");
return; break;
} }
ulong totalSize = ulong totalSize =
@@ -1322,7 +1322,7 @@ namespace Aaru.Core.Media.Info
{ {
AaruConsole.ErrorWriteLine("Cannot get PFI."); AaruConsole.ErrorWriteLine("Cannot get PFI.");
return; break;
} }
AaruConsole.DebugWriteLine("Dump-media command", "Video partition total size: {0} sectors", AaruConsole.DebugWriteLine("Dump-media command", "Video partition total size: {0} sectors",
@@ -1341,7 +1341,7 @@ namespace Aaru.Core.Media.Info
{ {
AaruConsole.ErrorWriteLine("Cannot unlock drive, not continuing."); AaruConsole.ErrorWriteLine("Cannot unlock drive, not continuing.");
return; break;
} }
sense = dev.ReadCapacity(out cmdBuf, out senseBuf, dev.Timeout, out _); sense = dev.ReadCapacity(out cmdBuf, out senseBuf, dev.Timeout, out _);
@@ -1367,7 +1367,7 @@ namespace Aaru.Core.Media.Info
{ {
AaruConsole.ErrorWriteLine("Cannot unlock drive, not continuing."); AaruConsole.ErrorWriteLine("Cannot unlock drive, not continuing.");
return; break;
} }
sense = dev.ReadCapacity(out cmdBuf, out senseBuf, dev.Timeout, out _); sense = dev.ReadCapacity(out cmdBuf, out senseBuf, dev.Timeout, out _);
@@ -1376,7 +1376,7 @@ namespace Aaru.Core.Media.Info
{ {
AaruConsole.ErrorWriteLine("Cannot get disc capacity."); AaruConsole.ErrorWriteLine("Cannot get disc capacity.");
return; break;
} }
totalSize = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]); totalSize = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]);
@@ -1388,7 +1388,7 @@ namespace Aaru.Core.Media.Info
{ {
AaruConsole.ErrorWriteLine("Cannot get PFI."); AaruConsole.ErrorWriteLine("Cannot get PFI.");
return; break;
} }
AaruConsole.DebugWriteLine("Dump-media command", "Unlocked total size: {0} sectors", AaruConsole.DebugWriteLine("Dump-media command", "Unlocked total size: {0} sectors",

View File

@@ -115,14 +115,14 @@ namespace Aaru.Devices
if(Error) if(Error)
return sense; return sense;
FixedSense? decodedSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decodedSense = Sense.Decode(senseBuffer);
switch(decodedSense?.SenseKey) switch(decodedSense?.SenseKey)
{ {
case SenseKeys.NoSense: return false; case SenseKeys.NoSense: return false;
case SenseKeys.Equal when decodedSense.Value.InformationValid: case SenseKeys.Equal when decodedSense.Value.Fixed?.InformationValid == true:
foundBlocks = decodedSense.Value.CommandSpecific; foundBlocks = decodedSense.Value.Fixed.Value.CommandSpecific;
foundLba = decodedSense.Value.Information; foundLba = decodedSense.Value.Fixed.Value.Information;
return false; return false;
default: return sense; default: return sense;

View File

@@ -44,7 +44,7 @@ namespace Aaru.Tests.Devices
if(!sense) if(!sense)
break; break;
FixedSense? decodedSense = Sense.DecodeFixed(senseBuffer); var decodedSense = Sense.Decode(senseBuffer);
if(decodedSense.Value.ASC != 0x04) if(decodedSense.Value.ASC != 0x04)
break; break;
@@ -152,7 +152,7 @@ namespace Aaru.Tests.Devices
if(!sense) if(!sense)
break; break;
FixedSense? decodedSense = Sense.DecodeFixed(senseBuffer); var decodedSense = Sense.Decode(senseBuffer);
if(decodedSense.Value.ASC != 0x04) if(decodedSense.Value.ASC != 0x04)
break; break;

View File

@@ -44,7 +44,7 @@ namespace Aaru.Tests.Devices
if(!sense) if(!sense)
break; break;
FixedSense? decodedSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decodedSense = Sense.Decode(senseBuffer);
if(decodedSense.Value.ASC != 0x04) if(decodedSense.Value.ASC != 0x04)
break; break;
@@ -95,7 +95,7 @@ namespace Aaru.Tests.Devices
int sec = ((leadOutTrack.PSEC >> 4) * 10) + (leadOutTrack.PSEC & 0x0F); int sec = ((leadOutTrack.PSEC >> 4) * 10) + (leadOutTrack.PSEC & 0x0F);
int frame = ((leadOutTrack.PFRAME >> 4) * 10) + (leadOutTrack.PFRAME & 0x0F); int frame = ((leadOutTrack.PFRAME >> 4) * 10) + (leadOutTrack.PFRAME & 0x0F);
int sectors = ((min * 60 * 75) + (sec * 75) + frame) - 150; int sectors = (min * 60 * 75) + (sec * 75) + frame - 150;
AaruConsole.WriteLine("Data disc shows {0} sectors...", sectors); AaruConsole.WriteLine("Data disc shows {0} sectors...", sectors);
@@ -120,7 +120,7 @@ namespace Aaru.Tests.Devices
if(!sense) if(!sense)
break; break;
FixedSense? decodedSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decodedSense = Sense.Decode(senseBuffer);
if(decodedSense.Value.ASC != 0x04) if(decodedSense.Value.ASC != 0x04)
break; break;
@@ -192,7 +192,7 @@ namespace Aaru.Tests.Devices
frame = ((leadOutTrack.PFRAME >> 4) * 10) + (leadOutTrack.PFRAME & 0x0F); frame = ((leadOutTrack.PFRAME >> 4) * 10) + (leadOutTrack.PFRAME & 0x0F);
} }
int trapSectors = ((min * 60 * 75) + (sec * 75) + frame) - 150; int trapSectors = (min * 60 * 75) + (sec * 75) + frame - 150;
AaruConsole.WriteLine("Trap disc shows {0} sectors...", trapSectors); AaruConsole.WriteLine("Trap disc shows {0} sectors...", trapSectors);
@@ -228,7 +228,7 @@ namespace Aaru.Tests.Devices
if(!sense) if(!sense)
break; break;
FixedSense? decodedSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decodedSense = Sense.Decode(senseBuffer);
if(decodedSense.Value.ASC != 0x04) if(decodedSense.Value.ASC != 0x04)
break; break;

View File

@@ -896,11 +896,13 @@ namespace Aaru.Commands.Device
if(sense) if(sense)
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decSense = Sense.Decode(senseBuffer);
if(decSense.HasValue) if(decSense.HasValue)
{ {
if(decSense.Value.ASC == 0x3A) switch(decSense.Value.ASC)
{
case 0x3A:
{ {
int leftRetries = 50; int leftRetries = 50;
@@ -908,7 +910,9 @@ namespace Aaru.Commands.Device
{ {
AaruConsole.Write("\rWaiting for drive to become ready"); AaruConsole.Write("\rWaiting for drive to become ready");
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout,
out _);
if(!sense) if(!sense)
break; break;
@@ -919,31 +923,12 @@ namespace Aaru.Commands.Device
AaruConsole.WriteLine(); AaruConsole.WriteLine();
mediaIsRecognized &= !sense; mediaIsRecognized &= !sense;
}
else if(decSense.Value.ASC == 0x04 &&
decSense.Value.ASCQ == 0x01)
{
int leftRetries = 50;
while(leftRetries > 0)
{
AaruConsole.Write("\rWaiting for drive to become ready");
Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
if(!sense)
break; break;
leftRetries--;
}
AaruConsole.WriteLine();
mediaIsRecognized &= !sense;
} }
// These should be trapped by the OS but seems in some cases they're not // These should be trapped by the OS but seems in some cases they're not
else if(decSense.Value.ASC == 0x28) case 0x04 when decSense.Value.ASCQ == 0x01:
{ {
int leftRetries = 50; int leftRetries = 50;
@@ -951,7 +936,9 @@ namespace Aaru.Commands.Device
{ {
AaruConsole.Write("\rWaiting for drive to become ready"); AaruConsole.Write("\rWaiting for drive to become ready");
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout,
out _);
if(!sense) if(!sense)
break; break;
@@ -962,15 +949,42 @@ namespace Aaru.Commands.Device
AaruConsole.WriteLine(); AaruConsole.WriteLine();
mediaIsRecognized &= !sense; mediaIsRecognized &= !sense;
break;
} }
else case 0x28:
{ {
int leftRetries = 50;
while(leftRetries > 0)
{
AaruConsole.Write("\rWaiting for drive to become ready");
Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout,
out _);
if(!sense)
break;
leftRetries--;
}
AaruConsole.WriteLine();
mediaIsRecognized &= !sense;
break;
}
default:
AaruConsole.DebugWriteLine("Device-Report command", AaruConsole.DebugWriteLine("Device-Report command",
"Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", "Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.SenseKey,
decSense.Value.ASCQ); decSense.Value.ASC, decSense.Value.ASCQ);
mediaIsRecognized = false; mediaIsRecognized = false;
break;
} }
} }
else else
@@ -1101,11 +1115,13 @@ namespace Aaru.Commands.Device
if(sense) if(sense)
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decSense = Sense.Decode(senseBuffer);
if(decSense.HasValue) if(decSense.HasValue)
{ {
if(decSense.Value.ASC == 0x3A) switch(decSense.Value.ASC)
{
case 0x3A:
{ {
int leftRetries = 50; int leftRetries = 50;
@@ -1124,31 +1140,12 @@ namespace Aaru.Commands.Device
AaruConsole.WriteLine(); AaruConsole.WriteLine();
mediaIsRecognized &= !sense; mediaIsRecognized &= !sense;
}
else if(decSense.Value.ASC == 0x04 &&
decSense.Value.ASCQ == 0x01)
{
int leftRetries = 50;
while(leftRetries > 0)
{
AaruConsole.Write("\rWaiting for drive to become ready");
Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
if(!sense)
break; break;
leftRetries--;
}
AaruConsole.WriteLine();
mediaIsRecognized &= !sense;
} }
// These should be trapped by the OS but seems in some cases they're not // These should be trapped by the OS but seems in some cases they're not
else if(decSense.Value.ASC == 0x28) case 0x04 when decSense.Value.ASCQ == 0x01:
{ {
int leftRetries = 50; int leftRetries = 50;
@@ -1167,15 +1164,40 @@ namespace Aaru.Commands.Device
AaruConsole.WriteLine(); AaruConsole.WriteLine();
mediaIsRecognized &= !sense; mediaIsRecognized &= !sense;
break;
} }
else case 0x28:
{ {
int leftRetries = 50;
while(leftRetries > 0)
{
AaruConsole.Write("\rWaiting for drive to become ready");
Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
if(!sense)
break;
leftRetries--;
}
AaruConsole.WriteLine();
mediaIsRecognized &= !sense;
break;
}
default:
AaruConsole.DebugWriteLine("Device-Report command", AaruConsole.DebugWriteLine("Device-Report command",
"Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h", "Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.SenseKey, decSense.Value.ASC,
decSense.Value.ASCQ); decSense.Value.ASCQ);
mediaIsRecognized = false; mediaIsRecognized = false;
break;
} }
} }
else else
@@ -1254,11 +1276,13 @@ namespace Aaru.Commands.Device
if(sense) if(sense)
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decSense = Sense.Decode(senseBuffer);
if(decSense.HasValue) if(decSense.HasValue)
{ {
if(decSense.Value.ASC == 0x3A) switch(decSense.Value.ASC)
{
case 0x3A:
{ {
int leftRetries = 50; int leftRetries = 50;
@@ -1277,31 +1301,12 @@ namespace Aaru.Commands.Device
AaruConsole.WriteLine(); AaruConsole.WriteLine();
mediaIsRecognized &= !sense; mediaIsRecognized &= !sense;
}
else if(decSense.Value.ASC == 0x04 &&
decSense.Value.ASCQ == 0x01)
{
int leftRetries = 50;
while(leftRetries > 0)
{
AaruConsole.Write("\rWaiting for drive to become ready");
Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
if(!sense)
break; break;
leftRetries--;
}
AaruConsole.WriteLine();
mediaIsRecognized &= !sense;
} }
// These should be trapped by the OS but seems in some cases they're not // These should be trapped by the OS but seems in some cases they're not
else if(decSense.Value.ASC == 0x28) case 0x04 when decSense.Value.ASCQ == 0x01:
{ {
int leftRetries = 50; int leftRetries = 50;
@@ -1320,15 +1325,40 @@ namespace Aaru.Commands.Device
AaruConsole.WriteLine(); AaruConsole.WriteLine();
mediaIsRecognized &= !sense; mediaIsRecognized &= !sense;
break;
} }
else case 0x28:
{ {
int leftRetries = 50;
while(leftRetries > 0)
{
AaruConsole.Write("\rWaiting for drive to become ready");
Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
if(!sense)
break;
leftRetries--;
}
AaruConsole.WriteLine();
mediaIsRecognized &= !sense;
break;
}
default:
AaruConsole.DebugWriteLine("Device-Report command", AaruConsole.DebugWriteLine("Device-Report command",
"Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", "Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h",
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.SenseKey, decSense.Value.ASC,
decSense.Value.ASCQ); decSense.Value.ASCQ);
mediaIsRecognized = false; mediaIsRecognized = false;
break;
} }
} }
else else
@@ -1480,10 +1510,12 @@ namespace Aaru.Commands.Device
if(sense) if(sense)
{ {
FixedSense? decSense = Sense.DecodeFixed(senseBuffer); DecodedSense? decSense = Sense.Decode(senseBuffer);
if(decSense.HasValue) if(decSense.HasValue)
if(decSense.Value.ASC == 0x3A) switch(decSense.Value.ASC)
{
case 0x3A:
{ {
int leftRetries = 20; int leftRetries = 20;
@@ -1491,7 +1523,9 @@ namespace Aaru.Commands.Device
{ {
AaruConsole.Write("\rWaiting for drive to become ready"); AaruConsole.Write("\rWaiting for drive to become ready");
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout,
out _);
if(!sense) if(!sense)
break; break;
@@ -1502,9 +1536,10 @@ namespace Aaru.Commands.Device
AaruConsole.WriteLine(); AaruConsole.WriteLine();
mediaIsRecognized &= !sense; mediaIsRecognized &= !sense;
break;
} }
else if(decSense.Value.ASC == 0x04 && case 0x04 when decSense.Value.ASCQ == 0x01:
decSense.Value.ASCQ == 0x01)
{ {
int leftRetries = 20; int leftRetries = 20;
@@ -1512,7 +1547,9 @@ namespace Aaru.Commands.Device
{ {
AaruConsole.Write("\rWaiting for drive to become ready"); AaruConsole.Write("\rWaiting for drive to become ready");
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout,
out _);
if(!sense) if(!sense)
break; break;
@@ -1523,10 +1560,13 @@ namespace Aaru.Commands.Device
AaruConsole.WriteLine(); AaruConsole.WriteLine();
mediaIsRecognized &= !sense; mediaIsRecognized &= !sense;
break;
} }
else default:
{
mediaIsRecognized = false; mediaIsRecognized = false;
break;
} }
else else
mediaIsRecognized = false; mediaIsRecognized = false;