From: titusr <[email protected]>

Generally we expect a PMBus sensor to issue writes after all pending
reads have completed. If a data read needs to be resumed, this state can
be tracked in the device model and the pending data placed in the output
buffer.

Signed-off-by: Titus Rwantare <[email protected]>
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Message-id: [email protected]
Signed-off-by: Peter Maydell <[email protected]>
---
 hw/i2c/pmbus_device.c      | 10 ++++++++++
 tests/qtest/adm1266-test.c | 10 ++++++----
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
index b1f9843f52e..1ca117bd3c1 100644
--- a/hw/i2c/pmbus_device.c
+++ b/hw/i2c/pmbus_device.c
@@ -1245,6 +1245,16 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t 
*buf, uint8_t len)
     pmdev->in_buf_len = len;
     pmdev->in_buf = buf;
 
+    /* clear the output buffer on any new write transaction */
+    if (pmdev->out_buf_len != 0) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: previous read was not completed, %d bytes 
dropped\n",
+                      __func__, pmdev->out_buf_len);
+
+        pmdev->out_buf_len = 0;
+        memset(pmdev->out_buf, 0, sizeof(pmdev->out_buf));
+    }
+
     pmdev->code = buf[0]; /* PMBus command code */
 
     if (pmdev->code == PMBUS_CLEAR_FAULTS) {
diff --git a/tests/qtest/adm1266-test.c b/tests/qtest/adm1266-test.c
index 5ae82062342..726e4759380 100644
--- a/tests/qtest/adm1266-test.c
+++ b/tests/qtest/adm1266-test.c
@@ -48,11 +48,13 @@
 static void compare_string(QI2CDevice *i2cdev, uint8_t reg,
                            const char *test_str)
 {
-    uint8_t len = i2c_get8(i2cdev, reg);
-    char i2c_str[SMBUS_DATA_MAX_LEN] = {0};
+    uint8_t expected_len = strlen(test_str);
+    uint8_t resp[SMBUS_DATA_MAX_LEN] = {0};
 
-    i2c_read_block(i2cdev, reg, (uint8_t *)i2c_str, len);
-    g_assert_cmpstr(i2c_str, ==, test_str);
+    g_assert(expected_len + 1 < SMBUS_DATA_MAX_LEN);
+    i2c_read_block(i2cdev, reg, resp, expected_len + 1);
+    g_assert_cmpint(resp[0], ==, expected_len);
+    g_assert_cmpstr((char *)resp + 1, ==, test_str);
 }
 
 static void write_and_compare_string(QI2CDevice *i2cdev, uint8_t reg,
-- 
2.43.0


Reply via email to