1- using System ;
2- using System . Diagnostics ;
1+ using System . Diagnostics ;
32using System . Threading ;
43
54namespace OpenHardwareMonitor . Hardware . Motherboard . Lpc . EC ;
@@ -17,7 +16,7 @@ public class WindowsEmbeddedControllerIO : IEmbeddedControllerIO
1716 private const int FailuresBeforeSkip = 20 ;
1817 private const int MaxRetries = 5 ;
1918
20- // implementation
19+ // implementation
2120 private const int WaitSpins = 50 ;
2221 private bool _disposed ;
2322
@@ -33,7 +32,7 @@ public WindowsEmbeddedControllerIO()
3332
3433 public void Read ( ushort [ ] registers , byte [ ] data )
3534 {
36- Trace . Assert ( registers . Length <= data . Length ,
35+ Trace . Assert ( registers . Length <= data . Length ,
3736 "data buffer length has to be greater or equal to the registers array length" ) ;
3837
3938 byte bank = 0 ;
@@ -58,15 +57,8 @@ public void Read(ushort[] registers, byte[] data)
5857 SwitchBank ( prevBank ) ;
5958 }
6059
61- private byte ReadByte ( byte register )
62- {
63- return ReadLoop < byte > ( register , ReadByteOp ) ;
64- }
65-
66- private void WriteByte ( byte register , byte value )
67- {
68- WriteLoop ( register , value , WriteByteOp ) ;
69- }
60+ private byte ReadByte ( byte register ) => ReadLoop < byte > ( register , ReadByteOp ) ;
61+ private void WriteByte ( byte register , byte value ) => WriteLoop ( register , value , WriteByteOp ) ;
7062
7163 public void Dispose ( )
7264 {
@@ -84,7 +76,7 @@ private byte SwitchBank(byte bank)
8476 return previous ;
8577 }
8678
87- private TResult ReadLoop < TResult > ( byte register , ReadOp < TResult > op ) where TResult : new ( )
79+ private static TResult ReadLoop < TResult > ( byte register , ReadOp < TResult > op ) where TResult : new ( )
8880 {
8981 TResult result = new ( ) ;
9082
@@ -99,7 +91,7 @@ private byte SwitchBank(byte bank)
9991 return result ;
10092 }
10193
102- private void WriteLoop < TValue > ( byte register , TValue value , WriteOp < TValue > op )
94+ private static void WriteLoop < TValue > ( byte register , TValue value , WriteOp < TValue > op )
10395 {
10496 for ( int i = 0 ; i < MaxRetries ; i ++ )
10597 {
@@ -110,11 +102,11 @@ private void WriteLoop<TValue>(byte register, TValue value, WriteOp<TValue> op)
110102 }
111103 }
112104
113- private bool WaitForStatus ( Status status , bool isSet )
105+ private static bool WaitForStatus ( Status status , bool isSet )
114106 {
115107 for ( int i = 0 ; i < WaitSpins ; i ++ )
116108 {
117- byte value = ReadIOPort ( Port . Command ) ;
109+ byte value = ReadIoPort ( Port . Command ) ;
118110
119111 if ( ( ( byte ) status & ( ! isSet ? value : ( byte ) ~ value ) ) == 0 )
120112 {
@@ -134,10 +126,31 @@ private bool WaitRead()
134126 return true ;
135127 }
136128
137- if ( WaitForStatus ( Status . OutputBufferFull , true ) )
129+ // Try OBF with reduced timeout
130+ for ( int i = 0 ; i < MaxRetries ; i ++ )
138131 {
139- _waitReadFailures = 0 ;
140- return true ;
132+ byte status = ReadIoPort ( Port . Command ) ;
133+ if ( ( status & ( byte ) Status . OutputBufferFull ) != 0 )
134+ {
135+ _waitReadFailures = 0 ;
136+ return true ;
137+ }
138+
139+ Thread . Sleep ( 1 ) ;
140+ }
141+
142+ // ASUS workaround: Wait for IBF to clear instead of OBF
143+ // Testing on Z170 Pro Gaming shows IBF clears in 1-3ms when data is ready
144+ for ( int i = 0 ; i < WaitSpins ; i ++ )
145+ {
146+ byte status = ReadIoPort ( Port . Command ) ;
147+ if ( ( status & ( byte ) Status . InputBufferFull ) == 0 )
148+ {
149+ _waitReadFailures = 0 ;
150+ return true ;
151+ }
152+
153+ Thread . Sleep ( 1 ) ;
141154 }
142155
143156 _waitReadFailures ++ ;
@@ -149,14 +162,49 @@ private bool WaitWrite()
149162 return WaitForStatus ( Status . InputBufferFull , false ) ;
150163 }
151164
152- private byte ReadIOPort ( Port port )
165+ private static byte ReadIoPort ( Port port ) => Ring0 . ReadIoPort ( ( byte ) port ) ;
166+
167+ private static void WriteIoPort ( Port port , byte datum ) => Ring0 . WriteIoPort ( ( byte ) port , datum ) ;
168+
169+ protected bool ReadByteOp ( byte register , out byte value )
153170 {
154- return Ring0 . ReadIoPort ( ( uint ) port ) ;
171+ if ( WaitWrite ( ) )
172+ {
173+ WriteIoPort ( Port . Command , ( byte ) Command . Read ) ;
174+
175+ if ( WaitWrite ( ) )
176+ {
177+ WriteIoPort ( Port . Data , register ) ;
178+
179+ if ( WaitWrite ( ) && WaitRead ( ) )
180+ {
181+ value = ReadIoPort ( Port . Data ) ;
182+ return true ;
183+ }
184+ }
185+ }
186+
187+ value = 0 ;
188+ return false ;
155189 }
156190
157- private void WriteIOPort ( Port port , byte datum )
191+ protected bool WriteByteOp ( byte register , byte value )
158192 {
159- Ring0 . WriteIoPort ( ( uint ) port , datum ) ;
193+ if ( WaitWrite ( ) )
194+ {
195+ WriteIoPort ( Port . Command , ( byte ) Command . Write ) ;
196+ if ( WaitWrite ( ) )
197+ {
198+ WriteIoPort ( Port . Data , register ) ;
199+ if ( WaitWrite ( ) )
200+ {
201+ WriteIoPort ( Port . Data , value ) ;
202+ return true ;
203+ }
204+ }
205+ }
206+
207+ return false ;
160208 }
161209
162210 public class BusMutexLockingFailedException : EmbeddedController . IOException
@@ -195,49 +243,4 @@ private enum Status : byte
195243 SciEventPending = 0x20 , // SCI_EVT
196244 SmiEventPending = 0x40 // SMI_EVT
197245 }
198-
199- #region Read/Write ops
200-
201- protected bool ReadByteOp ( byte register , out byte value )
202- {
203- if ( WaitWrite ( ) )
204- {
205- WriteIOPort ( Port . Command , ( byte ) Command . Read ) ;
206-
207- if ( WaitWrite ( ) )
208- {
209- WriteIOPort ( Port . Data , register ) ;
210-
211- if ( WaitWrite ( ) && WaitRead ( ) )
212- {
213- value = ReadIOPort ( Port . Data ) ;
214- return true ;
215- }
216- }
217- }
218-
219- value = 0 ;
220- return false ;
221- }
222-
223- protected bool WriteByteOp ( byte register , byte value )
224- {
225- if ( WaitWrite ( ) )
226- {
227- WriteIOPort ( Port . Command , ( byte ) Command . Write ) ;
228- if ( WaitWrite ( ) )
229- {
230- WriteIOPort ( Port . Data , register ) ;
231- if ( WaitWrite ( ) )
232- {
233- WriteIOPort ( Port . Data , value ) ;
234- return true ;
235- }
236- }
237- }
238-
239- return false ;
240- }
241-
242- #endregion
243246}
0 commit comments