aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2012-04-15 12:00:52 +0300
committerMichael S. Tsirkin <mst@redhat.com>2012-04-15 12:17:23 +0300
commit54bfa546a0b5af335128ef5c477f8af9834df498 (patch)
treebf9af539c14f94d22ae575f1f16f255e6497cce1
parent9290f364c1f0c0a5a2ee8e03607f4804455c0d0e (diff)
acpi: explicitly account for >1 device per slot
Slot present bit is cleared apparently for each device. Hotplug and non hotplug devices should not mix normally, and we only set the bit when we add a device so it should all work out, but it's more robust to explicitly account for more than one device per slot. Acked-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--hw/acpi_piix4.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 11c1f8532b..585da4e3eb 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -287,6 +287,7 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
DeviceState *qdev, *next;
BusState *bus = qdev_get_parent_bus(&s->dev.qdev);
int slot = ffs(slots) - 1;
+ bool slot_free = true;
/* Mark request as complete */
s->pci0_status.down &= ~(1U << slot);
@@ -294,11 +295,17 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
PCIDevice *dev = PCI_DEVICE(qdev);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
- if (PCI_SLOT(dev->devfn) == slot && !pc->no_hotplug) {
- s->pci0_slot_device_present &= ~(1U << slot);
- qdev_free(qdev);
+ if (PCI_SLOT(dev->devfn) == slot) {
+ if (pc->no_hotplug) {
+ slot_free = false;
+ } else {
+ qdev_free(qdev);
+ }
}
}
+ if (slot_free) {
+ s->pci0_slot_device_present &= ~(1U << slot);
+ }
}
static void piix4_update_hotplug(PIIX4PMState *s)