Improved the Micron/Crucial SSD SMART data interpretation.

This commit is contained in:
Michael Möller
2020-02-05 22:45:10 +01:00
parent 6faec63ef6
commit f659aa0f60
2 changed files with 85 additions and 8 deletions

View File

@@ -4,7 +4,7 @@
License, v. 2.0. If a copy of the MPL was not distributed with this License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/. file, You can obtain one at http://mozilla.org/MPL/2.0/.
Copyright (C) 2012-2015 Michael Möller <mmoeller@openhardwaremonitor.org> Copyright (C) 2012-2020 Michael Möller <mmoeller@openhardwaremonitor.org>
*/ */
@@ -13,15 +13,16 @@ using OpenHardwareMonitor.Collections;
namespace OpenHardwareMonitor.Hardware.HDD { namespace OpenHardwareMonitor.Hardware.HDD {
[NamePrefix(""), RequireSmart(0xAA), RequireSmart(0xAB), RequireSmart(0xAC), [NamePrefix(""), RequireSmart(0xAB), RequireSmart(0xAC),
RequireSmart(0xAD), RequireSmart(0xAE), RequireSmart(0xCA)] RequireSmart(0xAD), RequireSmart(0xAE), RequireSmart(0xC4),
RequireSmart(0xCA), RequireSmart(0xCE)]
internal class SSDMicron : AbstractHarddrive { internal class SSDMicron : AbstractHarddrive {
private static readonly IEnumerable<SmartAttribute> smartAttributes = private static readonly IEnumerable<SmartAttribute> smartAttributes =
new List<SmartAttribute> { new List<SmartAttribute> {
new SmartAttribute(0x01, SmartNames.ReadErrorRate, RawToInt), new SmartAttribute(0x01, SmartNames.ReadErrorRate, RawToInt),
new SmartAttribute(0x05, SmartNames.ReallocatedSectorsCount, RawToInt), new SmartAttribute(0x05, SmartNames.ReallocatedNANDBlockCount, RawToInt),
new SmartAttribute(0x09, SmartNames.PowerOnHours, RawToInt), new SmartAttribute(0x09, SmartNames.PowerOnHours, RawToInt),
new SmartAttribute(0x0C, SmartNames.PowerCycleCount, RawToInt), new SmartAttribute(0x0C, SmartNames.PowerCycleCount, RawToInt),
new SmartAttribute(0xAA, SmartNames.NewFailingBlockCount, RawToInt), new SmartAttribute(0xAA, SmartNames.NewFailingBlockCount, RawToInt),
@@ -29,13 +30,16 @@ namespace OpenHardwareMonitor.Hardware.HDD {
new SmartAttribute(0xAC, SmartNames.EraseFailCount, RawToInt), new SmartAttribute(0xAC, SmartNames.EraseFailCount, RawToInt),
new SmartAttribute(0xAD, SmartNames.WearLevelingCount, RawToInt), new SmartAttribute(0xAD, SmartNames.WearLevelingCount, RawToInt),
new SmartAttribute(0xAE, SmartNames.UnexpectedPowerLossCount, RawToInt), new SmartAttribute(0xAE, SmartNames.UnexpectedPowerLossCount, RawToInt),
new SmartAttribute(0xB4, SmartNames.UnusedReserveNANDBlocks, RawToInt),
new SmartAttribute(0xB5, SmartNames.Non4kAlignedAccess, new SmartAttribute(0xB5, SmartNames.Non4kAlignedAccess,
(byte[] raw, byte value, IReadOnlyArray<IParameter> p) (byte[] raw, byte value, IReadOnlyArray<IParameter> p)
=> { return 6e4f * ((raw[5] << 8) | raw[4]); }), => { return 6e4f * ((raw[5] << 8) | raw[4]); }),
new SmartAttribute(0xB7, SmartNames.SataDownshiftErrorCount, RawToInt), new SmartAttribute(0xB7, SmartNames.SataDownshiftErrorCount, RawToInt),
new SmartAttribute(0xB8, SmartNames.ErrorCorrectionCount, RawToInt),
new SmartAttribute(0xBB, SmartNames.ReportedUncorrectableErrors, RawToInt), new SmartAttribute(0xBB, SmartNames.ReportedUncorrectableErrors, RawToInt),
new SmartAttribute(0xBC, SmartNames.CommandTimeout, RawToInt), new SmartAttribute(0xBC, SmartNames.CommandTimeout, RawToInt),
new SmartAttribute(0xBD, SmartNames.FactoryBadBlockCount, RawToInt), new SmartAttribute(0xBD, SmartNames.FactoryBadBlockCount, RawToInt),
new SmartAttribute(0xC2, SmartNames.Temperature, RawToInt),
new SmartAttribute(0xC4, SmartNames.ReallocationEventCount, RawToInt), new SmartAttribute(0xC4, SmartNames.ReallocationEventCount, RawToInt),
new SmartAttribute(0xC5, SmartNames.CurrentPendingSectorCount), new SmartAttribute(0xC5, SmartNames.CurrentPendingSectorCount),
new SmartAttribute(0xC6, SmartNames.OffLineUncorrectableErrorCount, RawToInt), new SmartAttribute(0xC6, SmartNames.OffLineUncorrectableErrorCount, RawToInt),
@@ -47,10 +51,59 @@ namespace OpenHardwareMonitor.Hardware.HDD {
new SmartAttribute(0xCE, SmartNames.WriteErrorRate, new SmartAttribute(0xCE, SmartNames.WriteErrorRate,
(byte[] raw, byte value, IReadOnlyArray<IParameter> p) (byte[] raw, byte value, IReadOnlyArray<IParameter> p)
=> { return 6e4f * ((raw[1] << 8) | raw[0]); }), => { return 6e4f * ((raw[1] << 8) | raw[0]); }),
new SmartAttribute(0xD2, SmartNames.SuccessfulRAINRecoveryCount, RawToInt),
new SmartAttribute(0xF6, SmartNames.TotalLbasWritten,
(byte[] r, byte v, IReadOnlyArray<IParameter> p) => {
return (((long)r[5] << 40) | ((long)r[4] << 32) | ((long)r[3] << 24) |
((long)r[2] << 16) | ((long)r[1] << 8) | r[0]) *
(512.0f / 1024 / 1024 / 1024);
}, SensorType.Data, 0, "Total Bytes Written"),
new SmartAttribute(0xF7, SmartNames.HostProgramNANDPagesCount, RawToInt),
new SmartAttribute(0xF8, SmartNames.FTLProgramNANDPagesCount, RawToInt)
}; };
private Sensor temperature;
private Sensor writeAmplification;
public SSDMicron(ISmart smart, string name, string firmwareRevision, public SSDMicron(ISmart smart, string name, string firmwareRevision,
int index, ISettings settings) int index, ISettings settings)
: base(smart, name, firmwareRevision, index, smartAttributes, settings) {} : base(smart, name, firmwareRevision, index, smartAttributes, settings)
{
this.temperature = new Sensor("Temperature", 0, false,
SensorType.Temperature, this,
new[] { new ParameterDescription("Offset [°C]",
"Temperature offset of the thermal sensor.\n" +
"Temperature = Value + Offset.", 0) }, settings);
this.writeAmplification = new Sensor("Write Amplification", 0,
SensorType.Factor, this, settings);
}
public override void UpdateAdditionalSensors(DriveAttributeValue[] values) {
float? hostProgramPagesCount = null;
float? ftlProgramPagesCount = null;
foreach (DriveAttributeValue value in values) {
if (value.Identifier == 0xF7)
hostProgramPagesCount = RawToInt(value.RawValue, value.AttrValue, null);
if (value.Identifier == 0xF8)
ftlProgramPagesCount = RawToInt(value.RawValue, value.AttrValue, null);
if (value.Identifier == 0xC2) {
temperature.Value =
value.RawValue[0] + temperature.Parameters[0].Value;
if (value.RawValue[0] != 0)
ActivateSensor(temperature);
}
}
if (hostProgramPagesCount.HasValue && ftlProgramPagesCount.HasValue) {
if (hostProgramPagesCount.Value > 0)
writeAmplification.Value =
(hostProgramPagesCount.Value + ftlProgramPagesCount) /
hostProgramPagesCount.Value;
else
writeAmplification.Value = 0;
ActivateSensor(writeAmplification);
}
}
} }
} }

View File

@@ -4,7 +4,7 @@
License, v. 2.0. If a copy of the MPL was not distributed with this License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/. file, You can obtain one at http://mozilla.org/MPL/2.0/.
Copyright (C) 2011-2013 Michael Möller <mmoeller@openhardwaremonitor.org> Copyright (C) 2011-2020 Michael Möller <mmoeller@openhardwaremonitor.org>
Copyright (C) 2011 Roland Reinl <roland-reinl@gmx.de> Copyright (C) 2011 Roland Reinl <roland-reinl@gmx.de>
*/ */
@@ -203,6 +203,10 @@ namespace OpenHardwareMonitor.Hardware.HDD {
get { return "Reallocated Sectors Count"; } get { return "Reallocated Sectors Count"; }
} }
public static string ReallocatedNANDBlockCount {
get { return "Reallocated NAND Block Count"; }
}
public static string ReportedUncorrectableErrors { public static string ReportedUncorrectableErrors {
get { return "Reported Uncorrectable Errors"; } get { return "Reported Uncorrectable Errors"; }
} }
@@ -299,6 +303,10 @@ namespace OpenHardwareMonitor.Hardware.HDD {
get { return "Unknown"; } get { return "Unknown"; }
} }
public static string UnusedReserveNANDBlocks {
get { return "Unused Reserve NAND Blocks"; }
}
public static string VibrationDuringWrite { public static string VibrationDuringWrite {
get { return "Vibration During Write"; } get { return "Vibration During Write"; }
} }
@@ -405,7 +413,7 @@ namespace OpenHardwareMonitor.Hardware.HDD {
public static string MediaWearOutIndicator { public static string MediaWearOutIndicator {
get { return "Media Wear Out Indicator"; } get { return "Media Wear Out Indicator"; }
} }
public static string ProgramFailCountChip { public static string ProgramFailCountChip {
get { return "Program Fail Count (Chip)"; } get { return "Program Fail Count (Chip)"; }
@@ -494,5 +502,21 @@ namespace OpenHardwareMonitor.Hardware.HDD {
public static string PowerRecoveryCount { public static string PowerRecoveryCount {
get { return "Power Recovery Count"; } get { return "Power Recovery Count"; }
} }
public static string ErrorCorrectionCount {
get { return "Error Correction Count"; }
}
public static string SuccessfulRAINRecoveryCount {
get { return "Successful RAIN Recovery Count"; }
}
public static string HostProgramNANDPagesCount {
get { return "Host Program NAND Pages Count"; }
}
public static string FTLProgramNANDPagesCount {
get { return "FTL Program NAND Pages Count"; }
}
} }
} }