aboutsummaryrefslogtreecommitdiff
path: root/ioport.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2012-03-05 17:36:19 +0200
committerAvi Kivity <avi@redhat.com>2012-03-05 17:36:19 +0200
commitc5b703ac2073de8b968ef058793db0294f6a2979 (patch)
tree6ef106e5b7c3489709ded94d8f5699b8364e2690 /ioport.c
parent2aeabc08179553e1a7eed6cf26286c3efc06ee0b (diff)
downloadqemu-arm-c5b703ac2073de8b968ef058793db0294f6a2979.tar.gz
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>
Diffstat (limited to 'ioport.c')
-rw-r--r--ioport.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/ioport.c b/ioport.c
index 8a474d3492..78a3b890fb 100644
--- a/ioport.c
+++ b/ioport.c
@@ -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;