Esempio n. 1
0
        public static byte[] EncodeModePage_01(ModePage_01 page)
        {
            byte[] pg = new byte[8];

            pg[0] = 0x01;
            pg[1] = 6;

            if (page.PS)
            {
                pg[0] += 0x80;
            }
            if (page.AWRE)
            {
                pg[2] += 0x80;
            }
            if (page.ARRE)
            {
                pg[2] += 0x40;
            }
            if (page.TB)
            {
                pg[2] += 0x20;
            }
            if (page.RC)
            {
                pg[2] += 0x10;
            }
            if (page.EER)
            {
                pg[2] += 0x08;
            }
            if (page.PER)
            {
                pg[2] += 0x04;
            }
            if (page.DTE)
            {
                pg[2] += 0x02;
            }
            if (page.DCR)
            {
                pg[2] += 0x01;
            }

            pg[3] = page.ReadRetryCount;
            pg[4] = page.CorrectionSpan;
            pg[5] = (byte)page.HeadOffsetCount;
            pg[6] = (byte)page.DataStrobeOffsetCount;

            // This is from a newer version of SCSI unknown what happen for drives expecting an 8 byte page

            /*
             * pg[8] = page.WriteRetryCount;
             * if (page.LBPERE)
             *  pg[7] += 0x80;
             * pg[10] = (byte)((page.RecoveryTimeLimit & 0xFF00) << 8);
             * pg[11] = (byte)(page.RecoveryTimeLimit & 0xFF);*/

            return(pg);
        }
Esempio n. 2
0
        public static ModePage_01?DecodeModePage_01(byte[] pageResponse)
        {
            if ((pageResponse?[0] &0x40) == 0x40)
            {
                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 decoded = new ModePage_01();

            decoded.PS   |= (pageResponse[0] & 0x80) == 0x80;
            decoded.AWRE |= (pageResponse[2] & 0x80) == 0x80;
            decoded.ARRE |= (pageResponse[2] & 0x40) == 0x40;
            decoded.TB   |= (pageResponse[2] & 0x20) == 0x20;
            decoded.RC   |= (pageResponse[2] & 0x10) == 0x10;
            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.ReadRetryCount        = pageResponse[3];
            decoded.CorrectionSpan        = pageResponse[4];
            decoded.HeadOffsetCount       = (sbyte)pageResponse[5];
            decoded.DataStrobeOffsetCount = (sbyte)pageResponse[6];

            if (pageResponse.Length < 12)
            {
                return(decoded);
            }

            decoded.WriteRetryCount   = pageResponse[8];
            decoded.RecoveryTimeLimit = (ushort)((pageResponse[10] << 8) + pageResponse[11]);
            decoded.LBPERE           |= (pageResponse[7] & 0x80) == 0x80;

            return(decoded);
        }
Esempio n. 3
0
        public static string PrettifyModePage_01(ModePage_01?modePage)
        {
            if (!modePage.HasValue)
            {
                return(null);
            }

            ModePage_01   page = modePage.Value;
            StringBuilder sb   = new StringBuilder();

            sb.AppendLine("SCSI Read-write error recovery page:");

            if (page.PS)
            {
                sb.AppendLine("\tParameters can be saved");
            }

            if (page.AWRE)
            {
                sb.AppendLine("\tAutomatic write reallocation is enabled");
            }
            if (page.ARRE)
            {
                sb.AppendLine("\tAutomatic read reallocation is enabled");
            }
            if (page.TB)
            {
                sb.AppendLine("\tData not recovered within limits shall be transferred back before a CHECK CONDITION");
            }
            if (page.RC)
            {
                sb.AppendLine("\tDrive will transfer the entire requested length without delaying to perform error recovery");
            }
            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.ReadRetryCount > 0)
            {
                sb.AppendFormat("\tDrive will repeat read operations {0} times", page.ReadRetryCount).AppendLine();
            }
            if (page.WriteRetryCount > 0)
            {
                sb.AppendFormat("\tDrive will repeat write operations {0} times", page.WriteRetryCount).AppendLine();
            }
            if (page.RecoveryTimeLimit > 0)
            {
                sb.AppendFormat("\tDrive will employ a maximum of {0} ms to recover data", page.RecoveryTimeLimit)
                .AppendLine();
            }
            if (page.LBPERE)
            {
                sb.AppendLine("Logical block provisioning error reporting is enabled");
            }

            return(sb.ToString());
        }