* [Qemu-devel] [PATCH 1/6] qdev: Make qbus_walk_children() call busfn for root bus.
2010-09-02 9:25 [Qemu-devel] [PATCH 0/6 v3] introduce qbus reset callback and pci bus reset clean up Isaku Yamahata
@ 2010-09-02 9:25 ` Isaku Yamahata
2010-09-23 17:11 ` Markus Armbruster
2010-09-02 9:25 ` [Qemu-devel] [PATCH 2/6] qdev: introduce reset call back for qbus level Isaku Yamahata
` (5 subsequent siblings)
6 siblings, 1 reply; 9+ messages in thread
From: Isaku Yamahata @ 2010-09-02 9:25 UTC (permalink / raw)
To: qemu-devel
Cc: gleb, glommer, blauwirbel, yamahata, alex.williamson, avi,
pbonzini
Make qbus_walk_children() call busfn for root bus.
and it fixes qbus_realize_all().
The current qbus_walk_children() doesn't call busfn for root bus.
It cause qbus_relialize_all() to fail to call realize the system bus.
This patch also refactor qbus_walk_children() a bit.
Another only user of busfn, qbus_find_child_bus(), isn't affected by this.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
hw/qdev-core.h | 2 ++
hw/qdev.c | 51 ++++++++++++++++++++++++++++++---------------------
2 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/hw/qdev-core.h b/hw/qdev-core.h
index 5fdee3a..a9b7692 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -186,6 +186,8 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
/* Returns > 0 if either devfn or busfn terminate walk, 0 otherwise. */
int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
qbus_walkerfn *busfn, void *opaque);
+int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
+ qbus_walkerfn *busfn, void *opaque);
DeviceState *qbus_find_child_dev(BusState *bus, const char *id);
BusState *qbus_find_child_bus(BusState *bus, const char *id);
diff --git a/hw/qdev.c b/hw/qdev.c
index a981e05..c1ba6b8 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -296,33 +296,42 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
qbus_walkerfn *busfn, void *opaque)
{
DeviceState *dev;
+ int err;
+
+ if (busfn) {
+ err = busfn(bus, opaque);
+ if (err) {
+ return err;
+ }
+ }
QLIST_FOREACH(dev, &bus->children, sibling) {
- BusState *child;
- int err = 0;
+ err = qdev_walk_children(dev, devfn, busfn, opaque);
+ if (err < 0) {
+ return err;
+ }
+ }
- if (devfn) {
- err = devfn(dev, opaque);
+ return 0;
+}
+
+int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
+ qbus_walkerfn *busfn, void *opaque)
+{
+ BusState *bus;
+ int err;
+
+ if (devfn) {
+ err = devfn(dev, opaque);
+ if (err) {
+ return err;
}
+ }
- if (err > 0) {
+ QLIST_FOREACH(bus, &dev->child_bus, sibling) {
+ err = qbus_walk_children(bus, devfn, busfn, opaque);
+ if (err < 0) {
return err;
- } else if (err == 0) {
- QLIST_FOREACH(child, &dev->child_bus, sibling) {
- if (busfn) {
- err = busfn(child, opaque);
- if (err > 0) {
- return err;
- }
- }
-
- if (err == 0) {
- err = qbus_walk_children(child, devfn, busfn, opaque);
- if (err > 0) {
- return err;
- }
- }
- }
}
}
--
1.7.1.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/6] qdev: Make qbus_walk_children() call busfn for root bus.
2010-09-02 9:25 ` [Qemu-devel] [PATCH 1/6] qdev: Make qbus_walk_children() call busfn for root bus Isaku Yamahata
@ 2010-09-23 17:11 ` Markus Armbruster
0 siblings, 0 replies; 9+ messages in thread
From: Markus Armbruster @ 2010-09-23 17:11 UTC (permalink / raw)
To: Isaku Yamahata
Cc: gleb, glommer, qemu-devel, blauwirbel, alex.williamson, avi,
pbonzini
Please excuse my late reply. I'm so much behind in this list, it's not
funny anymore.
I agree with Anthony, this series looks nice. A few remarks inline.
Isaku Yamahata <yamahata@valinux.co.jp> writes:
> Make qbus_walk_children() call busfn for root bus.
Please don't repeat the subject in the body.
While I'm nit-picking about commit messages: subject is a heading, and
as such it shouldn't end in a period.
> and it fixes qbus_realize_all().
Can't see qbus_realize_all() in master; I guess it's in Anthony's tree.
> The current qbus_walk_children() doesn't call busfn for root bus.
> It cause qbus_relialize_all() to fail to call realize the system bus.
Do you mean qbus_realize_all()?
> This patch also refactor qbus_walk_children() a bit.
> Another only user of busfn, qbus_find_child_bus(), isn't affected by this.
>
> Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
> ---
> hw/qdev-core.h | 2 ++
> hw/qdev.c | 51 ++++++++++++++++++++++++++++++---------------------
> 2 files changed, 32 insertions(+), 21 deletions(-)
>
> diff --git a/hw/qdev-core.h b/hw/qdev-core.h
> index 5fdee3a..a9b7692 100644
> --- a/hw/qdev-core.h
> +++ b/hw/qdev-core.h
> @@ -186,6 +186,8 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
> /* Returns > 0 if either devfn or busfn terminate walk, 0 otherwise. */
> int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
> qbus_walkerfn *busfn, void *opaque);
> +int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
> + qbus_walkerfn *busfn, void *opaque);
>
> DeviceState *qbus_find_child_dev(BusState *bus, const char *id);
> BusState *qbus_find_child_bus(BusState *bus, const char *id);
> diff --git a/hw/qdev.c b/hw/qdev.c
> index a981e05..c1ba6b8 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -296,33 +296,42 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
> qbus_walkerfn *busfn, void *opaque)
> {
> DeviceState *dev;
> + int err;
> +
> + if (busfn) {
> + err = busfn(bus, opaque);
> + if (err) {
> + return err;
> + }
> + }
>
> QLIST_FOREACH(dev, &bus->children, sibling) {
> - BusState *child;
> - int err = 0;
> + err = qdev_walk_children(dev, devfn, busfn, opaque);
> + if (err < 0) {
> + return err;
> + }
> + }
>
> - if (devfn) {
> - err = devfn(dev, opaque);
> + return 0;
> +}
> +
> +int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
> + qbus_walkerfn *busfn, void *opaque)
> +{
> + BusState *bus;
> + int err;
> +
> + if (devfn) {
> + err = devfn(dev, opaque);
> + if (err) {
> + return err;
> }
> + }
>
> - if (err > 0) {
> + QLIST_FOREACH(bus, &dev->child_bus, sibling) {
> + err = qbus_walk_children(bus, devfn, busfn, opaque);
> + if (err < 0) {
> return err;
> - } else if (err == 0) {
> - QLIST_FOREACH(child, &dev->child_bus, sibling) {
> - if (busfn) {
> - err = busfn(child, opaque);
> - if (err > 0) {
> - return err;
> - }
> - }
> -
> - if (err == 0) {
> - err = qbus_walk_children(child, devfn, busfn, opaque);
> - if (err > 0) {
> - return err;
> - }
> - }
> - }
> }
> }
Isn't it funny that functions that work on a qdev sub-trees always come
in pairs? qdev_foo() and qbus_foo(). That's because of the split
between device and bus nodes.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 2/6] qdev: introduce reset call back for qbus level.
2010-09-02 9:25 [Qemu-devel] [PATCH 0/6 v3] introduce qbus reset callback and pci bus reset clean up Isaku Yamahata
2010-09-02 9:25 ` [Qemu-devel] [PATCH 1/6] qdev: Make qbus_walk_children() call busfn for root bus Isaku Yamahata
@ 2010-09-02 9:25 ` Isaku Yamahata
2010-09-02 9:25 ` [Qemu-devel] [PATCH 3/6] qdev: introduce a helper function which triggers reset from a given device Isaku Yamahata
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Isaku Yamahata @ 2010-09-02 9:25 UTC (permalink / raw)
To: qemu-devel
Cc: gleb, glommer, blauwirbel, yamahata, alex.williamson, avi,
pbonzini
and make it called via qbus_reset_all().
The qbus reset callback will be used by pci bus reset.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
hw/qdev-core.h | 3 +++
hw/qdev.c | 10 +++++++++-
2 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/hw/qdev-core.h b/hw/qdev-core.h
index a9b7692..49ac87a 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -58,12 +58,15 @@ typedef int (qbus_del_devfn)(BusState *bus, DeviceState *dev);
typedef void (qbus_realizefn)(BusState *bus);
+typedef int (qbus_resetfn)(BusState *bus);
+
struct BusInfo {
const char *name;
size_t size;
qbus_add_devfn *add_dev;
qbus_del_devfn *del_dev;
qbus_realizefn *realize;
+ qbus_resetfn *reset;
bus_get_dev_path get_dev_path;
Property *props;
};
diff --git a/hw/qdev.c b/hw/qdev.c
index c1ba6b8..9300d7f 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -166,9 +166,17 @@ static int qdev_reset_one(DeviceState *dev, void *opaque)
return 0;
}
+static int qbus_reset_one(BusState *bus, void *opaque)
+{
+ if (bus->info->reset) {
+ return bus->info->reset(bus);
+ }
+ return 0;
+}
+
void qbus_reset_all(BusState *bus)
{
- qbus_walk_children(bus, qdev_reset_one, NULL, NULL);
+ qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
}
static int qdev_realize_one(DeviceState *dev, void *opaque)
--
1.7.1.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 3/6] qdev: introduce a helper function which triggers reset from a given device.
2010-09-02 9:25 [Qemu-devel] [PATCH 0/6 v3] introduce qbus reset callback and pci bus reset clean up Isaku Yamahata
2010-09-02 9:25 ` [Qemu-devel] [PATCH 1/6] qdev: Make qbus_walk_children() call busfn for root bus Isaku Yamahata
2010-09-02 9:25 ` [Qemu-devel] [PATCH 2/6] qdev: introduce reset call back for qbus level Isaku Yamahata
@ 2010-09-02 9:25 ` Isaku Yamahata
2010-09-02 9:25 ` [Qemu-devel] [PATCH 4/6] pci: make pci reset use qdev reset frame work Isaku Yamahata
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Isaku Yamahata @ 2010-09-02 9:25 UTC (permalink / raw)
To: qemu-devel
Cc: gleb, glommer, blauwirbel, yamahata, alex.williamson, avi,
pbonzini
introduce a helper function which triggers reset on device tree
from a given device.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
hw/qdev-core.h | 1 +
hw/qdev.c | 5 +++++
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/hw/qdev-core.h b/hw/qdev-core.h
index 49ac87a..20ebe1f 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -195,6 +195,7 @@ int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
DeviceState *qbus_find_child_dev(BusState *bus, const char *id);
BusState *qbus_find_child_bus(BusState *bus, const char *id);
+void qdev_reset_all(DeviceState *dev);
void qbus_reset_all(BusState *bus);
void qbus_realize_all(BusState *bus);
diff --git a/hw/qdev.c b/hw/qdev.c
index 9300d7f..191dfac 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -174,6 +174,11 @@ static int qbus_reset_one(BusState *bus, void *opaque)
return 0;
}
+void qdev_reset_all(DeviceState *dev)
+{
+ qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
+}
+
void qbus_reset_all(BusState *bus)
{
qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
--
1.7.1.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 4/6] pci: make pci reset use qdev reset frame work.
2010-09-02 9:25 [Qemu-devel] [PATCH 0/6 v3] introduce qbus reset callback and pci bus reset clean up Isaku Yamahata
` (2 preceding siblings ...)
2010-09-02 9:25 ` [Qemu-devel] [PATCH 3/6] qdev: introduce a helper function which triggers reset from a given device Isaku Yamahata
@ 2010-09-02 9:25 ` Isaku Yamahata
2010-09-02 9:25 ` [Qemu-devel] [PATCH 5/6] pci: teach pci devices that have reset callback how to reset common registers Isaku Yamahata
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Isaku Yamahata @ 2010-09-02 9:25 UTC (permalink / raw)
To: qemu-devel
Cc: gleb, glommer, blauwirbel, yamahata, alex.williamson, avi,
pbonzini
make pci reset use qdev reset frame work.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
hw/pci.c | 38 ++++++++++++++++++++++++++++++++++----
hw/pci.h | 2 ++
2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/hw/pci.c b/hw/pci.c
index 655fead..4c99390 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -62,6 +62,7 @@ struct PCIBus {
static char *pcibus_get_dev_path(DeviceState *dev);
static int pcibus_add_dev(BusState *qbus, DeviceState *qdev);
static int pcibus_del_dev(BusState *qbus, DeviceState *qdev);
+static int pcibus_reset(BusState *qbus);
static struct BusInfo pci_bus_info = {
.name = "PCI",
@@ -69,6 +70,7 @@ static struct BusInfo pci_bus_info = {
.get_dev_path = pcibus_get_dev_path,
.add_dev = pcibus_add_dev,
.del_dev = pcibus_del_dev,
+ .reset = pcibus_reset,
.props = (Property[]) {
DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
@@ -153,7 +155,7 @@ static void pci_update_irq_status(PCIDevice *dev)
}
}
-static void pci_device_reset(PCIDevice *dev)
+void pci_device_reset_default(PCIDevice *dev)
{
int r;
@@ -181,9 +183,29 @@ static void pci_device_reset(PCIDevice *dev)
pci_update_mappings(dev);
}
-static void pci_bus_reset(void *opaque)
+static void pci_device_reset(PCIDevice *dev)
+{
+ if (!dev->qdev.info) {
+ /* not all pci devices haven't been qdev'fied yet
+ TODO: remove this when all pci devices are qdev'fied. */
+ pci_device_reset_default(dev);
+ } else {
+ /*
+ * TODO:
+ * each device should know what to do on RST#.
+ * move pci_device_reset_default() into each callback.
+ */
+ qdev_reset_all(&dev->qdev);
+ pci_device_reset_default(dev);
+ }
+}
+
+/*
+ * Trigger pci bus reset under a given bus.
+ * This functions emulates RST#.
+ */
+static void pci_bus_reset(PCIBus *bus)
{
- PCIBus *bus = opaque;
int i;
for (i = 0; i < bus->nirq; i++) {
@@ -196,6 +218,15 @@ static void pci_bus_reset(void *opaque)
}
}
+static int pcibus_reset(BusState *qbus)
+{
+ pci_bus_reset(DO_UPCAST(PCIBus, qbus, qbus));
+
+ /* topology traverse is done by pci_bus_reset().
+ Tell qbus/qdev walker not to traverse the tree */
+ return 1;
+}
+
static void pci_host_bus_register(int domain, PCIBus *bus)
{
struct PCIHostBus *host;
@@ -250,7 +281,6 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
pci_host_bus_register(0, bus); /* for now only pci domain 0 is supported */
vmstate_register(NULL, -1, &vmstate_pcibus, bus);
- qemu_register_reset(pci_bus_reset, bus);
}
PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min)
diff --git a/hw/pci.h b/hw/pci.h
index 51ba8b6..8e72d78 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -214,6 +214,8 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
void *irq_opaque, int devfn_min, int nirq);
+void pci_device_reset_default(PCIDevice *dev);
+
void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base);
PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
--
1.7.1.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 5/6] pci: teach pci devices that have reset callback how to reset common registers.
2010-09-02 9:25 [Qemu-devel] [PATCH 0/6 v3] introduce qbus reset callback and pci bus reset clean up Isaku Yamahata
` (3 preceding siblings ...)
2010-09-02 9:25 ` [Qemu-devel] [PATCH 4/6] pci: make pci reset use qdev reset frame work Isaku Yamahata
@ 2010-09-02 9:25 ` Isaku Yamahata
2010-09-02 9:25 ` [Qemu-devel] [PATCH 6/6] pci bridge: implement secondary bus reset Isaku Yamahata
2010-09-02 13:27 ` [Qemu-devel] Re: [PATCH 0/6 v3] introduce qbus reset callback and pci bus reset clean up Anthony Liguori
6 siblings, 0 replies; 9+ messages in thread
From: Isaku Yamahata @ 2010-09-02 9:25 UTC (permalink / raw)
To: qemu-devel
Cc: gleb, glommer, blauwirbel, yamahata, alex.williamson, avi,
pbonzini
teach pci devices that have reset callback how to reset common registers.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
hw/e1000.c | 1 +
hw/lsi53c895a.c | 2 ++
hw/pci.c | 6 ------
hw/pcnet.c | 1 +
hw/rtl8139.c | 2 ++
hw/virtio-pci.c | 1 +
6 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/hw/e1000.c b/hw/e1000.c
index 9972b48..1987ef6 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1077,6 +1077,7 @@ static void e1000_reset(void *opaque)
memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init);
d->rxbuf_min_shift = 1;
memset(&d->tx, 0, sizeof d->tx);
+ pci_device_reset_default(&d->dev);
}
static NetClientInfo net_e1000_info = {
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index ecff004..c1a920b 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -358,6 +358,8 @@ static void lsi_soft_reset(LSIState *s)
qemu_free(s->current);
s->current = NULL;
}
+
+ pci_device_reset_default(&s->dev);
}
static int lsi_dma_40bit(LSIState *s)
diff --git a/hw/pci.c b/hw/pci.c
index 4c99390..e23ac1b 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -190,13 +190,7 @@ static void pci_device_reset(PCIDevice *dev)
TODO: remove this when all pci devices are qdev'fied. */
pci_device_reset_default(dev);
} else {
- /*
- * TODO:
- * each device should know what to do on RST#.
- * move pci_device_reset_default() into each callback.
- */
qdev_reset_all(&dev->qdev);
- pci_device_reset_default(dev);
}
}
diff --git a/hw/pcnet.c b/hw/pcnet.c
index c8291bb..2910221 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -2025,6 +2025,7 @@ static void pci_reset(DeviceState *dev)
PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev.qdev, dev);
pcnet_h_reset(&d->state);
+ pci_device_reset_default(&d->pci_dev);
}
static PCIDeviceInfo pcnet_info = {
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 690d07b..a26a33a 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -1261,6 +1261,8 @@ static void rtl8139_reset(DeviceState *d)
/* reset tally counters */
RTL8139TallyCounters_clear(&s->tally_counters);
+
+ pci_device_reset_default(&s->dev);
}
static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters)
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 8fe6b3b..5a170a1 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -186,6 +186,7 @@ static void virtio_pci_reset(DeviceState *d)
virtio_reset(proxy->vdev);
msix_reset(&proxy->pci_dev);
proxy->bugs = 0;
+ pci_device_reset_default(&proxy->pci_dev);
}
static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
--
1.7.1.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 6/6] pci bridge: implement secondary bus reset.
2010-09-02 9:25 [Qemu-devel] [PATCH 0/6 v3] introduce qbus reset callback and pci bus reset clean up Isaku Yamahata
` (4 preceding siblings ...)
2010-09-02 9:25 ` [Qemu-devel] [PATCH 5/6] pci: teach pci devices that have reset callback how to reset common registers Isaku Yamahata
@ 2010-09-02 9:25 ` Isaku Yamahata
2010-09-02 13:27 ` [Qemu-devel] Re: [PATCH 0/6 v3] introduce qbus reset callback and pci bus reset clean up Anthony Liguori
6 siblings, 0 replies; 9+ messages in thread
From: Isaku Yamahata @ 2010-09-02 9:25 UTC (permalink / raw)
To: qemu-devel
Cc: gleb, glommer, blauwirbel, yamahata, alex.williamson, avi,
pbonzini
implement secondary bus reset.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
hw/pci.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/hw/pci.c b/hw/pci.c
index e23ac1b..183f595 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1626,6 +1626,9 @@ static void pci_bridge_update_mappings(PCIBus *b)
static void pci_bridge_write_config(PCIDevice *d,
uint32_t address, uint32_t val, int len)
{
+ PCIBridge *s = container_of(d, PCIBridge, dev);
+ uint16_t bridge_control = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
+
pci_default_write_config(d, address, val, len);
if (/* io base/limit */
@@ -1634,10 +1637,18 @@ static void pci_bridge_write_config(PCIDevice *d,
/* memory base/limit, prefetchable base/limit and
io base/limit upper 16 */
ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) {
- PCIBridge *s = container_of(d, PCIBridge, dev);
PCIBus *secondary_bus = &s->bus;
pci_bridge_update_mappings(secondary_bus);
}
+
+ if (ranges_overlap(address, len, PCI_BRIDGE_CONTROL, 2)) {
+ uint16_t new = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
+ if (!(bridge_control & PCI_BRIDGE_CTL_BUS_RESET) &&
+ (new & PCI_BRIDGE_CTL_BUS_RESET)) {
+ /* 0 -> 1 */
+ pci_bus_reset(&s->bus);
+ }
+ }
}
PCIBus *pci_find_bus(PCIBus *bus, int bus_num)
--
1.7.1.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] Re: [PATCH 0/6 v3] introduce qbus reset callback and pci bus reset clean up
2010-09-02 9:25 [Qemu-devel] [PATCH 0/6 v3] introduce qbus reset callback and pci bus reset clean up Isaku Yamahata
` (5 preceding siblings ...)
2010-09-02 9:25 ` [Qemu-devel] [PATCH 6/6] pci bridge: implement secondary bus reset Isaku Yamahata
@ 2010-09-02 13:27 ` Anthony Liguori
6 siblings, 0 replies; 9+ messages in thread
From: Anthony Liguori @ 2010-09-02 13:27 UTC (permalink / raw)
To: Isaku Yamahata
Cc: gleb, glommer, qemu-devel, blauwirbel, alex.williamson, avi,
pbonzini
On 09/02/2010 04:25 AM, Isaku Yamahata wrote:
> I recreated the patch series based on your qbus walker of
> git://repo.or.cz/qemu/aliguori.git
>
> Anthony, can you please review the first three patches and merge them
> if okay?
>
They look really nice, I'll merge them into my branch.
> BTW what's the merge plan of the repo? Any chance to merge the walker part
> first?
>
I'm still working on vmsd refactoring but I can split out an initial
series that doesn't contain that and includes your reset changes.
Regards,
Anthony LIguori
> Patch description:
> Introduce bus reset callback at qbus layer and clean up pci bus reset
> by utilizing it. At last implement pci secondary bus reset which is
> my motivation.
> But I suppose scsi bus and ide bus also can take advantage of
> this patch series.
>
> Changes v2 -> v3:
> - rebased to Anthony's qdev clean up tree.
> - utilize qbus walker.
>
> Changes v1 -> v2:
> - addressed personal feed back from Gerd.
> - reset signal are triggered by bus and propagated down into device.
> - Only 5/8 is modified. Other patches remains same.
>
> Isaku Yamahata (6):
> qdev: Make qbus_walk_children() call busfn for root bus.
> qdev: introduce reset call back for qbus level.
> qdev: introduce a helper function which triggers reset from a given
> device.
> pci: make pci reset use qdev reset frame work.
> pci: teach pci devices that have reset callback how to reset common
> registers.
> pci bridge: implement secondary bus reset.
>
> hw/e1000.c | 1 +
> hw/lsi53c895a.c | 2 +
> hw/pci.c | 45 +++++++++++++++++++++++++++++++++----
> hw/pci.h | 2 +
> hw/pcnet.c | 1 +
> hw/qdev-core.h | 6 +++++
> hw/qdev.c | 66 ++++++++++++++++++++++++++++++++++++------------------
> hw/rtl8139.c | 2 +
> hw/virtio-pci.c | 1 +
> 9 files changed, 99 insertions(+), 27 deletions(-)
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread