diff options
| author | Titus Rwantare <titusr@google.com> | 2023-10-23 23:46:40 +0000 |
|---|---|---|
| committer | Philippe Mathieu-Daudé <philmd@linaro.org> | 2023-11-07 13:08:48 +0100 |
| commit | cfb0884c6f941977db1e0ce53ac659a8428e4e48 (patch) | |
| tree | 53e15756068a300146595076aed41c37c7d5cd1c /hw/i2c | |
| parent | cc610857bbd3551f4b86ae2299336b5d9aa0db2b (diff) | |
| download | focaccia-qemu-cfb0884c6f941977db1e0ce53ac659a8428e4e48.tar.gz focaccia-qemu-cfb0884c6f941977db1e0ce53ac659a8428e4e48.zip | |
hw/i2c: pmbus add support for block receive
PMBus devices can send and receive variable length data using the block read and write format, with the first byte in the payload denoting the length. This is mostly used for strings and on-device logs. Devices can respond to a block read with an empty string. Reviewed-by: Hao Wu <wuhaotsh@google.com> Acked-by: Corey Minyard <cminyard@mvista.com> Signed-off-by: Titus Rwantare <titusr@google.com> Message-ID: <20231023-staging-pmbus-v3-v4-1-07a8cb7cd20a@google.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Diffstat (limited to 'hw/i2c')
| -rw-r--r-- | hw/i2c/pmbus_device.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c index cef51663d0..ea15490720 100644 --- a/hw/i2c/pmbus_device.c +++ b/hw/i2c/pmbus_device.c @@ -102,7 +102,6 @@ void pmbus_send_string(PMBusDevice *pmdev, const char *data) } size_t len = strlen(data); - g_assert(len > 0); g_assert(len + pmdev->out_buf_len < SMBUS_DATA_MAX_LEN); pmdev->out_buf[len + pmdev->out_buf_len] = len; @@ -112,6 +111,35 @@ void pmbus_send_string(PMBusDevice *pmdev, const char *data) pmdev->out_buf_len += len + 1; } +uint8_t pmbus_receive_block(PMBusDevice *pmdev, uint8_t *dest, size_t len) +{ + /* dest may contain data from previous writes */ + memset(dest, 0, len); + + /* Exclude command code from return value */ + pmdev->in_buf++; + pmdev->in_buf_len--; + + /* The byte after the command code denotes the length */ + uint8_t sent_len = pmdev->in_buf[0]; + + if (sent_len != pmdev->in_buf_len - 1) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: length mismatch. Expected %d bytes, got %d bytes\n", + __func__, sent_len, pmdev->in_buf_len - 1); + } + + /* exclude length byte */ + pmdev->in_buf++; + pmdev->in_buf_len--; + + if (pmdev->in_buf_len < len) { + len = pmdev->in_buf_len; + } + memcpy(dest, pmdev->in_buf, len); + return len; +} + static uint64_t pmbus_receive_uint(PMBusDevice *pmdev) { |