]> git.proxmox.com Git - mirror_qemu.git/commitdiff
ioport: add destructor method to IORange
authorAvi Kivity <avi@redhat.com>
Mon, 5 Mar 2012 15:36:19 +0000 (17:36 +0200)
committerAvi Kivity <avi@redhat.com>
Mon, 5 Mar 2012 15:36:19 +0000 (17:36 +0200)
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>
ioport.c
ioport.h
iorange.h

index 8a474d34928a2e1a6109afd422364f0a983ca0d2..78a3b890fbe887d99d124c5abd2f23190ab6d262 100644 (file)
--- 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;
index ab29c89fb3ac6bbe72b2b622172cb9ef7c462e62..23441cba088d3e865e7d49889100df1714cc5565 100644 (file)
--- a/ioport.h
+++ b/ioport.h
@@ -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,
index 97831683f02c96dd595886a1526b0c3a1d8b268f..cd980a8312a83590f0dfeea47ad2ce52e187ea3d 100644 (file)
--- a/iorange.h
+++ b/iorange.h
@@ -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 {