qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 4/4] qdev: switch reset to post-order


From: Michael S. Tsirkin
Subject: Re: [Qemu-devel] [PATCH 4/4] qdev: switch reset to post-order
Date: Thu, 19 Dec 2013 20:23:14 +0200

On Fri, Dec 06, 2013 at 05:54:27PM +0100, Paolo Bonzini wrote:
> Post-order is the only sensible direction for the reset signals.
> For example, suppose pre-order is used and the parent has some data
> structures that cache children state (for example a list of active
> requests).  When the reset method is invoked on the parent, these caches
> could be in any state.
> 
> If post-order is used, on the other hand, these will be in a known state
> when the reset method is invoked on the parent.
> 
> This change means that it is no longer possible to block the visit of
> the devices, so the callback is changed to return void.  This is not
> a problem, because PCI was returning 1 exactly in order to achieve the
> same ordering that this patch implements.
> 
> PCI can then rely on the qdev core having sent a "reset signal" (whatever
> that means) to the device, and only do the PCI-specific initialization
> with pci_do_device_reset.
> 
> Signed-off-by: Paolo Bonzini <address@hidden>
> ---
>  hw/core/qdev.c         |    6 +++---
>  hw/pci/pci.c           |   31 ++++++++++++++++---------------
>  include/hw/qdev-core.h |    2 +-
>  3 files changed, 20 insertions(+), 19 deletions(-)
> 
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index 1c114b7..9ba8ab1 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -233,19 +233,19 @@ static int qbus_reset_one(BusState *bus, void *opaque)
>  {
>      BusClass *bc = BUS_GET_CLASS(bus);
>      if (bc->reset) {
> -        return bc->reset(bus);
> +        bc->reset(bus);
>      }
>      return 0;
>  }
>  
>  void qdev_reset_all(DeviceState *dev)
>  {
> -    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, 
> NULL);
> +    qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, 
> NULL);
>  }
>  
>  void qbus_reset_all(BusState *bus)
>  {
> -    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, 
> NULL);
> +    qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, 
> NULL);
>  }
>  
>  void qbus_reset_all_fn(void *opaque)
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index 0efc544..e10d74b 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -46,7 +46,7 @@
>  static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
>  static char *pcibus_get_dev_path(DeviceState *dev);
>  static char *pcibus_get_fw_dev_path(DeviceState *dev);
> -static int pcibus_reset(BusState *qbus);
> +static void pcibus_reset(BusState *qbus);
>  
>  static Property pci_props[] = {
>      DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
> @@ -165,16 +165,10 @@ void pci_device_deassert_intx(PCIDevice *dev)
>      }
>  }
>  
> -/*
> - * This function is called on #RST and FLR.
> - * FLR if PCI_EXP_DEVCTL_BCR_FLR is set
> - */
> -void pci_device_reset(PCIDevice *dev)
> +static void pci_do_device_reset(PCIDevice *dev)
>  {
>      int r;
>  
> -    qdev_reset_all(&dev->qdev);
> -
>      dev->irq_state = 0;
>      pci_update_irq_status(dev);
>      pci_device_deassert_intx(dev);
> @@ -207,27 +201,34 @@ void pci_device_reset(PCIDevice *dev)
>  }
>  
>  /*
> + * This function is called on #RST and FLR.
> + * FLR if PCI_EXP_DEVCTL_BCR_FLR is set
> + */
> +void pci_device_reset(PCIDevice *dev)
> +{
> +    qdev_reset_all(&dev->qdev);
> +    pci_do_device_reset(dev);
> +}
> +
> +/*
>   * Trigger pci bus reset under a given bus.
> - * To be called on RST# assert.
> + * Called via qbus_reset_all on RST# assert, after the devices
> + * have been reset qdev_reset_all-ed already.
>   */
> -static int pcibus_reset(BusState *qbus)
> +static void pcibus_reset(BusState *qbus)
>  {
>      PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
>      int i;
>  
>      for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
>          if (bus->devices[i]) {
> -            pci_device_reset(bus->devices[i]);
> +            pci_do_device_reset(bus->devices[i]);
>          }
>      }
>  
>      for (i = 0; i < bus->nirq; i++) {
>          assert(bus->irq_count[i] == 0);
>      }
> -
> -    /* 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(PCIBus *bus, DeviceState *parent)
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index 21ea2c6..409fd71 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -178,7 +178,7 @@ struct BusClass {
>       * bindings can be found at http://playground.sun.com/1275/bindings/.
>       */
>      char *(*get_fw_dev_path)(DeviceState *dev);
> -    int (*reset)(BusState *bus);
> +    void (*reset)(BusState *bus);
>      /* maximum devices allowed on the bus, 0: no limit. */
>      int max_dev;
>  };
> -- 
> 1.7.1


This seems to break a bunch of stuff:

/scm/qemu/hw/s390x/virtio-ccw.c: In function
‘virtual_css_bus_class_init’:
/scm/qemu/hw/s390x/virtio-ccw.c:47:14: error: assignment from
incompatible pointer type [-Werror]
     k->reset = virtual_css_bus_reset;
              ^





reply via email to

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