diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Nct677X.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Nct677X.cs index 48390ed..ee0204d 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Nct677X.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Nct677X.cs @@ -817,11 +817,36 @@ internal class Nct677X : ISuperIO } byte page = (byte)(address >> 8); - byte index = (byte)(address & 0xFF); - Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, EC_SPACE_PAGE_SELECT); + byte index = (byte)(address & 0xFF); + + //wait for access, access == EC_SPACE_PAGE_SELECT + //timeout: after 500ms, abort and force access + byte access; + + DateTime timeout = DateTime.UtcNow.AddMilliseconds(500); + while (true) + { + access = Ring0.ReadIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET); + if (access == EC_SPACE_PAGE_SELECT || DateTime.UtcNow > timeout) + break; + + System.Threading.Thread.Sleep(1); + } + + if (access != EC_SPACE_PAGE_SELECT) + { + // Failed to gain access: force register access + Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, EC_SPACE_PAGE_SELECT); + } + Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, page); Ring0.WriteIoPort(_port + EC_SPACE_INDEX_REGISTER_OFFSET, index); - return Ring0.ReadIoPort(_port + EC_SPACE_DATA_REGISTER_OFFSET); + byte result = Ring0.ReadIoPort(_port + EC_SPACE_DATA_REGISTER_OFFSET); + + //free access for other instances + Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, EC_SPACE_PAGE_SELECT); + + return result; } private void WriteByte(ushort address, byte value) @@ -838,11 +863,34 @@ internal class Nct677X : ISuperIO else { byte page = (byte)(address >> 8); - byte index = (byte)(address & 0xFF); - Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, EC_SPACE_PAGE_SELECT); + byte index = (byte)(address & 0xFF); + + //wait for access, access == EC_SPACE_PAGE_SELECT + //timeout: after 500ms, abort and force access + byte access; + + DateTime timeout = DateTime.UtcNow.AddMilliseconds(500); + while (true) + { + access = Ring0.ReadIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET); + if (access == EC_SPACE_PAGE_SELECT || DateTime.UtcNow > timeout) + break; + + System.Threading.Thread.Sleep(1); + } + + if (access != EC_SPACE_PAGE_SELECT) + { + // Failed to gain access: force register access + Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, EC_SPACE_PAGE_SELECT); + } + Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, page); Ring0.WriteIoPort(_port + EC_SPACE_INDEX_REGISTER_OFFSET, index); Ring0.WriteIoPort(_port + EC_SPACE_DATA_REGISTER_OFFSET, value); + + //free access for other instances + Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, EC_SPACE_PAGE_SELECT); } }