[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/2] acpi: don't clear up/down on each host change
From: |
Michael S. Tsirkin |
Subject: |
[Qemu-devel] [PATCH 2/2] acpi: don't clear up/down on each host change |
Date: |
Sun, 18 Mar 2012 19:06:34 +0200 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
Instead of clearing up slot on each change, we clear:
- up: when slot is accessed
- down: when device is ejected
Signed-off-by: Michael S. Tsirkin <address@hidden>
---
hw/acpi_piix4.c | 32 +++++++++++++++++++++++++++-----
1 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 797ed24..b6bb486 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -49,6 +49,7 @@
struct pci_status {
uint32_t up;
uint32_t down;
+ BusState *bus;
};
typedef struct PIIX4PMState {
@@ -268,6 +269,21 @@ static const VMStateDescription vmstate_acpi = {
}
};
+/* Did guest access any devices in a slot? If yes, clear the up bit. */
+static void piix4_update_up(struct pci_status *s)
+{
+ DeviceState *qdev, *next;
+ int slot;
+
+ QTAILQ_FOREACH_SAFE(qdev, &s->bus->children, sibling, next) {
+ PCIDevice *pdev = PCI_DEVICE(qdev);
+ slot = PCI_SLOT(pdev->devfn);
+ if (pdev->accessed_since_reset) {
+ s->up &= ~(1 << slot);
+ }
+ }
+}
+
static void piix4_update_hotplug(PIIX4PMState *s)
{
PCIDevice *dev = &s->dev;
@@ -290,6 +306,7 @@ static void piix4_update_hotplug(PIIX4PMState *s)
static void piix4_reset(void *opaque)
{
PIIX4PMState *s = opaque;
+ struct pci_status *pci0_status = &s->pci0_status;
uint8_t *pci_conf = s->dev.config;
pci_conf[0x58] = 0;
@@ -301,6 +318,8 @@ static void piix4_reset(void *opaque)
/* Mark SMM as already inited (until KVM supports SMM). */
pci_conf[0x5B] = 0x02;
}
+ pci0_status->up = 0;
+ pci0_status->down = 0;
piix4_update_hotplug(s);
}
@@ -454,6 +473,7 @@ static uint32_t pcihotplug_read(void *opaque, uint32_t addr)
struct pci_status *g = opaque;
switch (addr) {
case PCI_BASE:
+ piix4_update_up(g);
val = g->up;
break;
case PCI_BASE + 4:
@@ -490,10 +510,13 @@ static uint32_t pciej_read(void *opaque, uint32_t addr)
static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
{
- BusState *bus = opaque;
+ struct pci_status *s = opaque;
+ BusState *bus = s->bus;
DeviceState *qdev, *next;
int slot = ffs(val) - 1;
+ s->down &= ~(1 << slot);
+ s->up &= ~(1 << slot);
QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
PCIDevice *dev = PCI_DEVICE(qdev);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
@@ -524,6 +547,7 @@ static int piix4_device_hotplug(DeviceState *qdev,
PCIDevice *dev,
static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
{
struct pci_status *pci0_status = &s->pci0_status;
+ pci0_status->bus = qdev_get_parent_bus(&s->dev.qdev);
register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s);
register_ioport_read(GPE_BASE, GPE_LEN, 1, gpe_readb, s);
@@ -532,8 +556,8 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus,
PIIX4PMState *s)
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, bus);
- register_ioport_read(PCI_EJ_BASE, 4, 4, pciej_read, bus);
+ register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, pci0_status);
+ register_ioport_read(PCI_EJ_BASE, 4, 4, pciej_read, pci0_status);
register_ioport_write(PCI_RMV_BASE, 4, 4, pcirmv_write, s);
register_ioport_read(PCI_RMV_BASE, 4, 4, pcirmv_read, s);
@@ -567,8 +591,6 @@ static int piix4_device_hotplug(DeviceState *qdev,
PCIDevice *dev,
return 0;
}
- s->pci0_status.up = 0;
- s->pci0_status.down = 0;
if (state == PCI_HOTPLUG_ENABLED) {
enable_device(s, slot);
} else {
--
1.7.9.111.gf3fb0