All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.