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);
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)
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)
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
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));
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)
/*
* 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) {
destroy_nic(pci_match_fn, d);
break;
}
-
- qdev_free(&d->qdev);
}
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);
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 */