From 6e65915cedee62580d5697cafc5a46382d2c69b6 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Thu, 13 Oct 2016 05:49:11 +0100 Subject: [PATCH] Updated EVPD Page 83h to SPC-5. --- ChangeLog | 6 ++ SCSI/EVPD.cs | 278 +++++++++++++++++++++++++++++++++++++++++++++----- SCSI/Enums.cs | 56 ++++++++++ SCSI/Modes.cs | 6 ++ 4 files changed, 322 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3719ea8ba..1b28cd4a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-10-13 Natalia Portillo + + * EVPD.cs: + * Modes.cs: + * Enums.cs: Updated EVPD Page 83h to SPC-5. + 2016-10-13 Natalia Portillo * EVPD.cs: Added SCSI EVPD page 83h. diff --git a/SCSI/EVPD.cs b/SCSI/EVPD.cs index e68b825ee..9b52f459c 100644 --- a/SCSI/EVPD.cs +++ b/SCSI/EVPD.cs @@ -132,6 +132,22 @@ namespace DiscImageChef.Decoders.SCSI #region EVPD Page 0x83: Device identification page + public enum IdentificationAssociation : byte + { + /// + /// Identifier field is associated with the addressed logical unit + /// + LogicalUnit = 0, + /// + /// Identifier field is associated with the target port + /// + TargetPort = 1, + /// + /// Identifier field is associated with the target device that contains the LUN + /// + TargetDevice = 2 + } + public enum IdentificationCodeSet : byte { /// @@ -141,7 +157,11 @@ namespace DiscImageChef.Decoders.SCSI /// /// Identifier is pure ASCII /// - ASCII = 2 + ASCII = 2, + /// + /// Identifier is in UTF-8 + /// + UTF8 = 3 } public enum IdentificationTypes : byte @@ -155,22 +175,58 @@ namespace DiscImageChef.Decoders.SCSI /// Inquiry = 1, /// - /// Identifier is a 64-bit IEEE EUI-64 + /// Identifier is a 64-bit IEEE EUI-64, or extended /// EUI = 2, /// - /// Identifier is a 64-bit FC-PH Name_Identifier + /// Identifier is compatible with 64-bit FC-PH Name_Identifier /// - FCPH = 3 + NAA = 3, + /// + /// Identifier to relative port in device + /// + Relative = 4, + /// + /// Identifier to group of target ports in device + /// + TargetPortGroup = 5, + /// + /// Identifier to group of target LUNs in device + /// + LogicalUnitGroup = 6, + /// + /// MD5 of device identification values + /// + MD5 = 7, + /// + /// SCSI name string + /// + SCSI = 8, + /// + /// Protocol specific port identifier + /// + ProtocolSpecific = 9 } public struct IdentificatonDescriptor { + /// + /// Protocol identifier + /// + public ProtocolIdentifiers ProtocolIdentifier; /// /// Defines how the identifier is stored /// public IdentificationCodeSet CodeSet; /// + /// Set if protocol identifier is valid + /// + public bool PIV; + /// + /// Identifies which decide the identifier associates with + /// + public IdentificationAssociation Association; + /// /// Defines the type of the identifier /// public IdentificationTypes Type; @@ -179,7 +235,7 @@ namespace DiscImageChef.Decoders.SCSI /// public byte Length; /// - /// Identifier as an ASCII string if applicable + /// Identifier as a string if applicable /// public string ASCII; /// @@ -242,19 +298,27 @@ namespace DiscImageChef.Decoders.SCSI while(position < pageResponse.Length) { IdentificatonDescriptor descriptor = new IdentificatonDescriptor(); + descriptor.ProtocolIdentifier = (ProtocolIdentifiers)((pageResponse[position] & 0xF0) >> 4); descriptor.CodeSet = (IdentificationCodeSet)(pageResponse[position] & 0x0F); + descriptor.PIV |= (pageResponse[position + 1] & 0x80) == 0x80; + descriptor.Association = (IdentificationAssociation)((pageResponse[position + 1] & 0x30) >> 4); descriptor.Type = (IdentificationTypes)(pageResponse[position + 1] & 0x0F); descriptor.Length = pageResponse[position + 3]; descriptor.Binary = new byte[descriptor.Length]; Array.Copy(pageResponse, position + 4, descriptor.Binary, 0, descriptor.Length); if(descriptor.CodeSet == IdentificationCodeSet.ASCII) descriptor.ASCII = StringHandlers.CToString(descriptor.Binary); + else if(descriptor.CodeSet == IdentificationCodeSet.UTF8) + descriptor.ASCII = Encoding.UTF8.GetString(descriptor.Binary); else descriptor.ASCII = ""; position += 4 + descriptor.Length; + descriptors.Add(descriptor); } + decoded.Descriptors = descriptors.ToArray(); + return decoded; } @@ -271,7 +335,7 @@ namespace DiscImageChef.Decoders.SCSI Page_83 page = modePage.Value; StringBuilder sb = new StringBuilder(); - sb.AppendLine("SCSI Device identification page:"); + sb.AppendLine("SCSI Device identification:"); if(page.Descriptors.Length == 0) { @@ -281,41 +345,207 @@ namespace DiscImageChef.Decoders.SCSI foreach(IdentificatonDescriptor descriptor in page.Descriptors) { + switch(descriptor.Association) + { + case IdentificationAssociation.LogicalUnit: + sb.AppendLine("\tIdentifier belongs to addressed logical unit"); + break; + case IdentificationAssociation.TargetPort: + sb.AppendLine("\tIdentifier belongs to target port"); + break; + case IdentificationAssociation.TargetDevice: + sb.AppendLine("\tIdentifier belongs to target device that contains the addressed logical unit"); + break; + default: + sb.AppendFormat("\tIndentifier has unknown association with code {0}", (byte)descriptor.Association).AppendLine(); + break; + } + + if(descriptor.PIV) + { + string protocol = ""; + switch(descriptor.ProtocolIdentifier) + { + case ProtocolIdentifiers.ADT: + protocol = "Automation/Drive Interface Transport"; + break; + case ProtocolIdentifiers.ATA: + protocol = "AT Attachment Interface (ATA/ATAPI)"; + break; + case ProtocolIdentifiers.FibreChannel: + protocol = "Fibre Channel"; + break; + case ProtocolIdentifiers.Firewire: + protocol = "IEEE 1394"; + break; + case ProtocolIdentifiers.iSCSI: + protocol = "Internet SCSI"; + break; + case ProtocolIdentifiers.NoProtocol: + protocol = "no specific"; + break; + case ProtocolIdentifiers.PCIe: + protocol = "PCI Express"; + break; + case ProtocolIdentifiers.RDMAP: + protocol = "SCSI Remote Direct Memory Access"; + break; + case ProtocolIdentifiers.SAS: + protocol = "Serial Attachment SCSI"; + break; + case ProtocolIdentifiers.SCSI: + protocol = "Parallel SCSI"; + break; + case ProtocolIdentifiers.SCSIe: + protocol = "SCSI over PCI Express"; + break; + case ProtocolIdentifiers.SSA: + protocol = "SSA"; + break; + case ProtocolIdentifiers.UAS: + protocol = "USB Attached SCSI"; + break; + default: + protocol = string.Format("unknown code {0}", (byte)descriptor.ProtocolIdentifier); + break; + } + sb.AppendFormat("\tDescriptor referes to {0} protocol", protocol).AppendLine(); + } + switch(descriptor.Type) { case IdentificationTypes.NoAuthority: - if(descriptor.CodeSet == IdentificationCodeSet.ASCII) - sb.AppendFormat("Vendor descriptor contains: {0}", descriptor.ASCII).AppendLine(); + if(descriptor.CodeSet == IdentificationCodeSet.ASCII || descriptor.CodeSet == IdentificationCodeSet.UTF8) + sb.AppendFormat("\tVendor descriptor contains: {0}", descriptor.ASCII).AppendLine(); else if(descriptor.CodeSet == IdentificationCodeSet.Binary) - sb.AppendFormat("Vendor descriptor contains binary data (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + sb.AppendFormat("\tVendor descriptor contains binary data (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); else - sb.AppendFormat("Vendor descriptor contains unknown kind {1} of data (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40), (byte)descriptor.CodeSet).AppendLine(); + sb.AppendFormat("\tVendor descriptor contains unknown kind {1} of data (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40), (byte)descriptor.CodeSet).AppendLine(); break; case IdentificationTypes.Inquiry: - if(descriptor.CodeSet == IdentificationCodeSet.ASCII) - sb.AppendFormat("Inquiry descriptor contains: {0}", descriptor.ASCII).AppendLine(); + if(descriptor.CodeSet == IdentificationCodeSet.ASCII || descriptor.CodeSet == IdentificationCodeSet.UTF8) + sb.AppendFormat("\tInquiry descriptor contains: {0}", descriptor.ASCII).AppendLine(); else if(descriptor.CodeSet == IdentificationCodeSet.Binary) - sb.AppendFormat("Inquiry descriptor contains binary data (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + sb.AppendFormat("\tInquiry descriptor contains binary data (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); else - sb.AppendFormat("Inquiry descriptor contains unknown kind {1} of data (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40), (byte)descriptor.CodeSet).AppendLine(); + sb.AppendFormat("\tInquiry descriptor contains unknown kind {1} of data (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40), (byte)descriptor.CodeSet).AppendLine(); break; case IdentificationTypes.EUI: - if(descriptor.CodeSet == IdentificationCodeSet.ASCII) - sb.AppendFormat("IEEE EUI-64: {0}", descriptor.ASCII).AppendLine(); + if(descriptor.CodeSet == IdentificationCodeSet.ASCII || descriptor.CodeSet == IdentificationCodeSet.UTF8) + sb.AppendFormat("\tIEEE EUI-64: {0}", descriptor.ASCII).AppendLine(); else - sb.AppendFormat("IEEE EUI-64: {0:X16}", descriptor.Binary).AppendLine(); + { + sb.AppendFormat("\tIEEE EUI-64: {0:X2}", descriptor.Binary[0]); + for(int i = 1; i < descriptor.Binary.Length; i++) + sb.AppendFormat(":{0:X2}", descriptor.Binary[i]); + sb.AppendLine(); + } break; - case IdentificationTypes.FCPH: - if(descriptor.CodeSet == IdentificationCodeSet.ASCII) - sb.AppendFormat("FC-PH Name_Identifier: {0}", descriptor.ASCII).AppendLine(); + case IdentificationTypes.NAA: + if(descriptor.CodeSet == IdentificationCodeSet.ASCII || descriptor.CodeSet == IdentificationCodeSet.UTF8) + sb.AppendFormat("\tNAA: {0}", descriptor.ASCII).AppendLine(); else - sb.AppendFormat("FC-PH Name_Identifier: {0:X16}", descriptor.Binary).AppendLine(); + { + sb.AppendFormat("\tNAA: {0:X2}", descriptor.Binary[0]); + for(int i = 1; i < descriptor.Binary.Length; i++) + sb.AppendFormat(":{0:X2}", descriptor.Binary[i]); + sb.AppendLine(); + } + break; + case IdentificationTypes.Relative: + if(descriptor.CodeSet == IdentificationCodeSet.ASCII || descriptor.CodeSet == IdentificationCodeSet.UTF8) + sb.AppendFormat("\tRelative target port identifier: {0}", descriptor.ASCII).AppendLine(); + else + sb.AppendFormat("\tRelative target port identifier: {0}", (descriptor.Binary[2] << 8) + descriptor.Binary[3]).AppendLine(); + break; + case IdentificationTypes.TargetPortGroup: + if(descriptor.CodeSet == IdentificationCodeSet.ASCII || descriptor.CodeSet == IdentificationCodeSet.UTF8) + sb.AppendFormat("\tTarget group identifier: {0}", descriptor.ASCII).AppendLine(); + else + sb.AppendFormat("\tTarget group identifier: {0}", (descriptor.Binary[2] << 8) + descriptor.Binary[3]).AppendLine(); + break; + case IdentificationTypes.LogicalUnitGroup: + if(descriptor.CodeSet == IdentificationCodeSet.ASCII || descriptor.CodeSet == IdentificationCodeSet.UTF8) + sb.AppendFormat("\tLogical unit group identifier: {0}", descriptor.ASCII).AppendLine(); + else + sb.AppendFormat("\tLogical unit group identifier: {0}", (descriptor.Binary[2] << 8) + descriptor.Binary[3]).AppendLine(); + break; + case IdentificationTypes.MD5: + if(descriptor.CodeSet == IdentificationCodeSet.ASCII || descriptor.CodeSet == IdentificationCodeSet.UTF8) + sb.AppendFormat("\tMD5 logical unit identifier: {0}", descriptor.ASCII).AppendLine(); + else + { + sb.AppendFormat("\tMD5 logical unit identifier: {0:x2}", descriptor.Binary[0]); + for(int i = 1; i < descriptor.Binary.Length; i++) + sb.AppendFormat("{0:x2}", descriptor.Binary[i]); + sb.AppendLine(); + } + break; + case IdentificationTypes.SCSI: + if(descriptor.CodeSet == IdentificationCodeSet.ASCII || descriptor.CodeSet == IdentificationCodeSet.UTF8) + sb.AppendFormat("\tSCSI name string identifier: {0}", descriptor.ASCII).AppendLine(); + else + { + sb.AppendFormat("\tSCSI name string identifier (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + } + break; + case IdentificationTypes.ProtocolSpecific: + { + if(descriptor.PIV) + { + switch(descriptor.ProtocolIdentifier) + { + case ProtocolIdentifiers.ADT: + sb.AppendFormat("\tProtocol (Automation/Drive Interface Transport) specific descriptor with unknown format (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + case ProtocolIdentifiers.ATA: + sb.AppendFormat("\tProtocol (ATA/ATAPI) specific descriptor with unknown format (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + case ProtocolIdentifiers.FibreChannel: + sb.AppendFormat("\tProtocol (Fibre Channel) specific descriptor with unknown format (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + case ProtocolIdentifiers.Firewire: + sb.AppendFormat("\tProtocol (IEEE 1394) specific descriptor with unknown format (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + case ProtocolIdentifiers.iSCSI: + sb.AppendFormat("\tProtocol (Internet SCSI) specific descriptor with unknown format (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + case ProtocolIdentifiers.NoProtocol: + sb.AppendFormat("\tProtocol (unknown) specific descriptor with unknown format (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + case ProtocolIdentifiers.PCIe: + sb.AppendFormat("\tProtocol (PCI Express) specific descriptor with unknown format (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + case ProtocolIdentifiers.RDMAP: + sb.AppendFormat("\tProtocol (SCSI Remote Direct Memory Access) specific descriptor with unknown format (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + case ProtocolIdentifiers.SAS: + sb.AppendFormat("\tProtocol (Serial Attachment SCSI) specific descriptor with unknown format (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + case ProtocolIdentifiers.SCSI: + sb.AppendFormat("\tProtocol (Parallel SCSI) specific descriptor with unknown format (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + case ProtocolIdentifiers.SSA: + sb.AppendFormat("\tProtocol (SSA) specific descriptor with unknown format (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + case ProtocolIdentifiers.SCSIe: + sb.AppendFormat("\tProtocol (SCSIe) specific descriptor: Routing ID is {0}", (descriptor.Binary[0] << 8) + descriptor.Binary[1]).AppendLine(); + break; + case ProtocolIdentifiers.UAS: + sb.AppendFormat("\tProtocol (UAS) specific descriptor: USB address {0} interface {1}", descriptor.Binary[0] & 0x7F, descriptor.Binary[2]).AppendLine(); + break; + default: + sb.AppendFormat("\tProtocol (unknown code {0}) specific descriptor with unknown format (hex): {1}", (byte)descriptor.ProtocolIdentifier, PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40)).AppendLine(); + break; + } + } + } break; default: - if(descriptor.CodeSet == IdentificationCodeSet.ASCII) - sb.AppendFormat("Unknown descriptor type {1} contains: {0}", descriptor.ASCII, (byte)descriptor.Type).AppendLine(); + if(descriptor.CodeSet == IdentificationCodeSet.ASCII || descriptor.CodeSet == IdentificationCodeSet.UTF8) + sb.AppendFormat("\tUnknown descriptor type {1} contains: {0}", descriptor.ASCII, (byte)descriptor.Type).AppendLine(); else if(descriptor.CodeSet == IdentificationCodeSet.Binary) - sb.AppendFormat("Inquiry descriptor type {1} contains binary data (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40), (byte)descriptor.Type).AppendLine(); + sb.AppendFormat("\tUnknown descriptor type {1} contains binary data (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40), (byte)descriptor.Type).AppendLine(); else sb.AppendFormat("Inquiry descriptor type {2} contains unknown kind {1} of data (hex): {0}", PrintHex.ByteArrayToHexArrayString(descriptor.Binary, 40), (byte)descriptor.CodeSet, (byte)descriptor.Type).AppendLine(); break; diff --git a/SCSI/Enums.cs b/SCSI/Enums.cs index 385d5ba0e..bf43ac0ef 100644 --- a/SCSI/Enums.cs +++ b/SCSI/Enums.cs @@ -247,5 +247,61 @@ namespace DiscImageChef.Decoders.SCSI /// Both = 0x03 } + + public enum ProtocolIdentifiers : byte + { + /// + /// Fibre Channel + /// + FibreChannel = 0, + /// + /// Parallel SCSI + /// + SCSI = 1, + /// + /// SSA + /// + SSA = 2, + /// + /// IEEE-1394 + /// + Firewire = 3, + /// + /// SCSI Remote Direct Memory Access Protocol + /// + RDMAP = 4, + /// + /// Internet SCSI + /// + iSCSI = 5, + /// + /// Serial SCSI + /// + SAS = 6, + /// + /// Automation/Drive Interface Transport Protocol + /// + ADT = 7, + /// + /// AT Attachment Interface (ATA/ATAPI) + /// + ATA = 8, + /// + /// USB Attached SCSI + /// + UAS = 9, + /// + /// SCSI over PCI Express + /// + SCSIe = 10, + /// + /// PCI Express + /// + PCIe = 11, + /// + /// No specific protocol + /// + NoProtocol = 15 + } } diff --git a/SCSI/Modes.cs b/SCSI/Modes.cs index 13d22b839..68c676a35 100644 --- a/SCSI/Modes.cs +++ b/SCSI/Modes.cs @@ -603,6 +603,12 @@ namespace DiscImageChef.Decoders.SCSI case DensityType.DDS2: density = "DDS-2"; break; + case DensityType.DDS3: + density = "DDS-3"; + break; + case DensityType.DDS4: + density = "DDS-4"; + break; default: density = string.Format("unknown density code 0x{0:X2}", (byte)descriptor.Density); break;