Patchwork [20/24] pci: windup acpi-based hotplug

login
register
mail settings
Submitter Gerd Hoffmann
Date Sept. 25, 2009, 7:42 p.m.
Message ID <1253907769-1067-21-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/34307/
State Superseded
Headers show

Comments

Gerd Hoffmann - Sept. 25, 2009, 7:42 p.m.
Switch over acpi-based PCI hotplug for pc over to the new
qdev-based pci hotplugging.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/acpi.c        |   41 +++++++++++++++++++++--------------------
 hw/pc.c          |    3 +--
 hw/pc.h          |    2 +-
 hw/pci-hotplug.c |   15 ++-------------
 sysemu.h         |    7 +------
 5 files changed, 26 insertions(+), 42 deletions(-)

Patch

diff --git a/hw/acpi.c b/hw/acpi.c
index b14b9f4..5091044 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -694,20 +694,30 @@  static uint32_t pciej_read(void *opaque, uint32_t addr)
 
 static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
 {
-#if defined (TARGET_I386)
+    BusState *bus = opaque;
+    DeviceState *qdev;
+    PCIDevice *dev;
     int slot = ffs(val) - 1;
 
-    pci_device_hot_remove_success(0, slot);
+    QLIST_FOREACH(qdev, &bus->children, sibling) {
+        dev = DO_UPCAST(PCIDevice, qdev, qdev);
+        if (PCI_SLOT(dev->devfn) == slot) {
+#if defined (TARGET_I386)
+            pci_device_hot_remove_success(dev);
 #endif
+            qdev_free(qdev);
+        }
+    }
+
 
 #if defined(DEBUG)
     printf("pciej write %x <== %d\n", addr, val);
 #endif
 }
 
-static void piix4_device_hot_add(int bus, int slot, int state);
+static int piix4_device_hotplug(PCIDevice *dev, int state);
 
-void piix4_acpi_system_hot_add_init(void)
+void piix4_acpi_system_hot_add_init(PCIBus *bus)
 {
     register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe);
     register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, &gpe);
@@ -715,10 +725,10 @@  void piix4_acpi_system_hot_add_init(void)
     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(PCI_EJ_BASE, 4, 4, pciej_write, NULL);
-    register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, NULL);
+    register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, bus);
+    register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, bus);
 
-    qemu_system_device_hot_add_register(piix4_device_hot_add);
+    pci_bus_hotplug(bus, piix4_device_hotplug);
 }
 
 static void enable_device(struct pci_status *p, struct gpe_regs *g, int slot)
@@ -733,8 +743,10 @@  static void disable_device(struct pci_status *p, struct gpe_regs *g, int slot)
     p->down |= (1 << slot);
 }
 
-static void piix4_device_hot_add(int bus, int slot, int state)
+static int piix4_device_hotplug(PCIDevice *dev, int state)
 {
+    int slot = PCI_SLOT(dev->devfn);
+
     pci0_status.up = 0;
     pci0_status.down = 0;
     if (state)
@@ -745,18 +757,7 @@  static void piix4_device_hot_add(int bus, int slot, int state)
         qemu_set_irq(pm_state->irq, 1);
         qemu_set_irq(pm_state->irq, 0);
     }
-}
-
-static qemu_system_device_hot_add_t device_hot_add_callback;
-void qemu_system_device_hot_add_register(qemu_system_device_hot_add_t callback)
-{
-    device_hot_add_callback = callback;
-}
-
-void qemu_system_device_hot_add(int pcibus, int slot, int state)
-{
-    if (device_hot_add_callback)
-        device_hot_add_callback(pcibus, slot, state);
+    return 0;
 }
 
 struct acpi_table_header
diff --git a/hw/pc.c b/hw/pc.c
index bc2875e..ce31629 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1354,8 +1354,6 @@  static void pc_init1(ram_addr_t ram_size,
             pci_nic_init(nd, "e1000", NULL);
     }
 
-    piix4_acpi_system_hot_add_init();
-
     if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
         fprintf(stderr, "qemu: too many IDE bus\n");
         exit(1);
@@ -1406,6 +1404,7 @@  static void pc_init1(ram_addr_t ram_size,
             qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
             qdev_init(eeprom);
         }
+        piix4_acpi_system_hot_add_init(pci_bus);
     }
 
     if (i440fx_state) {
diff --git a/hw/pc.h b/hw/pc.h
index c9cdd4a..cf4ff39 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -106,7 +106,7 @@  int acpi_table_add(const char *table_desc);
 i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                        qemu_irq sci_irq);
 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
-void piix4_acpi_system_hot_add_init(void);
+void piix4_acpi_system_hot_add_init(PCIBus *bus);
 
 /* hpet.c */
 extern int no_hpet;
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index 255decd..ac3d1ae 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -181,8 +181,6 @@  void pci_device_hot_add(Monitor *mon, const QDict *qdict)
         monitor_printf(mon, "invalid type: %s\n", type);
 
     if (dev) {
-        qemu_system_device_hot_add(pci_bus_num(dev->bus),
-                                   PCI_SLOT(dev->devfn), 1);
         monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n",
                        0, pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
                        PCI_FUNC(dev->devfn));
@@ -206,8 +204,7 @@  void pci_device_hot_remove(Monitor *mon, const char *pci_addr)
         monitor_printf(mon, "slot %d empty\n", slot);
         return;
     }
-
-    qemu_system_device_hot_add(bus, slot, 0);
+    qdev_unplug(&d->qdev);
 }
 
 void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict)
@@ -226,16 +223,10 @@  static int pci_match_fn(void *dev_private, void *arg)
 /*
  * OS has executed _EJ0 method, we now can remove the device
  */
-void pci_device_hot_remove_success(int pcibus, int slot)
+void pci_device_hot_remove_success(PCIDevice *d)
 {
-    PCIDevice *d = pci_find_device(pcibus, slot, 0);
     int class_code;
 
-    if (!d) {
-        monitor_printf(cur_mon, "invalid slot %d\n", slot);
-        return;
-    }
-
     class_code = d->config_read(d, PCI_CLASS_DEVICE+1, 1);
 
     switch(class_code) {
@@ -246,7 +237,5 @@  void pci_device_hot_remove_success(int pcibus, int slot)
         destroy_nic(pci_match_fn, d);
         break;
     }
-
-    qdev_free(&d->qdev);
 }
 
diff --git a/sysemu.h b/sysemu.h
index 8bf90ee..0ebbb03 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -197,11 +197,6 @@  BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type);
 extern QemuOpts *drive_add(const char *file, const char *fmt, ...);
 extern DriveInfo *drive_init(QemuOpts *arg, void *machine, int *fatal_error);
 
-/* acpi */
-typedef void (*qemu_system_device_hot_add_t)(int pcibus, int slot, int state);
-void qemu_system_device_hot_add_register(qemu_system_device_hot_add_t callback);
-void qemu_system_device_hot_add(int pcibus, int slot, int state);
-
 /* device-hotplug */
 
 typedef int (dev_match_fn)(void *dev_private, void *arg);
@@ -215,7 +210,7 @@  void pci_device_hot_add(Monitor *mon, const QDict *qdict);
 void drive_hot_add(Monitor *mon, const QDict *qdict);
 void pci_device_hot_remove(Monitor *mon, const char *pci_addr);
 void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
-void pci_device_hot_remove_success(int pcibus, int slot);
+void pci_device_hot_remove_success(PCIDevice *dev);
 
 /* serial ports */