OSDN Git Service

acpi: explicitly account for >1 device per slot
authorMichael S. Tsirkin <mst@redhat.com>
Sun, 15 Apr 2012 09:00:52 +0000 (12:00 +0300)
committerMichael S. Tsirkin <mst@redhat.com>
Sun, 15 Apr 2012 09:17:23 +0000 (12:17 +0300)
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>
hw/acpi_piix4.c

index 11c1f85..585da4e 100644 (file)
@@ -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)