On Sun, Oct 24, 2010 at 3:34 PM, Avi Kivity <avi@xxxxxxxxxx> wrote: > The current ioport callbacks are not type-safe, in that they accept an "opaque" > pointer as an argument whose type must match the argument to the registration > function; this is not checked by the compiler. > > This patch adds an alternative that is type-safe. ÂInstead of an opaque > argument, both registation and the callback use a new IOPort type. ÂThe > callback then uses container_of() to access its main structures. > > Currently the old and new methods exist side by side; once the old way is gone, > we can also save a bunch of memory since the new method requires one pointer > per ioport instead of 6. > > Signed-off-by: Avi Kivity <avi@xxxxxxxxxx> If we are going to change the interface, let's do it so that it's useful for other uses too: http://article.gmane.org/gmane.comp.emulators.qemu/76984 > --- > Âioport.c | Â 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > Âioport.h | Â 16 +++++++++++++++ > Â2 files changed, 80 insertions(+), 0 deletions(-) > > diff --git a/ioport.c b/ioport.c > index ec3dc65..47eafc3 100644 > --- a/ioport.c > +++ b/ioport.c > @@ -174,6 +174,70 @@ int register_ioport_write(pio_addr_t start, int length, int size, > Â Â return 0; > Â} > > +static uint32_t ioport_readb_thunk(void *opaque, uint32_t addr) > +{ > + Â ÂIOPort *ioport = opaque; > + > + Â Âreturn ioport->ops->readb(ioport, addr); > +} > + > +static uint32_t ioport_readw_thunk(void *opaque, uint32_t addr) > +{ > + Â ÂIOPort *ioport = opaque; > + > + Â Âreturn ioport->ops->readw(ioport, addr); > +} > + > +static uint32_t ioport_readl_thunk(void *opaque, uint32_t addr) > +{ > + Â ÂIOPort *ioport = opaque; > + > + Â Âreturn ioport->ops->readl(ioport, addr); > +} > + > +static void ioport_writeb_thunk(void *opaque, uint32_t addr, uint32_t data) > +{ > + Â ÂIOPort *ioport = opaque; > + > + Â Âreturn ioport->ops->writeb(ioport, addr, data); > +} > + > +static void ioport_writew_thunk(void *opaque, uint32_t addr, uint32_t data) > +{ > + Â ÂIOPort *ioport = opaque; > + > + Â Âreturn ioport->ops->writew(ioport, addr, data); > +} > + > +static void ioport_writel_thunk(void *opaque, uint32_t addr, uint32_t data) > +{ > + Â ÂIOPort *ioport = opaque; > + > + Â Âreturn ioport->ops->writel(ioport, addr, data); > +} > + > +void ioport_register(IOPort *ioport, pio_addr_t start, pio_addr_t length) > +{ > + Â Âif (ioport->ops->readb) { > + Â Â Â Âregister_ioport_read(start, length, 1, ioport_readb_thunk, ioport); > + Â Â} > + Â Âif (ioport->ops->readw) { > + Â Â Â Âregister_ioport_read(start, length, 2, ioport_readw_thunk, ioport); > + Â Â} > + Â Âif (ioport->ops->readl) { > + Â Â Â Âregister_ioport_read(start, length, 4, ioport_readl_thunk, ioport); > + Â Â} > + Â Âif (ioport->ops->writeb) { > + Â Â Â Âregister_ioport_write(start, length, 1, ioport_writeb_thunk, ioport); > + Â Â} > + Â Âif (ioport->ops->writew) { > + Â Â Â Âregister_ioport_write(start, length, 2, ioport_writew_thunk, ioport); > + Â Â} > + Â Âif (ioport->ops->writel) { > + Â Â Â Âregister_ioport_write(start, length, 4, ioport_writel_thunk, ioport); > + Â Â} > +} > + > Âvoid isa_unassign_ioport(pio_addr_t start, int length) > Â{ > Â Â int i; > diff --git a/ioport.h b/ioport.h > index 3d3c8a3..8036e59 100644 > --- a/ioport.h > +++ b/ioport.h > @@ -36,6 +36,22 @@ typedef uint32_t pio_addr_t; > Âtypedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data); > Âtypedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address); > > +struct IOPort; > + > +typedef struct IOPortOps { > + Â Âuint32_t (*readb)(struct IOPort *ioport, pio_addr_t addr); > + Â Âuint32_t (*readw)(struct IOPort *ioport, pio_addr_t addr); > + Â Âuint32_t (*readl)(struct IOPort *ioport, pio_addr_t addr); > + Â Âvoid (*writeb)(struct IOPort *ioport, pio_addr_t addr, uint32_t data); > + Â Âvoid (*writew)(struct IOPort *ioport, pio_addr_t addr, uint32_t data); > + Â Âvoid (*writel)(struct IOPort *ioport, pio_addr_t addr, uint32_t data); > +} IOPortOps; > + > +typedef struct IOPort { > + Â ÂIOPortOps *ops; const -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html