2017-05-19 20:28:49 +01:00
// /***************************************************************************
2015-10-16 01:55:55 +01:00
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
2016-07-28 18:13:49 +01:00
// Filename : Identify.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
2015-10-16 01:55:55 +01:00
//
2016-07-28 18:13:49 +01:00
// Component : Device structures decoders.
2015-10-16 01:55:55 +01:00
//
// --[ Description ] ----------------------------------------------------------
//
2016-07-28 18:13:49 +01:00
// Decodes ATA IDENTIFY DEVICE response.
2015-10-16 01:55:55 +01:00
//
// --[ License ] --------------------------------------------------------------
//
2016-07-28 18:13:49 +01:00
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
2015-10-16 01:55:55 +01:00
// License, or (at your option) any later version.
//
2016-07-28 18:13:49 +01:00
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
2015-10-16 01:55:55 +01:00
//
2016-07-28 18:13:49 +01:00
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
2015-10-16 01:55:55 +01:00
//
// ----------------------------------------------------------------------------
2018-12-29 17:34:38 +00:00
// Copyright © 2011-2019 Natalia Portillo
2015-10-16 01:55:55 +01:00
// ****************************************************************************/
2016-07-28 18:13:49 +01:00
2015-10-16 01:55:55 +01:00
using System ;
2017-12-23 18:31:38 +00:00
using System.Collections.Generic ;
2017-12-22 02:04:18 +00:00
using System.Diagnostics.CodeAnalysis ;
2015-10-16 01:55:55 +01:00
using System.Runtime.InteropServices ;
2015-10-17 01:26:17 +01:00
using System.Text ;
2015-10-18 22:04:03 +01:00
using DiscImageChef.Console ;
2017-12-21 14:30:38 +00:00
using DiscImageChef.Decoders.SCSI ;
2019-02-28 00:04:13 +00:00
using Marshal = DiscImageChef . Helpers . Marshal ;
2015-10-16 01:55:55 +01:00
2015-10-19 03:17:03 +01:00
namespace DiscImageChef.Decoders.ATA
2015-10-16 01:55:55 +01:00
{
/// <summary>
2019-11-25 00:54:38 +00:00
/// Information from following standards: T10-791D rev. 4c (ATA) T10-948D rev. 4c (ATA-2) T13-1153D rev. 18
/// (ATA/ATAPI-4) T13-1321D rev. 3 (ATA/ATAPI-5) T13-1410D rev. 3b (ATA/ATAPI-6) T13-1532D rev. 4b (ATA/ATAPI-7)
/// T13-1699D rev. 3f (ATA8-ACS) T13-1699D rev. 4a (ATA8-ACS) T13-2015D rev. 2 (ACS-2) T13-2161D rev. 5 (ACS-3) CF+
/// & CF Specification rev. 1.4 (CFA)
2015-10-16 01:55:55 +01:00
/// </summary>
2019-11-25 00:54:38 +00:00
[ SuppressMessage ( "ReSharper" , "InconsistentNaming" ) , SuppressMessage ( "ReSharper" , "MemberCanBeInternal" ) ,
SuppressMessage ( "ReSharper" , "MemberCanBePrivate.Global" ) ]
2015-10-19 03:17:03 +01:00
public static class Identify
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
/// <summary>Capabilities flag bits.</summary>
2015-10-16 01:55:55 +01:00
[Flags]
public enum CapabilitiesBit : ushort
{
2019-11-25 00:54:38 +00:00
/// <summary>ATAPI: Interleaved DMA supported</summary>
InterleavedDMA = 0x8000 , /// <summary>ATAPI: Command queueing supported</summary>
CommandQueue = 0x4000 , /// <summary>Standby timer values are standard</summary>
StandardStanbyTimer = 0x2000 , /// <summary>ATAPI: Overlap operation supported</summary>
OverlapOperation = 0x2000 , /// <summary>ATAPI: ATA software reset required Obsoleted in ATA/ATAPI-4</summary>
RequiresATASoftReset = 0x1000 , /// <summary>IORDY is supported</summary>
IORDY = 0x0800 , /// <summary>IORDY can be disabled</summary>
CanDisableIORDY = 0x0400 , /// <summary>LBA is supported</summary>
LBASupport = 0x0200 , /// <summary>DMA is supported</summary>
DMASupport = 0x0100 , /// <summary>Vendor unique Obsoleted in ATA/ATAPI-4</summary>
VendorBit7 = 0x0080 , /// <summary>Vendor unique Obsoleted in ATA/ATAPI-4</summary>
VendorBit6 = 0x0040 , /// <summary>Vendor unique Obsoleted in ATA/ATAPI-4</summary>
VendorBit5 = 0x0020 , /// <summary>Vendor unique Obsoleted in ATA/ATAPI-4</summary>
VendorBit4 = 0x0010 , /// <summary>Vendor unique Obsoleted in ATA/ATAPI-4</summary>
VendorBit3 = 0x0008 , /// <summary>Vendor unique Obsoleted in ATA/ATAPI-4</summary>
VendorBit2 = 0x0004 , /// <summary>Long Physical Alignment setting bit 1</summary>
PhysicalAlignment1 = 0x0002 , /// <summary>Long Physical Alignment setting bit 0</summary>
2015-10-16 01:55:55 +01:00
PhysicalAlignment0 = 0x0001
}
2019-11-25 00:54:38 +00:00
/// <summary>More capabilities flag bits.</summary>
2015-10-16 01:55:55 +01:00
[Flags]
public enum CapabilitiesBit2 : ushort
{
2019-11-25 00:54:38 +00:00
/// <summary>MUST NOT be set</summary>
MustBeClear = 0x8000 , /// <summary>MUST be set</summary>
MustBeSet = 0x4000 , Reserved13 = 0x2000 , Reserved12 = 0x1000 , Reserved11 = 0x0800 ,
Reserved10 = 0x0400 , Reserved09 = 0x0200 , Reserved08 = 0x0100 ,
Reserved07 = 0x0080 , Reserved06 = 0x0040 , Reserved05 = 0x0020 ,
Reserved04 = 0x0010 , Reserved03 = 0x0008 , Reserved02 = 0x0004 ,
Reserved01 = 0x0002 , /// <summary>Indicates a device specific minimum standby timer value</summary>
2017-12-21 02:52:12 +00:00
SpecificStandbyTimer = 0x0001
2015-10-16 01:55:55 +01:00
}
[Flags]
2019-11-25 00:54:38 +00:00
public enum CapabilitiesBit3 : byte
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
/// <summary>BLOCK ERASE EXT supported</summary>
BlockErase = 0x0080 , /// <summary>OVERWRITE EXT supported</summary>
Overwrite = 0x0040 , /// <summary>CRYPTO SCRAMBLE EXT supported</summary>
CryptoScramble = 0x0020 , /// <summary>Sanitize feature set is supported</summary>
Sanitize = 0x0010 , /// <summary>If unset, sanitize commands are specified by ACS-2</summary>
SanitizeCommands = 0x0008 , /// <summary>SANITIZE ANTIFREEZE LOCK EXT is supported</summary>
SanitizeAntifreeze = 0x0004 , Reserved01 = 0x0002 , /// <summary>Multiple logical sector setting is valid</summary>
MultipleValid = 0x0001
2015-10-16 01:55:55 +01:00
}
2019-11-25 00:54:38 +00:00
/// <summary>More capabilities flag bits.</summary>
2015-10-16 01:55:55 +01:00
[Flags]
public enum CommandSetBit : ushort
{
2019-11-25 00:54:38 +00:00
/// <summary>Already obsolete in ATA/ATAPI-4, reserved in ATA3</summary>
Obsolete15 = 0x8000 , /// <summary>NOP is supported</summary>
Nop = 0x4000 , /// <summary>READ BUFFER is supported</summary>
ReadBuffer = 0x2000 , /// <summary>WRITE BUFFER is supported</summary>
WriteBuffer = 0x1000 , /// <summary>Already obsolete in ATA/ATAPI-4, reserved in ATA3</summary>
Obsolete11 = 0x0800 , /// <summary>Host Protected Area is supported</summary>
HPA = 0x0400 , /// <summary>DEVICE RESET is supported</summary>
DeviceReset = 0x0200 , /// <summary>SERVICE interrupt is supported</summary>
Service = 0x0100 , /// <summary>Release is supported</summary>
Release = 0x0080 , /// <summary>Look-ahead is supported</summary>
LookAhead = 0x0040 , /// <summary>Write cache is supported</summary>
WriteCache = 0x0020 , /// <summary>PACKET command set is supported</summary>
Packet = 0x0010 , /// <summary>Power Management feature set is supported</summary>
PowerManagement = 0x0008 , /// <summary>Removable Media feature set is supported</summary>
RemovableMedia = 0x0004 , /// <summary>Security Mode feature set is supported</summary>
SecurityMode = 0x0002 , /// <summary>SMART feature set is supported</summary>
2017-12-21 02:52:12 +00:00
SMART = 0x0001
2015-10-16 01:55:55 +01:00
}
2019-11-25 00:54:38 +00:00
/// <summary>More capabilities flag bits.</summary>
2015-10-16 01:55:55 +01:00
[Flags]
public enum CommandSetBit2 : ushort
{
2019-11-25 00:54:38 +00:00
/// <summary>MUST NOT be set</summary>
MustBeClear = 0x8000 , /// <summary>MUST BE SET</summary>
MustBeSet = 0x4000 , /// <summary>FLUSH CACHE EXT supported</summary>
FlushCacheExt = 0x2000 , /// <summary>FLUSH CACHE supported</summary>
FlushCache = 0x1000 , /// <summary>Device Configuration Overlay feature set supported</summary>
DCO = 0x0800 , /// <summary>48-bit LBA supported</summary>
LBA48 = 0x0400 , /// <summary>Automatic Acoustic Management supported</summary>
AAM = 0x0200 , /// <summary>SET MAX security extension supported</summary>
SetMax = 0x0100 , /// <summary>Address Offset Reserved Area Boot NCITS TR27:2001</summary>
AddressOffsetReservedAreaBoot = 0x0080 , /// <summary>SET FEATURES required to spin-up</summary>
SetFeaturesRequired = 0x0040 , /// <summary>Power-Up in standby feature set supported</summary>
PowerUpInStandby = 0x0020 , /// <summary>Removable Media Status Notification feature set is supported</summary>
RemovableNotification = 0x0010 , /// <summary>Advanced Power Management feature set is supported</summary>
APM = 0x0008 , /// <summary>Compact Flash feature set is supported</summary>
CompactFlash = 0x0004 , /// <summary>READ DMA QUEUED and WRITE DMA QUEUED are supported</summary>
RWQueuedDMA = 0x0002 , /// <summary>DOWNLOAD MICROCODE is supported</summary>
2017-12-21 02:52:12 +00:00
DownloadMicrocode = 0x0001
2015-10-16 01:55:55 +01:00
}
2019-11-25 00:54:38 +00:00
/// <summary>More capabilities flag bits.</summary>
2015-10-16 01:55:55 +01:00
[Flags]
public enum CommandSetBit3 : ushort
{
2019-11-25 00:54:38 +00:00
/// <summary>MUST NOT be set</summary>
MustBeClear = 0x8000 , /// <summary>MUST BE SET</summary>
MustBeSet = 0x4000 , /// <summary>IDLE IMMEDIATE with UNLOAD FEATURE is supported</summary>
IdleImmediate = 0x2000 , /// <summary>Reserved for INCITS TR-37/2004</summary>
Reserved12 = 0x1000 , /// <summary>Reserved for INCITS TR-37/2004</summary>
Reserved11 = 0x0800 , /// <summary>URG bit is supported in WRITE STREAM DMA EXT and WRITE STREAM EXT</summary>
WriteURG = 0x0400 , /// <summary>URG bit is supported in READ STREAM DMA EXT and READ STREAM EXT</summary>
ReadURG = 0x0200 , /// <summary>64-bit World Wide Name is supported</summary>
WWN = 0x0100 , /// <summary>WRITE DMA QUEUED FUA EXT is supported</summary>
FUAWriteQ = 0x0080 , /// <summary>WRITE DMA FUA EXT and WRITE MULTIPLE FUA EXT are supported</summary>
FUAWrite = 0x0040 , /// <summary>General Purpose Logging feature supported</summary>
GPL = 0x0020 , /// <summary>Sstreaming feature set is supported</summary>
Streaming = 0x0010 , /// <summary>Media Card Pass Through command set supported</summary>
MCPT = 0x0008 , /// <summary>Media serial number supported</summary>
MediaSerial = 0x0004 , /// <summary>SMART self-test supported</summary>
SMARTSelfTest = 0x0002 , /// <summary>SMART error logging supported</summary>
2017-12-21 02:52:12 +00:00
SMARTLog = 0x0001
2015-10-16 01:55:55 +01:00
}
2019-11-25 00:54:38 +00:00
/// <summary>More capabilities flag bits.</summary>
2015-10-16 01:55:55 +01:00
[Flags]
2019-11-25 00:54:38 +00:00
public enum CommandSetBit4 : ushort
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
/// <summary>MUST NOT be set</summary>
MustBeClear = 0x8000 , /// <summary>MUST be set</summary>
MustBeSet = 0x4000 , Reserved13 = 0x2000 , Reserved12 = 0x1000 , Reserved11 = 0x0800 ,
Reserved10 = 0x0400 , /// <summary>DSN feature set is supported</summary>
DSN = 0x0200 , /// <summary>Accessible Max Address Configuration is supported</summary>
AMAC = 0x0100 , /// <summary>Extended Power Conditions is supported</summary>
ExtPowerCond = 0x0080 , /// <summary>Extended Status Reporting is supported</summary>
ExtStatusReport = 0x0040 , /// <summary>Free-fall Control feature set is supported</summary>
FreeFallControl = 0x0020 , /// <summary>Supports segmented feature in DOWNLOAD MICROCODE</summary>
SegmentedDownloadMicrocode = 0x0010 , /// <summary>READ/WRITE DMA EXT GPL are supported</summary>
RWDMAExtGpl = 0x0008 , /// <summary>WRITE UNCORRECTABLE is supported</summary>
WriteUnc = 0x0004 , /// <summary>Write/Read/Verify is supported</summary>
WRV = 0x0002 , /// <summary>Reserved for DT1825</summary>
DT1825 = 0x0001
2015-10-16 01:55:55 +01:00
}
[Flags]
2019-11-25 00:54:38 +00:00
public enum CommandSetBit5 : ushort
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
/// <summary>Supports CFast Specification</summary>
CFast = 0x8000 , /// <summary>Deterministic read after TRIM is supported</summary>
DeterministicTrim = 0x4000 , /// <summary>Long physical sector alignment error reporting control is supported</summary>
LongPhysSectorAligError = 0x2000 , /// <summary>DEVICE CONFIGURATION IDENTIFY DMA and DEVICE CONFIGURATION SET DMA are supported</summary>
DeviceConfDMA = 0x1000 , /// <summary>READ BUFFER DMA is supported</summary>
ReadBufferDMA = 0x0800 , /// <summary>WRITE BUFFER DMA is supported</summary>
WriteBufferDMA = 0x0400 , /// <summary>SET PASSWORD DMA and SET UNLOCK DMA are supported</summary>
SetMaxDMA = 0x0200 , /// <summary>DOWNLOAD MICROCODE DMA is supported</summary>
DownloadMicroCodeDMA = 0x0100 , /// <summary>Reserved for IEEE-1667</summary>
IEEE1667 = 0x0080 , /// <summary>Optional ATA 28-bit commands are supported</summary>
Ata28 = 0x0040 , /// <summary>Read zero after TRIM is supported</summary>
ReadZeroTrim = 0x0020 , /// <summary>Device encrypts all user data</summary>
Encrypted = 0x0010 , /// <summary>Extended number of user addressable sectors is supported</summary>
ExtSectors = 0x0008 , /// <summary>All write cache is non-volatile</summary>
AllCacheNV = 0x0004 , /// <summary>Zoned capabilities bit 1</summary>
ZonedBit1 = 0x0002 , /// <summary>Zoned capabilities bit 0</summary>
ZonedBit0 = 0x0001
2015-10-16 01:55:55 +01:00
}
2019-11-25 00:54:38 +00:00
[Flags]
public enum DataSetMgmtBit : ushort
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
Reserved15 = 0x8000 , Reserved14 = 0x4000 , Reserved13 = 0x2000 ,
Reserved12 = 0x1000 , Reserved11 = 0x0800 , Reserved10 = 0x0400 ,
Reserved09 = 0x0200 , Reserved08 = 0x0100 , Reserved07 = 0x0080 ,
Reserved06 = 0x0040 , Reserved05 = 0x0020 , Reserved04 = 0x0010 ,
Reserved03 = 0x0008 , Reserved02 = 0x0004 , Reserved01 = 0x0002 ,
/// <summary>TRIM is suported</summary>
Trim = 0x0001
}
public enum DeviceFormFactorEnum : ushort
{
/// <summary>Size not reported</summary>
NotReported = 0 , /// <summary>5.25"</summary>
FiveAndQuarter = 1 , /// <summary>3.5"</summary>
ThreeAndHalf = 2 , /// <summary>2.5"</summary>
TwoAndHalf = 3 , /// <summary>1.8"</summary>
OnePointEight = 4 , /// <summary>Less than 1.8"</summary>
LessThanOnePointEight = 5
2015-10-16 01:55:55 +01:00
}
2019-11-25 00:54:38 +00:00
/// <summary>Extended identify flag bits.</summary>
2015-10-16 01:55:55 +01:00
[Flags]
2019-11-25 00:54:38 +00:00
public enum ExtendedIdentifyBit : byte
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
/// <summary>Reserved</summary>
Reserved07 = 0x80 , /// <summary>Reserved</summary>
Reserved06 = 0x40 , /// <summary>Reserved</summary>
Reserved05 = 0x20 , /// <summary>Reserved</summary>
Reserved04 = 0x10 , /// <summary>Reserved</summary>
Reserved03 = 0x08 , /// <summary>Identify word 88 is valid</summary>
Word88Valid = 0x04 , /// <summary>Identify words 64 to 70 are valid</summary>
Words64to70Valid = 0x02 , /// <summary>Identify words 54 to 58 are valid</summary>
Words54to58Valid = 0x01
2015-10-16 01:55:55 +01:00
}
2019-11-25 00:54:38 +00:00
/// <summary>General configuration flag bits.</summary>
2015-10-16 01:55:55 +01:00
[Flags]
2019-11-25 00:54:38 +00:00
public enum GeneralConfigurationBit : ushort
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
/// <summary>Set on ATAPI</summary>
NonMagnetic = 0x8000 , /// <summary>Format speed tolerance gap is required Obsoleted in ATA-2</summary>
FormatGapReq = 0x4000 , /// <summary>Track offset option is available Obsoleted in ATA-2</summary>
TrackOffset = 0x2000 , /// <summary>Data strobe offset option is available Obsoleted in ATA-2</summary>
DataStrobeOffset = 0x1000 , /// <summary>Rotational speed tolerance is higher than 0,5% Obsoleted in ATA-2</summary>
RotationalSpeedTolerance = 0x0800 , /// <summary>Disk transfer rate is > 10 Mb/s Obsoleted in ATA-2</summary>
UltraFastIDE = 0x0400 , /// <summary>Disk transfer rate is > 5 Mb/s but <= 10 Mb/s Obsoleted in ATA-2</summary>
FastIDE = 0x0200 , /// <summary>Disk transfer rate is <= 5 Mb/s Obsoleted in ATA-2</summary>
SlowIDE = 0x0100 , /// <summary>Drive uses removable media</summary>
Removable = 0x0080 , /// <summary>Drive is fixed Obsoleted in ATA/ATAPI-6</summary>
Fixed = 0x0040 , /// <summary>Spindle motor control is implemented Obsoleted in ATA-2</summary>
SpindleControl = 0x0020 , /// <summary>Head switch time is bigger than 15 µsec. Obsoleted in ATA-2</summary>
HighHeadSwitch = 0x0010 , /// <summary>Drive is not MFM encoded Obsoleted in ATA-2</summary>
NotMFM = 0x0008 , /// <summary>Drive is soft sectored Obsoleted in ATA-2</summary>
SoftSector = 0x0004 , /// <summary>Response incomplete Since ATA/ATAPI-5</summary>
IncompleteResponse = 0x0004 , /// <summary>Drive is hard sectored Obsoleted in ATA-2</summary>
HardSector = 0x0002 , /// <summary>Reserved</summary>
Reserved = 0x0001
2015-10-16 01:55:55 +01:00
}
2019-11-25 00:54:38 +00:00
/// <summary>Word 80 Major version</summary>
2015-10-16 01:55:55 +01:00
[Flags]
2019-11-25 00:54:38 +00:00
public enum MajorVersionBit : ushort
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
Reserved15 = 0x8000 , Reserved14 = 0x4000 , Reserved13 = 0x2000 ,
Reserved12 = 0x1000 , /// <summary>ACS-4</summary>
ACS4 = 0x0800 , /// <summary>ACS-3</summary>
ACS3 = 0x0400 , /// <summary>ACS-2</summary>
ACS2 = 0x0200 , /// <summary>ATA8-ACS</summary>
Ata8ACS = 0x0100 , /// <summary>ATA/ATAPI-7</summary>
AtaAtapi7 = 0x0080 , /// <summary>ATA/ATAPI-6</summary>
AtaAtapi6 = 0x0040 , /// <summary>ATA/ATAPI-5</summary>
AtaAtapi5 = 0x0020 , /// <summary>ATA/ATAPI-4</summary>
AtaAtapi4 = 0x0010 , /// <summary>ATA-3</summary>
Ata3 = 0x0008 , /// <summary>ATA-2</summary>
Ata2 = 0x0004 , /// <summary>ATA-1</summary>
Ata1 = 0x0002 , Reserved00 = 0x0001
2015-10-16 01:55:55 +01:00
}
[Flags]
public enum SATACapabilitiesBit : ushort
{
2019-11-25 00:54:38 +00:00
/// <summary>Supports READ LOG DMA EXT</summary>
ReadLogDMAExt = 0x8000 , /// <summary>Supports device automatic partial to slumber transitions</summary>
DevSlumbTrans = 0x4000 , /// <summary>Supports host automatic partial to slumber transitions</summary>
HostSlumbTrans = 0x2000 , /// <summary>Supports NCQ priroty</summary>
NCQPriority = 0x1000 , /// <summary>Supports unload while NCQ commands are outstanding</summary>
UnloadNCQ = 0x0800 , /// <summary>Supports PHY Event Counters</summary>
PHYEventCounter = 0x0400 , /// <summary>Supports receipt of host initiated power management requests</summary>
PowerReceipt = 0x0200 , /// <summary>Supports NCQ</summary>
NCQ = 0x0100 , Reserved07 = 0x0080 , Reserved06 = 0x0040 , Reserved05 = 0x0020 ,
Reserved04 = 0x0010 , /// <summary>Supports SATA Gen. 3 Signaling Speed (6.0Gb/s)</summary>
Gen3Speed = 0x0008 , /// <summary>Supports SATA Gen. 2 Signaling Speed (3.0Gb/s)</summary>
Gen2Speed = 0x0004 , /// <summary>Supports SATA Gen. 1 Signaling Speed (1.5Gb/s)</summary>
Gen1Speed = 0x0002 , /// <summary>MUST NOT be set</summary>
Clear = 0x0001
}
[Flags]
public enum SATACapabilitiesBit2 : ushort
{
Reserved15 = 0x8000 , Reserved14 = 0x4000 , Reserved13 = 0x2000 ,
Reserved12 = 0x1000 , Reserved11 = 0x0800 , Reserved10 = 0x0400 ,
Reserved09 = 0x0200 , Reserved08 = 0x0100 , Reserved07 = 0x0080 ,
/// <summary>Supports RECEIVE FPDMA QUEUED and SEND FPDMA QUEUED</summary>
FPDMAQ = 0x0040 , /// <summary>Supports NCQ Queue Management</summary>
NCQMgmt = 0x0020 , /// <summary>ATAPI: Supports host environment detect</summary>
HostEnvDetect = 0x0020 , /// <summary>Supports NCQ streaming</summary>
NCQStream = 0x0010 , /// <summary>ATAPI: Supports device attention on slimline connected devices</summary>
DevAttSlimline = 0x0010 , /// <summary>Coded value indicating current negotiated Serial ATA signal speed</summary>
CurrentSpeedBit2 = 0x0008 , /// <summary>Coded value indicating current negotiated Serial ATA signal speed</summary>
CurrentSpeedBit1 = 0x0004 , /// <summary>Coded value indicating current negotiated Serial ATA signal speed</summary>
CurrentSpeedBit0 = 0x0002 , /// <summary>MUST NOT be set</summary>
2017-12-21 02:52:12 +00:00
Clear = 0x0001
2015-10-16 01:55:55 +01:00
}
[Flags]
public enum SATAFeaturesBit : ushort
{
2019-11-25 00:54:38 +00:00
Reserved15 = 0x8000 , Reserved14 = 0x4000 , Reserved13 = 0x2000 ,
Reserved12 = 0x1000 , Reserved11 = 0x0800 , Reserved10 = 0x0400 ,
Reserved09 = 0x0200 , Reserved08 = 0x0100 , /// <summary>Supports NCQ autosense</summary>
NCQAutoSense = 0x0080 , /// <summary>Automatic Partial to Slumber transitions are enabled</summary>
EnabledSlumber = 0x0080 , /// <summary>Supports Software Settings Preservation</summary>
SettingsPreserve = 0x0040 , /// <summary>Supports hardware feature control</summary>
HardwareFeatureControl = 0x0020 , /// <summary>ATAPI: Asynchronous notification</summary>
AsyncNotification = 0x0020 , /// <summary>Supports in-order data delivery</summary>
InOrderData = 0x0010 , /// <summary>Supports initiating power management</summary>
InitPowerMgmt = 0x0008 , /// <summary>Supports DMA Setup auto-activation</summary>
DMASetup = 0x0004 , /// <summary>Supports non-zero buffer offsets</summary>
NonZeroBufferOffset = 0x0002 , /// <summary>MUST NOT be set</summary>
2017-12-21 02:52:12 +00:00
Clear = 0x0001
2015-10-16 01:55:55 +01:00
}
[Flags]
2019-11-25 00:54:38 +00:00
public enum SCTCommandTransportBit : ushort
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
Vendor15 = 0x8000 , Vendor14 = 0x4000 , Vendor13 = 0x2000 ,
Vendor12 = 0x1000 , Reserved11 = 0x0800 , Reserved10 = 0x0400 ,
Reserved09 = 0x0200 , Reserved08 = 0x0100 , Reserved07 = 0x0080 ,
Reserved06 = 0x0040 , /// <summary>SCT Command Transport Data Tables supported</summary>
DataTables = 0x0020 , /// <summary>SCT Command Transport Features Control supported</summary>
FeaturesControl = 0x0010 , /// <summary>SCT Command Transport Error Recovery Control supported</summary>
ErrorRecoveryControl = 0x0008 , /// <summary>SCT Command Transport Write Same supported</summary>
WriteSame = 0x0004 , /// <summary>SCT Command Transport Long Sector Address supported</summary>
LongSectorAccess = 0x0002 , /// <summary>SCT Command Transport supported</summary>
Supported = 0x0001
2015-10-16 01:55:55 +01:00
}
2019-11-25 00:54:38 +00:00
/// <summary>More capabilities flag bits.</summary>
2015-10-16 01:55:55 +01:00
[Flags]
2019-11-25 00:54:38 +00:00
public enum SecurityStatusBit : ushort
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
Reserved15 = 0x8000 , Reserved14 = 0x4000 , Reserved13 = 0x2000 ,
Reserved12 = 0x1000 , Reserved11 = 0x0800 , Reserved10 = 0x0400 ,
Reserved09 = 0x0200 , /// <summary>Maximum security level</summary>
Maximum = 0x0100 , Reserved07 = 0x0080 , Reserved06 = 0x0040 , /// <summary>Supports enhanced security erase</summary>
Enhanced = 0x0020 , /// <summary>Security count expired</summary>
Expired = 0x0010 , /// <summary>Security frozen</summary>
Frozen = 0x0008 , /// <summary>Security locked</summary>
Locked = 0x0004 , /// <summary>Security enabled</summary>
Enabled = 0x0002 , /// <summary>Security supported</summary>
Supported = 0x0001
2015-10-16 01:55:55 +01:00
}
2019-11-25 00:54:38 +00:00
public enum SpecificConfigurationEnum : ushort
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
/// <summary>Device requires SET FEATURES to spin up and IDENTIFY DEVICE response is incomplete</summary>
RequiresSetIncompleteResponse = 0x37C8 , /// <summary>Device requires SET FEATURES to spin up and IDENTIFY DEVICE response is complete</summary>
RequiresSetCompleteResponse = 0x738C , /// <summary>Device does not requires SET FEATURES to spin up and IDENTIFY DEVICE response is incomplete</summary>
NotRequiresSetIncompleteResponse = 0x8C73 , /// <summary>Device does not requires SET FEATURES to spin up and IDENTIFY DEVICE response is complete</summary>
NotRequiresSetCompleteResponse = 0xC837
2015-10-16 01:55:55 +01:00
}
[Flags]
2019-11-25 00:54:38 +00:00
public enum TransferMode : byte
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
Mode7 = 0x80 , Mode6 = 0x40 , Mode5 = 0x20 ,
Mode4 = 0x10 , Mode3 = 0x08 , Mode2 = 0x04 ,
Mode1 = 0x02 , Mode0 = 0x01
2015-10-16 01:55:55 +01:00
}
[Flags]
2019-11-25 00:54:38 +00:00
public enum TrustedComputingBit : ushort
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
/// <summary>MUST NOT be set</summary>
Clear = 0x8000 , /// <summary>MUST be set</summary>
Set = 0x4000 , Reserved13 = 0x2000 , Reserved12 = 0x1000 , Reserved11 = 0x0800 ,
Reserved10 = 0x0400 , Reserved09 = 0x0200 , Reserved08 = 0x0100 ,
Reserved07 = 0x0080 , Reserved06 = 0x0040 , Reserved05 = 0x0020 ,
Reserved04 = 0x0010 , Reserved03 = 0x0008 , Reserved02 = 0x0004 ,
Reserved01 = 0x0002 , /// <summary>Trusted Computing feature set is supported</summary>
TrustedComputing = 0x0001
2015-10-16 01:55:55 +01:00
}
2015-10-19 03:17:03 +01:00
public static IdentifyDevice ? Decode ( byte [ ] IdentifyDeviceResponse )
2015-10-16 01:55:55 +01:00
{
2019-11-25 00:54:38 +00:00
if ( IdentifyDeviceResponse = = null )
return null ;
2016-04-19 02:11:47 +01:00
if ( IdentifyDeviceResponse . Length ! = 512 )
2015-10-18 22:04:03 +01:00
{
2017-12-19 20:33:03 +00:00
DicConsole . DebugWriteLine ( "ATA/ATAPI IDENTIFY decoder" ,
"IDENTIFY response is different than 512 bytes, not decoding." ) ;
2019-11-25 00:54:38 +00:00
2015-10-16 01:55:55 +01:00
return null ;
2015-10-18 22:04:03 +01:00
}
2015-10-16 01:55:55 +01:00
2019-11-25 00:54:38 +00:00
var ATAID = Marshal . ByteArrayToStructureLittleEndian < IdentifyDevice > ( IdentifyDeviceResponse ) ;
2015-10-17 01:26:17 +01:00
2018-06-22 08:08:38 +01:00
ATAID . WWN = DescrambleWWN ( ATAID . WWN ) ;
2015-10-17 01:26:17 +01:00
ATAID . WWNExtension = DescrambleWWN ( ATAID . WWNExtension ) ;
2018-06-22 08:08:38 +01:00
ATAID . SerialNumber = DescrambleATAString ( IdentifyDeviceResponse , 10 * 2 , 20 ) ;
ATAID . FirmwareRevision = DescrambleATAString ( IdentifyDeviceResponse , 23 * 2 , 8 ) ;
ATAID . Model = DescrambleATAString ( IdentifyDeviceResponse , 27 * 2 , 40 ) ;
ATAID . AdditionalPID = DescrambleATAString ( IdentifyDeviceResponse , 170 * 2 , 8 ) ;
ATAID . MediaSerial = DescrambleATAString ( IdentifyDeviceResponse , 176 * 2 , 40 ) ;
2016-04-19 02:11:47 +01:00
ATAID . MediaManufacturer = DescrambleATAString ( IdentifyDeviceResponse , 196 * 2 , 20 ) ;
2015-10-17 01:26:17 +01:00
return ATAID ;
}
2018-12-23 21:36:17 +00:00
public static byte [ ] Encode ( IdentifyDevice ? identify )
{
2019-11-25 00:54:38 +00:00
if ( identify is null )
return null ;
2018-12-23 21:36:17 +00:00
IdentifyDevice ataId = identify . Value ;
ataId . WWN = DescrambleWWN ( ataId . WWN ) ;
ataId . WWNExtension = DescrambleWWN ( ataId . WWNExtension ) ;
byte [ ] buf = new byte [ 512 ] ;
2019-02-28 00:04:13 +00:00
IntPtr ptr = System . Runtime . InteropServices . Marshal . AllocHGlobal ( 512 ) ;
System . Runtime . InteropServices . Marshal . StructureToPtr ( ataId , ptr , false ) ;
System . Runtime . InteropServices . Marshal . Copy ( ptr , buf , 0 , 512 ) ;
System . Runtime . InteropServices . Marshal . FreeHGlobal ( ptr ) ;
2018-12-23 21:36:17 +00:00
byte [ ] str = ScrambleATAString ( ataId . SerialNumber , 20 ) ;
Array . Copy ( str , 0 , buf , 10 * 2 , 20 ) ;
str = ScrambleATAString ( ataId . FirmwareRevision , 8 ) ;
Array . Copy ( str , 0 , buf , 23 * 2 , 8 ) ;
str = ScrambleATAString ( ataId . Model , 40 ) ;
Array . Copy ( str , 0 , buf , 27 * 2 , 40 ) ;
str = ScrambleATAString ( ataId . AdditionalPID , 8 ) ;
Array . Copy ( str , 0 , buf , 170 * 2 , 8 ) ;
str = ScrambleATAString ( ataId . MediaSerial , 40 ) ;
Array . Copy ( str , 0 , buf , 176 * 2 , 40 ) ;
str = ScrambleATAString ( ataId . MediaManufacturer , 20 ) ;
Array . Copy ( str , 0 , buf , 196 * 2 , 20 ) ;
return buf ;
}
2015-10-19 03:17:03 +01:00
public static string Prettify ( byte [ ] IdentifyDeviceResponse )
2015-10-17 01:26:17 +01:00
{
2019-11-25 00:54:38 +00:00
if ( IdentifyDeviceResponse . Length ! = 512 )
return null ;
2016-04-19 02:11:47 +01:00
2015-10-19 03:17:03 +01:00
IdentifyDevice ? decoded = Decode ( IdentifyDeviceResponse ) ;
2019-11-25 00:54:38 +00:00
2015-10-19 03:17:03 +01:00
return Prettify ( decoded ) ;
2015-10-17 01:26:17 +01:00
}
2015-10-19 03:17:03 +01:00
public static string Prettify ( IdentifyDevice ? IdentifyDeviceResponse )
2015-10-17 01:26:17 +01:00
{
2019-11-25 00:54:38 +00:00
if ( IdentifyDeviceResponse = = null )
return null ;
2015-10-17 01:26:17 +01:00
2019-11-25 00:54:38 +00:00
var sb = new StringBuilder ( ) ;
2015-10-17 01:26:17 +01:00
bool atapi = false ;
2018-06-22 08:08:38 +01:00
bool cfa = false ;
2015-10-17 01:26:17 +01:00
IdentifyDevice ATAID = IdentifyDeviceResponse . Value ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . NonMagnetic ) )
2018-06-22 08:08:38 +01:00
if ( ( ushort ) ATAID . GeneralConfiguration ! = 0x848A )
atapi = true ;
else
cfa = true ;
2015-10-17 01:26:17 +01:00
2019-11-25 00:54:38 +00:00
if ( atapi )
sb . AppendLine ( "ATAPI device" ) ;
else if ( cfa )
sb . AppendLine ( "CompactFlash device" ) ;
else
sb . AppendLine ( "ATA device" ) ;
if ( ATAID . Model ! = "" )
sb . AppendFormat ( "Model: {0}" , ATAID . Model ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . FirmwareRevision ! = "" )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Firmware revision: {0}" , ATAID . FirmwareRevision ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . SerialNumber ! = "" )
sb . AppendFormat ( "Serial #: {0}" , ATAID . SerialNumber ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( ATAID . AdditionalPID ! = "" )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Additional product ID: {0}" , ATAID . AdditionalPID ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . MustBeSet ) & &
2017-12-19 20:33:03 +00:00
! ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . MustBeClear ) )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( ATAID . EnabledCommandSet3 . HasFlag ( CommandSetBit3 . MediaSerial ) )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( ATAID . MediaManufacturer ! = "" )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Media manufacturer: {0}" , ATAID . MediaManufacturer ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . MediaSerial ! = "" )
sb . AppendFormat ( "Media serial #: {0}" , ATAID . MediaSerial ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
}
2017-12-23 18:31:38 +00:00
if ( ATAID . EnabledCommandSet3 . HasFlag ( CommandSetBit3 . WWN ) )
sb . AppendFormat ( "World Wide Name: {0:X16}" , ATAID . WWN ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
}
2019-11-25 00:54:38 +00:00
bool ata1 = false , ata2 = false , ata3 = false , ata4 = false , ata5 = false , ata6 = false , ata7 = false ,
acs = false , acs2 = false , acs3 = false , acs4 = false ;
2015-10-17 01:26:17 +01:00
2019-11-25 00:54:38 +00:00
if ( ( ushort ) ATAID . MajorVersion = = 0x0000 | |
( ushort ) ATAID . MajorVersion = = 0xFFFF )
2015-10-17 01:26:17 +01:00
{
// Obsolete in ATA-2, if present, device supports ATA-1
ata1 | = ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . FastIDE ) | |
2017-12-19 20:33:03 +00:00
ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . SlowIDE ) | |
ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . UltraFastIDE ) ;
2015-10-17 01:26:17 +01:00
ata2 | = ATAID . ExtendedIdentify . HasFlag ( ExtendedIdentifyBit . Words64to70Valid ) ;
2019-11-25 00:54:38 +00:00
if ( ! ata1 & &
! ata2 & &
! atapi & &
! cfa )
ata2 = true ;
2016-04-19 02:11:47 +01:00
2015-10-17 01:26:17 +01:00
ata4 | = atapi ;
ata3 | = cfa ;
2019-11-25 00:54:38 +00:00
if ( cfa & & ata1 )
ata1 = false ;
if ( cfa & & ata2 )
ata2 = false ;
2015-10-17 01:26:17 +01:00
ata5 | = ATAID . Signature = = 0xA5 ;
}
else
{
ata1 | = ATAID . MajorVersion . HasFlag ( MajorVersionBit . Ata1 ) ;
ata2 | = ATAID . MajorVersion . HasFlag ( MajorVersionBit . Ata2 ) ;
ata3 | = ATAID . MajorVersion . HasFlag ( MajorVersionBit . Ata3 ) ;
ata4 | = ATAID . MajorVersion . HasFlag ( MajorVersionBit . AtaAtapi4 ) ;
ata5 | = ATAID . MajorVersion . HasFlag ( MajorVersionBit . AtaAtapi5 ) ;
ata6 | = ATAID . MajorVersion . HasFlag ( MajorVersionBit . AtaAtapi6 ) ;
ata7 | = ATAID . MajorVersion . HasFlag ( MajorVersionBit . AtaAtapi7 ) ;
2018-06-22 08:08:38 +01:00
acs | = ATAID . MajorVersion . HasFlag ( MajorVersionBit . Ata8ACS ) ;
2015-10-17 01:26:17 +01:00
acs2 | = ATAID . MajorVersion . HasFlag ( MajorVersionBit . ACS2 ) ;
acs3 | = ATAID . MajorVersion . HasFlag ( MajorVersionBit . ACS3 ) ;
acs4 | = ATAID . MajorVersion . HasFlag ( MajorVersionBit . ACS4 ) ;
}
int maxatalevel = 0 ;
int minatalevel = 255 ;
sb . Append ( "Supported ATA versions: " ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ata1 )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "ATA-1 " ) ;
maxatalevel = 1 ;
2019-11-25 00:54:38 +00:00
if ( minatalevel > 1 )
minatalevel = 1 ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ata2 )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "ATA-2 " ) ;
maxatalevel = 2 ;
2019-11-25 00:54:38 +00:00
if ( minatalevel > 2 )
minatalevel = 2 ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ata3 )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "ATA-3 " ) ;
maxatalevel = 3 ;
2019-11-25 00:54:38 +00:00
if ( minatalevel > 3 )
minatalevel = 3 ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ata4 )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "ATA/ATAPI-4 " ) ;
maxatalevel = 4 ;
2019-11-25 00:54:38 +00:00
if ( minatalevel > 4 )
minatalevel = 4 ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ata5 )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "ATA/ATAPI-5 " ) ;
maxatalevel = 5 ;
2019-11-25 00:54:38 +00:00
if ( minatalevel > 5 )
minatalevel = 5 ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ata6 )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "ATA/ATAPI-6 " ) ;
maxatalevel = 6 ;
2019-11-25 00:54:38 +00:00
if ( minatalevel > 6 )
minatalevel = 6 ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ata7 )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "ATA/ATAPI-7 " ) ;
maxatalevel = 7 ;
2019-11-25 00:54:38 +00:00
if ( minatalevel > 7 )
minatalevel = 7 ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( acs )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "ATA8-ACS " ) ;
maxatalevel = 8 ;
2019-11-25 00:54:38 +00:00
if ( minatalevel > 8 )
minatalevel = 8 ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( acs2 )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "ATA8-ACS2 " ) ;
maxatalevel = 9 ;
2019-11-25 00:54:38 +00:00
if ( minatalevel > 9 )
minatalevel = 9 ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( acs3 )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "ATA8-ACS3 " ) ;
maxatalevel = 10 ;
2019-11-25 00:54:38 +00:00
if ( minatalevel > 10 )
minatalevel = 10 ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( acs4 )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "ATA8-ACS4 " ) ;
maxatalevel = 11 ;
2019-11-25 00:54:38 +00:00
if ( minatalevel > 11 )
minatalevel = 11 ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) ;
sb . Append ( "Maximum ATA revision supported: " ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( maxatalevel > = 3 )
switch ( ATAID . MinorVersion )
2015-10-17 01:26:17 +01:00
{
case 0x0000 :
case 0xFFFF :
sb . AppendLine ( "Minor ATA version not specified" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0001 :
sb . AppendLine ( "ATA (ATA-1) X3T9.2 781D prior to revision 4" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0002 :
sb . AppendLine ( "ATA-1 published, ANSI X3.221-1994" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0003 :
sb . AppendLine ( "ATA (ATA-1) X3T9.2 781D revision 4" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0004 :
sb . AppendLine ( "ATA-2 published, ANSI X3.279-1996" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0005 :
sb . AppendLine ( "ATA-2 X3T10 948D prior to revision 2k" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0006 :
sb . AppendLine ( "ATA-3 X3T10 2008D revision 1" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0007 :
sb . AppendLine ( "ATA-2 X3T10 948D revision 2k" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0008 :
sb . AppendLine ( "ATA-3 X3T10 2008D revision 0" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0009 :
sb . AppendLine ( "ATA-2 X3T10 948D revision 3" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x000A :
sb . AppendLine ( "ATA-3 published, ANSI X3.298-1997" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x000B :
sb . AppendLine ( "ATA-3 X3T10 2008D revision 6" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x000C :
sb . AppendLine ( "ATA-3 X3T13 2008D revision 7" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x000D :
sb . AppendLine ( "ATA/ATAPI-4 X3T13 1153D revision 6" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x000E :
sb . AppendLine ( "ATA/ATAPI-4 T13 1153D revision 13" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x000F :
sb . AppendLine ( "ATA/ATAPI-4 X3T13 1153D revision 7" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0010 :
sb . AppendLine ( "ATA/ATAPI-4 T13 1153D revision 18" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0011 :
sb . AppendLine ( "ATA/ATAPI-4 T13 1153D revision 15" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0012 :
sb . AppendLine ( "ATA/ATAPI-4 published, ANSI INCITS 317-1998" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0013 :
sb . AppendLine ( "ATA/ATAPI-5 T13 1321D revision 3" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0014 :
sb . AppendLine ( "ATA/ATAPI-4 T13 1153D revision 14" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0015 :
sb . AppendLine ( "ATA/ATAPI-5 T13 1321D revision 1" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0016 :
sb . AppendLine ( "ATA/ATAPI-5 published, ANSI INCITS 340-2000" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0017 :
sb . AppendLine ( "ATA/ATAPI-4 T13 1153D revision 17" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0018 :
sb . AppendLine ( "ATA/ATAPI-6 T13 1410D revision 0" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0019 :
sb . AppendLine ( "ATA/ATAPI-6 T13 1410D revision 3a" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x001A :
sb . AppendLine ( "ATA/ATAPI-7 T13 1532D revision 1" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x001B :
sb . AppendLine ( "ATA/ATAPI-6 T13 1410D revision 2" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x001C :
sb . AppendLine ( "ATA/ATAPI-6 T13 1410D revision 1" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x001D :
sb . AppendLine ( "ATA/ATAPI-7 published ANSI INCITS 397-2005" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x001E :
sb . AppendLine ( "ATA/ATAPI-7 T13 1532D revision 0" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x001F :
sb . AppendLine ( "ACS-3 Revision 3b" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0021 :
sb . AppendLine ( "ATA/ATAPI-7 T13 1532D revision 4a" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0022 :
sb . AppendLine ( "ATA/ATAPI-6 published, ANSI INCITS 361-2002" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0027 :
sb . AppendLine ( "ATA8-ACS revision 3c" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0028 :
sb . AppendLine ( "ATA8-ACS revision 6" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0029 :
sb . AppendLine ( "ATA8-ACS revision 4" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0031 :
sb . AppendLine ( "ACS-2 Revision 2" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0033 :
sb . AppendLine ( "ATA8-ACS Revision 3e" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0039 :
sb . AppendLine ( "ATA8-ACS Revision 4c" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0042 :
sb . AppendLine ( "ATA8-ACS Revision 3f" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0052 :
sb . AppendLine ( "ATA8-ACS revision 3b" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x006D :
sb . AppendLine ( "ACS-3 Revision 5" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0082 :
sb . AppendLine ( "ACS-2 published, ANSI INCITS 482-2012" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0107 :
sb . AppendLine ( "ATA8-ACS revision 2d" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x0110 :
sb . AppendLine ( "ACS-2 Revision 3" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x011B :
sb . AppendLine ( "ACS-3 Revision 4" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
default :
sb . AppendFormat ( "Unknown ATA revision 0x{0:X4}" , ATAID . MinorVersion ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
}
2016-04-19 02:11:47 +01:00
switch ( ( ATAID . TransportMajorVersion & 0xF000 ) > > 12 )
2015-10-17 01:26:17 +01:00
{
case 0x0 :
sb . Append ( "Parallel ATA device: " ) ;
2019-11-25 00:54:38 +00:00
if ( ( ATAID . TransportMajorVersion & 0x0002 ) = = 0x0002 )
sb . Append ( "ATA/ATAPI-7 " ) ;
if ( ( ATAID . TransportMajorVersion & 0x0001 ) = = 0x0001 )
sb . Append ( "ATA8-APT " ) ;
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0x1 :
sb . Append ( "Serial ATA device: " ) ;
2019-11-25 00:54:38 +00:00
if ( ( ATAID . TransportMajorVersion & 0x0001 ) = = 0x0001 )
sb . Append ( "ATA8-AST " ) ;
if ( ( ATAID . TransportMajorVersion & 0x0002 ) = = 0x0002 )
sb . Append ( "SATA 1.0a " ) ;
if ( ( ATAID . TransportMajorVersion & 0x0004 ) = = 0x0004 )
sb . Append ( "SATA II Extensions " ) ;
if ( ( ATAID . TransportMajorVersion & 0x0008 ) = = 0x0008 )
sb . Append ( "SATA 2.5 " ) ;
if ( ( ATAID . TransportMajorVersion & 0x0010 ) = = 0x0010 )
sb . Append ( "SATA 2.6 " ) ;
if ( ( ATAID . TransportMajorVersion & 0x0020 ) = = 0x0020 )
sb . Append ( "SATA 3.0 " ) ;
if ( ( ATAID . TransportMajorVersion & 0x0040 ) = = 0x0040 )
sb . Append ( "SATA 3.1 " ) ;
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 0xE :
sb . AppendLine ( "SATA Express device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
default :
2019-11-25 00:54:38 +00:00
sb . AppendFormat ( "Unknown transport type 0x{0:X1}" , ( ATAID . TransportMajorVersion & 0xF000 ) > > 12 ) .
AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
break ;
}
2016-04-19 02:11:47 +01:00
if ( atapi )
2015-10-17 01:26:17 +01:00
{
// Bits 12 to 8, SCSI Peripheral Device Type
2017-12-21 14:30:38 +00:00
switch ( ( PeripheralDeviceTypes ) ( ( ( ushort ) ATAID . GeneralConfiguration & 0x1F00 ) > > 8 ) )
2015-10-17 01:26:17 +01:00
{
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . DirectAccess : //0x00,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Direct-access device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . SequentialAccess : //0x01,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Sequential-access device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . PrinterDevice : //0x02,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Printer device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . ProcessorDevice : //0x03,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Processor device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . WriteOnceDevice : //0x04,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Write-once device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . MultiMediaDevice : //0x05,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI CD-ROM/DVD/etc device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . ScannerDevice : //0x06,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Scanner device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . OpticalDevice : //0x07,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Optical memory device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . MediumChangerDevice : //0x08,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Medium change device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . CommsDevice : //0x09,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Communications device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . PrePressDevice1 : //0x0A,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Graphics arts pre-press device (defined in ASC IT8)" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . PrePressDevice2 : //0x0B,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Graphics arts pre-press device (defined in ASC IT8)" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . ArrayControllerDevice : //0x0C,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Array controller device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . EnclosureServiceDevice : //0x0D,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Enclosure services device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . SimplifiedDevice : //0x0E,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Simplified direct-access device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . OCRWDevice : //0x0F,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Optical card reader/writer device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . BridgingExpander : //0x10,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Bridging Expanders" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . ObjectDevice : //0x11,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Object-based Storage Device" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . ADCDevice : //0x12,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Automation/Drive Interface" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . WellKnownDevice : //0x1E,
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Well known logical unit" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
2017-12-21 14:30:38 +00:00
case PeripheralDeviceTypes . UnknownDevice : //0x1F
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "ATAPI Unknown or no device type" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
default :
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "ATAPI Unknown device type field value 0x{0:X2}" ,
( ( ushort ) ATAID . GeneralConfiguration & 0x1F00 ) > > 8 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
}
// ATAPI DRQ behaviour
2016-04-19 02:11:47 +01:00
switch ( ( ( ushort ) ATAID . GeneralConfiguration & 0x60 ) > > 5 )
2015-10-17 01:26:17 +01:00
{
case 0 :
sb . AppendLine ( "Device shall set DRQ within 3 ms of receiving PACKET" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 1 :
sb . AppendLine ( "Device shall assert INTRQ when DRQ is set to one" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 2 :
sb . AppendLine ( "Device shall set DRQ within 50 µs of receiving PACKET" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
default :
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Unknown ATAPI DRQ behaviour code {0}" ,
( ( ushort ) ATAID . GeneralConfiguration & 0x60 ) > > 5 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
}
// ATAPI PACKET size
2016-04-19 02:11:47 +01:00
switch ( ( ushort ) ATAID . GeneralConfiguration & 0x03 )
2015-10-17 01:26:17 +01:00
{
case 0 :
sb . AppendLine ( "ATAPI device uses 12 byte command packet" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case 1 :
sb . AppendLine ( "ATAPI device uses 16 byte command packet" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
default :
2019-11-25 00:54:38 +00:00
sb . AppendFormat ( "Unknown ATAPI packet size code {0}" ,
( ushort ) ATAID . GeneralConfiguration & 0x03 ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
break ;
}
}
2016-04-19 02:11:47 +01:00
else if ( ! cfa )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( minatalevel > = 5 )
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . IncompleteResponse ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Incomplete identify response" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . NonMagnetic ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Device uses non-magnetic media" ) ;
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . Removable ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Device is removable" ) ;
2016-04-19 02:11:47 +01:00
if ( minatalevel < = 5 )
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . Fixed ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Device is fixed" ) ;
2016-04-19 02:11:47 +01:00
if ( ata1 )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . SlowIDE ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Device transfer rate is <= 5 Mb/s" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . FastIDE ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Device transfer rate is > 5 Mb/s but <= 10 Mb/s" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . UltraFastIDE ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Device transfer rate is > 10 Mb/s" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . SoftSector ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Device is soft sectored" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . HardSector ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Device is hard sectored" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . NotMFM ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Device is not MFM encoded" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . FormatGapReq ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Format speed tolerance gap is required" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . TrackOffset ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Track offset option is available" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . DataStrobeOffset ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Data strobe offset option is available" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . RotationalSpeedTolerance ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Rotational speed tolerance is higher than 0,5%" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . SpindleControl ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Spindle motor control is implemented" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . GeneralConfiguration . HasFlag ( GeneralConfigurationBit . HighHeadSwitch ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Head switch time is bigger than 15 µs." ) ;
}
}
2019-11-25 00:54:38 +00:00
if ( ATAID . NominalRotationRate ! = 0x0000 & &
ATAID . NominalRotationRate ! = 0xFFFF )
2018-06-22 08:08:38 +01:00
if ( ATAID . NominalRotationRate = = 0x0001 )
sb . AppendLine ( "Device does not rotate." ) ;
else
sb . AppendFormat ( "Device rotate at {0} rpm" , ATAID . NominalRotationRate ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
uint logicalsectorsize = 0 ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ! atapi )
2015-10-17 01:26:17 +01:00
{
uint physicalsectorsize ;
2019-11-25 00:54:38 +00:00
if ( ( ATAID . PhysLogSectorSize & 0x8000 ) = = 0x0000 & &
( ATAID . PhysLogSectorSize & 0x4000 ) = = 0x4000 )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( ( ATAID . PhysLogSectorSize & 0x1000 ) = = 0x1000 )
2019-11-25 00:54:38 +00:00
if ( ATAID . LogicalSectorWords < = 255 | |
ATAID . LogicalAlignment = = 0xFFFF )
2018-06-22 08:08:38 +01:00
logicalsectorsize = 512 ;
else
logicalsectorsize = ATAID . LogicalSectorWords * 2 ;
2019-11-25 00:54:38 +00:00
else
logicalsectorsize = 512 ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( ( ATAID . PhysLogSectorSize & 0x2000 ) = = 0x2000 )
2019-11-25 00:54:38 +00:00
physicalsectorsize = logicalsectorsize * ( uint ) Math . Pow ( 2 , ATAID . PhysLogSectorSize & 0xF ) ;
else
physicalsectorsize = logicalsectorsize ;
2015-10-17 01:26:17 +01:00
}
else
{
2018-06-22 08:08:38 +01:00
logicalsectorsize = 512 ;
2015-10-17 01:26:17 +01:00
physicalsectorsize = 512 ;
}
sb . AppendFormat ( "Physical sector size: {0} bytes" , physicalsectorsize ) . AppendLine ( ) ;
sb . AppendFormat ( "Logical sector size: {0} bytes" , logicalsectorsize ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( logicalsectorsize ! = physicalsectorsize & &
( ATAID . LogicalAlignment & 0x8000 ) = = 0x0000 & &
( ATAID . LogicalAlignment & 0x4000 ) = = 0x4000 )
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Logical sector starts at offset {0} from physical sector" ,
ATAID . LogicalAlignment & 0x3FFF ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( minatalevel < = 5 )
2019-11-25 00:54:38 +00:00
if ( ATAID . CurrentCylinders > 0 & &
ATAID . CurrentHeads > 0 & &
ATAID . CurrentSectorsPerTrack > 0 )
2017-06-06 18:16:13 +01:00
{
2019-11-25 00:54:38 +00:00
sb . AppendFormat ( "Cylinders: {0} max., {1} current" , ATAID . Cylinders , ATAID . CurrentCylinders ) .
AppendLine ( ) ;
2017-06-06 18:16:13 +01:00
sb . AppendFormat ( "Heads: {0} max., {1} current" , ATAID . Heads , ATAID . CurrentHeads ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Sectors per track: {0} max., {1} current" , ATAID . SectorsPerTrack ,
ATAID . CurrentSectorsPerTrack ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Sectors addressable in CHS mode: {0} max., {1} current" ,
2019-11-25 00:54:38 +00:00
ATAID . Cylinders * ATAID . Heads * ATAID . SectorsPerTrack , ATAID . CurrentSectors ) .
AppendLine ( ) ;
2017-06-06 18:16:13 +01:00
}
else
{
sb . AppendFormat ( "Cylinders: {0}" , ATAID . Cylinders ) . AppendLine ( ) ;
sb . AppendFormat ( "Heads: {0}" , ATAID . Heads ) . AppendLine ( ) ;
sb . AppendFormat ( "Sectors per track: {0}" , ATAID . SectorsPerTrack ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Sectors addressable in CHS mode: {0}" ,
ATAID . Cylinders * ATAID . Heads * ATAID . SectorsPerTrack ) . AppendLine ( ) ;
2017-06-06 18:16:13 +01:00
}
2015-10-17 01:26:17 +01:00
2017-12-23 18:31:38 +00:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . LBASupport ) )
sb . AppendFormat ( "{0} sectors in 28-bit LBA mode" , ATAID . LBASectors ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . LBA48 ) )
sb . AppendFormat ( "{0} sectors in 48-bit LBA mode" , ATAID . LBA48Sectors ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( minatalevel < = 5 )
2017-06-06 18:16:13 +01:00
if ( ATAID . CurrentSectors > 0 )
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Device size in CHS mode: {0} bytes, {1} Mb, {2} MiB" ,
2018-06-22 08:08:38 +01:00
( ulong ) ATAID . CurrentSectors * logicalsectorsize ,
2017-12-20 17:26:28 +00:00
( ulong ) ATAID . CurrentSectors * logicalsectorsize / 1000 / 1000 ,
2018-06-22 08:08:38 +01:00
( ulong ) ATAID . CurrentSectors * 512 / 1024 / 1024 ) . AppendLine ( ) ;
2017-06-06 18:16:13 +01:00
else
{
ulong currentSectors = ( ulong ) ( ATAID . Cylinders * ATAID . Heads * ATAID . SectorsPerTrack ) ;
2019-11-25 00:54:38 +00:00
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Device size in CHS mode: {0} bytes, {1} Mb, {2} MiB" ,
2018-06-22 08:08:38 +01:00
currentSectors * logicalsectorsize ,
2017-12-20 17:26:28 +00:00
currentSectors * logicalsectorsize / 1000 / 1000 ,
2018-06-22 08:08:38 +01:00
currentSectors * 512 / 1024 / 1024 ) . AppendLine ( ) ;
2017-06-06 18:16:13 +01:00
}
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . LBASupport ) )
2017-12-20 17:26:28 +00:00
if ( ( ulong ) ATAID . LBASectors * logicalsectorsize / 1024 / 1024 > 1000000 )
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Device size in 28-bit LBA mode: {0} bytes, {1} Tb, {2} TiB" ,
2018-06-22 08:08:38 +01:00
( ulong ) ATAID . LBASectors *
logicalsectorsize ,
2017-12-20 17:26:28 +00:00
( ulong ) ATAID . LBASectors * logicalsectorsize / 1000 / 1000 / 1000 / 1000 ,
2019-11-25 00:54:38 +00:00
( ulong ) ATAID . LBASectors * 512 / 1024 / 1024 / 1024 / 1024 ) .
AppendLine ( ) ;
2017-12-20 17:26:28 +00:00
else if ( ( ulong ) ATAID . LBASectors * logicalsectorsize / 1024 / 1024 > 1000 )
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Device size in 28-bit LBA mode: {0} bytes, {1} Gb, {2} GiB" ,
2018-06-22 08:08:38 +01:00
( ulong ) ATAID . LBASectors * logicalsectorsize ,
2017-12-20 17:26:28 +00:00
( ulong ) ATAID . LBASectors * logicalsectorsize / 1000 / 1000 / 1000 ,
2018-06-22 08:08:38 +01:00
( ulong ) ATAID . LBASectors * 512 / 1024 / 1024 / 1024 ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
else
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Device size in 28-bit LBA mode: {0} bytes, {1} Mb, {2} MiB" ,
2018-06-22 08:08:38 +01:00
( ulong ) ATAID . LBASectors * logicalsectorsize ,
2017-12-20 17:26:28 +00:00
( ulong ) ATAID . LBASectors * logicalsectorsize / 1000 / 1000 ,
2018-06-22 08:08:38 +01:00
( ulong ) ATAID . LBASectors * 512 / 1024 / 1024 ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . LBA48 ) )
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . ExtSectors ) )
2017-12-20 17:26:28 +00:00
if ( ATAID . ExtendedUserSectors * logicalsectorsize / 1024 / 1024 > 1000000 )
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Device size in 48-bit LBA mode: {0} bytes, {1} Tb, {2} TiB" ,
2018-06-22 08:08:38 +01:00
ATAID . ExtendedUserSectors *
logicalsectorsize ,
2017-12-20 17:26:28 +00:00
ATAID . ExtendedUserSectors * logicalsectorsize / 1000 / 1000 / 1000 / 1000 ,
2019-11-25 00:54:38 +00:00
ATAID . ExtendedUserSectors * logicalsectorsize / 1024 / 1024 / 1024 / 1024 ) .
AppendLine ( ) ;
2017-12-20 17:26:28 +00:00
else if ( ATAID . ExtendedUserSectors * logicalsectorsize / 1024 / 1024 > 1000 )
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Device size in 48-bit LBA mode: {0} bytes, {1} Gb, {2} GiB" ,
2018-06-22 08:08:38 +01:00
ATAID . ExtendedUserSectors *
logicalsectorsize ,
2017-12-20 17:26:28 +00:00
ATAID . ExtendedUserSectors * logicalsectorsize / 1000 / 1000 / 1000 ,
2019-11-25 00:54:38 +00:00
ATAID . ExtendedUserSectors * logicalsectorsize / 1024 / 1024 / 1024 ) .
AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
else
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Device size in 48-bit LBA mode: {0} bytes, {1} Mb, {2} MiB" ,
2018-06-22 08:08:38 +01:00
ATAID . ExtendedUserSectors * logicalsectorsize ,
2017-12-20 17:26:28 +00:00
ATAID . ExtendedUserSectors * logicalsectorsize / 1000 / 1000 ,
ATAID . ExtendedUserSectors * logicalsectorsize / 1024 / 1024 ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
else
{
2017-12-20 17:26:28 +00:00
if ( ATAID . LBA48Sectors * logicalsectorsize / 1024 / 1024 > 1000000 )
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Device size in 48-bit LBA mode: {0} bytes, {1} Tb, {2} TiB" ,
2018-06-22 08:08:38 +01:00
ATAID . LBA48Sectors *
logicalsectorsize ,
2017-12-20 17:26:28 +00:00
ATAID . LBA48Sectors * logicalsectorsize / 1000 / 1000 / 1000 / 1000 ,
2019-11-25 00:54:38 +00:00
ATAID . LBA48Sectors * logicalsectorsize / 1024 / 1024 / 1024 / 1024 ) .
AppendLine ( ) ;
2017-12-20 17:26:28 +00:00
else if ( ATAID . LBA48Sectors * logicalsectorsize / 1024 / 1024 > 1000 )
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Device size in 48-bit LBA mode: {0} bytes, {1} Gb, {2} GiB" ,
2018-06-22 08:08:38 +01:00
ATAID . LBA48Sectors * logicalsectorsize ,
2017-12-20 17:26:28 +00:00
ATAID . LBA48Sectors * logicalsectorsize / 1000 / 1000 / 1000 ,
ATAID . LBA48Sectors * logicalsectorsize / 1024 / 1024 / 1024 ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
else
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Device size in 48-bit LBA mode: {0} bytes, {1} Mb, {2} MiB" ,
2018-06-22 08:08:38 +01:00
ATAID . LBA48Sectors * logicalsectorsize ,
2017-12-20 17:26:28 +00:00
ATAID . LBA48Sectors * logicalsectorsize / 1000 / 1000 ,
ATAID . LBA48Sectors * logicalsectorsize / 1024 / 1024 ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
}
2016-04-19 02:11:47 +01:00
if ( ata1 | | cfa )
2015-10-17 01:26:17 +01:00
{
2019-11-25 00:54:38 +00:00
if ( cfa )
sb . AppendFormat ( "{0} sectors in card" , ATAID . SectorsPerCard ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
if ( ATAID . UnformattedBPT > 0 )
sb . AppendFormat ( "{0} bytes per unformatted track" , ATAID . UnformattedBPT ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
if ( ATAID . UnformattedBPS > 0 )
sb . AppendFormat ( "{0} bytes per unformatted sector" , ATAID . UnformattedBPS ) . AppendLine ( ) ;
}
}
2018-06-22 08:08:38 +01:00
2019-11-25 00:54:38 +00:00
if ( ( ushort ) ATAID . SpecificConfiguration ! = 0x0000 & &
( ushort ) ATAID . SpecificConfiguration ! = 0xFFFF )
2016-04-19 02:11:47 +01:00
switch ( ATAID . SpecificConfiguration )
2015-10-17 01:26:17 +01:00
{
case SpecificConfigurationEnum . RequiresSetIncompleteResponse :
sb . AppendLine ( "Device requires SET FEATURES to spin up and IDENTIFY DEVICE response is incomplete." ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case SpecificConfigurationEnum . RequiresSetCompleteResponse :
sb . AppendLine ( "Device requires SET FEATURES to spin up and IDENTIFY DEVICE response is complete." ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case SpecificConfigurationEnum . NotRequiresSetIncompleteResponse :
sb . AppendLine ( "Device does not require SET FEATURES to spin up and IDENTIFY DEVICE response is incomplete." ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case SpecificConfigurationEnum . NotRequiresSetCompleteResponse :
sb . AppendLine ( "Device does not require SET FEATURES to spin up and IDENTIFY DEVICE response is complete." ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
default :
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "Unknown device specific configuration 0x{0:X4}" ,
( ushort ) ATAID . SpecificConfiguration ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
}
// Obsolete since ATA-2, however, it is yet used in ATA-8 devices
2019-11-25 00:54:38 +00:00
if ( ATAID . BufferSize ! = 0x0000 & &
ATAID . BufferSize ! = 0xFFFF & &
ATAID . BufferType ! = 0x0000 & &
2017-12-19 20:33:03 +00:00
ATAID . BufferType ! = 0xFFFF )
2016-04-19 02:11:47 +01:00
switch ( ATAID . BufferType )
2015-10-17 01:26:17 +01:00
{
case 1 :
2019-11-25 00:54:38 +00:00
sb . AppendFormat ( "{0} KiB of single ported single sector buffer" , ATAID . BufferSize * 512 / 1024 ) .
AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
break ;
case 2 :
2019-11-25 00:54:38 +00:00
sb . AppendFormat ( "{0} KiB of dual ported multi sector buffer" , ATAID . BufferSize * 512 / 1024 ) .
AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
break ;
case 3 :
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "{0} KiB of dual ported multi sector buffer with read caching" ,
2017-12-20 17:26:28 +00:00
ATAID . BufferSize * 512 / 1024 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
default :
2017-12-20 17:26:28 +00:00
sb . AppendFormat ( "{0} KiB of unknown type {1} buffer" , ATAID . BufferSize * 512 / 1024 ,
2017-12-19 20:33:03 +00:00
ATAID . BufferType ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
}
2019-11-25 00:54:38 +00:00
if ( ATAID . EccBytes ! = 0x0000 & &
ATAID . EccBytes ! = 0xFFFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "READ/WRITE LONG has {0} extra bytes" , ATAID . EccBytes ) . AppendLine ( ) ;
sb . AppendLine ( ) ;
sb . Append ( "Device capabilities:" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . StandardStanbyTimer ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "Standby time values are standard" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . IORDY ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "IORDY is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . CanDisableIORDY ) )
sb . Append ( " and can be disabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2019-11-25 00:54:38 +00:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . DMASupport ) )
sb . AppendLine ( ) . Append ( "DMA is supported" ) ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities2 . HasFlag ( CapabilitiesBit2 . MustBeSet ) & &
2015-10-17 01:26:17 +01:00
! ATAID . Capabilities2 . HasFlag ( CapabilitiesBit2 . MustBeClear ) )
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities2 . HasFlag ( CapabilitiesBit2 . SpecificStandbyTimer ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "Device indicates a specific minimum standby timer value" ) ;
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities3 . HasFlag ( CapabilitiesBit3 . MultipleValid ) )
2015-10-17 01:26:17 +01:00
{
2019-11-25 00:54:38 +00:00
sb . AppendLine ( ) .
AppendFormat ( "A maximum of {0} sectors can be transferred per interrupt on READ/WRITE MULTIPLE" ,
2017-12-19 20:33:03 +00:00
ATAID . MultipleSectorNumber ) ;
2019-11-25 00:54:38 +00:00
2017-12-19 20:33:03 +00:00
sb . AppendLine ( ) . AppendFormat ( "Device supports setting a maximum of {0} sectors" ,
ATAID . MultipleMaxSectors ) ;
2015-10-17 01:26:17 +01:00
}
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . PhysicalAlignment1 ) | |
2017-12-19 20:33:03 +00:00
ATAID . Capabilities . HasFlag ( CapabilitiesBit . PhysicalAlignment0 ) )
sb . AppendLine ( ) . AppendFormat ( "Long Physical Alignment setting is {0}" ,
( ushort ) ATAID . Capabilities & 0x03 ) ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( ata1 )
if ( ATAID . TrustedComputing . HasFlag ( TrustedComputingBit . TrustedComputing ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "Device supports doubleword I/O" ) ;
if ( atapi )
{
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . InterleavedDMA ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "ATAPI device supports interleaved DMA" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . CommandQueue ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "ATAPI device supports command queueing" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . OverlapOperation ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "ATAPI device supports overlapped operations" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . RequiresATASoftReset ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "ATAPI device requires ATA software reset" ) ;
}
2016-04-19 02:11:47 +01:00
if ( minatalevel < = 3 )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . AppendFormat ( "PIO timing mode: {0}" , ATAID . PIOTransferTimingMode ) ;
sb . AppendLine ( ) . AppendFormat ( "DMA timing mode: {0}" , ATAID . DMATransferTimingMode ) ;
}
sb . AppendLine ( ) . Append ( "Advanced PIO: " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . APIOSupported . HasFlag ( TransferMode . Mode0 ) )
sb . Append ( "PIO0 " ) ;
if ( ATAID . APIOSupported . HasFlag ( TransferMode . Mode1 ) )
sb . Append ( "PIO1 " ) ;
if ( ATAID . APIOSupported . HasFlag ( TransferMode . Mode2 ) )
sb . Append ( "PIO2 " ) ;
if ( ATAID . APIOSupported . HasFlag ( TransferMode . Mode3 ) )
sb . Append ( "PIO3 " ) ;
if ( ATAID . APIOSupported . HasFlag ( TransferMode . Mode4 ) )
sb . Append ( "PIO4 " ) ;
if ( ATAID . APIOSupported . HasFlag ( TransferMode . Mode5 ) )
sb . Append ( "PIO5 " ) ;
if ( ATAID . APIOSupported . HasFlag ( TransferMode . Mode6 ) )
sb . Append ( "PIO6 " ) ;
if ( ATAID . APIOSupported . HasFlag ( TransferMode . Mode7 ) )
sb . Append ( "PIO7 " ) ;
if ( minatalevel < = 3 & &
! atapi )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Single-word DMA: " ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
if ( ATAID . DMASupported . HasFlag ( TransferMode . Mode0 ) )
{
sb . Append ( "DMA0 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . DMAActive . HasFlag ( TransferMode . Mode0 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . DMASupported . HasFlag ( TransferMode . Mode1 ) )
{
sb . Append ( "DMA1 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . DMAActive . HasFlag ( TransferMode . Mode1 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . DMASupported . HasFlag ( TransferMode . Mode2 ) )
{
sb . Append ( "DMA2 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . DMAActive . HasFlag ( TransferMode . Mode2 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . DMASupported . HasFlag ( TransferMode . Mode3 ) )
{
sb . Append ( "DMA3 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . DMAActive . HasFlag ( TransferMode . Mode3 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . DMASupported . HasFlag ( TransferMode . Mode4 ) )
{
sb . Append ( "DMA4 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . DMAActive . HasFlag ( TransferMode . Mode4 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . DMASupported . HasFlag ( TransferMode . Mode5 ) )
{
sb . Append ( "DMA5 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . DMAActive . HasFlag ( TransferMode . Mode5 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . DMASupported . HasFlag ( TransferMode . Mode6 ) )
{
sb . Append ( "DMA6 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . DMAActive . HasFlag ( TransferMode . Mode6 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . DMASupported . HasFlag ( TransferMode . Mode7 ) )
{
sb . Append ( "DMA7 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . DMAActive . HasFlag ( TransferMode . Mode7 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
}
sb . AppendLine ( ) . Append ( "Multi-word DMA: " ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
if ( ATAID . MDMASupported . HasFlag ( TransferMode . Mode0 ) )
{
sb . Append ( "MDMA0 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . MDMAActive . HasFlag ( TransferMode . Mode0 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . MDMASupported . HasFlag ( TransferMode . Mode1 ) )
{
sb . Append ( "MDMA1 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . MDMAActive . HasFlag ( TransferMode . Mode1 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . MDMASupported . HasFlag ( TransferMode . Mode2 ) )
{
sb . Append ( "MDMA2 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . MDMAActive . HasFlag ( TransferMode . Mode2 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . MDMASupported . HasFlag ( TransferMode . Mode3 ) )
{
sb . Append ( "MDMA3 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . MDMAActive . HasFlag ( TransferMode . Mode3 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . MDMASupported . HasFlag ( TransferMode . Mode4 ) )
{
sb . Append ( "MDMA4 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . MDMAActive . HasFlag ( TransferMode . Mode4 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . MDMASupported . HasFlag ( TransferMode . Mode5 ) )
{
sb . Append ( "MDMA5 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . MDMAActive . HasFlag ( TransferMode . Mode5 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . MDMASupported . HasFlag ( TransferMode . Mode6 ) )
{
sb . Append ( "MDMA6 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . MDMAActive . HasFlag ( TransferMode . Mode6 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . MDMASupported . HasFlag ( TransferMode . Mode7 ) )
{
sb . Append ( "MDMA7 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . MDMAActive . HasFlag ( TransferMode . Mode7 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
sb . AppendLine ( ) . Append ( "Ultra DMA: " ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
if ( ATAID . UDMASupported . HasFlag ( TransferMode . Mode0 ) )
{
sb . Append ( "UDMA0 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . UDMAActive . HasFlag ( TransferMode . Mode0 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . UDMASupported . HasFlag ( TransferMode . Mode1 ) )
{
sb . Append ( "UDMA1 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . UDMAActive . HasFlag ( TransferMode . Mode1 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . UDMASupported . HasFlag ( TransferMode . Mode2 ) )
{
sb . Append ( "UDMA2 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . UDMAActive . HasFlag ( TransferMode . Mode2 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . UDMASupported . HasFlag ( TransferMode . Mode3 ) )
{
sb . Append ( "UDMA3 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . UDMAActive . HasFlag ( TransferMode . Mode3 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . UDMASupported . HasFlag ( TransferMode . Mode4 ) )
{
sb . Append ( "UDMA4 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . UDMAActive . HasFlag ( TransferMode . Mode4 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . UDMASupported . HasFlag ( TransferMode . Mode5 ) )
{
sb . Append ( "UDMA5 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . UDMAActive . HasFlag ( TransferMode . Mode5 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . UDMASupported . HasFlag ( TransferMode . Mode6 ) )
{
sb . Append ( "UDMA6 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . UDMAActive . HasFlag ( TransferMode . Mode6 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . UDMASupported . HasFlag ( TransferMode . Mode7 ) )
{
sb . Append ( "UDMA7 " ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . UDMAActive . HasFlag ( TransferMode . Mode7 ) )
sb . Append ( "(active) " ) ;
2015-10-17 01:26:17 +01:00
}
2019-11-25 00:54:38 +00:00
if ( ATAID . MinMDMACycleTime ! = 0 & &
ATAID . RecMDMACycleTime ! = 0 )
sb . AppendLine ( ) .
AppendFormat ( "At minimum {0} ns. transfer cycle time per word in MDMA, " + "{1} ns. recommended" ,
2017-12-19 20:33:03 +00:00
ATAID . MinMDMACycleTime , ATAID . RecMDMACycleTime ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . MinPIOCycleTimeNoFlow ! = 0 )
2019-11-25 00:54:38 +00:00
sb . AppendLine ( ) .
AppendFormat ( "At minimum {0} ns. transfer cycle time per word in PIO, " + "without flow control" ,
2017-12-19 20:33:03 +00:00
ATAID . MinPIOCycleTimeNoFlow ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . MinPIOCycleTimeFlow ! = 0 )
2019-11-25 00:54:38 +00:00
sb . AppendLine ( ) .
AppendFormat ( "At minimum {0} ns. transfer cycle time per word in PIO, " + "with IORDY flow control" ,
2017-12-19 20:33:03 +00:00
ATAID . MinPIOCycleTimeFlow ) ;
2015-10-17 01:26:17 +01:00
2017-12-23 18:31:38 +00:00
if ( ATAID . MaxQueueDepth ! = 0 )
sb . AppendLine ( ) . AppendFormat ( "{0} depth of queue maximum" , ATAID . MaxQueueDepth + 1 ) ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( atapi )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( ATAID . PacketBusRelease ! = 0 )
2017-12-19 20:33:03 +00:00
sb . AppendLine ( ) . AppendFormat ( "{0} ns. typical to release bus from receipt of PACKET" ,
ATAID . PacketBusRelease ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . ServiceBusyClear ! = 0 )
2017-12-19 20:33:03 +00:00
sb . AppendLine ( ) . AppendFormat ( "{0} ns. typical to clear BSY bit from receipt of SERVICE" ,
ATAID . ServiceBusyClear ) ;
2015-10-17 01:26:17 +01:00
}
2017-12-20 17:26:28 +00:00
if ( ( ATAID . TransportMajorVersion & 0xF000 ) > > 12 = = 0x1 | |
( ATAID . TransportMajorVersion & 0xF000 ) > > 12 = = 0xE )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( ! ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . Clear ) )
2015-10-17 01:26:17 +01:00
{
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . Gen1Speed ) )
sb . AppendLine ( ) . Append ( "SATA 1.5Gb/s is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . Gen2Speed ) )
sb . AppendLine ( ) . Append ( "SATA 3.0Gb/s is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . Gen3Speed ) )
sb . AppendLine ( ) . Append ( "SATA 6.0Gb/s is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . PowerReceipt ) )
sb . AppendLine ( ) . Append ( "Receipt of host initiated power management requests is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . PHYEventCounter ) )
sb . AppendLine ( ) . Append ( "PHY Event counters are supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . HostSlumbTrans ) )
sb . AppendLine ( ) . Append ( "Supports host automatic partial to slumber transitions is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . DevSlumbTrans ) )
sb . AppendLine ( ) . Append ( "Supports device automatic partial to slumber transitions is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . NCQ ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "NCQ is supported" ) ;
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . NCQPriority ) )
sb . AppendLine ( ) . Append ( "NCQ priority is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . UnloadNCQ ) )
sb . AppendLine ( ) . Append ( "Unload is supported with outstanding NCQ commands" ) ;
2015-10-17 01:26:17 +01:00
}
}
2016-04-19 02:11:47 +01:00
if ( ! ATAID . SATACapabilities2 . HasFlag ( SATACapabilitiesBit2 . Clear ) )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( ! ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . Clear ) & &
2017-12-19 20:33:03 +00:00
ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . NCQ ) )
2015-10-17 01:26:17 +01:00
{
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities2 . HasFlag ( SATACapabilitiesBit2 . NCQMgmt ) )
sb . AppendLine ( ) . Append ( "NCQ queue management is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities2 . HasFlag ( SATACapabilitiesBit2 . NCQStream ) )
sb . AppendLine ( ) . Append ( "NCQ streaming is supported" ) ;
2015-10-17 01:26:17 +01:00
}
2016-04-19 02:11:47 +01:00
if ( atapi )
2015-10-17 01:26:17 +01:00
{
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities2 . HasFlag ( SATACapabilitiesBit2 . HostEnvDetect ) )
sb . AppendLine ( ) . Append ( "ATAPI device supports host environment detection" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . SATACapabilities2 . HasFlag ( SATACapabilitiesBit2 . DevAttSlimline ) )
sb . AppendLine ( ) . Append ( "ATAPI device supports attention on slimline connected devices" ) ;
2015-10-17 01:26:17 +01:00
}
//sb.AppendFormat("Negotiated speed = {0}", ((ushort)ATAID.SATACapabilities2 & 0x000E) >> 1);
2016-04-19 02:11:47 +01:00
}
2015-10-17 01:26:17 +01:00
}
2019-11-25 00:54:38 +00:00
if ( ATAID . InterseekDelay ! = 0x0000 & &
ATAID . InterseekDelay ! = 0xFFFF )
2017-12-19 20:33:03 +00:00
sb . AppendLine ( ) . AppendFormat ( "{0} microseconds of interseek delay for ISO-7779 accoustic testing" ,
ATAID . InterseekDelay ) ;
2015-10-17 01:26:17 +01:00
2019-11-25 00:54:38 +00:00
if ( ( ushort ) ATAID . DeviceFormFactor ! = 0x0000 & &
( ushort ) ATAID . DeviceFormFactor ! = 0xFFFF )
2016-04-19 02:11:47 +01:00
switch ( ATAID . DeviceFormFactor )
2015-10-17 01:26:17 +01:00
{
case DeviceFormFactorEnum . FiveAndQuarter :
sb . AppendLine ( ) . Append ( "Device nominal size is 5.25\"" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case DeviceFormFactorEnum . ThreeAndHalf :
sb . AppendLine ( ) . Append ( "Device nominal size is 3.5\"" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case DeviceFormFactorEnum . TwoAndHalf :
sb . AppendLine ( ) . Append ( "Device nominal size is 2.5\"" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case DeviceFormFactorEnum . OnePointEight :
sb . AppendLine ( ) . Append ( "Device nominal size is 1.8\"" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
case DeviceFormFactorEnum . LessThanOnePointEight :
sb . AppendLine ( ) . Append ( "Device nominal size is smaller than 1.8\"" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
default :
2017-12-19 20:33:03 +00:00
sb . AppendLine ( ) . AppendFormat ( "Device nominal size field value {0} is unknown" ,
ATAID . DeviceFormFactor ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
break ;
}
2016-04-19 02:11:47 +01:00
if ( atapi )
if ( ATAID . ATAPIByteCount > 0 )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . AppendFormat ( "{0} bytes count limit for ATAPI" , ATAID . ATAPIByteCount ) ;
2016-04-19 02:11:47 +01:00
if ( cfa )
if ( ( ATAID . CFAPowerMode & 0x8000 ) = = 0x8000 )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "CompactFlash device supports power mode 1" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ( ATAID . CFAPowerMode & 0x2000 ) = = 0x2000 )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "CompactFlash power mode 1 required for one or more commands" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ( ATAID . CFAPowerMode & 0x1000 ) = = 0x1000 )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "CompactFlash power mode 1 is disabled" ) ;
2017-12-19 20:33:03 +00:00
sb . AppendLine ( ) . AppendFormat ( "CompactFlash device uses a maximum of {0} mA" ,
2017-12-20 17:26:28 +00:00
ATAID . CFAPowerMode & 0x0FFF ) ;
2015-10-17 01:26:17 +01:00
}
sb . AppendLine ( ) ;
sb . AppendLine ( ) . Append ( "Command set and features:" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . Nop ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "NOP is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . Nop ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . ReadBuffer ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "READ BUFFER is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . ReadBuffer ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . WriteBuffer ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "WRITE BUFFER is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . WriteBuffer ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . HPA ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Host Protected Area is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . HPA ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . DeviceReset ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "DEVICE RESET is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . DeviceReset ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . Service ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "SERVICE interrupt is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . Service ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . Release ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Release is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . Release ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . LookAhead ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Look-ahead read is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . LookAhead ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . WriteCache ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Write cache is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . WriteCache ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . Packet ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "PACKET is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . Packet ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . PowerManagement ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Power management is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . PowerManagement ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . RemovableMedia ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Removable media feature set is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . RemovableMedia ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . SecurityMode ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Security mode is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . SecurityMode ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities . HasFlag ( CapabilitiesBit . LBASupport ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "28-bit LBA is supported" ) ;
2016-04-19 02:11:47 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . MustBeSet ) & &
2017-12-19 20:33:03 +00:00
! ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . MustBeClear ) )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . LBA48 ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "48-bit LBA is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . LBA48 ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . FlushCache ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "FLUSH CACHE is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . FlushCache ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . FlushCacheExt ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "FLUSH CACHE EXT is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . FlushCacheExt ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . DCO ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Device Configuration Overlay feature set is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . DCO ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . AAM ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Automatic Acoustic Management is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . AAM ) )
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( " and enabled with value {0} (vendor recommends {1}" , ATAID . CurrentAAM ,
ATAID . RecommendedAAM ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . SetMax ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "SET MAX security extension is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . SetMax ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . AddressOffsetReservedAreaBoot ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Address Offset Reserved Area Boot is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . AddressOffsetReservedAreaBoot ) )
2015-10-17 01:26:17 +01:00
sb . Append ( " and enabled" ) ;
}
2018-06-22 08:08:38 +01:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . SetFeaturesRequired ) )
sb . AppendLine ( ) . Append ( "SET FEATURES is required before spin-up" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . PowerUpInStandby ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Power-up in standby is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . PowerUpInStandby ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . RemovableNotification ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Removable Media Status Notification is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . RemovableNotification ) )
2015-10-17 01:26:17 +01:00
sb . Append ( " and enabled" ) ;
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . APM ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Advanced Power Management is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . APM ) )
sb . AppendFormat ( " and enabled with value {0}" , ATAID . CurrentAPM ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . CompactFlash ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "CompactFlash feature set is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . CompactFlash ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . RWQueuedDMA ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "READ DMA QUEUED and WRITE DMA QUEUED are supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . RWQueuedDMA ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet2 . HasFlag ( CommandSetBit2 . DownloadMicrocode ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "DOWNLOAD MICROCODE is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet2 . HasFlag ( CommandSetBit2 . DownloadMicrocode ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
}
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet . HasFlag ( CommandSetBit . SMART ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "S.M.A.R.T. is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet . HasFlag ( CommandSetBit . SMART ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
if ( ATAID . SCTCommandTransport . HasFlag ( SCTCommandTransportBit . Supported ) )
sb . AppendLine ( ) . Append ( "S.M.A.R.T. Command Transport is supported" ) ;
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . MustBeSet ) & &
2015-10-17 01:26:17 +01:00
! ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . MustBeClear ) )
{
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . SMARTSelfTest ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "S.M.A.R.T. self-testing is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet3 . HasFlag ( CommandSetBit3 . SMARTSelfTest ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . SMARTLog ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "S.M.A.R.T. error logging is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet3 . HasFlag ( CommandSetBit3 . SMARTLog ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . IdleImmediate ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "IDLE IMMEDIATE with UNLOAD FEATURE is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet3 . HasFlag ( CommandSetBit3 . IdleImmediate ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . WriteURG ) )
sb . AppendLine ( ) . Append ( "URG bit is supported in WRITE STREAM DMA EXT and WRITE STREAM EXT" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . ReadURG ) )
sb . AppendLine ( ) . Append ( "URG bit is supported in READ STREAM DMA EXT and READ STREAM EXT" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . WWN ) )
sb . AppendLine ( ) . Append ( "Device has a World Wide Name" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . FUAWriteQ ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "WRITE DMA QUEUED FUA EXT is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet3 . HasFlag ( CommandSetBit3 . FUAWriteQ ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . FUAWrite ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "WRITE DMA FUA EXT and WRITE MULTIPLE FUA EXT are supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet3 . HasFlag ( CommandSetBit3 . FUAWrite ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . GPL ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "General Purpose Logging is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet3 . HasFlag ( CommandSetBit3 . GPL ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . Streaming ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Streaming feature set is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet3 . HasFlag ( CommandSetBit3 . Streaming ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . MCPT ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Media Card Pass Through command set is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet3 . HasFlag ( CommandSetBit3 . MCPT ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . MediaSerial ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Media Serial is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet3 . HasFlag ( CommandSetBit3 . MediaSerial ) )
sb . Append ( " and valid" ) ;
2015-10-17 01:26:17 +01:00
}
}
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . MustBeSet ) & &
2017-12-19 20:33:03 +00:00
! ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . MustBeClear ) )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . DSN ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "DSN feature set is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet4 . HasFlag ( CommandSetBit4 . DSN ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . AMAC ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Accessible Max Address Configuration is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet4 . HasFlag ( CommandSetBit4 . AMAC ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . ExtPowerCond ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Extended Power Conditions are supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet4 . HasFlag ( CommandSetBit4 . ExtPowerCond ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . ExtStatusReport ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Extended Status Reporting is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet4 . HasFlag ( CommandSetBit4 . ExtStatusReport ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . FreeFallControl ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Free-fall control feature set is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet4 . HasFlag ( CommandSetBit4 . FreeFallControl ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . SegmentedDownloadMicrocode ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Segmented feature in DOWNLOAD MICROCODE is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . EnabledCommandSet4 . HasFlag ( CommandSetBit4 . SegmentedDownloadMicrocode ) )
2015-10-17 01:26:17 +01:00
sb . Append ( " and enabled" ) ;
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . RWDMAExtGpl ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "READ/WRITE DMA EXT GPL are supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet4 . HasFlag ( CommandSetBit4 . RWDMAExtGpl ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . WriteUnc ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "WRITE UNCORRECTABLE is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet4 . HasFlag ( CommandSetBit4 . WriteUnc ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . WRV ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Write/Read/Verify is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet4 . HasFlag ( CommandSetBit4 . WRV ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . AppendFormat ( "{0} sectors for Write/Read/Verify mode 2" , ATAID . WRVSectorCountMode2 ) ;
sb . AppendLine ( ) . AppendFormat ( "{0} sectors for Write/Read/Verify mode 3" , ATAID . WRVSectorCountMode3 ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . EnabledCommandSet4 . HasFlag ( CommandSetBit4 . WRV ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . AppendFormat ( "Current Write/Read/Verify mode: {0}" , ATAID . WRVMode ) ;
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet4 . HasFlag ( CommandSetBit4 . DT1825 ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "DT1825 is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledCommandSet4 . HasFlag ( CommandSetBit4 . DT1825 ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
}
2018-06-22 08:08:38 +01:00
2015-10-17 01:26:17 +01:00
if ( ATAID . Capabilities3 . HasFlag ( CapabilitiesBit3 . BlockErase ) )
sb . AppendLine ( ) . Append ( "BLOCK ERASE EXT is supported" ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
if ( ATAID . Capabilities3 . HasFlag ( CapabilitiesBit3 . Overwrite ) )
sb . AppendLine ( ) . Append ( "OVERWRITE EXT is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-14 19:20:47 +00:00
if ( ATAID . Capabilities3 . HasFlag ( CapabilitiesBit3 . CryptoScramble ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "CRYPTO SCRAMBLE EXT is supported" ) ;
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . DeviceConfDMA ) )
2019-11-25 00:54:38 +00:00
sb . AppendLine ( ) .
Append ( "DEVICE CONFIGURATION IDENTIFY DMA and DEVICE CONFIGURATION SET DMA are supported" ) ;
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . ReadBufferDMA ) )
sb . AppendLine ( ) . Append ( "READ BUFFER DMA is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . WriteBufferDMA ) )
sb . AppendLine ( ) . Append ( "WRITE BUFFER DMA is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . DownloadMicroCodeDMA ) )
sb . AppendLine ( ) . Append ( "DOWNLOAD MICROCODE DMA is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . SetMaxDMA ) )
sb . AppendLine ( ) . Append ( "SET PASSWORD DMA and SET UNLOCK DMA are supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . Ata28 ) )
sb . AppendLine ( ) . Append ( "Not all 28-bit commands are supported" ) ;
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . CFast ) )
sb . AppendLine ( ) . Append ( "Device follows CFast specification" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . IEEE1667 ) )
sb . AppendLine ( ) . Append ( "Device follows IEEE-1667" ) ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . DeterministicTrim ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Read after TRIM is deterministic" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . ReadZeroTrim ) )
sb . AppendLine ( ) . Append ( "Read after TRIM returns empty data" ) ;
}
2018-06-22 08:08:38 +01:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . LongPhysSectorAligError ) )
sb . AppendLine ( ) . Append ( "Device supports Long Physical Sector Alignment Error Reporting Control" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . Encrypted ) )
sb . AppendLine ( ) . Append ( "Device encrypts all user data" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . AllCacheNV ) )
sb . AppendLine ( ) . Append ( "Device's write cache is non-volatile" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . ZonedBit0 ) | |
2019-11-25 00:54:38 +00:00
ATAID . CommandSet5 . HasFlag ( CommandSetBit5 . ZonedBit1 ) )
sb . AppendLine ( ) . Append ( "Device is zoned" ) ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities3 . HasFlag ( CapabilitiesBit3 . Sanitize ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Sanitize feature set is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-22 02:04:18 +00:00
sb . AppendLine ( ) . Append ( ATAID . Capabilities3 . HasFlag ( CapabilitiesBit3 . SanitizeCommands )
? "Sanitize commands are specified by ACS-3 or higher"
: "Sanitize commands are specified by ACS-2" ) ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . Capabilities3 . HasFlag ( CapabilitiesBit3 . SanitizeAntifreeze ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "SANITIZE ANTIFREEZE LOCK EXT is supported" ) ;
}
2019-11-25 00:54:38 +00:00
if ( ! ata1 & &
maxatalevel > = 8 )
2018-06-22 08:08:38 +01:00
if ( ATAID . TrustedComputing . HasFlag ( TrustedComputingBit . Set ) & &
2017-12-19 20:33:03 +00:00
! ATAID . TrustedComputing . HasFlag ( TrustedComputingBit . Clear ) & &
ATAID . TrustedComputing . HasFlag ( TrustedComputingBit . TrustedComputing ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "Trusted Computing feature set is supported" ) ;
2017-12-20 17:26:28 +00:00
if ( ( ATAID . TransportMajorVersion & 0xF000 ) > > 12 = = 0x1 | |
( ATAID . TransportMajorVersion & 0xF000 ) > > 12 = = 0xE )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( ! ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . Clear ) )
if ( ATAID . SATACapabilities . HasFlag ( SATACapabilitiesBit . ReadLogDMAExt ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "READ LOG DMA EXT is supported" ) ;
2016-04-19 02:11:47 +01:00
if ( ! ATAID . SATACapabilities2 . HasFlag ( SATACapabilitiesBit2 . Clear ) )
if ( ATAID . SATACapabilities2 . HasFlag ( SATACapabilitiesBit2 . FPDMAQ ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . Append ( "RECEIVE FPDMA QUEUED and SEND FPDMA QUEUED are supported" ) ;
2016-04-19 02:11:47 +01:00
if ( ! ATAID . SATAFeatures . HasFlag ( SATAFeaturesBit . Clear ) )
2015-10-17 01:26:17 +01:00
{
2016-04-19 02:11:47 +01:00
if ( ATAID . SATAFeatures . HasFlag ( SATAFeaturesBit . NonZeroBufferOffset ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Non-zero buffer offsets are supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . EnabledSATAFeatures . HasFlag ( SATAFeaturesBit . NonZeroBufferOffset ) )
2015-10-17 01:26:17 +01:00
sb . Append ( " and enabled" ) ;
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SATAFeatures . HasFlag ( SATAFeaturesBit . DMASetup ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "DMA Setup auto-activation is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledSATAFeatures . HasFlag ( SATAFeaturesBit . DMASetup ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SATAFeatures . HasFlag ( SATAFeaturesBit . InitPowerMgmt ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Device-initiated power management is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledSATAFeatures . HasFlag ( SATAFeaturesBit . InitPowerMgmt ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SATAFeatures . HasFlag ( SATAFeaturesBit . InOrderData ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "In-order data delivery is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . EnabledSATAFeatures . HasFlag ( SATAFeaturesBit . InOrderData ) )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ! atapi )
if ( ATAID . SATAFeatures . HasFlag ( SATAFeaturesBit . HardwareFeatureControl ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Hardware Feature Control is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . EnabledSATAFeatures . HasFlag ( SATAFeaturesBit . HardwareFeatureControl ) )
2015-10-17 01:26:17 +01:00
sb . Append ( " and enabled" ) ;
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( atapi )
if ( ATAID . SATAFeatures . HasFlag ( SATAFeaturesBit . AsyncNotification ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Asynchronous notification is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . EnabledSATAFeatures . HasFlag ( SATAFeaturesBit . AsyncNotification ) )
2015-10-17 01:26:17 +01:00
sb . Append ( " and enabled" ) ;
}
2018-06-22 08:08:38 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SATAFeatures . HasFlag ( SATAFeaturesBit . SettingsPreserve ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . Append ( "Software Settings Preservation is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . EnabledSATAFeatures . HasFlag ( SATAFeaturesBit . SettingsPreserve ) )
2015-10-17 01:26:17 +01:00
sb . Append ( " and enabled" ) ;
}
2018-06-22 08:08:38 +01:00
2017-12-23 18:31:38 +00:00
if ( ATAID . SATAFeatures . HasFlag ( SATAFeaturesBit . NCQAutoSense ) )
sb . AppendLine ( ) . Append ( "NCQ Autosense is supported" ) ;
2019-11-25 00:54:38 +00:00
2017-12-23 18:31:38 +00:00
if ( ATAID . EnabledSATAFeatures . HasFlag ( SATAFeaturesBit . EnabledSlumber ) )
sb . AppendLine ( ) . Append ( "Automatic Partial to Slumber transitions are enabled" ) ;
2015-10-17 01:26:17 +01:00
}
}
2018-06-22 08:08:38 +01:00
2017-12-23 18:31:38 +00:00
if ( ( ATAID . RemovableStatusSet & 0x03 ) > 0 )
sb . AppendLine ( ) . Append ( "Removable Media Status Notification feature set is supported" ) ;
2015-10-17 01:26:17 +01:00
2019-11-25 00:54:38 +00:00
if ( ATAID . FreeFallSensitivity ! = 0x00 & &
ATAID . FreeFallSensitivity ! = 0xFF )
2017-12-23 18:31:38 +00:00
sb . AppendLine ( ) . AppendFormat ( "Free-fall sensitivity set to {0}" , ATAID . FreeFallSensitivity ) ;
2015-10-17 01:26:17 +01:00
2019-11-25 00:54:38 +00:00
if ( ATAID . DataSetMgmt . HasFlag ( DataSetMgmtBit . Trim ) )
sb . AppendLine ( ) . Append ( "TRIM is supported" ) ;
2016-04-19 02:11:47 +01:00
if ( ATAID . DataSetMgmtSize > 0 )
2017-12-19 20:33:03 +00:00
sb . AppendLine ( ) . AppendFormat ( "DATA SET MANAGEMENT can receive a maximum of {0} blocks of 512 bytes" ,
ATAID . DataSetMgmtSize ) ;
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SecurityStatus . HasFlag ( SecurityStatusBit . Supported ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( "Security:" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SecurityStatus . HasFlag ( SecurityStatusBit . Enabled ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( "Security is enabled" ) ;
2019-11-25 00:54:38 +00:00
sb . AppendLine ( ATAID . SecurityStatus . HasFlag ( SecurityStatusBit . Locked ) ? "Security is locked"
2017-12-22 02:04:18 +00:00
: "Security is not locked" ) ;
2016-04-19 02:11:47 +01:00
2019-11-25 00:54:38 +00:00
sb . AppendLine ( ATAID . SecurityStatus . HasFlag ( SecurityStatusBit . Frozen ) ? "Security is frozen"
2017-12-22 02:04:18 +00:00
: "Security is not frozen" ) ;
2016-04-19 02:11:47 +01:00
2019-11-25 00:54:38 +00:00
sb . AppendLine ( ATAID . SecurityStatus . HasFlag ( SecurityStatusBit . Expired ) ? "Security count has expired"
2017-12-22 02:04:18 +00:00
: "Security count has notexpired" ) ;
2016-04-19 02:11:47 +01:00
2019-11-25 00:54:38 +00:00
sb . AppendLine ( ATAID . SecurityStatus . HasFlag ( SecurityStatusBit . Maximum ) ? "Security level is maximum"
2017-12-22 02:04:18 +00:00
: "Security level is high" ) ;
2015-10-17 01:26:17 +01:00
}
2019-11-25 00:54:38 +00:00
else
sb . AppendLine ( "Security is not enabled" ) ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SecurityStatus . HasFlag ( SecurityStatusBit . Enhanced ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "Supports enhanced security erase" ) ;
sb . AppendFormat ( "{0} minutes to complete secure erase" , ATAID . SecurityEraseTime * 2 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SecurityStatus . HasFlag ( SecurityStatusBit . Enhanced ) )
2017-12-19 20:33:03 +00:00
sb . AppendFormat ( "{0} minutes to complete enhanced secure erase" ,
ATAID . EnhancedSecurityEraseTime * 2 ) . AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Master password revision code: {0}" , ATAID . MasterPasswordRevisionCode ) . AppendLine ( ) ;
}
2018-06-22 08:08:38 +01:00
if ( ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . MustBeSet ) & &
2017-12-19 20:33:03 +00:00
! ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . MustBeClear ) & &
ATAID . CommandSet3 . HasFlag ( CommandSetBit3 . Streaming ) )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . AppendLine ( "Streaming:" ) ;
2019-11-25 00:54:38 +00:00
sb . AppendFormat ( "Minimum request size is {0}" , ATAID . StreamMinReqSize ) ;
sb . AppendFormat ( "Streaming transfer time in PIO is {0}" , ATAID . StreamTransferTimePIO ) ;
sb . AppendFormat ( "Streaming transfer time in DMA is {0}" , ATAID . StreamTransferTimeDMA ) ;
sb . AppendFormat ( "Streaming access latency is {0}" , ATAID . StreamAccessLatency ) ;
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Streaming performance granularity is {0}" , ATAID . StreamPerformanceGranularity ) ;
}
if ( ATAID . SCTCommandTransport . HasFlag ( SCTCommandTransportBit . Supported ) )
{
sb . AppendLine ( ) . AppendLine ( "S.M.A.R.T. Command Transport (SCT):" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SCTCommandTransport . HasFlag ( SCTCommandTransportBit . LongSectorAccess ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "SCT Long Sector Address is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SCTCommandTransport . HasFlag ( SCTCommandTransportBit . WriteSame ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "SCT Write Same is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SCTCommandTransport . HasFlag ( SCTCommandTransportBit . ErrorRecoveryControl ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "SCT Error Recovery Control is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SCTCommandTransport . HasFlag ( SCTCommandTransportBit . FeaturesControl ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "SCT Features Control is supported" ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ATAID . SCTCommandTransport . HasFlag ( SCTCommandTransportBit . DataTables ) )
2015-10-17 01:26:17 +01:00
sb . AppendLine ( "SCT Data Tables are supported" ) ;
}
2016-04-19 02:11:47 +01:00
if ( ( ATAID . NVCacheCaps & 0x0010 ) = = 0x0010 )
2015-10-17 01:26:17 +01:00
{
sb . AppendLine ( ) . AppendLine ( "Non-Volatile Cache:" ) ;
sb . AppendLine ( ) . AppendFormat ( "Version {0}" , ( ATAID . NVCacheCaps & 0xF000 ) > > 12 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2016-04-19 02:11:47 +01:00
if ( ( ATAID . NVCacheCaps & 0x0001 ) = = 0x0001 )
2015-10-17 01:26:17 +01:00
{
sb . Append ( "Power mode feature set is supported" ) ;
2019-11-25 00:54:38 +00:00
if ( ( ATAID . NVCacheCaps & 0x0002 ) = = 0x0002 )
sb . Append ( " and enabled" ) ;
2015-10-17 01:26:17 +01:00
sb . AppendLine ( ) ;
sb . AppendLine ( ) . AppendFormat ( "Version {0}" , ( ATAID . NVCacheCaps & 0x0F00 ) > > 8 ) . AppendLine ( ) ;
}
2018-06-22 08:08:38 +01:00
2019-11-25 00:54:38 +00:00
sb . AppendLine ( ) . AppendFormat ( "Non-Volatile Cache is {0} bytes" , ATAID . NVCacheSize * logicalsectorsize ) .
AppendLine ( ) ;
2015-10-17 01:26:17 +01:00
}
2019-11-25 00:54:38 +00:00
#if DEBUG
2016-04-19 02:11:47 +01:00
sb . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . VendorWord9 ! = 0x0000 & &
ATAID . VendorWord9 ! = 0xFFFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 9: 0x{0:X4}" , ATAID . VendorWord9 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ( ATAID . VendorWord47 & 0x7F ) ! = 0x7F & &
( ATAID . VendorWord47 & 0x7F ) ! = 0x00 )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 47 bits 15 to 8: 0x{0:X2}" , ATAID . VendorWord47 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . VendorWord51 ! = 0x00 & &
ATAID . VendorWord51 ! = 0xFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 51 bits 7 to 0: 0x{0:X2}" , ATAID . VendorWord51 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . VendorWord52 ! = 0x00 & &
ATAID . VendorWord52 ! = 0xFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 52 bits 7 to 0: 0x{0:X2}" , ATAID . VendorWord52 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedWord64 ! = 0x00 & &
ATAID . ReservedWord64 ! = 0xFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 64 bits 15 to 8: 0x{0:X2}" , ATAID . ReservedWord64 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedWord70 ! = 0x0000 & &
ATAID . ReservedWord70 ! = 0xFFFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 70: 0x{0:X4}" , ATAID . ReservedWord70 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedWord73 ! = 0x0000 & &
ATAID . ReservedWord73 ! = 0xFFFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 73: 0x{0:X4}" , ATAID . ReservedWord73 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedWord74 ! = 0x0000 & &
ATAID . ReservedWord74 ! = 0xFFFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 74: 0x{0:X4}" , ATAID . ReservedWord74 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedWord116 ! = 0x0000 & &
ATAID . ReservedWord116 ! = 0xFFFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 116: 0x{0:X4}" , ATAID . ReservedWord116 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
for ( int i = 0 ; i < ATAID . ReservedWords121 . Length ; i + + )
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedWords121 [ i ] ! = 0x0000 & &
ATAID . ReservedWords121 [ i ] ! = 0xFFFF )
2016-04-19 02:11:47 +01:00
sb . AppendFormat ( "Word {1}: 0x{0:X4}" , ATAID . ReservedWords121 [ i ] , 121 + i ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
for ( int i = 0 ; i < ATAID . ReservedWords129 . Length ; i + + )
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedWords129 [ i ] ! = 0x0000 & &
ATAID . ReservedWords129 [ i ] ! = 0xFFFF )
2016-04-19 02:11:47 +01:00
sb . AppendFormat ( "Word {1}: 0x{0:X4}" , ATAID . ReservedWords129 [ i ] , 129 + i ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
for ( int i = 0 ; i < ATAID . ReservedCFA . Length ; i + + )
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedCFA [ i ] ! = 0x0000 & &
ATAID . ReservedCFA [ i ] ! = 0xFFFF )
2016-04-19 02:11:47 +01:00
sb . AppendFormat ( "Word {1} (CFA): 0x{0:X4}" , ATAID . ReservedCFA [ i ] , 161 + i ) . AppendLine ( ) ;
2017-12-19 20:33:03 +00:00
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedWord174 ! = 0x0000 & &
ATAID . ReservedWord174 ! = 0xFFFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 174: 0x{0:X4}" , ATAID . ReservedWord174 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedWord175 ! = 0x0000 & &
ATAID . ReservedWord175 ! = 0xFFFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 175: 0x{0:X4}" , ATAID . ReservedWord175 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedCEATAWord207 ! = 0x0000 & &
ATAID . ReservedCEATAWord207 ! = 0xFFFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 207 (CE-ATA): 0x{0:X4}" , ATAID . ReservedCEATAWord207 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedCEATAWord208 ! = 0x0000 & &
ATAID . ReservedCEATAWord208 ! = 0xFFFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 208 (CE-ATA): 0x{0:X4}" , ATAID . ReservedCEATAWord208 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . NVReserved ! = 0x00 & &
ATAID . NVReserved ! = 0xFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 219 bits 15 to 8: 0x{0:X2}" , ATAID . NVReserved ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . WRVReserved ! = 0x00 & &
ATAID . WRVReserved ! = 0xFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 220 bits 15 to 8: 0x{0:X2}" , ATAID . WRVReserved ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedWord221 ! = 0x0000 & &
ATAID . ReservedWord221 ! = 0xFFFF )
2015-10-17 01:26:17 +01:00
sb . AppendFormat ( "Word 221: 0x{0:X4}" , ATAID . ReservedWord221 ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
for ( int i = 0 ; i < ATAID . ReservedCEATA224 . Length ; i + + )
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedCEATA224 [ i ] ! = 0x0000 & &
ATAID . ReservedCEATA224 [ i ] ! = 0xFFFF )
2016-04-19 02:11:47 +01:00
sb . AppendFormat ( "Word {1} (CE-ATA): 0x{0:X4}" , ATAID . ReservedCEATA224 [ i ] , 224 + i ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
for ( int i = 0 ; i < ATAID . ReservedWords . Length ; i + + )
2019-11-25 00:54:38 +00:00
if ( ATAID . ReservedWords [ i ] ! = 0x0000 & &
ATAID . ReservedWords [ i ] ! = 0xFFFF )
2016-04-19 02:11:47 +01:00
sb . AppendFormat ( "Word {1}: 0x{0:X4}" , ATAID . ReservedWords [ i ] , 236 + i ) . AppendLine ( ) ;
2019-11-25 00:54:38 +00:00
#endif
2015-10-17 01:26:17 +01:00
return sb . ToString ( ) ;
}
static ulong DescrambleWWN ( ulong WWN )
{
2018-06-22 08:08:38 +01:00
byte [ ] qwb = BitConverter . GetBytes ( WWN ) ;
2015-10-17 01:26:17 +01:00
byte [ ] qword = new byte [ 8 ] ;
qword [ 7 ] = qwb [ 1 ] ;
qword [ 6 ] = qwb [ 0 ] ;
qword [ 5 ] = qwb [ 3 ] ;
qword [ 4 ] = qwb [ 2 ] ;
qword [ 3 ] = qwb [ 5 ] ;
qword [ 2 ] = qwb [ 4 ] ;
qword [ 1 ] = qwb [ 7 ] ;
qword [ 0 ] = qwb [ 6 ] ;
return BitConverter . ToUInt64 ( qword , 0 ) ;
}
2017-12-23 18:31:38 +00:00
static string DescrambleATAString ( IList < byte > buffer , int offset , int length )
2015-10-17 01:26:17 +01:00
{
2017-12-22 02:04:18 +00:00
byte [ ] outbuf = buffer [ offset + length - 1 ] ! = 0x00 ? new byte [ length + 1 ] : new byte [ length ] ;
2015-10-17 01:26:17 +01:00
2016-04-19 02:11:47 +01:00
for ( int i = 0 ; i < length ; i + = 2 )
2015-10-17 01:26:17 +01:00
{
outbuf [ i ] = buffer [ offset + i + 1 ] ;
2018-06-22 08:08:38 +01:00
outbuf [ i + 1 ] = buffer [ offset + i ] ;
2015-10-17 01:26:17 +01:00
}
string outStr = StringHandlers . CToString ( outbuf ) ;
2019-11-25 00:54:38 +00:00
2015-10-17 01:26:17 +01:00
return outStr . Trim ( ) ;
2015-10-16 01:55:55 +01:00
}
2018-12-23 21:36:17 +00:00
static byte [ ] ScrambleATAString ( string str , int length )
{
2019-11-25 00:54:38 +00:00
byte [ ] buf = new byte [ length ] ;
2018-12-23 23:51:40 +00:00
2019-11-25 00:54:38 +00:00
for ( int i = 0 ; i < length ; i + + )
buf [ i ] = 0x20 ;
if ( str is null )
return buf ;
2018-12-23 23:51:40 +00:00
byte [ ] bytes = Encoding . ASCII . GetBytes ( str ) ;
2018-12-24 04:15:15 +00:00
if ( bytes . Length % 2 ! = 0 )
{
byte [ ] tmp = new byte [ bytes . Length + 1 ] ;
2018-12-31 13:17:27 +00:00
tmp [ tmp . Length - 1 ] = 0x20 ;
2018-12-24 04:15:15 +00:00
Array . Copy ( bytes , 0 , tmp , 0 , bytes . Length ) ;
bytes = tmp ;
}
for ( int i = 0 ; i < bytes . Length ; i + = 2 )
{
buf [ i ] = bytes [ i + 1 ] ;
2018-12-31 13:17:27 +00:00
buf [ i + 1 ] = bytes [ i ] ;
2018-12-24 04:15:15 +00:00
}
string test1 = StringHandlers . CToString ( buf ) ;
string test2 = DescrambleATAString ( buf , 0 , length ) ;
2019-11-25 00:54:38 +00:00
2018-12-23 21:36:17 +00:00
return buf ;
}
2019-11-25 00:54:38 +00:00
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 2)]
public struct IdentifyDevice
{
/// <summary>
/// Word 0 General device configuration On ATAPI devices: Bits 12 to 8 indicate device type as SCSI defined Bits 6
/// to 5: 0 = Device shall set DRQ within 3 ms of receiving PACKET 1 = Device shall assert INTRQ when DRQ is set to one
/// 2 = Device shall set DRQ within 50 µs of receiving PACKET Bits 1 to 0: 0 = 12 byte command packet 1 = 16 byte
/// command packet CompactFlash is 0x848A (non magnetic, removable, not MFM, hardsector, and UltraFAST)
/// </summary>
public GeneralConfigurationBit GeneralConfiguration ;
/// <summary>Word 1 Cylinders in default translation mode Obsoleted in ATA/ATAPI-6</summary>
public ushort Cylinders ;
/// <summary>Word 2 Specific configuration</summary>
public SpecificConfigurationEnum SpecificConfiguration ;
/// <summary>Word 3 Heads in default translation mode Obsoleted in ATA/ATAPI-6</summary>
public ushort Heads ;
/// <summary>Word 4 Unformatted bytes per track in default translation mode Obsoleted in ATA-2</summary>
public ushort UnformattedBPT ;
/// <summary>Word 5 Unformatted bytes per sector in default translation mode Obsoleted in ATA-2</summary>
public ushort UnformattedBPS ;
/// <summary>Word 6 Sectors per track in default translation mode Obsoleted in ATA/ATAPI-6</summary>
public ushort SectorsPerTrack ;
/// <summary>Words 7 to 8 CFA: Number of sectors per card</summary>
public uint SectorsPerCard ;
/// <summary>Word 9 Vendor unique Obsoleted in ATA/ATAPI-4</summary>
public ushort VendorWord9 ;
/// <summary>Words 10 to 19 Device serial number, right justified, padded with spaces</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string SerialNumber ;
/// <summary>
/// Word 20 Manufacturer defined Obsoleted in ATA-2 0x0001 = single ported single sector buffer 0x0002 = dual
/// ported multi sector buffer 0x0003 = dual ported multi sector buffer with reading
/// </summary>
public ushort BufferType ;
/// <summary>Word 21 Size of buffer in 512 byte increments Obsoleted in ATA-2</summary>
public ushort BufferSize ;
/// <summary>Word 22 Bytes of ECC available in READ/WRITE LONG commands Obsoleted in ATA/ATAPI-4</summary>
public ushort EccBytes ;
/// <summary>Words 23 to 26 Firmware revision, left justified, padded with spaces</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string FirmwareRevision ;
/// <summary>Words 27 to 46 Model number, left justified, padded with spaces</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
public string Model ;
/// <summary>
/// Word 47 bits 7 to 0 Maximum number of sectors that can be transferred per interrupt on read and write multiple
/// commands
/// </summary>
public byte MultipleMaxSectors ;
/// <summary>Word 47 bits 15 to 8 Vendor unique ATA/ATAPI-4 says it must be 0x80</summary>
public byte VendorWord47 ;
/// <summary>
/// Word 48 ATA-1: Set to 1 if it can perform doubleword I/O ATA-2 to ATA/ATAPI-7: Reserved ATA8-ACS: Trusted
/// Computing feature set
/// </summary>
public TrustedComputingBit TrustedComputing ;
/// <summary>Word 49 Capabilities</summary>
public CapabilitiesBit Capabilities ;
/// <summary>Word 50 Capabilities</summary>
public CapabilitiesBit2 Capabilities2 ;
/// <summary>Word 51 bits 7 to 0 Vendor unique Obsoleted in ATA/ATAPI-4</summary>
public byte VendorWord51 ;
/// <summary>Word 51 bits 15 to 8 Transfer timing mode in PIO Obsoleted in ATA/ATAPI-4</summary>
public byte PIOTransferTimingMode ;
/// <summary>Word 52 bits 7 to 0 Vendor unique Obsoleted in ATA/ATAPI-4</summary>
public byte VendorWord52 ;
/// <summary>Word 52 bits 15 to 8 Transfer timing mode in DMA Obsoleted in ATA/ATAPI-4</summary>
public byte DMATransferTimingMode ;
/// <summary>Word 53 bits 7 to 0 Reports if words 54 to 58 are valid</summary>
public ExtendedIdentifyBit ExtendedIdentify ;
/// <summary>Word 53 bits 15 to 8 Free-fall Control Sensitivity</summary>
public byte FreeFallSensitivity ;
/// <summary>Word 54 Cylinders in current translation mode Obsoleted in ATA/ATAPI-6</summary>
public ushort CurrentCylinders ;
/// <summary>Word 55 Heads in current translation mode Obsoleted in ATA/ATAPI-6</summary>
public ushort CurrentHeads ;
/// <summary>Word 56 Sectors per track in current translation mode Obsoleted in ATA/ATAPI-6</summary>
public ushort CurrentSectorsPerTrack ;
/// <summary>Words 57 to 58 Total sectors currently user-addressable Obsoleted in ATA/ATAPI-6</summary>
public uint CurrentSectors ;
/// <summary>Word 59 bits 7 to 0 Number of sectors currently set to transfer on a READ/WRITE MULTIPLE command</summary>
public byte MultipleSectorNumber ;
/// <summary>Word 59 bits 15 to 8 Indicates if <see cref="MultipleSectorNumber" /> is valid</summary>
public CapabilitiesBit3 Capabilities3 ;
/// <summary>Words 60 to 61 If drive supports LBA, how many sectors are addressable using LBA</summary>
public uint LBASectors ;
/// <summary>
/// Word 62 bits 7 to 0 Single word DMA modes available Obsoleted in ATA/ATAPI-4 In ATAPI it's not obsolete,
/// indicates UDMA mode (UDMA7 is instead MDMA0)
/// </summary>
public TransferMode DMASupported ;
/// <summary>
/// Word 62 bits 15 to 8 Single word DMA mode currently active Obsoleted in ATA/ATAPI-4 In ATAPI it's not
/// obsolete, bits 0 and 1 indicate MDMA mode+1, bit 10 indicates DMA is supported and bit 15 indicates DMADIR bit in
/// PACKET is required for DMA transfers
/// </summary>
public TransferMode DMAActive ;
/// <summary>Word 63 bits 7 to 0 Multiword DMA modes available</summary>
public TransferMode MDMASupported ;
/// <summary>Word 63 bits 15 to 8 Multiword DMA mode currently active</summary>
public TransferMode MDMAActive ;
/// <summary>Word 64 bits 7 to 0 Supported Advanced PIO transfer modes</summary>
public TransferMode APIOSupported ;
/// <summary>Word 64 bits 15 to 8 Reserved</summary>
public byte ReservedWord64 ;
/// <summary>Word 65 Minimum MDMA transfer cycle time per word in nanoseconds</summary>
public ushort MinMDMACycleTime ;
/// <summary>Word 66 Recommended MDMA transfer cycle time per word in nanoseconds</summary>
public ushort RecMDMACycleTime ;
/// <summary>Word 67 Minimum PIO transfer cycle time without flow control in nanoseconds</summary>
public ushort MinPIOCycleTimeNoFlow ;
/// <summary>Word 68 Minimum PIO transfer cycle time with IORDY flow control in nanoseconds</summary>
public ushort MinPIOCycleTimeFlow ;
/// <summary>Word 69 Additional supported</summary>
public CommandSetBit5 CommandSet5 ;
/// <summary>Word 70 Reserved</summary>
public ushort ReservedWord70 ;
/// <summary>Word 71 ATAPI: Typical time in ns from receipt of PACKET to release bus</summary>
public ushort PacketBusRelease ;
/// <summary>Word 72 ATAPI: Typical time in ns from receipt of SERVICE to clear BSY</summary>
public ushort ServiceBusyClear ;
/// <summary>Word 73 Reserved</summary>
public ushort ReservedWord73 ;
/// <summary>Word 74 Reserved</summary>
public ushort ReservedWord74 ;
/// <summary>Word 75 Maximum Queue depth</summary>
public ushort MaxQueueDepth ;
/// <summary>Word 76 Serial ATA Capabilities</summary>
public SATACapabilitiesBit SATACapabilities ;
/// <summary>Word 77 Serial ATA Additional Capabilities</summary>
public SATACapabilitiesBit2 SATACapabilities2 ;
/// <summary>Word 78 Supported Serial ATA features</summary>
public SATAFeaturesBit SATAFeatures ;
/// <summary>Word 79 Enabled Serial ATA features</summary>
public SATAFeaturesBit EnabledSATAFeatures ;
/// <summary>Word 80 Major version of ATA/ATAPI standard supported</summary>
public MajorVersionBit MajorVersion ;
/// <summary>Word 81 Minimum version of ATA/ATAPI standard supported</summary>
public ushort MinorVersion ;
/// <summary>Word 82 Supported command/feature sets</summary>
public CommandSetBit CommandSet ;
/// <summary>Word 83 Supported command/feature sets</summary>
public CommandSetBit2 CommandSet2 ;
/// <summary>Word 84 Supported command/feature sets</summary>
public CommandSetBit3 CommandSet3 ;
/// <summary>Word 85 Enabled command/feature sets</summary>
public CommandSetBit EnabledCommandSet ;
/// <summary>Word 86 Enabled command/feature sets</summary>
public CommandSetBit2 EnabledCommandSet2 ;
/// <summary>Word 87 Enabled command/feature sets</summary>
public CommandSetBit3 EnabledCommandSet3 ;
/// <summary>Word 88 bits 7 to 0 Supported Ultra DMA transfer modes</summary>
public TransferMode UDMASupported ;
/// <summary>Word 88 bits 15 to 8 Selected Ultra DMA transfer modes</summary>
public TransferMode UDMAActive ;
/// <summary>Word 89 Time required for security erase completion</summary>
public ushort SecurityEraseTime ;
/// <summary>Word 90 Time required for enhanced security erase completion</summary>
public ushort EnhancedSecurityEraseTime ;
/// <summary>Word 91 Current advanced power management value</summary>
public ushort CurrentAPM ;
/// <summary>Word 92 Master password revision code</summary>
public ushort MasterPasswordRevisionCode ;
/// <summary>Word 93 Hardware reset result</summary>
public ushort HardwareResetResult ;
/// <summary>Word 94 bits 7 to 0 Current AAM value</summary>
public byte CurrentAAM ;
/// <summary>Word 94 bits 15 to 8 Vendor's recommended AAM value</summary>
public byte RecommendedAAM ;
/// <summary>Word 95 Stream minimum request size</summary>
public ushort StreamMinReqSize ;
/// <summary>Word 96 Streaming transfer time in DMA</summary>
public ushort StreamTransferTimeDMA ;
/// <summary>Word 97 Streaming access latency in DMA and PIO</summary>
public ushort StreamAccessLatency ;
/// <summary>Words 98 to 99 Streaming performance granularity</summary>
public uint StreamPerformanceGranularity ;
/// <summary>Words 100 to 103 48-bit LBA addressable sectors</summary>
public ulong LBA48Sectors ;
/// <summary>Word 104 Streaming transfer time in PIO</summary>
public ushort StreamTransferTimePIO ;
/// <summary>Word 105 Maximum number of 512-byte block per DATA SET MANAGEMENT command</summary>
public ushort DataSetMgmtSize ;
/// <summary>
/// Word 106 Bit 15 should be zero Bit 14 should be one Bit 13 set indicates device has multiple logical sectors
/// per physical sector Bit 12 set indicates logical sector has more than 256 words (512 bytes) Bits 11 to 4 are
/// reserved Bits 3 to 0 indicate power of two of logical sectors per physical sector
/// </summary>
public ushort PhysLogSectorSize ;
/// <summary>Word 107 Interseek delay for ISO-7779 acoustic testing, in microseconds</summary>
public ushort InterseekDelay ;
/// <summary>Words 108 to 111 World Wide Name</summary>
public ulong WWN ;
/// <summary>Words 112 to 115 Reserved for WWN extension to 128 bit</summary>
public ulong WWNExtension ;
/// <summary>Word 116 Reserved for technical report</summary>
public ushort ReservedWord116 ;
/// <summary>Words 117 to 118 Words per logical sector</summary>
public uint LogicalSectorWords ;
/// <summary>Word 119 Supported command/feature sets</summary>
public CommandSetBit4 CommandSet4 ;
/// <summary>Word 120 Supported command/feature sets</summary>
public CommandSetBit4 EnabledCommandSet4 ;
/// <summary>Words 121 to 125 Reserved</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public ushort [ ] ReservedWords121 ;
/// <summary>Word 126 ATAPI byte count limit</summary>
public ushort ATAPIByteCount ;
/// <summary>
/// Word 127 Removable Media Status Notification feature set support Bits 15 to 2 are reserved Bits 1 to 0 must be
/// 0 for not supported or 1 for supported. 2 and 3 are reserved. Obsoleted in ATA8-ACS
/// </summary>
public ushort RemovableStatusSet ;
/// <summary>Word 128 Security status</summary>
public SecurityStatusBit SecurityStatus ;
/// <summary>Words 129 to 159</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 31)]
public ushort [ ] ReservedWords129 ;
/// <summary>
/// Word 160 CFA power mode Bit 15 must be set Bit 13 indicates mode 1 is required for one or more commands Bit 12
/// indicates mode 1 is disabled Bits 11 to 0 indicates maximum current in mA
/// </summary>
public ushort CFAPowerMode ;
/// <summary>Words 161 to 167 Reserved for CFA</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public ushort [ ] ReservedCFA ;
/// <summary>Word 168 Bits 15 to 4, reserved Bits 3 to 0, device nominal form factor</summary>
public DeviceFormFactorEnum DeviceFormFactor ;
/// <summary>Word 169 DATA SET MANAGEMENT support</summary>
public DataSetMgmtBit DataSetMgmt ;
/// <summary>Words 170 to 173 Additional product identifier</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string AdditionalPID ;
/// <summary>Word 174 Reserved</summary>
public ushort ReservedWord174 ;
/// <summary>Word 175 Reserved</summary>
public ushort ReservedWord175 ;
/// <summary>Words 176 to 195 Current media serial number</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
public string MediaSerial ;
/// <summary>Words 196 to 205 Current media manufacturer</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string MediaManufacturer ;
/// <summary>Word 206 SCT Command Transport features</summary>
public SCTCommandTransportBit SCTCommandTransport ;
/// <summary>Word 207 Reserved for CE-ATA</summary>
public ushort ReservedCEATAWord207 ;
/// <summary>Word 208 Reserved for CE-ATA</summary>
public ushort ReservedCEATAWord208 ;
/// <summary>
/// Word 209 Alignment of logical block within a larger physical block Bit 15 shall be cleared to zero Bit 14
/// shall be set to one Bits 13 to 0 indicate logical sector offset within the first physical sector
/// </summary>
public ushort LogicalAlignment ;
/// <summary>Words 210 to 211 Write/Read/Verify sector count mode 3 only</summary>
public uint WRVSectorCountMode3 ;
/// <summary>Words 212 to 213 Write/Read/Verify sector count mode 2 only</summary>
public uint WRVSectorCountMode2 ;
/// <summary>
/// Word 214 NV Cache capabilities Bits 15 to 12 feature set version Bits 11 to 18 power mode feature set version
/// Bits 7 to 5 reserved Bit 4 feature set enabled Bits 3 to 2 reserved Bit 1 power mode feature set enabled Bit 0
/// power mode feature set supported
/// </summary>
public ushort NVCacheCaps ;
/// <summary>Words 215 to 216 NV Cache Size in Logical BLocks</summary>
public uint NVCacheSize ;
/// <summary>Word 217 Nominal media rotation rate In ACS-1 meant NV Cache read speed in MB/s</summary>
public ushort NominalRotationRate ;
/// <summary>Word 218 NV Cache write speed in MB/s Reserved since ACS-2</summary>
public ushort NVCacheWriteSpeed ;
/// <summary>Word 219 bits 7 to 0 Estimated device spin up in seconds</summary>
public byte NVEstimatedSpinUp ;
/// <summary>Word 219 bits 15 to 8 NV Cache reserved</summary>
public byte NVReserved ;
/// <summary>Word 220 bits 7 to 0 Write/Read/Verify feature set current mode</summary>
public byte WRVMode ;
/// <summary>Word 220 bits 15 to 8 Reserved</summary>
public byte WRVReserved ;
/// <summary>Word 221 Reserved</summary>
public ushort ReservedWord221 ;
/// <summary>
/// Word 222 Transport major revision number Bits 15 to 12 indicate transport type. 0 parallel, 1 serial, 0xE
/// PCIe. Bits 11 to 0 indicate revision
/// </summary>
public ushort TransportMajorVersion ;
/// <summary>Word 223 Transport minor revision number</summary>
public ushort TransportMinorVersion ;
/// <summary>Words 224 to 229 Reserved for CE-ATA</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public ushort [ ] ReservedCEATA224 ;
/// <summary>Words 230 to 233 48-bit LBA if Word 69 bit 3 is set</summary>
public ulong ExtendedUserSectors ;
/// <summary>Word 234 Minimum number of 512 byte units per DOWNLOAD MICROCODE mode 3</summary>
public ushort MinDownloadMicroMode3 ;
/// <summary>Word 235 Maximum number of 512 byte units per DOWNLOAD MICROCODE mode 3</summary>
public ushort MaxDownloadMicroMode3 ;
/// <summary>Words 236 to 254</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 19)]
public ushort [ ] ReservedWords ;
/// <summary>Word 255 bits 7 to 0 Should be 0xA5</summary>
public byte Signature ;
/// <summary>Word 255 bits 15 to 8 Checksum</summary>
public byte Checksum ;
}
2015-10-16 01:55:55 +01:00
}
2017-12-19 20:33:03 +00:00
}