qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [v15 10/15] pci: Introduce device hot reset


From: Cao jin
Subject: [Qemu-devel] [v15 10/15] pci: Introduce device hot reset
Date: Tue, 5 Jan 2016 09:20:51 +0800

From: Chen Fan <address@hidden>

The secondary bus reset in bridge control register setting trigger
a hot reset, Specially for vfio device, we usually need to do a hot
reset for the host bus other than the device reset.

Signed-off-by: Chen Fan <address@hidden>
---
 hw/core/qdev.c         | 24 ++++++++++++++++++++++++
 hw/pci/pci_bridge.c    |  2 +-
 include/hw/qdev-core.h |  3 +++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index b3ad467..9c48bae 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -311,6 +311,13 @@ static int qdev_reset_one(DeviceState *dev, void *opaque)
     return 0;
 }
 
+static int qdev_hot_reset_one(DeviceState *dev, void *opaque)
+{
+    device_hot_reset(dev);
+
+    return 0;
+}
+
 static int qbus_reset_one(BusState *bus, void *opaque)
 {
     BusClass *bc = BUS_GET_CLASS(bus);
@@ -335,6 +342,11 @@ void qbus_reset_all(BusState *bus)
     qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
 }
 
+void qbus_hot_reset_all(BusState *bus)
+{
+    qbus_walk_children(bus, NULL, NULL, qdev_hot_reset_one, qbus_reset_one, 
NULL);
+}
+
 void qbus_reset_all_fn(void *opaque)
 {
     BusState *bus = opaque;
@@ -1284,6 +1296,18 @@ void device_reset(DeviceState *dev)
     }
 }
 
+void device_hot_reset(DeviceState *dev)
+{
+    DeviceClass *klass = DEVICE_GET_CLASS(dev);
+
+    if (klass->hot_reset) {
+        klass->hot_reset(dev);
+        return;
+    }
+
+    device_reset(dev);
+}
+
 Object *qdev_get_machine(void)
 {
     static Object *dev;
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index 40c97b1..f1903db 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -268,7 +268,7 @@ void pci_bridge_write_config(PCIDevice *d,
     newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
     if (~oldctl & newctl & PCI_BRIDGE_CTL_BUS_RESET) {
         /* Trigger hot reset on 0->1 transition. */
-        qbus_reset_all(&s->sec_bus.qbus);
+        qbus_hot_reset_all(&s->sec_bus.qbus);
     }
 }
 
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index c537969..e9fe4b3 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -131,6 +131,7 @@ typedef struct DeviceClass {
 
     /* callbacks */
     void (*reset)(DeviceState *dev);
+    void (*hot_reset)(DeviceState *dev);
     DeviceRealize realize;
     DeviceUnrealize unrealize;
 
@@ -351,6 +352,7 @@ void qdev_reset_all_fn(void *opaque);
  */
 void qbus_reset_all(BusState *bus);
 void qbus_reset_all_fn(void *opaque);
+void qbus_hot_reset_all(BusState *bus);
 
 /* This should go away once we get rid of the NULL bus hack */
 BusState *sysbus_get_default(void);
@@ -372,6 +374,7 @@ void qdev_machine_init(void);
  * Reset a single device (by calling the reset method).
  */
 void device_reset(DeviceState *dev);
+void device_hot_reset(DeviceState *dev);
 
 const struct VMStateDescription *qdev_get_vmsd(DeviceState *dev);
 
-- 
1.9.3






reply via email to

[Prev in Thread] Current Thread [Next in Thread]