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]> --- 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 e2e1e0e945..8befc27895 100644 --- a/hw/i2c/pmbus_device.c +++ b/hw/i2c/pmbus_device.c @@ -1284,6 +1284,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 5ae8206234..726e475938 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.55.0.rc2.803.g1fd1e6609c-goog
