From 965bc740a025dfccc402d53f68672879560a90fa Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Fri, 30 Oct 2015 17:39:21 +0000 Subject: [PATCH] Implemented decoding mode pages 01h and 07h for multimedia devices. --- ChangeLog | 6 ++ SCSI/Modes.cs | 290 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 296 insertions(+) diff --git a/ChangeLog b/ChangeLog index fe88f1d..fcf88d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2015-10-30 Natalia Portillo + + * SCSI/Modes.cs: + Implemented decoding mode pages 01h and 07h for multimedia + devices. + 2015-10-30 Natalia Portillo * SCSI/Modes.cs: diff --git a/SCSI/Modes.cs b/SCSI/Modes.cs index d3b8489..259bbd5 100644 --- a/SCSI/Modes.cs +++ b/SCSI/Modes.cs @@ -3137,6 +3137,296 @@ namespace DiscImageChef.Decoders.SCSI return sb.ToString(); } #endregion Mode Page 0x0D: CD-ROM parameteres page + + #region Mode Page 0x01: Read error recovery page for MultiMedia Devices + /// + /// Read error recovery page for MultiMedia Devices + /// Page code 0x01 + /// 8 bytes in SCSI-2 + /// + public struct ModePage_01_MMC + { + /// + /// Parameters can be saved + /// + public bool PS; + /// + /// Error recovery parameter + /// + public byte Parameter; + /// + /// How many times to retry a read operation + /// + public byte ReadRetryCount; + } + + public static ModePage_01_MMC? DecodeModePage_01_MMC(byte[] pageResponse) + { + if (pageResponse == null) + return null; + + if ((pageResponse[0] & 0x3F) != 0x01) + return null; + + if (pageResponse[1] + 2 != pageResponse.Length) + return null; + + if (pageResponse.Length < 8) + return null; + + ModePage_01_MMC decoded = new ModePage_01_MMC(); + + decoded.PS |= (pageResponse[0] & 0x80) == 0x80; + decoded.Parameter = pageResponse[2]; + decoded.ReadRetryCount = pageResponse[3]; + + return decoded; + } + + public static string PrettifyModePage_01_MMC(byte[] pageResponse) + { + return PrettifyModePage_01_MMC(DecodeModePage_01_MMC(pageResponse)); + } + + public static string PrettifyModePage_01_MMC(ModePage_01_MMC? modePage) + { + if (!modePage.HasValue) + return null; + + ModePage_01_MMC page = modePage.Value; + StringBuilder sb = new StringBuilder(); + + sb.AppendLine("SCSI Read error recovery page for MultiMedia Devices:"); + + if (page.PS) + sb.AppendLine("\tParameters can be saved"); + if (page.ReadRetryCount > 0) + sb.AppendFormat("\tDrive will repeat read operations {0} times", page.ReadRetryCount).AppendLine(); + + 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."; + + switch (page.Parameter) + { + case 0x00: + sb.AppendLine(AllUsed + RecoveredNotReported + UnrecECCAbort); + break; + case 0x01: + sb.AppendLine(CIRCRetriesUsed + RecoveredNotReported + UnrecCIRCAbort); + break; + case 0x04: + sb.AppendLine(AllUsed + RecoveredReported + UnrecECCAbort); + break; + case 0x05: + sb.AppendLine(CIRCRetriesUsed + RecoveredReported + UnrecCIRCAbort); + break; + case 0x06: + sb.AppendLine(AllUsed + RecoveredAbort + UnrecECCAbort); + break; + case 0x07: + sb.AppendLine(RetriesUsed + RecoveredAbort + UnrecCIRCAbort); + break; + case 0x10: + sb.AppendLine(AllUsed + RecoveredNotReported + UnrecECCNotAbort); + break; + case 0x11: + sb.AppendLine(CIRCRetriesUsed + RecoveredNotReported + UnrecCIRCNotAbort); + break; + case 0x14: + sb.AppendLine(AllUsed + RecoveredReported + UnrecECCNotAbort); + break; + case 0x15: + sb.AppendLine(CIRCRetriesUsed + RecoveredReported + UnrecCIRCNotAbort); + break; + case 0x20: + sb.AppendLine(AllUsed + RecoveredNotReported + UnrecECCAbortData); + break; + case 0x21: + sb.AppendLine(CIRCRetriesUsed + RecoveredNotReported + UnrecCIRCAbortData); + break; + case 0x24: + sb.AppendLine(AllUsed + RecoveredReported + UnrecECCAbortData); + break; + case 0x25: + sb.AppendLine(CIRCRetriesUsed + RecoveredReported + UnrecCIRCAbortData); + break; + case 0x26: + sb.AppendLine(AllUsed + RecoveredAbort + UnrecECCAbortData); + break; + case 0x27: + sb.AppendLine(RetriesUsed + RecoveredAbort + UnrecCIRCAbortData); + break; + case 0x30: + goto case 0x10; + case 0x31: + goto case 0x11; + case 0x34: + goto case 0x14; + case 0x35: + goto case 0x15; + default: + sb.AppendFormat("Unknown recovery parameter 0x{0:X2}", page.Parameter).AppendLine(); + break; + } + + 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 + /// + /// Verify error recovery page for MultiMedia Devices + /// Page code 0x07 + /// 8 bytes in SCSI-2 + /// + public struct ModePage_07_MMC + { + /// + /// Parameters can be saved + /// + public bool PS; + /// + /// Error recovery parameter + /// + public byte Parameter; + /// + /// How many times to retry a verify operation + /// + public byte VerifyRetryCount; + } + + public static ModePage_07_MMC? DecodeModePage_07_MMC(byte[] pageResponse) + { + if (pageResponse == null) + return null; + + if ((pageResponse[0] & 0x3F) != 0x07) + return null; + + if (pageResponse[1] + 2 != pageResponse.Length) + return null; + + if (pageResponse.Length < 8) + return null; + + ModePage_07_MMC decoded = new ModePage_07_MMC(); + + decoded.PS |= (pageResponse[0] & 0x80) == 0x80; + decoded.Parameter = pageResponse[2]; + decoded.VerifyRetryCount = pageResponse[3]; + + return decoded; + } + + public static string PrettifyModePage_07_MMC(byte[] pageResponse) + { + return PrettifyModePage_07_MMC(DecodeModePage_07_MMC(pageResponse)); + } + + public static string PrettifyModePage_07_MMC(ModePage_07_MMC? modePage) + { + if (!modePage.HasValue) + return null; + + ModePage_07_MMC page = modePage.Value; + StringBuilder sb = new StringBuilder(); + + sb.AppendLine("SCSI Verify error recovery page for MultiMedia Devices:"); + + if (page.PS) + sb.AppendLine("\tParameters can be saved"); + if (page.VerifyRetryCount > 0) + sb.AppendFormat("\tDrive will repeat verify operations {0} times", page.VerifyRetryCount).AppendLine(); + + 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."; + + switch (page.Parameter) + { + case 0x00: + sb.AppendLine(AllUsed + RecoveredNotReported + UnrecECCAbort); + break; + case 0x01: + sb.AppendLine(CIRCRetriesUsed + RecoveredNotReported + UnrecCIRCAbort); + break; + case 0x04: + sb.AppendLine(AllUsed + RecoveredReported + UnrecECCAbort); + break; + case 0x05: + sb.AppendLine(CIRCRetriesUsed + RecoveredReported + UnrecCIRCAbort); + break; + case 0x06: + sb.AppendLine(AllUsed + RecoveredAbort + UnrecECCAbort); + break; + case 0x07: + sb.AppendLine(RetriesUsed + RecoveredAbort + UnrecCIRCAbort); + break; + case 0x10: + sb.AppendLine(AllUsed + RecoveredNotReported + UnrecECCNotAbort); + break; + case 0x11: + sb.AppendLine(CIRCRetriesUsed + RecoveredNotReported + UnrecCIRCNotAbort); + break; + case 0x14: + sb.AppendLine(AllUsed + RecoveredReported + UnrecECCNotAbort); + break; + case 0x15: + sb.AppendLine(CIRCRetriesUsed + RecoveredReported + UnrecCIRCNotAbort); + break; + case 0x20: + sb.AppendLine(AllUsed + RecoveredNotReported + UnrecECCAbortData); + break; + case 0x21: + sb.AppendLine(CIRCRetriesUsed + RecoveredNotReported + UnrecCIRCAbortData); + break; + case 0x24: + sb.AppendLine(AllUsed + RecoveredReported + UnrecECCAbortData); + break; + case 0x25: + sb.AppendLine(CIRCRetriesUsed + RecoveredReported + UnrecCIRCAbortData); + break; + case 0x26: + sb.AppendLine(AllUsed + RecoveredAbort + UnrecECCAbortData); + break; + case 0x27: + sb.AppendLine(RetriesUsed + RecoveredAbort + UnrecCIRCAbortData); + break; + case 0x30: + goto case 0x10; + case 0x31: + goto case 0x11; + case 0x34: + goto case 0x14; + case 0x35: + goto case 0x15; + default: + sb.AppendFormat("Unknown recovery parameter 0x{0:X2}", page.Parameter).AppendLine(); + break; + } + + return sb.ToString(); + } + #endregion Mode Page 0x07: Verify error recovery page for MultiMedia Devices } }