diff mbox series

p8-i2c: Fix random data corruption

Message ID 20170830123606.8490-1-oohall@gmail.com
State Accepted
Headers show
Series p8-i2c: Fix random data corruption | expand

Commit Message

Oliver O'Halloran Aug. 30, 2017, 12:36 p.m. UTC
While waiting for the OCC to signal that it has finished using the I2C
master we put the master into the, poorly named, occache_dis state.
While in this state the transaction hasn't been started, but
p8_i2c_check_status() will only skip it's checks when the master is in
the idle state. Any action that checks that cranks the I2C state machine
(interrupt, poll, etc) will call p8_i2c_check_status() and since the
master is not idle, it will check the status register, see the
transaction complete flag set and complete the i2c request without
actually doing anything.

If the transaction was a I2C read, the resulting output will be a
zeroed data buffer.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
 hw/p8-i2c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Stewart Smith Aug. 31, 2017, 4:08 a.m. UTC | #1
Oliver O'Halloran <oohall@gmail.com> writes:
> While waiting for the OCC to signal that it has finished using the I2C
> master we put the master into the, poorly named, occache_dis state.
> While in this state the transaction hasn't been started, but
> p8_i2c_check_status() will only skip it's checks when the master is in
> the idle state. Any action that checks that cranks the I2C state machine
> (interrupt, poll, etc) will call p8_i2c_check_status() and since the
> master is not idle, it will check the status register, see the
> transaction complete flag set and complete the i2c request without
> actually doing anything.
>
> If the transaction was a I2C read, the resulting output will be a
> zeroed data buffer.
>
> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>

Aren't state machines fun! Merged in as
b73d15fa328ee242102dce4f7cda1cc650c787aa
diff mbox series

Patch

diff --git a/hw/p8-i2c.c b/hw/p8-i2c.c
index a6274171debb..9cc016fe98a5 100644
--- a/hw/p8-i2c.c
+++ b/hw/p8-i2c.c
@@ -892,7 +892,7 @@  static void  p8_i2c_check_status(struct p8_i2c_master *master)
 	/* If we are idle, just return, we'll catch error conditions
 	 * when we next try to enqueue a request
 	 */
-	if (master->state == state_idle)
+	if (master->state == state_idle || master->state == state_occache_dis)
 		return;
 
 	/* Read status register */