[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 5/8] qdev: introduce bus reset callback and helpe
From: |
Isaku Yamahata |
Subject: |
[Qemu-devel] [PATCH v2 5/8] qdev: introduce bus reset callback and helper functions. |
Date: |
Thu, 5 Aug 2010 11:09:02 +0900 |
Introduce bus reset callback to support bus reset at qbus layer
and a function to trigger bus reset.
Now qdev reset callback is triggered by parent qbus reset callback.
And qdev should trigger child qbus reset callback.
Signed-off-by: Isaku Yamahata <address@hidden>
---
changes v1 -> v2
- eliminate qemu_register_reset() from qdev_create()
as Gerd suggested.
- Inserted qdev_reset_default() as appropriate.
This is required for qdev which has reset callback and child bus.
---
hw/esp.c | 2 ++
hw/lsi53c895a.c | 1 +
hw/qdev.c | 42 +++++++++++++++++++++++++++++++++++++++---
hw/qdev.h | 7 +++++++
4 files changed, 49 insertions(+), 3 deletions(-)
diff --git a/hw/esp.c b/hw/esp.c
index 349052a..cafc257 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -423,6 +423,8 @@ static void esp_hard_reset(DeviceState *d)
{
ESPState *s = container_of(d, ESPState, busdev.qdev);
+ qdev_reset_default(d);
+
memset(s->rregs, 0, ESP_REGS);
memset(s->wregs, 0, ESP_REGS);
s->rregs[ESP_TCHI] = TCHI_FAS100A; // Indicate fas100a
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index bd7b661..33a8eb2 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2042,6 +2042,7 @@ static void lsi_scsi_reset(DeviceState *dev)
{
LSIState *s = DO_UPCAST(LSIState, dev.qdev, dev);
+ qdev_reset_default(dev);
lsi_soft_reset(s);
}
diff --git a/hw/qdev.c b/hw/qdev.c
index 322b315..8352f20 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -256,6 +256,14 @@ DeviceState *qdev_device_add(QemuOpts *opts)
return qdev;
}
+void qdev_reset_default(DeviceState *dev)
+{
+ BusState *bus;
+ QLIST_FOREACH(bus, &dev->child_bus, sibling) {
+ qbus_reset(bus);
+ }
+}
+
/*
* reset the device.
* Bring the device into initial known state (to some extent)
@@ -275,8 +283,11 @@ DeviceState *qdev_device_add(QemuOpts *opts)
*/
void qdev_reset(DeviceState *dev)
{
- if (dev->info->reset)
+ if (dev->info->reset) {
dev->info->reset(dev);
+ } else {
+ qdev_reset_default(dev);
+ }
}
static void qdev_reset_fn(void *opaque)
@@ -299,7 +310,6 @@ int qdev_init(DeviceState *dev)
qdev_free(dev);
return rc;
}
- qemu_register_reset(qdev_reset_fn, dev);
if (dev->info->vmsd) {
vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
dev->instance_id_alias,
@@ -671,6 +681,29 @@ static BusState *qbus_find(const char *path)
}
}
+void qbus_reset_default(BusState *bus)
+{
+ DeviceState *dev;
+ QLIST_FOREACH(dev, &bus->children, sibling) {
+ qdev_reset(dev);
+ }
+}
+
+/* trigger bus reset */
+void qbus_reset(BusState *bus)
+{
+ if (bus->info->reset) {
+ bus->info->reset(bus);
+ } else {
+ qbus_reset_default(bus);
+ }
+}
+
+static void qbus_reset_fn(void *opaque)
+{
+ qbus_reset(opaque);
+}
+
void qbus_create_inplace(BusState *bus, BusInfo *info,
DeviceState *parent, const char *name)
{
@@ -705,7 +738,10 @@ void qbus_create_inplace(BusState *bus, BusInfo *info,
QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
parent->num_child_bus++;
}
-
+ if (!parent || !parent->info) {
+ /* parent device takes care of child bus reset */
+ qemu_register_reset(qbus_reset_fn, bus);
+ }
}
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
diff --git a/hw/qdev.h b/hw/qdev.h
index 10f6769..af76f31 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -50,6 +50,7 @@ struct DeviceState {
typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
typedef char *(*bus_get_dev_path)(DeviceState *dev);
+typedef void (*bus_resetfn)(BusState *bus);
struct BusInfo {
const char *name;
@@ -57,6 +58,9 @@ struct BusInfo {
bus_dev_printfn print_dev;
bus_get_dev_path get_dev_path;
Property *props;
+
+ /* bus reset callbacks */
+ bus_resetfn reset;
};
struct BusState {
@@ -163,6 +167,7 @@ extern DeviceInfo *device_info_list;
void qdev_register(DeviceInfo *info);
void qdev_reset(DeviceState *dev);
+void qdev_reset_default(DeviceState *dev);
/* Register device properties. */
/* GPIO inputs also double as IRQ sinks. */
@@ -179,6 +184,8 @@ void qbus_create_inplace(BusState *bus, BusInfo *info,
DeviceState *parent, const char *name);
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
void qbus_free(BusState *bus);
+void qbus_reset(BusState *bus);
+void qbus_reset_default(BusState *bus);
#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
--
1.7.1.1
- [Qemu-devel] [PATCH v2 0/8] qbus reset callback and implement pci bus reset, Isaku Yamahata, 2010/08/04
- [Qemu-devel] [PATCH v2 5/8] qdev: introduce bus reset callback and helper functions.,
Isaku Yamahata <=
- [Qemu-devel] [PATCH v2 3/8] pci: export pci_bus_reset() and pci_device_reset() for later use., Isaku Yamahata, 2010/08/04
- [Qemu-devel] [PATCH v2 7/8] pci: eliminate work around in pci_device_reset()., Isaku Yamahata, 2010/08/04
- [Qemu-devel] [PATCH v2 4/8] pci: make pci_device_reset() aware of qdev., Isaku Yamahata, 2010/08/04
- [Qemu-devel] [PATCH v2 6/8] pci: use qbus bus reset callback., Isaku Yamahata, 2010/08/04
- [Qemu-devel] [PATCH v2 1/8] apb: fix typo., Isaku Yamahata, 2010/08/04
- [Qemu-devel] [PATCH v2 2/8] qdev: export qdev_reset() for later use., Isaku Yamahata, 2010/08/04
- [Qemu-devel] [PATCH v2 8/8] pci bridge: implement secondary bus reset., Isaku Yamahata, 2010/08/04