From e325bc848a5bbdc965402d81cf4a0f4253cbba70 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Fri, 30 Oct 2015 02:53:36 +0000 Subject: [PATCH] Implemented decoding mode page 07h. --- ChangeLog | 5 +++ SCSI/Modes.cs | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) diff --git a/ChangeLog b/ChangeLog index b18420f1e..b4299a9cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2015-10-30 Natalia Portillo + + * SCSI/Modes.cs: + Implemented decoding mode page 07h. + 2015-10-30 Natalia Portillo * SCSI/Modes.cs: diff --git a/SCSI/Modes.cs b/SCSI/Modes.cs index 9acdefa9b..cc750bd0f 100644 --- a/SCSI/Modes.cs +++ b/SCSI/Modes.cs @@ -2417,6 +2417,112 @@ namespace DiscImageChef.Decoders.SCSI return sb.ToString(); } #endregion Mode Page 0x04: Rigid disk drive geometry page + + #region Mode Page 0x07: Verify error recovery page + /// + /// Disconnect-reconnect page + /// Page code 0x07 + /// 12 bytes in SCSI-2 + /// + public struct ModePage_07 + { + /// + /// Parameters can be saved + /// + public bool PS; + /// + /// Enable early recovery + /// + public bool EER; + /// + /// Post error reporting + /// + public bool PER; + /// + /// Disable transfer on error + /// + public bool DTE; + /// + /// Disable correction + /// + public bool DCR; + /// + /// How many times to retry a verify operation + /// + public byte VerifyRetryCount; + /// + /// How many bits of largest data burst error is maximum to apply error correction on it + /// + public byte CorrectionSpan; + /// + /// Maximum time in ms to use in data error recovery procedures + /// + public ushort RecoveryTimeLimit; + } + + public static ModePage_07? DecodeModePage_07(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 < 12) + return null; + + ModePage_07 decoded = new ModePage_07(); + + decoded.PS |= (pageResponse[0] & 0x80) == 0x80; + decoded.EER |= (pageResponse[2] & 0x08) == 0x08; + decoded.PER |= (pageResponse[2] & 0x04) == 0x04; + decoded.DTE |= (pageResponse[2] & 0x02) == 0x02; + decoded.DCR |= (pageResponse[2] & 0x01) == 0x01; + + decoded.VerifyRetryCount = pageResponse[3]; + decoded.CorrectionSpan = pageResponse[4]; + decoded.RecoveryTimeLimit = (ushort)((pageResponse[10] << 8) + pageResponse[11]); + + return decoded; + } + + public static string PrettifyModePage_07(byte[] pageResponse) + { + return PrettifyModePage_07(DecodeModePage_07(pageResponse)); + } + + public static string PrettifyModePage_07(ModePage_07? modePage) + { + if (!modePage.HasValue) + return null; + + ModePage_07 page = modePage.Value; + StringBuilder sb = new StringBuilder(); + + sb.AppendLine("SCSI Verify error recovery page:"); + + if (page.PS) + sb.AppendLine("\tParameters can be saved"); + + if (page.EER) + sb.AppendLine("\tDrive will use the most expedient form of error recovery first"); + if (page.PER) + sb.AppendLine("\tDrive shall report recovered errors"); + if (page.DTE) + sb.AppendLine("\tTransfer will be terminated upon error detection"); + if (page.DCR) + sb.AppendLine("\tError correction is disabled"); + if (page.VerifyRetryCount > 0) + sb.AppendFormat("\tDrive will repeat verify operations {0} times", page.VerifyRetryCount).AppendLine(); + if (page.RecoveryTimeLimit > 0) + sb.AppendFormat("\tDrive will employ a maximum of {0} ms to recover data", page.RecoveryTimeLimit).AppendLine(); + + return sb.ToString(); + } + #endregion Mode Page 0x07: Verify error recovery page } }