public static ModePage_10_SSC?DecodeModePage_10_SSC(byte[] pageResponse) { if ((pageResponse?[0] &0x40) == 0x40) { return(null); } if ((pageResponse?[0] &0x3F) != 0x10) { return(null); } if (pageResponse[1] + 2 != pageResponse.Length) { return(null); } if (pageResponse.Length < 16) { return(null); } ModePage_10_SSC decoded = new ModePage_10_SSC(); decoded.PS |= (pageResponse[0] & 0x80) == 0x80; decoded.CAP |= (pageResponse[2] & 0x40) == 0x40; decoded.CAF |= (pageResponse[2] & 0x20) == 0x20; decoded.ActiveFormat = (byte)(pageResponse[2] & 0x1F); decoded.ActivePartition = pageResponse[3]; decoded.WriteBufferFullRatio = pageResponse[4]; decoded.ReadBufferEmptyRatio = pageResponse[5]; decoded.WriteDelayTime = (ushort)((pageResponse[6] << 8) + pageResponse[7]); decoded.DBR |= (pageResponse[8] & 0x80) == 0x80; decoded.BIS |= (pageResponse[8] & 0x40) == 0x40; decoded.RSmk |= (pageResponse[8] & 0x20) == 0x20; decoded.AVC |= (pageResponse[8] & 0x10) == 0x10; decoded.RBO |= (pageResponse[8] & 0x02) == 0x02; decoded.REW |= (pageResponse[8] & 0x01) == 0x01; decoded.EEG |= (pageResponse[10] & 0x10) == 0x10; decoded.SEW |= (pageResponse[10] & 0x08) == 0x08; decoded.SOCF = (byte)((pageResponse[8] & 0x0C) >> 2); decoded.BufferSizeEarlyWarning = (uint)((pageResponse[11] << 16) + (pageResponse[12] << 8) + pageResponse[13]); decoded.SelectedCompression = pageResponse[14]; decoded.SWP |= (pageResponse[10] & 0x04) == 0x04; decoded.ASOCWP |= (pageResponse[15] & 0x04) == 0x04; decoded.PERSWP |= (pageResponse[15] & 0x02) == 0x02; decoded.PRMWP |= (pageResponse[15] & 0x01) == 0x01; decoded.BAML |= (pageResponse[10] & 0x02) == 0x02; decoded.BAM |= (pageResponse[10] & 0x01) == 0x01; decoded.RewindOnReset = (byte)((pageResponse[15] & 0x18) >> 3); decoded.OIR |= (pageResponse[15] & 0x20) == 0x20; decoded.WTRE = (byte)((pageResponse[15] & 0xC0) >> 6); return(decoded); }
public static string PrettifyModePage_10_SSC(ModePage_10_SSC?modePage) { if (!modePage.HasValue) { return(null); } ModePage_10_SSC page = modePage.Value; StringBuilder sb = new StringBuilder(); sb.AppendLine("SCSI Device configuration page:"); if (page.PS) { sb.AppendLine("\tParameters can be saved"); } sb.AppendFormat("\tActive format: {0}", page.ActiveFormat).AppendLine(); sb.AppendFormat("\tActive partition: {0}", page.ActivePartition).AppendLine(); sb.AppendFormat("\tWrite buffer shall have a full ratio of {0} before being flushed to medium", page.WriteBufferFullRatio).AppendLine(); sb.AppendFormat("\tRead buffer shall have an empty ratio of {0} before more data is read from medium", page.ReadBufferEmptyRatio).AppendLine(); sb .AppendFormat("\tDrive will delay {0} ms before buffered data is forcefully written to the medium even before buffer is full", page.WriteDelayTime * 100).AppendLine(); if (page.DBR) { sb.AppendLine("\tDrive supports recovering data from buffer"); sb.AppendLine(page.RBO ? "\tRecovered buffer data comes in LIFO order" : "\tRecovered buffer data comes in FIFO order"); } if (page.BIS) { sb.AppendLine("\tMedium supports block IDs"); } if (page.RSmk) { sb.AppendLine("\tDrive reports setmarks"); } switch (page.SOCF) { case 0: sb.AppendLine("\tDrive will pre-read until buffer is full"); break; case 1: sb.AppendLine("\tDrive will pre-read until one filemark is detected"); break; case 2: sb.AppendLine("\tDrive will pre-read until two filemark is detected"); break; case 3: sb.AppendLine("\tDrive will pre-read until three filemark is detected"); break; } if (page.REW) { sb.AppendLine("\tDrive reports early warnings"); if (page.SEW) { sb.AppendLine("\tDrive will synchronize buffer to medium on early warnings"); } } switch (page.GapSize) { case 0: break; case 1: sb.AppendLine("\tInter-block gap is long enough to support update in place"); break; case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: sb.AppendFormat("\tInter-block gap is {0} times the device's defined gap size", page.GapSize) .AppendLine(); break; default: sb.AppendFormat("\tInter-block gap is unknown value {0}", page.GapSize).AppendLine(); break; } if (page.EEG) { sb.AppendLine("\tDrive generates end-of-data"); } switch (page.SelectedCompression) { case 0: sb.AppendLine("\tDrive does not use compression"); break; case 1: sb.AppendLine("\tDrive uses default compression"); break; default: sb.AppendFormat("\tDrive uses unknown compression {0}", page.SelectedCompression).AppendLine(); break; } if (page.SWP) { sb.AppendLine("\tSoftware write protect is enabled"); } if (page.ASOCWP) { sb.AppendLine("\tAssociated write protect is enabled"); } if (page.PERSWP) { sb.AppendLine("\tPersistent write protect is enabled"); } if (page.PRMWP) { sb.AppendLine("\tPermanent write protect is enabled"); } if (page.BAML) { sb.AppendLine(page.BAM ? "\tDrive operates using explicit address mode" : "\tDrive operates using implicit address mode"); } switch (page.RewindOnReset) { case 1: sb.AppendLine("\tDrive shall position to beginning of default data partition on reset"); break; case 2: sb.AppendLine("\tDrive shall maintain its position on reset"); break; } switch (page.WTRE) { case 1: sb.AppendLine("\tDrive will do nothing on WORM tampered medium"); break; case 2: sb.AppendLine("\tDrive will return CHECK CONDITION on WORM tampered medium"); break; } if (page.OIR) { sb.AppendLine("\tDrive will only respond to commands if it has received a reservation"); } return(sb.ToString()); }