mirror of
https://github.com/openhardwaremonitor/openhardwaremonitor
synced 2025-09-02 15:25:22 +00:00
Added additional smart attribute identification and a write amplification sensor for Sandforce based SSDs.
This commit is contained in:
@@ -183,6 +183,7 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
settings);
|
settings);
|
||||||
|
|
||||||
sensors.Add(attribute, sensor);
|
sensors.Add(attribute, sensor);
|
||||||
|
ActivateSensor(sensor);
|
||||||
sensorTypeAndChannels.Add(pair);
|
sensorTypeAndChannels.Add(pair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,13 +193,7 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
get { return HardwareType.HDD; }
|
get { return HardwareType.HDD; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ISensor[] Sensors {
|
public virtual void UpdateAdditionalSensors(DriveAttributeValue[] values) {}
|
||||||
get {
|
|
||||||
Sensor[] array = new Sensor[sensors.Count];
|
|
||||||
sensors.Values.CopyTo(array, 0);
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update() {
|
public override void Update() {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
@@ -212,7 +207,9 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
sensor.Value = attribute.ConvertValue(value);
|
sensor.Value = attribute.ConvertValue(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateAdditionalSensors(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
|
@@ -44,30 +44,58 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
|
|
||||||
private static readonly IEnumerable<SmartAttribute> smartAttributes =
|
private static readonly IEnumerable<SmartAttribute> smartAttributes =
|
||||||
new List<SmartAttribute> {
|
new List<SmartAttribute> {
|
||||||
new SmartAttribute(0x05, SmartNames.RetiredBlockCount),
|
new SmartAttribute(0x01, SmartNames.RawReadErrorRate),
|
||||||
|
new SmartAttribute(0x05, SmartNames.RetiredBlockCount, 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(0xAB, SmartNames.ProgramFailCount),
|
new SmartAttribute(0xAB, SmartNames.ProgramFailCount, RawToInt),
|
||||||
new SmartAttribute(0xAC, SmartNames.EraseFailCount),
|
new SmartAttribute(0xAC, SmartNames.EraseFailCount, RawToInt),
|
||||||
new SmartAttribute(0xAE, SmartNames.UnexpectedPowerLossCount),
|
new SmartAttribute(0xAE, SmartNames.UnexpectedPowerLossCount, RawToInt),
|
||||||
new SmartAttribute(0xB1, SmartNames.WearRangeDelta),
|
new SmartAttribute(0xB1, SmartNames.WearRangeDelta, RawToInt),
|
||||||
new SmartAttribute(0xB5, SmartNames.AlternativeProgramFailCount),
|
new SmartAttribute(0xB5, SmartNames.AlternativeProgramFailCount, RawToInt),
|
||||||
new SmartAttribute(0xB6, SmartNames.AlternativeEraseFailCount),
|
new SmartAttribute(0xB6, SmartNames.AlternativeEraseFailCount, RawToInt),
|
||||||
|
new SmartAttribute(0xBB, SmartNames.UncorrectableErrorCount, RawToInt),
|
||||||
|
new SmartAttribute(0xC2, SmartNames.Temperature,
|
||||||
|
(byte[] raw, byte value) => { return value; }),
|
||||||
new SmartAttribute(0xC3, SmartNames.UnrecoverableEcc),
|
new SmartAttribute(0xC3, SmartNames.UnrecoverableEcc),
|
||||||
new SmartAttribute(0xC4, SmartNames.ReallocationEventCount),
|
new SmartAttribute(0xC4, SmartNames.ReallocationEventCount, RawToInt),
|
||||||
new SmartAttribute(0xE7, SmartNames.RemainingLife,
|
new SmartAttribute(0xE7, SmartNames.RemainingLife, null,
|
||||||
null, SensorType.Level, 0),
|
SensorType.Level, 0),
|
||||||
new SmartAttribute(0xF1, SmartNames.HostWrites,
|
new SmartAttribute(0xE9, SmartNames.ControllerWritesToNAND, RawToInt,
|
||||||
(byte[] r, byte v) => { return RawToInt(r, v); },
|
|
||||||
SensorType.Data, 0),
|
SensorType.Data, 0),
|
||||||
new SmartAttribute(0xF2, SmartNames.HostReads,
|
new SmartAttribute(0xEA, SmartNames.HostWritesToController, RawToInt,
|
||||||
(byte[] r, byte v) => { return RawToInt(r, v); },
|
SensorType.Data, 1),
|
||||||
SensorType.Data, 1)
|
new SmartAttribute(0xF1, SmartNames.HostWrites, RawToInt,
|
||||||
|
SensorType.Data, 1),
|
||||||
|
new SmartAttribute(0xF2, SmartNames.HostReads, RawToInt,
|
||||||
|
SensorType.Data, 2)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private Sensor writeAmplification;
|
||||||
|
|
||||||
public SSDSandforce(ISmart smart, string name, string firmwareRevision,
|
public SSDSandforce(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.writeAmplification = new Sensor("Write Amplification", 1,
|
||||||
|
SensorType.Level, this, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateAdditionalSensors(DriveAttributeValue[] values) {
|
||||||
|
float? controllerWritesToNAND = null;
|
||||||
|
float? hostWritesToController = null;
|
||||||
|
foreach (DriveAttributeValue value in values) {
|
||||||
|
if (value.Identifier == 0xE9)
|
||||||
|
controllerWritesToNAND = RawToInt(value.RawValue, value.AttrValue);
|
||||||
|
|
||||||
|
if (value.Identifier == 0xEA)
|
||||||
|
hostWritesToController = RawToInt(value.RawValue, value.AttrValue);
|
||||||
|
}
|
||||||
|
if (controllerWritesToNAND.HasValue && hostWritesToController.HasValue) {
|
||||||
|
writeAmplification.Value = 100 *
|
||||||
|
controllerWritesToNAND.Value / hostWritesToController.Value;
|
||||||
|
ActivateSensor(writeAmplification);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -493,5 +493,17 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
public static string ExceptionModeStatus {
|
public static string ExceptionModeStatus {
|
||||||
get { return "Exception Mode Status"; }
|
get { return "Exception Mode Status"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string ControllerWritesToNAND {
|
||||||
|
get { return "Controller Writes to NAND"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string HostWritesToController {
|
||||||
|
get { return "Host Writes to Controller"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string RawReadErrorRate {
|
||||||
|
get { return "Raw Read Error Rate"; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -37,5 +37,5 @@
|
|||||||
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
[assembly: AssemblyVersion("0.4.0.1")]
|
[assembly: AssemblyVersion("0.4.0.2")]
|
||||||
[assembly: AssemblyInformationalVersion("0.4.0.1 Alpha")]
|
[assembly: AssemblyInformationalVersion("0.4.0.2 Alpha")]
|
Reference in New Issue
Block a user