Implemented decoding mode page 04h.

This commit is contained in:
2015-10-30 02:50:05 +00:00
parent cb415f7023
commit ad4eb17533
2 changed files with 137 additions and 0 deletions

View File

@@ -2285,6 +2285,138 @@ 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
/// 24 bytes in SCSI-2
/// </summary>
public struct ModePage_04
{
/// <summary>
/// Parameters can be saved
/// </summary>
public bool PS;
/// <summary>
/// Cylinders used for data storage
/// </summary>
public uint Cylinders;
/// <summary>
/// Heads for reading and/or writing
/// </summary>
public byte Heads;
/// <summary>
/// Cylinder where write precompensation starts
/// </summary>
public uint WritePrecompCylinder;
/// <summary>
/// Cylinder where write current reduction starts
/// </summary>
public uint WriteReduceCylinder;
/// <summary>
/// Step rate in 100 ns units
/// </summary>
public ushort DriveStepRate;
/// <summary>
/// Cylinder where the heads park
/// </summary>
public int LandingCylinder;
/// <summary>
/// Rotational position locking
/// </summary>
public byte RPL;
/// <summary>
/// Rotational skew to apply when synchronized
/// </summary>
public byte RotationalOffset;
/// <summary>
/// Medium speed in rpm
/// </summary>
public ushort MediumRotationRate;
}
public static ModePage_04? DecodeModePage_04(byte[] pageResponse)
{
if (pageResponse == null)
return null;
if ((pageResponse[0] & 0x3F) != 0x04)
return null;
if (pageResponse[1] + 2 != pageResponse.Length)
return null;
if (pageResponse.Length < 24)
return null;
ModePage_04 decoded = new ModePage_04();
decoded.PS |= (pageResponse[0] & 0x80) == 0x80;
decoded.Cylinders = (uint)((pageResponse[2] << 16) + (pageResponse[3] << 8) + pageResponse[4]);
decoded.Heads = pageResponse[5];
decoded.WritePrecompCylinder = (uint)((pageResponse[6] << 16) + (pageResponse[7] << 8) + pageResponse[8]);
decoded.WriteReduceCylinder = (uint)((pageResponse[9] << 16) + (pageResponse[10] << 8) + pageResponse[11]);
decoded.DriveStepRate = (ushort)((pageResponse[12] << 8) + pageResponse[13]);
decoded.LandingCylinder = ((pageResponse[14] << 16) + (pageResponse[15] << 8) + pageResponse[16]);
decoded.RPL = (byte)(pageResponse[17] & 0x03);
decoded.RotationalOffset = pageResponse[18];
decoded.MediumRotationRate = (ushort)((pageResponse[20] << 8) + pageResponse[21]);
return decoded;
}
public static string PrettifyModePage_04(byte[] pageResponse)
{
return PrettifyModePage_04(DecodeModePage_04(pageResponse));
}
public static string PrettifyModePage_04(ModePage_04? modePage)
{
if (!modePage.HasValue)
return null;
ModePage_04 page = modePage.Value;
StringBuilder sb = new StringBuilder();
sb.AppendLine("SCSI Rigid disk drive geometry page:");
if (page.PS)
sb.AppendLine("\tParameters can be saved");
sb.AppendFormat("\t{0} heads", page.Heads).AppendLine();
sb.AppendFormat("\t{0} cylinders", page.Cylinders).AppendLine();
if(page.WritePrecompCylinder < page.Cylinders)
sb.AppendFormat("\tWrite pre-compensation starts at cylinder {0}", page.WritePrecompCylinder).AppendLine();
if(page.WriteReduceCylinder < page.Cylinders)
sb.AppendFormat("\tWrite current reduction starts at cylinder {0}", page.WriteReduceCylinder).AppendLine();
if (page.DriveStepRate > 0)
sb.AppendFormat("\tDrive steps in {0} ns", (uint)page.DriveStepRate * 100).AppendLine();
sb.AppendFormat("\tHeads park in cylinder {0}", page.LandingCylinder).AppendLine();
if (page.MediumRotationRate > 0)
sb.AppendFormat("\tMedium rotates at {0} rpm", page.MediumRotationRate).AppendLine();
switch (page.RPL)
{
case 0:
sb.AppendLine("\tSpindle synchronization is disable or unsupported");
break;
case 1:
sb.AppendLine("\tTarget operates as a synchronized-spindle slave");
break;
case 2:
sb.AppendLine("\tTarget operates as a synchronized-spindle master");
break;
case 3:
sb.AppendLine("\tTarget operates as a synchronized-spindle master control");
break;
}
return sb.ToString();
}
#endregion Mode Page 0x04: Rigid disk drive geometry page
}
}