[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2] i2c: Fix SMBus read transactions to avoid do
From: |
Peter Maydell |
Subject: |
Re: [Qemu-devel] [PATCH v2] i2c: Fix SMBus read transactions to avoid double events |
Date: |
Fri, 21 Oct 2016 18:57:55 +0100 |
On 2 August 2016 at 17:00, <address@hidden> wrote:
> From: Corey Minyard <address@hidden>
>
> Change 2293c27faddf (i2c: implement broadcast write) added broadcast
> capability to the I2C bus, but it broke SMBus read transactions.
> An SMBus read transaction does two i2c_start_transaction() calls
> without an intervening i2c_end_transfer() call. This will
> result in i2c_start_transfer() adding the same device to the
> current_devs list twice, and then the ->event() for the same
> device gets called twice in the second call to i2c_start_transfer(),
> resulting in the smbus code getting confused.
>
> Note that this happens even with pure I2C devices when simulating
> SMBus over I2C.
>
> This fix only scans the bus if the current set of devices is empty.
> This means that the current set of devices stays fixed until
> i2c_end_transfer() is called, which is really what you want.
>
> This also deletes the empty check from the top of i2c_end_transfer().
> It's unnecessary, and it prevents the broadcast variable from being
> set to false at the end of the transaction if no devices were on
> the bus.
>
> Cc: KONRAD Frederic <address@hidden>
> Cc: Alistair Francis <address@hidden>
> Cc: Peter Crosthwaite <address@hidden>
> Cc: Kwon <address@hidden>
> Cc: Peter Maydell <address@hidden>
> Signed-off-by: Corey Minyard <address@hidden>
> Reviewed-by: KONRAD Frederic <address@hidden>
> Tested-by: KONRAD Frederic <address@hidden>
Hi. Did this patch get lost, or was the bug fixed in a different
way instead?
I got here because Coverity complains that the
i2c_start_transfer() calls in smbus.c don't check their
return value. That suggests to me that we'd be better off
having a different function (i2c_restart_transfer() ??)
for the "I know we already did this once, so don't try to
re-determine who to send this to" case, rather than trying to
handle both cases in the same function.
> ---
> hw/i2c/core.c | 32 +++++++++++++++++++-------------
> 1 file changed, 19 insertions(+), 13 deletions(-)
>
> Can we get this in for the next release? SMBus is completely
> broken without it.
Is there an easy test case?
> diff --git a/hw/i2c/core.c b/hw/i2c/core.c
> index abb3efb..8fd329b 100644
> --- a/hw/i2c/core.c
> +++ b/hw/i2c/core.c
> @@ -101,15 +101,25 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address,
> int recv)
> bus->broadcast = true;
> }
>
> - QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
> - DeviceState *qdev = kid->child;
> - I2CSlave *candidate = I2C_SLAVE(qdev);
> - if ((candidate->address == address) || (bus->broadcast)) {
> - node = g_malloc(sizeof(struct I2CNode));
> - node->elt = candidate;
> - QLIST_INSERT_HEAD(&bus->current_devs, node, next);
> - if (!bus->broadcast) {
> - break;
> + /*
> + * If there are already devices in the list, that means we are in
> + * the middle of a transaction and we shouldn't rescan the bus.
> + *
> + * This happens with any SMBus transaction, even on a pure I2C
> + * device. The interface does a transaction start without
> + * terminating the previous transaction.
> + */
> + if (QLIST_EMPTY(&bus->current_devs)) {
> + QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
> + DeviceState *qdev = kid->child;
> + I2CSlave *candidate = I2C_SLAVE(qdev);
> + if ((candidate->address == address) || (bus->broadcast)) {
> + node = g_malloc(sizeof(struct I2CNode));
> + node->elt = candidate;
> + QLIST_INSERT_HEAD(&bus->current_devs, node, next);
> + if (!bus->broadcast) {
> + break;
> + }
> }
> }
> }
> @@ -134,10 +144,6 @@ void i2c_end_transfer(I2CBus *bus)
> I2CSlaveClass *sc;
> I2CNode *node, *next;
>
> - if (QLIST_EMPTY(&bus->current_devs)) {
> - return;
> - }
> -
> QLIST_FOREACH_SAFE(node, &bus->current_devs, next, next) {
> sc = I2C_SLAVE_GET_CLASS(node->elt);
> if (sc->event) {
> --
> 2.7.4
thanks
-- PMM
- Re: [Qemu-devel] [PATCH v2] i2c: Fix SMBus read transactions to avoid double events,
Peter Maydell <=