diff options
author | Avi Kivity <avi@redhat.com> | 2012-03-05 17:36:19 +0200 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-03-05 17:36:19 +0200 |
commit | c5b703ac2073de8b968ef058793db0294f6a2979 (patch) | |
tree | 6ef106e5b7c3489709ded94d8f5699b8364e2690 | |
parent | 2aeabc08179553e1a7eed6cf26286c3efc06ee0b (diff) | |
download | qemu-c5b703ac2073de8b968ef058793db0294f6a2979.zip |
ioport: add destructor method to IORange
Previously all callers had a containing object with a destructor that
could be used to trigger cleanup of the IORange objects (typically
just freeing the containing object), but a forthcoming memory API
change doesn't fit this pattern. Rather than setting up a new global
table, extend the ioport system to support destructors.
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | ioport.c | 15 | ||||
-rw-r--r-- | ioport.h | 1 | ||||
-rw-r--r-- | iorange.h | 1 |
3 files changed, 17 insertions, 0 deletions
@@ -52,6 +52,7 @@ static void *ioport_opaque[MAX_IOPORTS]; static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; +static IOPortDestructor *ioport_destructor_table[MAX_IOPORTS]; static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl; static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel; @@ -225,6 +226,15 @@ static void ioport_writel_thunk(void *opaque, uint32_t addr, uint32_t data) ioport->ops->write(ioport, addr - ioport->base, 4, data); } +static void iorange_destructor_thunk(void *opaque) +{ + IORange *iorange = opaque; + + if (iorange->ops->destructor) { + iorange->ops->destructor(iorange); + } +} + void ioport_register(IORange *ioport) { register_ioport_read(ioport->base, ioport->len, 1, @@ -239,12 +249,17 @@ void ioport_register(IORange *ioport) ioport_writew_thunk, ioport); register_ioport_write(ioport->base, ioport->len, 4, ioport_writel_thunk, ioport); + ioport_destructor_table[ioport->base] = iorange_destructor_thunk; } void isa_unassign_ioport(pio_addr_t start, int length) { int i; + if (ioport_destructor_table[start]) { + ioport_destructor_table[start](ioport_opaque[start]); + ioport_destructor_table[start] = NULL; + } for(i = start; i < start + length; i++) { ioport_read_table[0][i] = NULL; ioport_read_table[1][i] = NULL; @@ -36,6 +36,7 @@ typedef uint32_t pio_addr_t; /* These should really be in isa.h, but are here to make pc.h happy. */ typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data); typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address); +typedef void (IOPortDestructor)(void *opaque); void ioport_register(IORange *iorange); int register_ioport_read(pio_addr_t start, int length, int size, @@ -11,6 +11,7 @@ struct IORangeOps { uint64_t *data); void (*write)(IORange *iorange, uint64_t offset, unsigned width, uint64_t data); + void (*destructor)(IORange *iorange); }; struct IORange { |