* DiscImageChef.Decoders/SCSI/Modes.cs:

Polished some bugs and typos and format

	* DiscImageChef.Devices/Device/ScsiCommands.cs:
	  Corrected math typo.

	* DiscImageChef/Commands/DeviceInfo.cs:
	  Added MODE SENSE to device information.
This commit is contained in:
2015-10-31 21:03:18 +00:00
parent cd1ce818ff
commit 6b9f8f97c8
6 changed files with 704 additions and 356 deletions

View File

@@ -1,3 +1,8 @@
2015-10-31 Natalia Portillo <claunia@claunia.com>
* SCSI/Modes.cs:
Polished some bugs and typos and format
2015-10-31 Natalia Portillo <claunia@claunia.com>
* SCSI/Modes.cs:

View File

@@ -172,6 +172,7 @@ namespace DiscImageChef.Decoders.SCSI
#endregion Medium Types defined in SCSI-2 for MultiMedia devices
#region Medium Types defined in SFF-8020i
/// <summary>
/// Unknown medium type
/// </summary>
@@ -279,6 +280,7 @@ namespace DiscImageChef.Decoders.SCSI
#endregion Medium Types defined in SFF-8020i
#region Medium Types defined in USB Mass Storage Class - UFI Command Specification
/// <summary>
/// 3.5-inch, 135 tpi, 12362 bits/radian, double-sided MFM (aka 1.25Mb)
/// </summary>
@@ -290,6 +292,7 @@ namespace DiscImageChef.Decoders.SCSI
#endregion Medium Types defined in USB Mass Storage Class - UFI Command Specification
#region Medium Types defined in INF-8070
/// <summary>
/// Unknown type block device
/// </summary>
@@ -302,6 +305,7 @@ namespace DiscImageChef.Decoders.SCSI
/// Read/Write block device
/// </summary>
ReadWriteBlockDevice = 0x42
#endregion Medium Types defined in INF-8070
}
@@ -561,7 +565,7 @@ namespace DiscImageChef.Decoders.SCSI
StringBuilder sb = new StringBuilder();
sb.AppendLine("SCSI Mode Page 0:");
sb.AppendLine("SCSI Mode Sense Header:");
switch (deviceType)
{
@@ -569,7 +573,7 @@ namespace DiscImageChef.Decoders.SCSI
{
if (header.Value.MediumType != MediumTypes.Default)
{
sb.Append("Medium is ");
sb.Append("\tMedium is ");
switch (header.Value.MediumType)
{
@@ -631,11 +635,13 @@ namespace DiscImageChef.Decoders.SCSI
}
if (header.Value.WriteProtected)
sb.AppendLine("Medium is write protected");
sb.AppendLine("\tMedium is write protected");
if (header.Value.DPOFUA)
sb.AppendLine("Drive supports DPO and FUA bits");
sb.AppendLine("\tDrive supports DPO and FUA bits");
if (header.Value.BlockDescriptors != null)
{
foreach (BlockDescriptor descriptor in header.Value.BlockDescriptors)
{
string density = "";
@@ -660,16 +666,17 @@ namespace DiscImageChef.Decoders.SCSI
if (density != "")
{
if (descriptor.Blocks == 0)
sb.AppendFormat("All remaining blocks have {0} and are {1} bytes each", density, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\tAll remaining blocks have {0} and are {1} bytes each", density, descriptor.BlockLength).AppendLine();
else
sb.AppendFormat("{0} blocks have {1} and are {2} bytes each", descriptor.Blocks, density, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\t{0} blocks have {1} and are {2} bytes each", descriptor.Blocks, density, descriptor.BlockLength).AppendLine();
}
else
{
if (descriptor.Blocks == 0)
sb.AppendFormat("All remaining blocks are {0} bytes each", descriptor.BlockLength).AppendLine();
sb.AppendFormat("\tAll remaining blocks are {0} bytes each", descriptor.BlockLength).AppendLine();
else
sb.AppendFormat("{0} blocks are {1} bytes each", descriptor.Blocks, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\t{0} blocks are {1} bytes each", descriptor.Blocks, descriptor.BlockLength).AppendLine();
}
}
}
@@ -680,27 +687,29 @@ namespace DiscImageChef.Decoders.SCSI
switch (header.Value.BufferedMode)
{
case 0:
sb.AppendLine("Device writes directly to media");
sb.AppendLine("\tDevice writes directly to media");
break;
case 1:
sb.AppendLine("Device uses a write cache");
sb.AppendLine("\tDevice uses a write cache");
break;
case 2:
sb.AppendLine("Device uses a write cache but doesn't return until cache is flushed");
sb.AppendLine("\tDevice uses a write cache but doesn't return until cache is flushed");
break;
default:
sb.AppendFormat("Unknown buffered mode code 0x{0:X2}", header.Value.BufferedMode).AppendLine();
sb.AppendFormat("\tUnknown buffered mode code 0x{0:X2}", header.Value.BufferedMode).AppendLine();
break;
}
if (header.Value.Speed == 0)
sb.AppendLine("Device uses default speed");
sb.AppendLine("\tDevice uses default speed");
else
sb.AppendFormat("Device uses speed {0}", header.Value.Speed).AppendLine();
sb.AppendFormat("\tDevice uses speed {0}", header.Value.Speed).AppendLine();
if (header.Value.WriteProtected)
sb.AppendLine("Medium is write protected");
sb.AppendLine("\tMedium is write protected");
if (header.Value.BlockDescriptors != null)
{
foreach (BlockDescriptor descriptor in header.Value.BlockDescriptors)
{
string density = "";
@@ -784,16 +793,16 @@ namespace DiscImageChef.Decoders.SCSI
if (descriptor.Blocks == 0)
{
if (descriptor.BlockLength == 0)
sb.AppendFormat("All remaining blocks conform to {0} and have a variable length", density).AppendLine();
sb.AppendFormat("\tAll remaining blocks conform to {0} and have a variable length", density).AppendLine();
else
sb.AppendFormat("All remaining blocks conform to {0} and are {1} bytes each", density, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\tAll remaining blocks conform to {0} and are {1} bytes each", density, descriptor.BlockLength).AppendLine();
}
else
{
if (descriptor.BlockLength == 0)
sb.AppendFormat("{0} blocks conform to {1} and have a variable length", descriptor.Blocks, density).AppendLine();
sb.AppendFormat("\t{0} blocks conform to {1} and have a variable length", descriptor.Blocks, density).AppendLine();
else
sb.AppendFormat("{0} blocks conform to {1} and are {2} bytes each", descriptor.Blocks, density, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\t{0} blocks conform to {1} and are {2} bytes each", descriptor.Blocks, density, descriptor.BlockLength).AppendLine();
}
}
else
@@ -801,16 +810,17 @@ namespace DiscImageChef.Decoders.SCSI
if (descriptor.Blocks == 0)
{
if (descriptor.BlockLength == 0)
sb.AppendFormat("All remaining blocks have a variable length").AppendLine();
sb.AppendFormat("\tAll remaining blocks have a variable length").AppendLine();
else
sb.AppendFormat("All remaining blocks are {0} bytes each", descriptor.BlockLength).AppendLine();
sb.AppendFormat("\tAll remaining blocks are {0} bytes each", descriptor.BlockLength).AppendLine();
}
else
{
if (descriptor.BlockLength == 0)
sb.AppendFormat("{0} blocks have a variable length", descriptor.Blocks).AppendLine();
sb.AppendFormat("\t{0} blocks have a variable length", descriptor.Blocks).AppendLine();
else
sb.AppendFormat("{0} blocks are {1} bytes each", descriptor.Blocks, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\t{0} blocks are {1} bytes each", descriptor.Blocks, descriptor.BlockLength).AppendLine();
}
}
}
}
@@ -822,13 +832,13 @@ namespace DiscImageChef.Decoders.SCSI
switch (header.Value.BufferedMode)
{
case 0:
sb.AppendLine("Device prints directly");
sb.AppendLine("\tDevice prints directly");
break;
case 1:
sb.AppendLine("Device uses a print cache");
sb.AppendLine("\tDevice uses a print cache");
break;
default:
sb.AppendFormat("Unknown buffered mode code 0x{0:X2}", header.Value.BufferedMode).AppendLine();
sb.AppendFormat("\tUnknown buffered mode code 0x{0:X2}", header.Value.BufferedMode).AppendLine();
break;
}
break;
@@ -837,7 +847,7 @@ namespace DiscImageChef.Decoders.SCSI
{
if (header.Value.MediumType != MediumTypes.Default)
{
sb.Append("Medium is ");
sb.Append("\tMedium is ");
switch (header.Value.MediumType)
{
@@ -866,12 +876,14 @@ namespace DiscImageChef.Decoders.SCSI
}
if (header.Value.WriteProtected)
sb.AppendLine("Medium is write protected");
sb.AppendLine("\tMedium is write protected");
if (header.Value.EBC)
sb.AppendLine("Blank checking during write is enabled");
sb.AppendLine("\tBlank checking during write is enabled");
if (header.Value.DPOFUA)
sb.AppendLine("Drive supports DPO and FUA bits");
sb.AppendLine("\tDrive supports DPO and FUA bits");
if (header.Value.BlockDescriptors != null)
{
foreach (BlockDescriptor descriptor in header.Value.BlockDescriptors)
{
string density = "";
@@ -916,16 +928,16 @@ namespace DiscImageChef.Decoders.SCSI
if (descriptor.Blocks == 0)
{
if (descriptor.BlockLength == 0)
sb.AppendFormat("All remaining blocks are {0} and have a variable length", density).AppendLine();
sb.AppendFormat("\tAll remaining blocks are {0} and have a variable length", density).AppendLine();
else
sb.AppendFormat("All remaining blocks are {0} and are {1} bytes each", density, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\tAll remaining blocks are {0} and are {1} bytes each", density, descriptor.BlockLength).AppendLine();
}
else
{
if (descriptor.BlockLength == 0)
sb.AppendFormat("{0} blocks are {1} and have a variable length", descriptor.Blocks, density).AppendLine();
sb.AppendFormat("\t{0} blocks are {1} and have a variable length", descriptor.Blocks, density).AppendLine();
else
sb.AppendFormat("{0} blocks are {1} and are {2} bytes each", descriptor.Blocks, density, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\t{0} blocks are {1} and are {2} bytes each", descriptor.Blocks, density, descriptor.BlockLength).AppendLine();
}
}
else
@@ -933,16 +945,17 @@ namespace DiscImageChef.Decoders.SCSI
if (descriptor.Blocks == 0)
{
if (descriptor.BlockLength == 0)
sb.AppendFormat("All remaining blocks have a variable length").AppendLine();
sb.AppendFormat("\tAll remaining blocks have a variable length").AppendLine();
else
sb.AppendFormat("All remaining blocks are {0} bytes each", descriptor.BlockLength).AppendLine();
sb.AppendFormat("\tAll remaining blocks are {0} bytes each", descriptor.BlockLength).AppendLine();
}
else
{
if (descriptor.BlockLength == 0)
sb.AppendFormat("{0} blocks have a variable length", descriptor.Blocks).AppendLine();
sb.AppendFormat("\t{0} blocks have a variable length", descriptor.Blocks).AppendLine();
else
sb.AppendFormat("{0} blocks are {1} bytes each", descriptor.Blocks, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\t{0} blocks are {1} bytes each", descriptor.Blocks, descriptor.BlockLength).AppendLine();
}
}
}
}
@@ -951,7 +964,7 @@ namespace DiscImageChef.Decoders.SCSI
}
case PeripheralDeviceTypes.MultiMediaDevice:
{
sb.Append("Medium is ");
sb.Append("\tMedium is ");
switch (header.Value.MediumType)
{
@@ -1066,11 +1079,13 @@ namespace DiscImageChef.Decoders.SCSI
}
if (header.Value.WriteProtected)
sb.AppendLine("Medium is write protected");
sb.AppendLine("\tMedium is write protected");
if (header.Value.DPOFUA)
sb.AppendLine("Drive supports DPO and FUA bits");
sb.AppendLine("\tDrive supports DPO and FUA bits");
if (header.Value.BlockDescriptors != null)
{
foreach (BlockDescriptor descriptor in header.Value.BlockDescriptors)
{
string density = "";
@@ -1098,16 +1113,17 @@ namespace DiscImageChef.Decoders.SCSI
if (density != "")
{
if (descriptor.Blocks == 0)
sb.AppendFormat("All remaining blocks have {0} and are {1} bytes each", density, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\tAll remaining blocks have {0} and are {1} bytes each", density, descriptor.BlockLength).AppendLine();
else
sb.AppendFormat("{0} blocks have {1} and are {2} bytes each", descriptor.Blocks, density, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\t{0} blocks have {1} and are {2} bytes each", descriptor.Blocks, density, descriptor.BlockLength).AppendLine();
}
else
{
if (descriptor.Blocks == 0)
sb.AppendFormat("All remaining blocks are {0} bytes each", descriptor.BlockLength).AppendLine();
sb.AppendFormat("\tAll remaining blocks are {0} bytes each", descriptor.BlockLength).AppendLine();
else
sb.AppendFormat("{0} blocks are {1} bytes each", descriptor.Blocks, descriptor.BlockLength).AppendLine();
sb.AppendFormat("\t{0} blocks are {1} bytes each", descriptor.Blocks, descriptor.BlockLength).AppendLine();
}
}
}
@@ -1221,6 +1237,7 @@ namespace DiscImageChef.Decoders.SCSI
}
#region Mode Page 0x0A: Control mode page
/// <summary>
/// Control mode page
/// Page code 0x0A
@@ -1553,9 +1570,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x0A: Control mode page
#region Mode Page 0x02: Disconnect-reconnect page
/// <summary>
/// Disconnect-reconnect page
/// Page code 0x02
@@ -1704,9 +1723,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x02: Disconnect-reconnect page
#region Mode Page 0x08: Caching page
/// <summary>
/// Disconnect-reconnect page
/// Page code 0x08
@@ -1969,9 +1990,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x08: Caching page
#region Mode Page 0x05: Flexible disk page
/// <summary>
/// Disconnect-reconnect page
/// Page code 0x05
@@ -2300,9 +2323,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x05: Flexible disk page
#region Mode Page 0x03: Format device page
/// <summary>
/// Disconnect-reconnect page
/// Page code 0x03
@@ -2446,9 +2471,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x03: Format device page
#region Mode Page 0x0B: Medium types supported page
/// <summary>
/// Disconnect-reconnect page
/// Page code 0x0B
@@ -2517,13 +2544,17 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x0B: Medium types supported page
#region Mode Page 0x0C: Notch page
// TODO: Implement this page
#endregion Mode Page 0x0C: Notch page
#region Mode Page 0x01: Read-write error recovery page
/// <summary>
/// Disconnect-reconnect page
/// Page code 0x01
@@ -2687,9 +2718,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x01: Read-write error recovery page
#region Mode Page 0x04: Rigid disk drive geometry page
/// <summary>
/// Disconnect-reconnect page
/// Page code 0x04
@@ -2822,9 +2855,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x04: Rigid disk drive geometry page
#region Mode Page 0x07: Verify error recovery page
/// <summary>
/// Disconnect-reconnect page
/// Page code 0x07
@@ -2931,9 +2966,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x07: Verify error recovery page
#region Mode Page 0x10: Device configuration page
/// <summary>
/// Device configuration page
/// Page code 0x10
@@ -3256,9 +3293,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x10: Device configuration page
#region Mode Page 0x0E: CD-ROM audio control parameters page
/// <summary>
/// CD-ROM audio control parameters
/// Page code 0x0E
@@ -3398,7 +3437,7 @@ namespace DiscImageChef.Decoders.SCSI
if (page.OutputPort0ChannelSelection > 0)
{
sb.Append("Output port 0 has channels ");
sb.Append("\tOutput port 0 has channels ");
if ((page.OutputPort0ChannelSelection & 0x01) == 0x01)
sb.Append("0 ");
if ((page.OutputPort0ChannelSelection & 0x02) == 0x02)
@@ -3424,7 +3463,7 @@ namespace DiscImageChef.Decoders.SCSI
if (page.OutputPort1ChannelSelection > 0)
{
sb.Append("Output port 1 has channels ");
sb.Append("\tOutput port 1 has channels ");
if ((page.OutputPort1ChannelSelection & 0x01) == 0x01)
sb.Append("0 ");
if ((page.OutputPort1ChannelSelection & 0x02) == 0x02)
@@ -3450,7 +3489,7 @@ namespace DiscImageChef.Decoders.SCSI
if (page.OutputPort2ChannelSelection > 0)
{
sb.Append("Output port 2 has channels ");
sb.Append("\tOutput port 2 has channels ");
if ((page.OutputPort2ChannelSelection & 0x01) == 0x01)
sb.Append("0 ");
if ((page.OutputPort2ChannelSelection & 0x02) == 0x02)
@@ -3476,7 +3515,7 @@ namespace DiscImageChef.Decoders.SCSI
if (page.OutputPort3ChannelSelection > 0)
{
sb.Append("Output port 3 has channels ");
sb.Append("\tOutput port 3 has channels ");
if ((page.OutputPort3ChannelSelection & 0x01) == 0x01)
sb.Append("0 ");
if ((page.OutputPort3ChannelSelection & 0x02) == 0x02)
@@ -3502,9 +3541,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x0E: CD-ROM audio control parameters page
#region Mode Page 0x0D: CD-ROM parameteres page
/// <summary>
/// CD-ROM parameteres page
/// Page code 0x0D
@@ -3577,65 +3618,67 @@ namespace DiscImageChef.Decoders.SCSI
switch (page.InactivityTimerMultiplier)
{
case 0:
sb.AppendLine("Drive will remain in track hold state a vendor-specified time after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state a vendor-specified time after a seek or read");
break;
case 1:
sb.AppendLine("Drive will remain in track hold state 125 ms after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 125 ms after a seek or read");
break;
case 2:
sb.AppendLine("Drive will remain in track hold state 250 ms after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 250 ms after a seek or read");
break;
case 3:
sb.AppendLine("Drive will remain in track hold state 500 ms after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 500 ms after a seek or read");
break;
case 4:
sb.AppendLine("Drive will remain in track hold state 1 second after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 1 second after a seek or read");
break;
case 5:
sb.AppendLine("Drive will remain in track hold state 2 seconds after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 2 seconds after a seek or read");
break;
case 6:
sb.AppendLine("Drive will remain in track hold state 4 seconds after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 4 seconds after a seek or read");
break;
case 7:
sb.AppendLine("Drive will remain in track hold state 8 seconds after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 8 seconds after a seek or read");
break;
case 8:
sb.AppendLine("Drive will remain in track hold state 16 seconds after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 16 seconds after a seek or read");
break;
case 9:
sb.AppendLine("Drive will remain in track hold state 32 seconds after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 32 seconds after a seek or read");
break;
case 10:
sb.AppendLine("Drive will remain in track hold state 1 minute after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 1 minute after a seek or read");
break;
case 11:
sb.AppendLine("Drive will remain in track hold state 2 minutes after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 2 minutes after a seek or read");
break;
case 12:
sb.AppendLine("Drive will remain in track hold state 4 minutes after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 4 minutes after a seek or read");
break;
case 13:
sb.AppendLine("Drive will remain in track hold state 8 minutes after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 8 minutes after a seek or read");
break;
case 14:
sb.AppendLine("Drive will remain in track hold state 16 minutes after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 16 minutes after a seek or read");
break;
case 15:
sb.AppendLine("Drive will remain in track hold state 32 minutes after a seek or read");
sb.AppendLine("\tDrive will remain in track hold state 32 minutes after a seek or read");
break;
}
if (page.SecondsPerMinute > 0)
sb.AppendFormat("Each minute has {0} seconds", page.SecondsPerMinute).AppendLine();
sb.AppendFormat("\tEach minute has {0} seconds", page.SecondsPerMinute).AppendLine();
if (page.FramesPerSecond > 0)
sb.AppendFormat("Each second has {0} frames", page.FramesPerSecond).AppendLine();
sb.AppendFormat("\tEach second has {0} frames", page.FramesPerSecond).AppendLine();
return sb.ToString();
}
#endregion Mode Page 0x0D: CD-ROM parameteres page
#region Mode Page 0x01: Read error recovery page for MultiMedia Devices
/// <summary>
/// Read error recovery page for MultiMedia Devices
/// Page code 0x01
@@ -3721,15 +3764,15 @@ namespace DiscImageChef.Decoders.SCSI
string AllUsed = "\tAll available recovery procedures will be used.\n";
string CIRCRetriesUsed = "\tOnly retries and CIRC are used.\n";
string RetriesUsed = "\tOnly retries are used.\n";
string RecoveredNotReported = "Recovered errors will not be reported.\n";
string RecoveredReported = "Recovered errors will be reported.\n";
string RecoveredAbort = "Recovered errors will be reported and aborted with CHECK CONDITION.\n";
string UnrecECCAbort = "Unrecovered ECC errors will return CHECK CONDITION.";
string UnrecCIRCAbort = "Unrecovered CIRC errors will return CHECK CONDITION.";
string UnrecECCNotAbort = "Unrecovered ECC errors will not abort the transfer.";
string UnrecCIRCNotAbort = "Unrecovered CIRC errors will not abort the transfer.";
string UnrecECCAbortData = "Unrecovered ECC errors will return CHECK CONDITION and the uncorrected data.";
string UnrecCIRCAbortData = "Unrecovered CIRC errors will return CHECK CONDITION and the uncorrected data.";
string RecoveredNotReported = "\tRecovered errors will not be reported.\n";
string RecoveredReported = "\tRecovered errors will be reported.\n";
string RecoveredAbort = "\tRecovered errors will be reported and aborted with CHECK CONDITION.\n";
string UnrecECCAbort = "\tUnrecovered ECC errors will return CHECK CONDITION.";
string UnrecCIRCAbort = "\tUnrecovered CIRC errors will return CHECK CONDITION.";
string UnrecECCNotAbort = "\tUnrecovered ECC errors will not abort the transfer.";
string UnrecCIRCNotAbort = "\tUnrecovered CIRC errors will not abort the transfer.";
string UnrecECCAbortData = "\tUnrecovered ECC errors will return CHECK CONDITION and the uncorrected data.";
string UnrecCIRCAbortData = "\tUnrecovered CIRC errors will return CHECK CONDITION and the uncorrected data.";
switch (page.Parameter)
{
@@ -3801,9 +3844,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x01: Read error recovery page for MultiMedia Devices
#region Mode Page 0x07: Verify error recovery page for MultiMedia Devices
/// <summary>
/// Verify error recovery page for MultiMedia Devices
/// Page code 0x07
@@ -3874,15 +3919,15 @@ namespace DiscImageChef.Decoders.SCSI
string AllUsed = "\tAll available recovery procedures will be used.\n";
string CIRCRetriesUsed = "\tOnly retries and CIRC are used.\n";
string RetriesUsed = "\tOnly retries are used.\n";
string RecoveredNotReported = "Recovered errors will not be reported.\n";
string RecoveredReported = "Recovered errors will be reported.\n";
string RecoveredAbort = "Recovered errors will be reported and aborted with CHECK CONDITION.\n";
string UnrecECCAbort = "Unrecovered ECC errors will return CHECK CONDITION.";
string UnrecCIRCAbort = "Unrecovered CIRC errors will return CHECK CONDITION.";
string UnrecECCNotAbort = "Unrecovered ECC errors will not abort the transfer.";
string UnrecCIRCNotAbort = "Unrecovered CIRC errors will not abort the transfer.";
string UnrecECCAbortData = "Unrecovered ECC errors will return CHECK CONDITION and the uncorrected data.";
string UnrecCIRCAbortData = "Unrecovered CIRC errors will return CHECK CONDITION and the uncorrected data.";
string RecoveredNotReported = "\tRecovered errors will not be reported.\n";
string RecoveredReported = "\tRecovered errors will be reported.\n";
string RecoveredAbort = "\tRecovered errors will be reported and aborted with CHECK CONDITION.\n";
string UnrecECCAbort = "\tUnrecovered ECC errors will return CHECK CONDITION.";
string UnrecCIRCAbort = "\tUnrecovered CIRC errors will return CHECK CONDITION.";
string UnrecECCNotAbort = "\tUnrecovered ECC errors will not abort the transfer.";
string UnrecCIRCNotAbort = "\tUnrecovered CIRC errors will not abort the transfer.";
string UnrecECCAbortData = "\tUnrecovered ECC errors will return CHECK CONDITION and the uncorrected data.";
string UnrecCIRCAbortData = "\tUnrecovered CIRC errors will return CHECK CONDITION and the uncorrected data.";
switch (page.Parameter)
{
@@ -3949,9 +3994,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x07: Verify error recovery page for MultiMedia Devices
#region Mode Page 0x06: Optical memory page
/// <summary>
/// Optical memory page
/// Page code 0x06
@@ -4016,9 +4063,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x06: Optical memory page
#region Mode Page 0x2A: CD-ROM capabilities page
/// <summary>
/// CD-ROM capabilities page
/// Page code 0x2A
@@ -4467,9 +4516,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x2A: CD-ROM capabilities page
#region Mode Page 0x1C: Informational exceptions control page
/// <summary>
/// Informational exceptions control page
/// Page code 0x1C
@@ -4644,9 +4695,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x1C: Informational exceptions control page
#region Mode Page 0x1A: Power condition page
/// <summary>
/// Power condition page
/// Page code 0x1A
@@ -4812,9 +4865,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x1A: Power condition page
#region Mode Page 0x0A subpage 0x01: Control Extension mode page
/// <summary>
/// Control Extension mode page
/// Page code 0x0A
@@ -4928,9 +4983,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x0A subpage 0x01: Control Extension mode page
#region Mode Page 0x1A subpage 0x01: Power Consumption mode page
/// <summary>
/// Power Consumption mode page
/// Page code 0x1A
@@ -5018,9 +5075,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x1A subpage 0x01: Power Consumption mode page
#region Mode Page 0x10: XOR control mode page
/// <summary>
/// XOR control mode page
/// Page code 0x10
@@ -5118,9 +5177,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x10: XOR control mode page
#region Mode Page 0x1C subpage 0x01: Background Control mode page
/// <summary>
/// Background Control mode page
/// Page code 0x1A
@@ -5245,9 +5306,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x1C subpage 0x01: Background Control mode page
#region Mode Page 0x0F: Data compression page
/// <summary>
/// Data compression page
/// Page code 0x0F
@@ -5408,9 +5471,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x0F: Data compression page
#region Mode Page 0x1B: Removable Block Access Capabilities page
/// <summary>
/// Removable Block Access Capabilities page
/// Page code 0x1B
@@ -5505,9 +5570,11 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x1B: Removable Block Access Capabilities page
#region Mode Page 0x1C: Timer & Protect page
/// <summary>
/// Timer & Protect page
/// Page code 0x1C
@@ -5587,60 +5654,62 @@ namespace DiscImageChef.Decoders.SCSI
switch (page.InactivityTimeMultiplier)
{
case 0:
sb.AppendLine("Drive will remain in same status a vendor-specified time after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status a vendor-specified time after a seek, read or write operation");
break;
case 1:
sb.AppendLine("Drive will remain in same status 125 ms after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 125 ms after a seek, read or write operation");
break;
case 2:
sb.AppendLine("Drive will remain in same status 250 ms after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 250 ms after a seek, read or write operation");
break;
case 3:
sb.AppendLine("Drive will remain in same status 500 ms after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 500 ms after a seek, read or write operation");
break;
case 4:
sb.AppendLine("Drive will remain in same status 1 second after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 1 second after a seek, read or write operation");
break;
case 5:
sb.AppendLine("Drive will remain in same status 2 seconds after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 2 seconds after a seek, read or write operation");
break;
case 6:
sb.AppendLine("Drive will remain in same status 4 seconds after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 4 seconds after a seek, read or write operation");
break;
case 7:
sb.AppendLine("Drive will remain in same status 8 seconds after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 8 seconds after a seek, read or write operation");
break;
case 8:
sb.AppendLine("Drive will remain in same status 16 seconds after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 16 seconds after a seek, read or write operation");
break;
case 9:
sb.AppendLine("Drive will remain in same status 32 seconds after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 32 seconds after a seek, read or write operation");
break;
case 10:
sb.AppendLine("Drive will remain in same status 1 minute after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 1 minute after a seek, read or write operation");
break;
case 11:
sb.AppendLine("Drive will remain in same status 2 minutes after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 2 minutes after a seek, read or write operation");
break;
case 12:
sb.AppendLine("Drive will remain in same status 4 minutes after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 4 minutes after a seek, read or write operation");
break;
case 13:
sb.AppendLine("Drive will remain in same status 8 minutes after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 8 minutes after a seek, read or write operation");
break;
case 14:
sb.AppendLine("Drive will remain in same status 16 minutes after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 16 minutes after a seek, read or write operation");
break;
case 15:
sb.AppendLine("Drive will remain in same status 32 minutes after a seek, read or write operation");
sb.AppendLine("\tDrive will remain in same status 32 minutes after a seek, read or write operation");
break;
}
return sb.ToString();
}
#endregion Mode Page 0x1C: Timer & Protect page
#region Mode Page 0x00: Drive Operation Mode page
/// <summary>
/// Drive Operation Mode page
/// Page code 0x00
@@ -5734,9 +5803,10 @@ namespace DiscImageChef.Decoders.SCSI
return sb.ToString();
}
#endregion Mode Page 0x00: Drive Operation Mode page
public struct PageNumber
public struct ModePage
{
public byte Page;
public byte Subpage;
@@ -5746,7 +5816,7 @@ namespace DiscImageChef.Decoders.SCSI
public struct DecodedMode
{
public ModeHeader Header;
public PageNumber[] Pages;
public ModePage[] Pages;
}
public static DecodedMode? DecodeMode6(byte[] modeResponse, PeripheralDeviceTypes deviceType)
@@ -5757,19 +5827,22 @@ namespace DiscImageChef.Decoders.SCSI
DecodedMode decoded = new DecodedMode();
decoded.Header = hdr.Value;
int blkDrLength = 0;
if (decoded.Header.BlockDescriptors != null)
blkDrLength = decoded.Header.BlockDescriptors.Length;
int offset = 4 + decoded.Header.BlockDescriptors.Length * 8;
int length = modeResponse[0];
int offset = 4 + blkDrLength * 8;
int length = modeResponse[0] + 1;
if (length != modeResponse.Length)
return decoded;
List<PageNumber> listpages = new List<PageNumber>();
List<ModePage> listpages = new List<ModePage>();
while (offset < modeResponse.Length)
{
bool isSubpage = (modeResponse[offset] & 0x40) == 0x40;
PageNumber pg = new PageNumber();
ModePage pg = new ModePage();
if (isSubpage)
{
@@ -5806,23 +5879,27 @@ namespace DiscImageChef.Decoders.SCSI
decoded.Header = hdr.Value;
bool longlba = (modeResponse[4] & 0x01) == 0x01;
int offset;
int blkDrLength = 0;
if (decoded.Header.BlockDescriptors != null)
blkDrLength = decoded.Header.BlockDescriptors.Length;
if (longlba)
offset = 8 + decoded.Header.BlockDescriptors.Length * 16;
offset = 8 + blkDrLength * 16;
else
offset = 8 + decoded.Header.BlockDescriptors.Length * 8;
offset = 8 + blkDrLength * 8;
int length = (modeResponse[0] << 8);
length += modeResponse[1];
length += 2;
if (length != modeResponse.Length)
return decoded;
List<PageNumber> listpages = new List<PageNumber>();
List<ModePage> listpages = new List<ModePage>();
while (offset < modeResponse.Length)
{
bool isSubpage = (modeResponse[offset] & 0x40) == 0x40;
PageNumber pg = new PageNumber();
ModePage pg = new ModePage();
if (isSubpage)
{

View File

@@ -1,3 +1,8 @@
2015-10-31 Natalia Portillo <claunia@claunia.com>
* Device/ScsiCommands.cs:
Corrected math typo.
2015-10-24 Natalia Portillo <claunia@claunia.com>
* Enums.cs:

View File

@@ -357,7 +357,7 @@ namespace DiscImageChef.Devices
if (sense)
return true;
ushort modeLength = (ushort)(((int)buffer[0] << 8) + buffer[1]);
ushort modeLength = (ushort)(((int)buffer[0] << 8) + buffer[1] + 2);
buffer = new byte[modeLength];
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);

View File

@@ -1,3 +1,8 @@
2015-10-31 Natalia Portillo <claunia@claunia.com>
* Commands/DeviceInfo.cs:
Added MODE SENSE to device information.
2015-10-24 Natalia Portillo <claunia@claunia.com>
* DiscImageChef.csproj:

View File

@@ -139,7 +139,8 @@ namespace DiscImageChef.Commands
if (dev.Type != DeviceType.ATAPI)
DicConsole.WriteLine("SCSI device");
DicConsole.WriteLine(Decoders.SCSI.Inquiry.Prettify(inqBuf));
Decoders.SCSI.Inquiry.SCSIInquiry? inq = Decoders.SCSI.Inquiry.Decode(inqBuf);
DicConsole.WriteLine(Decoders.SCSI.Inquiry.Prettify(inq));
bool scsi83 = false;
string scsiSerial = null;
@@ -151,6 +152,8 @@ namespace DiscImageChef.Commands
{
byte[] pages = Decoders.SCSI.EVPD.DecodePage00(inqBuf);
if (pages != null)
{
foreach (byte page in pages)
{
if (page >= 0x01 && page <= 0x7F)
@@ -179,6 +182,7 @@ namespace DiscImageChef.Commands
}
}
}
}
if (scsi83)
DicConsole.WriteLine("Unit Serial Number: {0}", scsiSerial);
@@ -189,6 +193,258 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine(sb.ToString());
}
byte[] modeBuf;
double duration;
Decoders.SCSI.Modes.DecodedMode? decMode = null;
Decoders.SCSI.PeripheralDeviceTypes devType = (DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes)inq.Value.PeripheralDeviceType;
sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current, 0x3F, 0xFF, dev.Timeout, out duration);
if (sense)
{
sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, dev.Timeout, out duration);
}
if (!sense)
{
decMode = Decoders.SCSI.Modes.DecodeMode10(modeBuf, devType);
}
else
{
sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, dev.Timeout, out duration);
if(sense)
sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, dev.Timeout, out duration);
if(sense)
sense = dev.ModeSense(out modeBuf, out senseBuf, 15000, out duration);
if(!sense)
decMode = Decoders.SCSI.Modes.DecodeMode6(modeBuf, devType);
}
if (decMode.HasValue)
{
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModeHeader(decMode.Value.Header, devType));
if (decMode.Value.Pages != null)
{
foreach (Decoders.SCSI.Modes.ModePage page in decMode.Value.Pages)
{
//DicConsole.WriteLine("Page {0:X2}h subpage {1:X2}h is {2} bytes long", page.Page, page.Subpage, page.PageResponse.Length);
switch (page.Page)
{
case 0x00:
{
if (devType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice && page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_00_SFF(page.PageResponse));
else
{
if (page.Subpage != 0)
DicConsole.WriteLine("Found unknown vendor mode page {0:X2}h subpage {1:X2}h", page.Page, page.Subpage);
else
DicConsole.WriteLine("Found unknown vendor mode page {0:X2}h", page.Page);
}
break;
}
case 0x01:
{
if (page.Subpage == 0)
{
if (devType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_01_MMC(page.PageResponse));
else
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_01(page.PageResponse));
}
else
goto default;
break;
}
case 0x02:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_02(page.PageResponse));
else
goto default;
break;
}
case 0x03:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_03(page.PageResponse));
else
goto default;
break;
}
case 0x04:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_04(page.PageResponse));
else
goto default;
break;
}
case 0x05:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_05(page.PageResponse));
else
goto default;
break;
}
case 0x06:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_06(page.PageResponse));
else
goto default;
break;
}
case 0x07:
{
if (page.Subpage == 0)
{
if (devType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_07_MMC(page.PageResponse));
else
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_07(page.PageResponse));
}
else
goto default;
break;
}
case 0x08:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_08(page.PageResponse));
else
goto default;
break;
}
case 0x0A:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_0A(page.PageResponse));
else if (page.Subpage == 1)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_0A_S01(page.PageResponse));
else
goto default;
break;
}
case 0x0B:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_0B(page.PageResponse));
else
goto default;
break;
}
case 0x0D:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_0D(page.PageResponse));
else
goto default;
break;
}
case 0x0E:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_0E(page.PageResponse));
else
goto default;
break;
}
case 0x0F:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_0F(page.PageResponse));
else
goto default;
break;
}
case 0x10:
{
if (page.Subpage == 0)
{
if (devType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.SequentialAccess)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_10_SSC(page.PageResponse));
else
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_10(page.PageResponse));
}
else
goto default;
break;
}
case 0x1A:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_1A(page.PageResponse));
else if (page.Subpage == 1)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_1A_S01(page.PageResponse));
else
goto default;
break;
}
case 0x1B:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_1B(page.PageResponse));
else
goto default;
break;
}
case 0x1C:
{
if (page.Subpage == 0)
{
if (devType == DiscImageChef.Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_1C_SFF(page.PageResponse));
else
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_1C(page.PageResponse));
}
else if (page.Subpage == 1)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_1C_S01(page.PageResponse));
else
goto default;
break;
}
case 0x2A:
{
if (page.Subpage == 0)
DicConsole.WriteLine(Decoders.SCSI.Modes.PrettifyModePage_2A(page.PageResponse));
else
goto default;
break;
}
default:
{
if (page.Subpage != 0)
DicConsole.WriteLine("Found unknown mode page {0:X2}h subpage {1:X2}h", page.Page, page.Subpage);
else
DicConsole.WriteLine("Found unknown mode page {0:X2}h", page.Page);
break;
}
}
}
}
}
break;
}
default: