From 41742927ee37527462a13160380860653d4f1c84 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 2 Jul 2019 17:38:44 +0100 Subject: hw/i2c/bitbang_i2c: Use in-place rather than malloc'd bitbang_i2c_interface struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the bitbang_i2c_init() function allocates a bitbang_i2c_interface struct which it returns. This is unfortunate because it means that if the function is used from a DeviceState init method then the memory will be leaked by an "init then delete" cycle, as used by the qmp/hmp commands that list device properties. Since three out of four of the uses of this function are in device init methods, switch the function to do an in-place initialization of a struct that can be embedded in the device state struct of the caller. This fixes LeakSanitizer leak warnings that have appeared in the patchew configuration (which only tries to run the sanitizers for the x86_64-softmmu target) now that we use the bitbang-i2c code in an x86-64 config. Signed-off-by: Peter Maydell Reviewed-by: BALATON Zoltan Tested-by: BALATON Zoltan Acked-by: David Gibson Reviewed-by: Philippe Mathieu-Daudé Message-id: 20190702163844.20458-1-peter.maydell@linaro.org Signed-off-by: Gerd Hoffmann --- hw/i2c/bitbang_i2c.c | 47 ++++------------------------------------------- hw/i2c/ppc4xx_i2c.c | 6 +++--- hw/i2c/versatile_i2c.c | 8 ++++---- 3 files changed, 11 insertions(+), 50 deletions(-) (limited to 'hw/i2c') diff --git a/hw/i2c/bitbang_i2c.c b/hw/i2c/bitbang_i2c.c index 3cb0509b02..60c7a9be0b 100644 --- a/hw/i2c/bitbang_i2c.c +++ b/hw/i2c/bitbang_i2c.c @@ -25,39 +25,6 @@ do { printf("bitbang_i2c: " fmt , ## __VA_ARGS__); } while (0) #define DPRINTF(fmt, ...) do {} while(0) #endif -typedef enum bitbang_i2c_state { - STOPPED = 0, - SENDING_BIT7, - SENDING_BIT6, - SENDING_BIT5, - SENDING_BIT4, - SENDING_BIT3, - SENDING_BIT2, - SENDING_BIT1, - SENDING_BIT0, - WAITING_FOR_ACK, - RECEIVING_BIT7, - RECEIVING_BIT6, - RECEIVING_BIT5, - RECEIVING_BIT4, - RECEIVING_BIT3, - RECEIVING_BIT2, - RECEIVING_BIT1, - RECEIVING_BIT0, - SENDING_ACK, - SENT_NACK -} bitbang_i2c_state; - -struct bitbang_i2c_interface { - I2CBus *bus; - bitbang_i2c_state state; - int last_data; - int last_clock; - int device_out; - uint8_t buffer; - int current_addr; -}; - static void bitbang_i2c_enter_stop(bitbang_i2c_interface *i2c) { DPRINTF("STOP\n"); @@ -184,18 +151,12 @@ int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level) abort(); } -bitbang_i2c_interface *bitbang_i2c_init(I2CBus *bus) +void bitbang_i2c_init(bitbang_i2c_interface *s, I2CBus *bus) { - bitbang_i2c_interface *s; - - s = g_malloc0(sizeof(bitbang_i2c_interface)); - s->bus = bus; s->last_data = 1; s->last_clock = 1; s->device_out = 1; - - return s; } /* GPIO interface. */ @@ -207,7 +168,7 @@ typedef struct GPIOI2CState { SysBusDevice parent_obj; MemoryRegion dummy_iomem; - bitbang_i2c_interface *bitbang; + bitbang_i2c_interface bitbang; int last_level; qemu_irq out; } GPIOI2CState; @@ -216,7 +177,7 @@ static void bitbang_i2c_gpio_set(void *opaque, int irq, int level) { GPIOI2CState *s = opaque; - level = bitbang_i2c_set(s->bitbang, irq, level); + level = bitbang_i2c_set(&s->bitbang, irq, level); if (level != s->last_level) { s->last_level = level; qemu_set_irq(s->out, level); @@ -234,7 +195,7 @@ static void gpio_i2c_init(Object *obj) sysbus_init_mmio(sbd, &s->dummy_iomem); bus = i2c_init_bus(dev, "i2c"); - s->bitbang = bitbang_i2c_init(bus); + bitbang_i2c_init(&s->bitbang, bus); qdev_init_gpio_in(dev, bitbang_i2c_gpio_set, 2); qdev_init_gpio_out(dev, &s->out, 1); diff --git a/hw/i2c/ppc4xx_i2c.c b/hw/i2c/ppc4xx_i2c.c index 5fb4f86c38..462729db4e 100644 --- a/hw/i2c/ppc4xx_i2c.c +++ b/hw/i2c/ppc4xx_i2c.c @@ -311,9 +311,9 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, case IIC_DIRECTCNTL: i2c->directcntl = value & (IIC_DIRECTCNTL_SDAC & IIC_DIRECTCNTL_SCLC); i2c->directcntl |= (value & IIC_DIRECTCNTL_SCLC ? 1 : 0); - bitbang_i2c_set(i2c->bitbang, BITBANG_I2C_SCL, + bitbang_i2c_set(&i2c->bitbang, BITBANG_I2C_SCL, i2c->directcntl & IIC_DIRECTCNTL_MSCL); - i2c->directcntl |= bitbang_i2c_set(i2c->bitbang, BITBANG_I2C_SDA, + i2c->directcntl |= bitbang_i2c_set(&i2c->bitbang, BITBANG_I2C_SDA, (value & IIC_DIRECTCNTL_SDAC) != 0) << 1; break; default: @@ -347,7 +347,7 @@ static void ppc4xx_i2c_init(Object *o) sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq); s->bus = i2c_init_bus(DEVICE(s), "i2c"); - s->bitbang = bitbang_i2c_init(s->bus); + bitbang_i2c_init(&s->bitbang, s->bus); } static void ppc4xx_i2c_class_init(ObjectClass *klass, void *data) diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c index 24b6e36b6d..1ac2a6f59a 100644 --- a/hw/i2c/versatile_i2c.c +++ b/hw/i2c/versatile_i2c.c @@ -35,7 +35,7 @@ typedef struct VersatileI2CState { SysBusDevice parent_obj; MemoryRegion iomem; - bitbang_i2c_interface *bitbang; + bitbang_i2c_interface bitbang; int out; int in; } VersatileI2CState; @@ -70,8 +70,8 @@ static void versatile_i2c_write(void *opaque, hwaddr offset, qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%x\n", __func__, (int)offset); } - bitbang_i2c_set(s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0); - s->in = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0); + bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0); + s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0); } static const MemoryRegionOps versatile_i2c_ops = { @@ -88,7 +88,7 @@ static void versatile_i2c_init(Object *obj) I2CBus *bus; bus = i2c_init_bus(dev, "i2c"); - s->bitbang = bitbang_i2c_init(bus); + bitbang_i2c_init(&s->bitbang, bus); memory_region_init_io(&s->iomem, obj, &versatile_i2c_ops, s, "versatile_i2c", 0x1000); sysbus_init_mmio(sbd, &s->iomem); -- cgit v1.2.3