public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Marcelo Tosatti <mtosatti@redhat.com>
To: Avi Kivity <avi@qumranet.com>, Anthony Liguori <aliguori@us.ibm.com>
Cc: kvm-devel <kvm-devel@lists.sourceforge.net>
Subject: [patch 04/13] QEMU: plug QEMUDevice pt1 / ioport awareness
Date: Thu, 17 Apr 2008 17:10:25 -0300	[thread overview]
Message-ID: <20080417203026.508456803@localhost.localdomain> (raw)
In-Reply-To: 20080417201021.515148882@localhost.localdomain

[-- Attachment #1: use-qemu-device --]
[-- Type: text/plain, Size: 65059 bytes --]

Plug QEMUDevice.

ISA drivers should add QEMUDevice to their structures and call qemu_register_device()
themselves, while the PCI layer does it automatically.

Pass QEMUDevice to register_ioport() making the ioport->device relationship
visible.

Index: kvm-userspace.io/qemu/hw/pci.h
===================================================================
--- kvm-userspace.io.orig/qemu/hw/pci.h
+++ kvm-userspace.io/qemu/hw/pci.h
@@ -11,6 +11,28 @@
 /* PCI bus */
 extern target_phys_addr_t pci_mem_base;
 
+typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level);
+typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
+
+struct PCIBus {
+    QEMUDevice qemu_dev;
+    int bus_num;
+    int devfn_min;
+    pci_set_irq_fn set_irq;
+    pci_map_irq_fn map_irq;
+    uint32_t config_reg; /* XXX: suppress */
+    /* low level pic */
+    SetIRQFunc *low_set_irq;
+    qemu_irq *irq_opaque;
+    PCIDevice *devices[256];
+    PCIDevice *parent_dev;
+    PCIBus *next;
+    /* The bus IRQ state is the logical OR of the connected devices.
+       Keep a count of the number of devices with raised IRQs.  */
+    int nirq;
+    int irq_count[];
+};
+
 typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
                                 uint32_t address, uint32_t data, int len);
 typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
@@ -47,6 +69,7 @@ typedef struct PCIIORegion {
 #define PCI_MAX_LAT		0x3f	/* 8 bits */
 
 struct PCIDevice {
+    QEMUDevice qemu_dev;
     /* PCI config space */
     uint8_t config[256];
 
@@ -88,8 +111,6 @@ void pci_default_write_config(PCIDevice 
 void pci_device_save(PCIDevice *s, QEMUFile *f);
 int pci_device_load(PCIDevice *s, QEMUFile *f);
 
-typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level);
-typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
 PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          qemu_irq *pic, int devfn_min, int nirq);
 
Index: kvm-userspace.io/qemu/hw/pci.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/pci.c
+++ kvm-userspace.io/qemu/hw/pci.c
@@ -29,24 +29,6 @@
 
 //#define DEBUG_PCI
 
-struct PCIBus {
-    int bus_num;
-    int devfn_min;
-    pci_set_irq_fn set_irq;
-    pci_map_irq_fn map_irq;
-    uint32_t config_reg; /* XXX: suppress */
-    /* low level pic */
-    SetIRQFunc *low_set_irq;
-    qemu_irq *irq_opaque;
-    PCIDevice *devices[256];
-    PCIDevice *parent_dev;
-    PCIBus *next;
-    /* The bus IRQ state is the logical OR of the connected devices.
-       Keep a count of the number of devices with raised IRQs.  */
-    int nirq;
-    int irq_count[];
-};
-
 static void pci_update_mappings(PCIDevice *d);
 static void pci_set_irq(void *opaque, int irq_num, int level);
 
@@ -92,6 +74,7 @@ PCIBus *pci_register_bus(pci_set_irq_fn 
     static int nbus = 0;
 
     bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
+    qemu_register_device(&bus->qemu_dev);
     bus->set_irq = set_irq;
     bus->map_irq = map_irq;
     bus->irq_opaque = pic;
@@ -168,6 +151,7 @@ PCIDevice *pci_register_device(PCIBus *b
     pci_dev = qemu_mallocz(instance_size);
     if (!pci_dev)
         return NULL;
+    qemu_register_device(&pci_dev->qemu_dev);
     pci_dev->bus = bus;
     pci_dev->devfn = devfn;
     pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
Index: kvm-userspace.io/qemu/hw/eepro100.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/eepro100.c
+++ kvm-userspace.io/qemu/hw/eepro100.c
@@ -1374,17 +1374,18 @@ static void pci_map(PCIDevice * pci_dev,
 {
     PCIEEPRO100State *d = (PCIEEPRO100State *) pci_dev;
     EEPRO100State *s = &d->eepro100;
+    QEMUDevice *dev = &pci_dev->qemu_dev;
 
     logout("region %d, addr=0x%08x, size=0x%08x, type=%d\n",
            region_num, addr, size, type);
 
     assert(region_num == 1);
-    register_ioport_write(addr, size, 1, ioport_write1, s);
-    register_ioport_read(addr, size, 1, ioport_read1, s);
-    register_ioport_write(addr, size, 2, ioport_write2, s);
-    register_ioport_read(addr, size, 2, ioport_read2, s);
-    register_ioport_write(addr, size, 4, ioport_write4, s);
-    register_ioport_read(addr, size, 4, ioport_read4, s);
+    register_ioport_write(dev, addr, size, 1, ioport_write1, s);
+    register_ioport_read(dev, addr, size, 1, ioport_read1, s);
+    register_ioport_write(dev, addr, size, 2, ioport_write2, s);
+    register_ioport_read(dev, addr, size, 2, ioport_read2, s);
+    register_ioport_write(dev, addr, size, 4, ioport_write4, s);
+    register_ioport_read(dev, addr, size, 4, ioport_read4, s);
 
     s->region[region_num] = addr;
 }
Index: kvm-userspace.io/qemu/hw/isa.h
===================================================================
--- kvm-userspace.io.orig/qemu/hw/isa.h
+++ kvm-userspace.io/qemu/hw/isa.h
@@ -2,9 +2,9 @@
 
 extern target_phys_addr_t isa_mem_base;
 
-int register_ioport_read(int start, int length, int size,
+int register_ioport_read(QEMUDevice *dev, int start, int length, int size,
                          IOPortReadFunc *func, void *opaque);
-int register_ioport_write(int start, int length, int size,
+int register_ioport_write(QEMUDevice *dev, int start, int length, int size,
                           IOPortWriteFunc *func, void *opaque);
 void isa_unassign_ioport(int start, int length);
 
Index: kvm-userspace.io/qemu/hw/lsi53c895a.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/lsi53c895a.c
+++ kvm-userspace.io/qemu/hw/lsi53c895a.c
@@ -1794,15 +1794,16 @@ static void lsi_io_mapfunc(PCIDevice *pc
                            uint32_t addr, uint32_t size, int type)
 {
     LSIState *s = (LSIState *)pci_dev;
+    QEMUDevice *dev = &pci_dev->qemu_dev;
 
     DPRINTF("Mapping IO at %08x\n", addr);
 
-    register_ioport_write(addr, 256, 1, lsi_io_writeb, s);
-    register_ioport_read(addr, 256, 1, lsi_io_readb, s);
-    register_ioport_write(addr, 256, 2, lsi_io_writew, s);
-    register_ioport_read(addr, 256, 2, lsi_io_readw, s);
-    register_ioport_write(addr, 256, 4, lsi_io_writel, s);
-    register_ioport_read(addr, 256, 4, lsi_io_readl, s);
+    register_ioport_write(dev, addr, 256, 1, lsi_io_writeb, s);
+    register_ioport_read(dev, addr, 256, 1, lsi_io_readb, s);
+    register_ioport_write(dev, addr, 256, 2, lsi_io_writew, s);
+    register_ioport_read(dev, addr, 256, 2, lsi_io_readw, s);
+    register_ioport_write(dev, addr, 256, 4, lsi_io_writel, s);
+    register_ioport_read(dev, addr, 256, 4, lsi_io_readl, s);
 }
 
 static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num,
Index: kvm-userspace.io/qemu/hw/ne2000.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/ne2000.c
+++ kvm-userspace.io/qemu/hw/ne2000.c
@@ -122,6 +122,7 @@
 #define NE2000_MEM_SIZE     NE2000_PMEM_END
 
 typedef struct NE2000State {
+    QEMUDevice qemu_dev;
     uint8_t cmd;
     uint32_t start;
     uint32_t stop;
@@ -723,21 +724,25 @@ static int ne2000_load(QEMUFile* f,void*
 void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd)
 {
     NE2000State *s;
+    QEMUDevice *dev;
 
     s = qemu_mallocz(sizeof(NE2000State));
     if (!s)
         return;
 
-    register_ioport_write(base, 16, 1, ne2000_ioport_write, s);
-    register_ioport_read(base, 16, 1, ne2000_ioport_read, s);
+    dev = &s->qemu_dev;
+    qemu_register_device(dev);
 
-    register_ioport_write(base + 0x10, 1, 1, ne2000_asic_ioport_write, s);
-    register_ioport_read(base + 0x10, 1, 1, ne2000_asic_ioport_read, s);
-    register_ioport_write(base + 0x10, 2, 2, ne2000_asic_ioport_write, s);
-    register_ioport_read(base + 0x10, 2, 2, ne2000_asic_ioport_read, s);
+    register_ioport_write(dev, base, 16, 1, ne2000_ioport_write, s);
+    register_ioport_read(dev, base, 16, 1, ne2000_ioport_read, s);
 
-    register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
-    register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
+    register_ioport_write(dev, base + 0x10, 1, 1, ne2000_asic_ioport_write, s);
+    register_ioport_read(dev, base + 0x10, 1, 1, ne2000_asic_ioport_read, s);
+    register_ioport_write(dev, base + 0x10, 2, 2, ne2000_asic_ioport_write, s);
+    register_ioport_read(dev, base + 0x10, 2, 2, ne2000_asic_ioport_read, s);
+
+    register_ioport_write(dev, base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
+    register_ioport_read(dev, base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
     s->irq = irq;
     memcpy(s->macaddr, nd->macaddr, 6);
 
@@ -771,19 +776,20 @@ static void ne2000_map(PCIDevice *pci_de
 {
     PCINE2000State *d = (PCINE2000State *)pci_dev;
     NE2000State *s = &d->ne2000;
+    QEMUDevice *dev = &pci_dev->qemu_dev;
 
-    register_ioport_write(addr, 16, 1, ne2000_ioport_write, s);
-    register_ioport_read(addr, 16, 1, ne2000_ioport_read, s);
+    register_ioport_write(dev, addr, 16, 1, ne2000_ioport_write, s);
+    register_ioport_read(dev, addr, 16, 1, ne2000_ioport_read, s);
 
-    register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s);
-    register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s);
-    register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s);
-    register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s);
-    register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s);
-    register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s);
+    register_ioport_write(dev, addr + 0x10, 1, 1, ne2000_asic_ioport_write, s);
+    register_ioport_read(dev, addr + 0x10, 1, 1, ne2000_asic_ioport_read, s);
+    register_ioport_write(dev, addr + 0x10, 2, 2, ne2000_asic_ioport_write, s);
+    register_ioport_read(dev, addr + 0x10, 2, 2, ne2000_asic_ioport_read, s);
+    register_ioport_write(dev, addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s);
+    register_ioport_read(dev, addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s);
 
-    register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
-    register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
+    register_ioport_write(dev, addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
+    register_ioport_read(dev, addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
 }
 
 PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
Index: kvm-userspace.io/qemu/vl.c
===================================================================
--- kvm-userspace.io.orig/qemu/vl.c
+++ kvm-userspace.io/qemu/vl.c
@@ -346,7 +346,7 @@ static void init_ioports(void)
 }
 
 /* size is the word size in byte */
-int register_ioport_read(int start, int length, int size,
+int register_ioport_read(QEMUDevice *dev, int start, int length, int size,
                          IOPortReadFunc *func, void *opaque)
 {
     int i, bsize;
@@ -371,7 +371,7 @@ int register_ioport_read(int start, int 
 }
 
 /* size is the word size in byte */
-int register_ioport_write(int start, int length, int size,
+int register_ioport_write(QEMUDevice *dev, int start, int length, int size,
                           IOPortWriteFunc *func, void *opaque)
 {
     int i, bsize;
Index: kvm-userspace.io/qemu/audio/audio.h
===================================================================
--- kvm-userspace.io.orig/qemu/audio/audio.h
+++ kvm-userspace.io/qemu/audio/audio.h
@@ -78,6 +78,7 @@ typedef struct CaptureVoiceOut CaptureVo
 typedef struct SWVoiceIn SWVoiceIn;
 
 typedef struct QEMUSoundCard {
+    QEMUDevice qemu_dev;
     AudioState *audio;
     char *name;
     LIST_ENTRY (QEMUSoundCard) entries;
Index: kvm-userspace.io/qemu/hw/acpi.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/acpi.c
+++ kvm-userspace.io/qemu/hw/acpi.c
@@ -80,6 +80,7 @@ typedef struct PIIX4PMState {
 #define SMBBLKDAT 0x07
 
 PIIX4PMState *pm_state;
+QEMUDevice *pm_dev;
 
 static void update_pmtmr(PIIX4PMState *s)
 {
@@ -425,10 +426,10 @@ static void pm_io_space_update(PIIX4PMSt
 #if defined(DEBUG)
         printf("PM: mapping to 0x%x\n", pm_io_base);
 #endif
-        register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s);
-        register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s);
-        register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s);
-        register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s);
+        register_ioport_write(pm_dev, pm_io_base, 64, 2, pm_ioport_writew, s);
+        register_ioport_read(pm_dev, pm_io_base, 64, 2, pm_ioport_readw, s);
+        register_ioport_write(pm_dev, pm_io_base, 64, 4, pm_ioport_writel, s);
+        register_ioport_read(pm_dev, pm_io_base, 64, 4, pm_ioport_readl, s);
     }
 }
 
@@ -490,6 +491,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int 
                                          "PM", sizeof(PIIX4PMState),
                                          devfn, NULL, pm_write_config);
     pm_state = s;
+    pm_dev = &pm_state->dev.qemu_dev;
     pci_conf = s->dev.config;
     pci_conf[0x00] = 0x86;
     pci_conf[0x01] = 0x80;
@@ -506,10 +508,10 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int 
 
     pci_conf[0x40] = 0x01; /* PM io base read only bit */
 
-    register_ioport_write(0xb2, 2, 1, pm_smi_writeb, s);
-    register_ioport_read(0xb2, 2, 1, pm_smi_readb, s);
+    register_ioport_write(pm_dev, 0xb2, 2, 1, pm_smi_writeb, s);
+    register_ioport_read(pm_dev, 0xb2, 2, 1, pm_smi_readb, s);
 
-    register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
+    register_ioport_write(pm_dev, ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
 
     /* XXX: which specification is used ? The i82731AB has different
        mappings */
@@ -521,8 +523,8 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int 
     pci_conf[0x90] = smb_io_base | 1;
     pci_conf[0x91] = smb_io_base >> 8;
     pci_conf[0xd2] = 0x09;
-    register_ioport_write(smb_io_base, 64, 1, smb_ioport_writeb, s);
-    register_ioport_read(smb_io_base, 64, 1, smb_ioport_readb, s);
+    register_ioport_write(pm_dev, smb_io_base, 64, 1, smb_ioport_writeb, s);
+    register_ioport_read(pm_dev, smb_io_base, 64, 1, smb_ioport_readb, s);
 
     s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s);
 
@@ -689,17 +691,17 @@ static const char *model;
 
 void qemu_system_hot_add_init(const char *cpu_model)
 {
-    register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe);
-    register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, &gpe);
+    register_ioport_write(pm_dev, GPE_BASE, 4, 1, gpe_writeb, &gpe);
+    register_ioport_read(pm_dev, GPE_BASE, 4, 1,  gpe_readb, &gpe);
 
-    register_ioport_write(PROC_BASE, 4, 1, gpe_writeb, &gpe);
-    register_ioport_read(PROC_BASE, 4, 1,  gpe_readb, &gpe);
+    register_ioport_write(pm_dev, PROC_BASE, 4, 1, gpe_writeb, &gpe);
+    register_ioport_read(pm_dev, PROC_BASE, 4, 1,  gpe_readb, &gpe);
 
-    register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
-    register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, &pci0_status);
+    register_ioport_write(pm_dev, PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
+    register_ioport_read(pm_dev, PCI_BASE, 8, 4,  pcihotplug_read, &pci0_status);
 
-    register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, NULL);
-    register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, NULL);
+    register_ioport_write(pm_dev, PCI_EJ_BASE, 4, 4, pciej_write, NULL);
+    register_ioport_read(pm_dev, PCI_EJ_BASE, 4, 4,  pciej_read, NULL);
 
     model = cpu_model;
 }
Index: kvm-userspace.io/qemu/hw/cirrus_vga.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/cirrus_vga.c
+++ kvm-userspace.io/qemu/hw/cirrus_vga.c
@@ -235,6 +235,7 @@ typedef void (*cirrus_fill_t)(struct Cir
 typedef struct CirrusVGAState {
     VGA_STATE_COMMON
 
+    QEMUDevice qemu_dev;
     int cirrus_linear_io_addr;
     int cirrus_linear_bitblt_io_addr;
     int cirrus_mmio_io_addr;
@@ -3215,7 +3216,8 @@ static int cirrus_vga_load(QEMUFile *f, 
  *
  ***************************************/
 
-static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
+static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
+                               QEMUDevice *dev)
 {
     int vga_io_memory, i;
     static int inited;
@@ -3242,19 +3244,19 @@ static void cirrus_init_common(CirrusVGA
         rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
     }
 
-    register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
+    register_ioport_write(dev, 0x3c0, 16, 1, vga_ioport_write, s);
 
-    register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
-    register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
-    register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
-    register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
-
-    register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
-
-    register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
-    register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
-    register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
-    register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
+    register_ioport_write(dev, 0x3b4, 2, 1, vga_ioport_write, s);
+    register_ioport_write(dev, 0x3d4, 2, 1, vga_ioport_write, s);
+    register_ioport_write(dev, 0x3ba, 1, 1, vga_ioport_write, s);
+    register_ioport_write(dev, 0x3da, 1, 1, vga_ioport_write, s);
+
+    register_ioport_read(dev, 0x3c0, 16, 1, vga_ioport_read, s);
+
+    register_ioport_read(dev, 0x3b4, 2, 1, vga_ioport_read, s);
+    register_ioport_read(dev, 0x3d4, 2, 1, vga_ioport_read, s);
+    register_ioport_read(dev, 0x3ba, 1, 1, vga_ioport_read, s);
+    register_ioport_read(dev, 0x3da, 1, 1, vga_ioport_read, s);
 
     vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read,
                                            cirrus_vga_mem_write, s);
@@ -3334,12 +3336,16 @@ void isa_cirrus_vga_init(DisplayState *d
                          unsigned long vga_ram_offset, int vga_ram_size)
 {
     CirrusVGAState *s;
+    QEMUDevice *dev;
 
     s = qemu_mallocz(sizeof(CirrusVGAState));
 
+    dev = &s->qemu_dev;
+    qemu_register_device(dev);
+
     vga_common_init((VGAState *)s,
                     ds, vga_ram_base, vga_ram_offset, vga_ram_size);
-    cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
+    cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0, dev);
     /* XXX ISA-LFB support */
 }
 
@@ -3386,6 +3392,7 @@ void pci_cirrus_vga_init(PCIBus *bus, Di
     uint8_t *pci_conf;
     CirrusVGAState *s;
     int device_id;
+    QEMUDevice *dev;
 
     device_id = CIRRUS_ID_CLGD5446;
 
@@ -3403,11 +3410,13 @@ void pci_cirrus_vga_init(PCIBus *bus, Di
     pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
     pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
 
+    dev = &d->dev.qemu_dev;
+
     /* setup VGA */
     s = &d->cirrus_vga;
     vga_common_init((VGAState *)s,
                     ds, vga_ram_base, vga_ram_offset, vga_ram_size);
-    cirrus_init_common(s, device_id, 1);
+    cirrus_init_common(s, device_id, 1, dev);
 
     graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump,
                          s->text_update, s);
Index: kvm-userspace.io/qemu/hw/dma.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/dma.c
+++ kvm-userspace.io/qemu/hw/dma.c
@@ -55,6 +55,7 @@ struct dma_regs {
 #define COUNT 1
 
 static struct dma_cont {
+    QEMUDevice qemu_dev;
     uint8_t status;
     uint8_t command;
     uint8_t mask;
@@ -448,30 +449,31 @@ static int dma_phony_handler (void *opaq
 static void dma_init2(struct dma_cont *d, int base, int dshift,
                       int page_base, int pageh_base)
 {
+    QEMUDevice *dev = &d->qemu_dev;
     const static int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
     int i;
 
     d->dshift = dshift;
     for (i = 0; i < 8; i++) {
-        register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
-        register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
+        register_ioport_write (dev, base + (i << dshift), 1, 1, write_chan, d);
+        register_ioport_read (dev, base + (i << dshift), 1, 1, read_chan, d);
     }
     for (i = 0; i < LENOFA (page_port_list); i++) {
-        register_ioport_write (page_base + page_port_list[i], 1, 1,
+        register_ioport_write (dev, page_base + page_port_list[i], 1, 1,
                                write_page, d);
-        register_ioport_read (page_base + page_port_list[i], 1, 1,
+        register_ioport_read (dev, page_base + page_port_list[i], 1, 1,
                               read_page, d);
         if (pageh_base >= 0) {
-            register_ioport_write (pageh_base + page_port_list[i], 1, 1,
+            register_ioport_write (dev, pageh_base + page_port_list[i], 1, 1,
                                    write_pageh, d);
-            register_ioport_read (pageh_base + page_port_list[i], 1, 1,
+            register_ioport_read (dev, pageh_base + page_port_list[i], 1, 1,
                                   read_pageh, d);
         }
     }
     for (i = 0; i < 8; i++) {
-        register_ioport_write (base + ((i + 8) << dshift), 1, 1,
+        register_ioport_write (dev, base + ((i + 8) << dshift), 1, 1,
                                write_cont, d);
-        register_ioport_read (base + ((i + 8) << dshift), 1, 1,
+        register_ioport_read (dev, base + ((i + 8) << dshift), 1, 1,
                               read_cont, d);
     }
     qemu_register_reset(dma_reset, d);
Index: kvm-userspace.io/qemu/hw/es1370.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/es1370.c
+++ kvm-userspace.io/qemu/hw/es1370.c
@@ -917,18 +917,19 @@ static void es1370_map (PCIDevice *pci_d
 {
     PCIES1370State *d = (PCIES1370State *) pci_dev;
     ES1370State *s = &d->es1370;
+    QEMUDevice *dev = &pci_dev->qemu_dev;
 
     (void) region_num;
     (void) size;
     (void) type;
 
-    register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s);
-    register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s);
-    register_ioport_write (addr, 0x40, 4, es1370_writel, s);
-
-    register_ioport_read (addr, 0x40 * 4, 1, es1370_readb, s);
-    register_ioport_read (addr, 0x40 * 2, 2, es1370_readw, s);
-    register_ioport_read (addr, 0x40, 4, es1370_readl, s);
+    register_ioport_write (dev, addr, 0x40 * 4, 1, es1370_writeb, s);
+    register_ioport_write (dev, addr, 0x40 * 2, 2, es1370_writew, s);
+    register_ioport_write (dev, addr, 0x40, 4, es1370_writel, s);
+
+    register_ioport_read (dev, addr, 0x40 * 4, 1, es1370_readb, s);
+    register_ioport_read (dev, addr, 0x40 * 2, 2, es1370_readw, s);
+    register_ioport_read (dev, addr, 0x40, 4, es1370_readl, s);
 }
 
 static void es1370_save (QEMUFile *f, void *opaque)
Index: kvm-userspace.io/qemu/hw/extboot.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/extboot.c
+++ kvm-userspace.io/qemu/hw/extboot.c
@@ -116,6 +116,12 @@ static void extboot_write_cmd(void *opaq
     }
 }
 
+/*
+ * XXX: extboot should use the disk controller's QEMUDevice, but since this
+ * happens at boot only it should be fine wrt synchronization.
+ */
+QEMUDevice extboot_dev;
+
 void extboot_init(BlockDriverState *bs, int cmd)
 {
     int *pcmd;
@@ -125,8 +131,9 @@ void extboot_init(BlockDriverState *bs, 
 	fprintf(stderr, "Error allocating memory\n");
 	exit(1);
     }
+    qemu_register_device(&extboot_dev);
 
     *pcmd = cmd;
-    register_ioport_read(0x404, 1, 1, extboot_read, pcmd);
-    register_ioport_write(0x405, 1, 2, extboot_write_cmd, bs);
+    register_ioport_read(&extboot_dev, 0x404, 1, 1, extboot_read, pcmd);
+    register_ioport_write(&extboot_dev, 0x405, 1, 2, extboot_write_cmd, bs);
 }
Index: kvm-userspace.io/qemu/hw/fdc.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/fdc.c
+++ kvm-userspace.io/qemu/hw/fdc.c
@@ -464,6 +464,7 @@ do { (state) = ((state) & ~FD_STATE_STAT
 #define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT)
 
 struct fdctrl_t {
+    QEMUDevice qemu_dev;
     fdctrl_t *fdctrl;
     /* Controller's identification */
     uint8_t version;
@@ -699,6 +700,7 @@ static fdctrl_t *fdctrl_init_common (qem
                                      BlockDriverState **fds)
 {
     fdctrl_t *fdctrl;
+    QEMUDevice *dev;
     int i;
 
     FLOPPY_DPRINTF("init controller\n");
@@ -712,6 +714,8 @@ static fdctrl_t *fdctrl_init_common (qem
     }
     fdctrl->result_timer = qemu_new_timer(vm_clock,
                                           fdctrl_result_timer, fdctrl);
+    dev = &fdctrl->qemu_dev;
+    qemu_register_device(dev);
 
     fdctrl->version = 0x90; /* Intel 82078 controller */
     fdctrl->irq = irq;
@@ -743,9 +747,11 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int
                        BlockDriverState **fds)
 {
     fdctrl_t *fdctrl;
+    QEMUDevice *dev;
     int io_mem;
 
     fdctrl = fdctrl_init_common(irq, dma_chann, io_base, fds);
+    dev = &fdctrl->qemu_dev;
 
     fdctrl->sun4m = 0;
     if (mem_mapped) {
@@ -753,14 +759,14 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int
                                         fdctrl);
         cpu_register_physical_memory(io_base, 0x08, io_mem);
     } else {
-        register_ioport_read((uint32_t)io_base + 0x01, 5, 1, &fdctrl_read,
+        register_ioport_read(dev, (uint32_t)io_base + 0x01, 5, 1, &fdctrl_read,
                              fdctrl);
-        register_ioport_read((uint32_t)io_base + 0x07, 1, 1, &fdctrl_read,
+        register_ioport_read(dev, (uint32_t)io_base + 0x07, 1, 1, &fdctrl_read,
                              fdctrl);
-        register_ioport_write((uint32_t)io_base + 0x01, 5, 1, &fdctrl_write,
-                              fdctrl);
-        register_ioport_write((uint32_t)io_base + 0x07, 1, 1, &fdctrl_write,
-                              fdctrl);
+        register_ioport_write(dev, (uint32_t)io_base + 0x01, 5, 1,
+                              &fdctrl_write, fdctrl);
+        register_ioport_write(dev, (uint32_t)io_base + 0x07, 1, 1,
+                              &fdctrl_write, fdctrl);
     }
 
     return fdctrl;
Index: kvm-userspace.io/qemu/hw/hypercall.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/hypercall.c
+++ kvm-userspace.io/qemu/hw/hypercall.c
@@ -189,9 +189,12 @@ static void hp_map(PCIDevice *pci_dev, i
 {
     PCIHypercallState *d = (PCIHypercallState *)pci_dev;
     HypercallState *s = &d->hp;
+    QEMUDevice *dev = &pci_dev->qemu_dev;
 
-    register_ioport_write(addr, HYPERCALL_IOPORT_SIZE, 1, hp_ioport_write, s);
-    register_ioport_read(addr, HYPERCALL_IOPORT_SIZE, 1, hp_ioport_read, s);
+    register_ioport_write(dev, addr, HYPERCALL_IOPORT_SIZE, 1,
+                          hp_ioport_write, s);
+    register_ioport_read(dev, addr, HYPERCALL_IOPORT_SIZE, 1,
+                         hp_ioport_read, s);
 
 }
 
Index: kvm-userspace.io/qemu/hw/i8254.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/i8254.c
+++ kvm-userspace.io/qemu/hw/i8254.c
@@ -463,6 +463,9 @@ PITState *pit_init(int base, qemu_irq ir
 {
     PITState *pit = &pit_state;
     PITChannelState *s;
+    QEMUDevice *dev = &pit->qemu_dev;
+
+    qemu_register_device(dev);
 
     s = &pit->channels[0];
     /* the timer 0 is connected to an IRQ */
@@ -473,8 +476,8 @@ PITState *pit_init(int base, qemu_irq ir
 		    pit_save, pit_load, pit);
 
     qemu_register_reset(pit_reset, pit);
-    register_ioport_write(base, 4, 1, pit_ioport_write, pit);
-    register_ioport_read(base, 3, 1, pit_ioport_read, pit);
+    register_ioport_write(dev, base, 4, 1, pit_ioport_write, pit);
+    register_ioport_read(dev, base, 3, 1, pit_ioport_read, pit);
 
     pit_reset(pit);
 
Index: kvm-userspace.io/qemu/hw/i8254.h
===================================================================
--- kvm-userspace.io.orig/qemu/hw/i8254.h
+++ kvm-userspace.io/qemu/hw/i8254.h
@@ -54,6 +54,7 @@ typedef struct PITChannelState {
 } PITChannelState;
 
 struct PITState {
+    QEMUDevice qemu_dev;
     PITChannelState channels[3];
 };
 
Index: kvm-userspace.io/qemu/hw/i8259.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/i8259.c
+++ kvm-userspace.io/qemu/hw/i8259.c
@@ -35,6 +35,7 @@
 //#define DEBUG_IRQ_COUNT
 
 typedef struct PicState {
+    QEMUDevice qemu_dev;
     uint8_t last_irr; /* edge detection */
     uint8_t irr; /* interrupt request register */
     uint8_t imr; /* interrupt mask register */
@@ -594,11 +595,15 @@ static int pic_load(QEMUFile *f, void *o
 /* XXX: add generic master/slave system */
 static void pic_init1(int io_addr, int elcr_addr, PicState *s)
 {
-    register_ioport_write(io_addr, 2, 1, pic_ioport_write, s);
-    register_ioport_read(io_addr, 2, 1, pic_ioport_read, s);
+    QEMUDevice *dev = &s->qemu_dev;
+
+    qemu_register_device(dev);
+
+    register_ioport_write(dev, io_addr, 2, 1, pic_ioport_write, s);
+    register_ioport_read(dev, io_addr, 2, 1, pic_ioport_read, s);
     if (elcr_addr >= 0) {
-        register_ioport_write(elcr_addr, 1, 1, elcr_ioport_write, s);
-        register_ioport_read(elcr_addr, 1, 1, elcr_ioport_read, s);
+        register_ioport_write(dev, elcr_addr, 1, 1, elcr_ioport_write, s);
+        register_ioport_read(dev, elcr_addr, 1, 1, elcr_ioport_read, s);
     }
     register_savevm("i8259", io_addr, 1, pic_save, pic_load, s);
     qemu_register_reset(pic_reset, s);
Index: kvm-userspace.io/qemu/hw/ide.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/ide.c
+++ kvm-userspace.io/qemu/hw/ide.c
@@ -370,6 +370,7 @@ typedef void EndTransferFunc(struct IDES
 
 /* NOTE: IDEState represents in fact one drive */
 typedef struct IDEState {
+    QEMUDevice qemu_dev;
     /* ide config */
     int is_cdrom;
     int is_cf;
@@ -2499,20 +2500,21 @@ static void ide_init2(IDEState *ide_stat
     }
 }
 
-static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
+static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2,
+                            QEMUDevice *dev)
 {
-    register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
-    register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
+    register_ioport_write(dev, iobase, 8, 1, ide_ioport_write, ide_state);
+    register_ioport_read(dev, iobase, 8, 1, ide_ioport_read, ide_state);
     if (iobase2) {
-        register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
-        register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
+        register_ioport_read(dev, iobase2, 1, 1, ide_status_read, ide_state);
+        register_ioport_write(dev, iobase2, 1, 1, ide_cmd_write, ide_state);
     }
 
     /* data ports */
-    register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
-    register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
-    register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
-    register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
+    register_ioport_write(dev, iobase, 2, 2, ide_data_writew, ide_state);
+    register_ioport_read(dev, iobase, 2, 2, ide_data_readw, ide_state);
+    register_ioport_write(dev, iobase, 4, 4, ide_data_writel, ide_state);
+    register_ioport_read(dev, iobase, 4, 4, ide_data_readl, ide_state);
 }
 
 /* save per IDE drive data */
@@ -2578,13 +2580,17 @@ void isa_ide_init(int iobase, int iobase
                   BlockDriverState *hd0, BlockDriverState *hd1)
 {
     IDEState *ide_state;
+    QEMUDevice *dev;
 
     ide_state = qemu_mallocz(sizeof(IDEState) * 2);
     if (!ide_state)
         return;
 
+    dev = &ide_state->qemu_dev;
+    qemu_register_device(dev);
+
     ide_init2(ide_state, hd0, hd1, irq);
-    ide_init_ioport(ide_state, iobase, iobase2);
+    ide_init_ioport(ide_state, iobase, iobase2, dev);
 }
 
 /***********************************************************/
@@ -2597,21 +2603,24 @@ static void ide_map(PCIDevice *pci_dev, 
 {
     PCIIDEState *d = (PCIIDEState *)pci_dev;
     IDEState *ide_state;
+    QEMUDevice *dev = &pci_dev->qemu_dev;
 
     if (region_num <= 3) {
         ide_state = &d->ide_if[(region_num >> 1) * 2];
         if (region_num & 1) {
-            register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state);
-            register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state);
+            register_ioport_read(dev, addr + 2, 1, 1, ide_status_read,
+                                 ide_state);
+            register_ioport_write(dev, addr + 2, 1, 1, ide_cmd_write,
+                                 ide_state);
         } else {
-            register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state);
-            register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state);
+            register_ioport_write(dev, addr, 8, 1, ide_ioport_write, ide_state);
+            register_ioport_read(dev, addr, 8, 1, ide_ioport_read, ide_state);
 
             /* data ports */
-            register_ioport_write(addr, 2, 2, ide_data_writew, ide_state);
-            register_ioport_read(addr, 2, 2, ide_data_readw, ide_state);
-            register_ioport_write(addr, 4, 4, ide_data_writel, ide_state);
-            register_ioport_read(addr, 4, 4, ide_data_readl, ide_state);
+            register_ioport_write(dev, addr, 2, 2, ide_data_writew, ide_state);
+            register_ioport_read(dev, addr, 2, 2, ide_data_readw, ide_state);
+            register_ioport_write(dev, addr, 4, 4, ide_data_writel, ide_state);
+            register_ioport_read(dev, addr, 4, 4, ide_data_readl, ide_state);
         }
     }
 }
@@ -2762,6 +2771,7 @@ static void bmdma_map(PCIDevice *pci_dev
                     uint32_t addr, uint32_t size, int type)
 {
     PCIIDEState *d = (PCIIDEState *)pci_dev;
+    QEMUDevice *dev = &pci_dev->qemu_dev;
     int i;
 
     for(i = 0;i < 2; i++) {
@@ -2770,13 +2780,13 @@ static void bmdma_map(PCIDevice *pci_dev
         d->ide_if[2 * i + 1].bmdma = bm;
         bm->pci_dev = (PCIIDEState *)pci_dev;
 
-        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
+        register_ioport_write(dev, addr, 1, 1, bmdma_cmd_writeb, bm);
 
-        register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
-        register_ioport_read(addr, 4, 1, bmdma_readb, bm);
+        register_ioport_write(dev, addr + 1, 3, 1, bmdma_writeb, bm);
+        register_ioport_read(dev, addr, 4, 1, bmdma_readb, bm);
 
-        register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
-        register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
+        register_ioport_write(dev, addr + 4, 4, 4, bmdma_addr_writel, bm);
+        register_ioport_read(dev, addr + 4, 4, 4, bmdma_addr_readl, bm);
         addr += 8;
     }
 }
@@ -2969,8 +2979,8 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
 
     ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
     ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
-    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
-    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6, &d->dev.qemu_dev);
+    ide_init_ioport(&d->ide_if[2], 0x170, 0x376, &d->dev.qemu_dev);
 
     for (i = 0; i < 4; i++)
         if (hd_table[i])
@@ -3011,8 +3021,8 @@ void pci_piix4_ide_init(PCIBus *bus, Blo
 
     ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
     ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
-    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
-    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6, &d->dev.qemu_dev);
+    ide_init_ioport(&d->ide_if[2], 0x170, 0x376, &d->dev.qemu_dev);
 
     register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
 }
Index: kvm-userspace.io/qemu/hw/mc146818rtc.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/mc146818rtc.c
+++ kvm-userspace.io/qemu/hw/mc146818rtc.c
@@ -55,6 +55,7 @@
 #define REG_B_UIE 0x10
 
 struct RTCState {
+    QEMUDevice qemu_dev;
     uint8_t cmos_data[128];
     uint8_t cmos_index;
     struct tm current_tm;
@@ -457,11 +458,15 @@ static int rtc_load(QEMUFile *f, void *o
 RTCState *rtc_init(int base, qemu_irq irq)
 {
     RTCState *s;
+    QEMUDevice *dev;
 
     s = qemu_mallocz(sizeof(RTCState));
     if (!s)
         return NULL;
 
+    dev = &s->qemu_dev;
+    qemu_register_device(dev);
+
     s->irq = irq;
     s->cmos_data[RTC_REG_A] = 0x26;
     s->cmos_data[RTC_REG_B] = 0x02;
@@ -480,8 +485,8 @@ RTCState *rtc_init(int base, qemu_irq ir
     s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
     qemu_mod_timer(s->second_timer2, s->next_second_time);
 
-    register_ioport_write(base, 2, 1, cmos_ioport_write, s);
-    register_ioport_read(base, 2, 1, cmos_ioport_read, s);
+    register_ioport_write(dev, base, 2, 1, cmos_ioport_write, s);
+    register_ioport_read(dev, base, 2, 1, cmos_ioport_read, s);
 
     register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
     return s;
Index: kvm-userspace.io/qemu/hw/parallel.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/parallel.c
+++ kvm-userspace.io/qemu/hw/parallel.c
@@ -64,6 +64,7 @@
 #define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
 
 struct ParallelState {
+    QEMUDevice qemu_dev;
     uint8_t dataw;
     uint8_t datar;
     uint8_t status;
@@ -431,6 +432,7 @@ static void parallel_reset(ParallelState
 ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr)
 {
     ParallelState *s;
+    QEMUDevice *dev;
     uint8_t dummy;
 
     s = qemu_mallocz(sizeof(ParallelState));
@@ -438,24 +440,27 @@ ParallelState *parallel_init(int base, q
         return NULL;
     parallel_reset(s, irq, chr);
 
+    dev = &s->qemu_dev;
+    qemu_register_device(dev);
+
     if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
         s->hw_driver = 1;
         s->status = dummy;
     }
 
     if (s->hw_driver) {
-        register_ioport_write(base, 8, 1, parallel_ioport_write_hw, s);
-        register_ioport_read(base, 8, 1, parallel_ioport_read_hw, s);
-        register_ioport_write(base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s);
-        register_ioport_read(base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s);
-        register_ioport_write(base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s);
-        register_ioport_read(base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s);
-        register_ioport_write(base+0x400, 8, 1, parallel_ioport_ecp_write, s);
-        register_ioport_read(base+0x400, 8, 1, parallel_ioport_ecp_read, s);
+        register_ioport_write(dev, base, 8, 1, parallel_ioport_write_hw, s);
+        register_ioport_read(dev, base, 8, 1, parallel_ioport_read_hw, s);
+        register_ioport_write(dev, base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s);
+        register_ioport_read(dev, base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s);
+        register_ioport_write(dev, base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s);
+        register_ioport_read(dev, base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s);
+        register_ioport_write(dev, base+0x400, 8, 1, parallel_ioport_ecp_write, s);
+        register_ioport_read(dev, base+0x400, 8, 1, parallel_ioport_ecp_read, s);
     }
     else {
-        register_ioport_write(base, 8, 1, parallel_ioport_write_sw, s);
-        register_ioport_read(base, 8, 1, parallel_ioport_read_sw, s);
+        register_ioport_write(dev, base, 8, 1, parallel_ioport_write_sw, s);
+        register_ioport_read(dev, base, 8, 1, parallel_ioport_read_sw, s);
     }
     return s;
 }
Index: kvm-userspace.io/qemu/hw/pc.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/pc.c
+++ kvm-userspace.io/qemu/hw/pc.c
@@ -375,18 +375,20 @@ static void bochs_bios_write(void *opaqu
     }
 }
 
+QEMUDevice pc_basic_hw;
+
 static void bochs_bios_init(void)
 {
-    register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL);
-    register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL);
-    register_ioport_write(0x402, 1, 1, bochs_bios_write, NULL);
-    register_ioport_write(0x403, 1, 1, bochs_bios_write, NULL);
-    register_ioport_write(0x8900, 1, 1, bochs_bios_write, NULL);
-
-    register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL);
-    register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL);
-    register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL);
-    register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL);
+    register_ioport_write(&pc_basic_hw, 0x400, 1, 2, bochs_bios_write, NULL);
+    register_ioport_write(&pc_basic_hw, 0x401, 1, 2, bochs_bios_write, NULL);
+    register_ioport_write(&pc_basic_hw, 0x402, 1, 1, bochs_bios_write, NULL);
+    register_ioport_write(&pc_basic_hw, 0x403, 1, 1, bochs_bios_write, NULL);
+    register_ioport_write(&pc_basic_hw, 0x8900, 1, 1, bochs_bios_write, NULL);
+
+    register_ioport_write(&pc_basic_hw, 0x501, 1, 2, bochs_bios_write, NULL);
+    register_ioport_write(&pc_basic_hw, 0x502, 1, 2, bochs_bios_write, NULL);
+    register_ioport_write(&pc_basic_hw, 0x500, 1, 1, bochs_bios_write, NULL);
+    register_ioport_write(&pc_basic_hw, 0x503, 1, 1, bochs_bios_write, NULL);
 }
 
 /* Generate an initial boot sector which sets state and jump to
@@ -929,6 +931,8 @@ static void pc_init1(ram_addr_t ram_size
         }
     }
 
+    qemu_register_device(&pc_basic_hw);
+
     bochs_bios_init();
 
     if (linux_boot)
@@ -946,9 +950,9 @@ static void pc_init1(ram_addr_t ram_size
     }
 
     /* init basic PC hardware */
-    register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
+    register_ioport_write(&pc_basic_hw, 0x80, 1, 1, ioport80_write, NULL);
 
-    register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
+    register_ioport_write(&pc_basic_hw, 0xf0, 1, 1, ioportF0_write, NULL);
 
     if (cirrus_vga_enabled) {
         if (pci_enabled) {
@@ -977,8 +981,8 @@ static void pc_init1(ram_addr_t ram_size
 
     rtc_state = rtc_init(0x70, i8259[8]);
 
-    register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
-    register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
+    register_ioport_read(&pc_basic_hw, 0x92, 1, 1, ioport92_read, NULL);
+    register_ioport_write(&pc_basic_hw, 0x92, 1, 1, ioport92_write, NULL);
 
     if (pci_enabled) {
         ioapic = ioapic_init();
Index: kvm-userspace.io/qemu/hw/pckbd.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/pckbd.c
+++ kvm-userspace.io/qemu/hw/pckbd.c
@@ -115,6 +115,7 @@
 #define KBD_PENDING_AUX         2
 
 typedef struct KBDState {
+    QEMUDevice qemu_dev;
     uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
     uint8_t status;
     uint8_t mode;
@@ -368,16 +369,19 @@ static int kbd_load(QEMUFile* f, void* o
 void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base)
 {
     KBDState *s = &kbd_state;
+    QEMUDevice *dev = &s->qemu_dev;
 
     s->irq_kbd = kbd_irq;
     s->irq_mouse = mouse_irq;
 
+    qemu_register_device(dev);
+
     kbd_reset(s);
     register_savevm("pckbd", 0, 3, kbd_save, kbd_load, s);
-    register_ioport_read(io_base, 1, 1, kbd_read_data, s);
-    register_ioport_write(io_base, 1, 1, kbd_write_data, s);
-    register_ioport_read(io_base + 4, 1, 1, kbd_read_status, s);
-    register_ioport_write(io_base + 4, 1, 1, kbd_write_command, s);
+    register_ioport_read(dev, io_base, 1, 1, kbd_read_data, s);
+    register_ioport_write(dev, io_base, 1, 1, kbd_write_data, s);
+    register_ioport_read(dev, io_base + 4, 1, 1, kbd_read_status, s);
+    register_ioport_write(dev, io_base + 4, 1, 1, kbd_write_command, s);
 
     s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
     s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
Index: kvm-userspace.io/qemu/hw/pcnet.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/pcnet.c
+++ kvm-userspace.io/qemu/hw/pcnet.c
@@ -1726,18 +1726,19 @@ static void pcnet_ioport_map(PCIDevice *
                              uint32_t addr, uint32_t size, int type)
 {
     PCNetState *d = (PCNetState *)pci_dev;
+    QEMUDevice *dev = &pci_dev->qemu_dev;
 
 #ifdef PCNET_DEBUG_IO
     printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
 #endif
 
-    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
-    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
+    register_ioport_write(dev, addr, 16, 1, pcnet_aprom_writeb, d);
+    register_ioport_read(dev, addr, 16, 1, pcnet_aprom_readb, d);
 
-    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
-    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
-    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
-    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
+    register_ioport_write(dev, addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
+    register_ioport_read(dev, addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
+    register_ioport_write(dev, addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
+    register_ioport_read(dev, addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
 }
 
 static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
Index: kvm-userspace.io/qemu/hw/pcspk.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/pcspk.c
+++ kvm-userspace.io/qemu/hw/pcspk.c
@@ -144,8 +144,11 @@ static void pcspk_ioport_write(void *opa
 void pcspk_init(PITState *pit)
 {
     PCSpkState *s = &pcspk_state;
+    QEMUDevice *dev = &pcspk_state.card.qemu_dev;
+
+    qemu_register_device(dev);
 
     s->pit = pit;
-    register_ioport_read(0x61, 1, 1, pcspk_ioport_read, s);
-    register_ioport_write(0x61, 1, 1, pcspk_ioport_write, s);
+    register_ioport_read(dev, 0x61, 1, 1, pcspk_ioport_read, s);
+    register_ioport_write(dev, 0x61, 1, 1, pcspk_ioport_write, s);
 }
Index: kvm-userspace.io/qemu/hw/piix_pci.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/piix_pci.c
+++ kvm-userspace.io/qemu/hw/piix_pci.c
@@ -174,20 +174,23 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_
     PCIBus *b;
     PCIDevice *d;
     I440FXState *s;
+    QEMUDevice *dev;
 
     s = qemu_mallocz(sizeof(I440FXState));
     b = pci_register_bus(piix3_set_irq, pci_slot_get_pirq, pic, 0, 4);
     s->bus = b;
 
-    register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
-    register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s);
+    dev = &s->bus->qemu_dev;
 
-    register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);
-    register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);
-    register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);
-    register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
-    register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
-    register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
+    register_ioport_write(dev, 0xcf8, 4, 4, i440fx_addr_writel, s);
+    register_ioport_read(dev, 0xcf8, 4, 4, i440fx_addr_readl, s);
+
+    register_ioport_write(dev, 0xcfc, 4, 1, pci_host_data_writeb, s);
+    register_ioport_write(dev, 0xcfc, 4, 2, pci_host_data_writew, s);
+    register_ioport_write(dev, 0xcfc, 4, 4, pci_host_data_writel, s);
+    register_ioport_read(dev, 0xcfc, 4, 1, pci_host_data_readb, s);
+    register_ioport_read(dev, 0xcfc, 4, 2, pci_host_data_readw, s);
+    register_ioport_read(dev, 0xcfc, 4, 4, pci_host_data_readl, s);
 
     d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0,
                             NULL, i440fx_write_config);
Index: kvm-userspace.io/qemu/hw/rtl8139.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/rtl8139.c
+++ kvm-userspace.io/qemu/hw/rtl8139.c
@@ -3324,15 +3324,16 @@ static void rtl8139_ioport_map(PCIDevice
 {
     PCIRTL8139State *d = (PCIRTL8139State *)pci_dev;
     RTL8139State *s = &d->rtl8139;
+    QEMUDevice *dev = &pci_dev->qemu_dev;
 
-    register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s);
-    register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb,  s);
+    register_ioport_write(dev, addr, 0x100, 1, rtl8139_ioport_writeb, s);
+    register_ioport_read( dev, addr, 0x100, 1, rtl8139_ioport_readb,  s);
 
-    register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s);
-    register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw,  s);
+    register_ioport_write(dev, addr, 0x100, 2, rtl8139_ioport_writew, s);
+    register_ioport_read( dev, addr, 0x100, 2, rtl8139_ioport_readw,  s);
 
-    register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s);
-    register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl,  s);
+    register_ioport_write(dev, addr, 0x100, 4, rtl8139_ioport_writel, s);
+    register_ioport_read( dev, addr, 0x100, 4, rtl8139_ioport_readl,  s);
 }
 
 static CPUReadMemoryFunc *rtl8139_mmio_read[3] = {
Index: kvm-userspace.io/qemu/hw/sb16.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/sb16.c
+++ kvm-userspace.io/qemu/hw/sb16.c
@@ -1406,6 +1406,7 @@ int SB16_init (AudioState *audio, qemu_i
     int i;
     static const uint8_t dsp_write_ports[] = {0x6, 0xc};
     static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
+    QEMUDevice *dev;
 
     if (!audio) {
         dolog ("No audio state\n");
@@ -1419,6 +1420,9 @@ int SB16_init (AudioState *audio, qemu_i
         return -1;
     }
 
+    dev = &s->card.qemu_dev;
+    qemu_register_device(dev);
+
     s->cmd = -1;
     s->pic = pic;
     s->irq = conf.irq;
@@ -1441,17 +1445,19 @@ int SB16_init (AudioState *audio, qemu_i
     }
 
     for (i = 0; i < LENOFA (dsp_write_ports); i++) {
-        register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
+        register_ioport_write (dev, s->port + dsp_write_ports[i], 1, 1,
+                               dsp_write, s);
     }
 
     for (i = 0; i < LENOFA (dsp_read_ports); i++) {
-        register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
+        register_ioport_read (dev, s->port + dsp_read_ports[i], 1, 1,
+                              dsp_read, s);
     }
 
-    register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
-    register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
-    register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
-    register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
+    register_ioport_write (dev, s->port + 0x4, 1, 1, mixer_write_indexb, s);
+    register_ioport_write (dev, s->port + 0x4, 1, 2, mixer_write_indexw, s);
+    register_ioport_read (dev, s->port + 0x5, 1, 1, mixer_read, s);
+    register_ioport_write (dev, s->port + 0x5, 1, 1, mixer_write_datab, s);
 
     DMA_register_channel (s->hdma, SB_read_DMA, s);
     DMA_register_channel (s->dma, SB_read_DMA, s);
Index: kvm-userspace.io/qemu/hw/serial.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/serial.c
+++ kvm-userspace.io/qemu/hw/serial.c
@@ -74,6 +74,7 @@
 #define UART_LSR_DR	0x01	/* Receiver data ready */
 
 struct SerialState {
+    QEMUDevice qemu_dev;
     uint16_t divider;
     uint8_t rbr; /* receive register */
     uint8_t ier;
@@ -381,19 +382,23 @@ static void serial_reset(void *opaque)
 SerialState *serial_init(int base, qemu_irq irq, CharDriverState *chr)
 {
     SerialState *s;
+    QEMUDevice *dev;
 
     s = qemu_mallocz(sizeof(SerialState));
     if (!s)
         return NULL;
     s->irq = irq;
 
+    dev = &s->qemu_dev;
+    qemu_register_device(dev);
+
     qemu_register_reset(serial_reset, s);
     serial_reset(s);
 
     register_savevm("serial", base, 2, serial_save, serial_load, s);
 
-    register_ioport_write(base, 8, 1, serial_ioport_write, s);
-    register_ioport_read(base, 8, 1, serial_ioport_read, s);
+    register_ioport_write(dev, base, 8, 1, serial_ioport_write, s);
+    register_ioport_read(dev, base, 8, 1, serial_ioport_read, s);
     s->chr = chr;
     qemu_chr_add_handlers(chr, serial_can_receive1, serial_receive1,
                           serial_event, s);
Index: kvm-userspace.io/qemu/hw/usb-uhci.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/usb-uhci.c
+++ kvm-userspace.io/qemu/hw/usb-uhci.c
@@ -873,13 +873,14 @@ static void uhci_map(PCIDevice *pci_dev,
                     uint32_t addr, uint32_t size, int type)
 {
     UHCIState *s = (UHCIState *)pci_dev;
+    QEMUDevice *dev = &pci_dev->qemu_dev;
 
-    register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
-    register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
-    register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
-    register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
-    register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
-    register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
+    register_ioport_write(dev, addr, 32, 2, uhci_ioport_writew, s);
+    register_ioport_read(dev, addr, 32, 2, uhci_ioport_readw, s);
+    register_ioport_write(dev, addr, 32, 4, uhci_ioport_writel, s);
+    register_ioport_read(dev, addr, 32, 4, uhci_ioport_readl, s);
+    register_ioport_write(dev, addr, 32, 1, uhci_ioport_writeb, s);
+    register_ioport_read(dev, addr, 32, 1, uhci_ioport_readb, s);
 }
 
 void usb_uhci_piix3_init(PCIBus *bus, int devfn)
Index: kvm-userspace.io/qemu/hw/vga.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/vga.c
+++ kvm-userspace.io/qemu/hw/vga.c
@@ -2200,49 +2200,49 @@ void vga_common_init(VGAState *s, Displa
 }
 
 /* used by both ISA and PCI */
-void vga_init(VGAState *s)
+void vga_init(VGAState *s, QEMUDevice *dev)
 {
     int vga_io_memory;
 
     register_savevm("vga", 0, 2, vga_save, vga_load, s);
 
-    register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
+    register_ioport_write(dev, 0x3c0, 16, 1, vga_ioport_write, s);
 
-    register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
-    register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
-    register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
-    register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
-
-    register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
-
-    register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
-    register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
-    register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
-    register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
+    register_ioport_write(dev, 0x3b4, 2, 1, vga_ioport_write, s);
+    register_ioport_write(dev, 0x3d4, 2, 1, vga_ioport_write, s);
+    register_ioport_write(dev, 0x3ba, 1, 1, vga_ioport_write, s);
+    register_ioport_write(dev, 0x3da, 1, 1, vga_ioport_write, s);
+
+    register_ioport_read(dev, 0x3c0, 16, 1, vga_ioport_read, s);
+
+    register_ioport_read(dev, 0x3b4, 2, 1, vga_ioport_read, s);
+    register_ioport_read(dev, 0x3d4, 2, 1, vga_ioport_read, s);
+    register_ioport_read(dev, 0x3ba, 1, 1, vga_ioport_read, s);
+    register_ioport_read(dev, 0x3da, 1, 1, vga_ioport_read, s);
     s->bank_offset = 0;
 
 #ifdef CONFIG_BOCHS_VBE
     s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0;
     s->vbe_bank_mask = ((s->vram_size >> 16) - 1);
 #if defined (TARGET_I386)
-    register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
-    register_ioport_read(0x1cf, 1, 2, vbe_ioport_read_data, s);
+    register_ioport_read(dev, 0x1ce, 1, 2, vbe_ioport_read_index, s);
+    register_ioport_read(dev, 0x1cf, 1, 2, vbe_ioport_read_data, s);
 
-    register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
-    register_ioport_write(0x1cf, 1, 2, vbe_ioport_write_data, s);
+    register_ioport_write(dev, 0x1ce, 1, 2, vbe_ioport_write_index, s);
+    register_ioport_write(dev, 0x1cf, 1, 2, vbe_ioport_write_data, s);
 
     /* old Bochs IO ports */
-    register_ioport_read(0xff80, 1, 2, vbe_ioport_read_index, s);
-    register_ioport_read(0xff81, 1, 2, vbe_ioport_read_data, s);
+    register_ioport_read(dev, 0xff80, 1, 2, vbe_ioport_read_index, s);
+    register_ioport_read(dev, 0xff81, 1, 2, vbe_ioport_read_data, s);
 
-    register_ioport_write(0xff80, 1, 2, vbe_ioport_write_index, s);
-    register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s);
+    register_ioport_write(dev, 0xff80, 1, 2, vbe_ioport_write_index, s);
+    register_ioport_write(dev, 0xff81, 1, 2, vbe_ioport_write_data, s);
 #else
-    register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
-    register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s);
+    register_ioport_read(dev, 0x1ce, 1, 2, vbe_ioport_read_index, s);
+    register_ioport_read(dev, 0x1d0, 1, 2, vbe_ioport_read_data, s);
 
-    register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
-    register_ioport_write(0x1d0, 1, 2, vbe_ioport_write_data, s);
+    register_ioport_write(dev, 0x1ce, 1, 2, vbe_ioport_write_index, s);
+    register_ioport_write(dev, 0x1d0, 1, 2, vbe_ioport_write_data, s);
 #endif
 #endif /* CONFIG_BOCHS_VBE */
 
@@ -2330,13 +2330,15 @@ int isa_vga_init(DisplayState *ds, uint8
                  unsigned long vga_ram_offset, int vga_ram_size)
 {
     VGAState *s;
+    QEMUDevice *dev = &s->qemu_dev;
 
     s = qemu_mallocz(sizeof(VGAState));
     if (!s)
         return -1;
+    qemu_register_device(dev);
 
     vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
-    vga_init(s);
+    vga_init(s, dev);
 
     graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump,
                          s->text_update, s);
@@ -2380,6 +2382,7 @@ int pci_vga_init(PCIBus *bus, DisplaySta
 {
     PCIVGAState *d;
     VGAState *s;
+    QEMUDevice *dev;
     uint8_t *pci_conf;
 
     d = (PCIVGAState *)pci_register_device(bus, "VGA",
@@ -2388,9 +2391,10 @@ int pci_vga_init(PCIBus *bus, DisplaySta
     if (!d)
         return -1;
     s = &d->vga_state;
+    dev = &d->dev.qemu_dev;
 
     vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
-    vga_init(s);
+    vga_init(s, dev);
 
     graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump,
                          s->text_update, s);
Index: kvm-userspace.io/qemu/hw/vga_int.h
===================================================================
--- kvm-userspace.io.orig/qemu/hw/vga_int.h
+++ kvm-userspace.io/qemu/hw/vga_int.h
@@ -157,6 +157,7 @@
 
 typedef struct VGAState {
     VGA_STATE_COMMON
+    QEMUDevice qemu_dev;
 } VGAState;
 
 static inline int c6_to_8(int v)
@@ -169,7 +170,7 @@ static inline int c6_to_8(int v)
 
 void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
                      unsigned long vga_ram_offset, int vga_ram_size);
-void vga_init(VGAState *s);
+void vga_init(VGAState *s, QEMUDevice *dev);
 uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
 void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
 void vga_invalidate_scanlines(VGAState *s, int y1, int y2);
Index: kvm-userspace.io/qemu/hw/virtio.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/virtio.c
+++ kvm-userspace.io/qemu/hw/virtio.c
@@ -337,26 +337,27 @@ static void virtio_map(PCIDevice *pci_de
 		       uint32_t addr, uint32_t size, int type)
 {
     VirtIODevice *vdev = to_virtio_device(pci_dev);
+    QEMUDevice *dev = &pci_dev->qemu_dev;
     int i;
 
     vdev->addr = addr;
     for (i = 0; i < 3; i++) {
-	register_ioport_write(addr, 20, 1 << i, virtio_ioport_write, vdev);
-	register_ioport_read(addr, 20, 1 << i, virtio_ioport_read, vdev);
+	register_ioport_write(dev, addr, 20, 1 << i, virtio_ioport_write, vdev);
+	register_ioport_read(dev, addr, 20, 1 << i, virtio_ioport_read, vdev);
     }
 
     if (vdev->config_len) {
-	register_ioport_write(addr + 20, vdev->config_len, 1,
+	register_ioport_write(dev, addr + 20, vdev->config_len, 1,
 			      virtio_config_writeb, vdev);
-	register_ioport_write(addr + 20, vdev->config_len, 2,
+	register_ioport_write(dev, addr + 20, vdev->config_len, 2,
 			      virtio_config_writew, vdev);
-	register_ioport_write(addr + 20, vdev->config_len, 4,
+	register_ioport_write(dev, addr + 20, vdev->config_len, 4,
 			      virtio_config_writel, vdev);
-	register_ioport_read(addr + 20, vdev->config_len, 1,
+	register_ioport_read(dev, addr + 20, vdev->config_len, 1,
 			     virtio_config_readb, vdev);
-	register_ioport_read(addr + 20, vdev->config_len, 2,
+	register_ioport_read(dev, addr + 20, vdev->config_len, 2,
 			     virtio_config_readw, vdev);
-	register_ioport_read(addr + 20, vdev->config_len, 4,
+	register_ioport_read(dev, addr + 20, vdev->config_len, 4,
 			     virtio_config_readl, vdev);
 
 	vdev->update_config(vdev, vdev->config);
Index: kvm-userspace.io/qemu/hw/vmport.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/vmport.c
+++ kvm-userspace.io/qemu/hw/vmport.c
@@ -38,6 +38,7 @@ typedef struct _VMPortState
 {
     IOPortReadFunc *func[VMPORT_ENTRIES];
     void *opaque[VMPORT_ENTRIES];
+    QEMUDevice qemu_dev;
 } VMPortState;
 
 static VMPortState port_state;
@@ -99,7 +100,10 @@ static uint32_t vmport_cmd_ram_size(void
 
 void vmport_init(void)
 {
-    register_ioport_read(0x5658, 1, 4, vmport_ioport_read, &port_state);
+    QEMUDevice *dev = &port_state.qemu_dev;
+
+    qemu_register_device(dev);
+    register_ioport_read(dev, 0x5658, 1, 4, vmport_ioport_read, &port_state);
 
     /* Register some generic port commands */
     vmport_register(VMPORT_CMD_GETVERSION, vmport_cmd_get_version, NULL);
Index: kvm-userspace.io/qemu/hw/vmware_vga.c
===================================================================
--- kvm-userspace.io.orig/qemu/hw/vmware_vga.c
+++ kvm-userspace.io/qemu/hw/vmware_vga.c
@@ -1107,10 +1107,11 @@ static int vmsvga_load(struct vmsvga_sta
     return 0;
 }
 
-static void vmsvga_init(struct vmsvga_state_s *s, DisplayState *ds,
+static void vmsvga_init(struct pci_vmsvga_state_s *p, DisplayState *ds,
                 uint8_t *vga_ram_base, unsigned long vga_ram_offset,
                 int vga_ram_size)
 {
+    struct vmsvga_state_s *s = &p->chip;
     s->ds = ds;
     s->vram = vga_ram_base;
     s->vram_size = vga_ram_size;
@@ -1127,7 +1128,7 @@ static void vmsvga_init(struct vmsvga_st
 #ifdef EMBED_STDVGA
     vga_common_init((VGAState *) s, ds,
                     vga_ram_base, vga_ram_offset, vga_ram_size);
-    vga_init((VGAState *) s);
+    vga_init((VGAState *) s, &p->card.qemu_dev);
 #endif
 }
 
@@ -1159,18 +1160,19 @@ static void pci_vmsvga_map_ioport(PCIDev
 {
     struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
     struct vmsvga_state_s *s = &d->chip;
+    QEMUDevice *dev = &pci_dev->qemu_dev;
 
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
+    register_ioport_read(dev, addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
                     1, 4, vmsvga_index_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
+    register_ioport_write(dev, addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
                     1, 4, vmsvga_index_write, s);
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
+    register_ioport_read(dev, addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
                     1, 4, vmsvga_value_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
+    register_ioport_write(dev, addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
                     1, 4, vmsvga_value_write, s);
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
+    register_ioport_read(dev, addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
                     1, 4, vmsvga_bios_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
+    register_ioport_write(dev, addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
                     1, 4, vmsvga_bios_write, s);
 }
 
@@ -1240,7 +1242,7 @@ void pci_vmsvga_init(PCIBus *bus, Displa
     pci_register_io_region(&s->card, 0, vga_ram_size,
                     PCI_ADDRESS_SPACE_MEM_PREFETCH, pci_vmsvga_map_mem);
 
-    vmsvga_init(&s->chip, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
+    vmsvga_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
 
     register_savevm("vmware_vga", 0, 0, pci_vmsvga_save, pci_vmsvga_load, s);
 }

-- 


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

  parent reply	other threads:[~2008-04-17 20:10 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-17 20:10 [patch 00/13] RFC: split the global mutex Marcelo Tosatti
2008-04-17 20:10 ` [patch 01/13] QEMU: get rid of global cpu_single_env Marcelo Tosatti
2008-04-17 20:10 ` [patch 02/13] QEMU: introduce QEMUDevice Marcelo Tosatti
2008-04-17 20:10 ` [patch 03/13] QEMU: make esp.c build conditional to SPARC target Marcelo Tosatti
2008-04-17 20:10 ` Marcelo Tosatti [this message]
2008-04-17 20:10 ` [patch 05/13] QEMU: add a mutex to protect IRQ chip data structures Marcelo Tosatti
2008-04-17 20:10 ` [patch 06/13] QEMU: plug QEMUDevice pt2 / iomem awareness Marcelo Tosatti
2008-04-17 20:10 ` [patch 07/13] QEMU: grab device lock for ioport/iomem processing Marcelo Tosatti
2008-04-17 20:10 ` [patch 08/13] QEMU: character device locking Marcelo Tosatti
2008-04-17 20:10 ` [patch 09/13] QEMU: network " Marcelo Tosatti
2008-04-17 20:10 ` [patch 10/13] QEMU: get rid of aiocb cache Marcelo Tosatti
2008-04-17 20:10 ` [patch 11/13] QEMU: block device locking Marcelo Tosatti
2008-04-17 20:10 ` [patch 12/13] QEMU: scsi-disk reentrancy fix Marcelo Tosatti
2008-04-17 20:10 ` [patch 13/13] QEMU/KVM: get rid of global lock Marcelo Tosatti
2008-04-20 11:16 ` [patch 00/13] RFC: split the global mutex Avi Kivity
2008-04-21  0:00   ` Marcelo Tosatti
2008-04-21  6:10     ` Avi Kivity

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080417203026.508456803@localhost.localdomain \
    --to=mtosatti@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=avi@qumranet.com \
    --cc=kvm-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox