On Wed, Nov 17, 2010 at 01:50:25PM +0900, Isaku Yamahata wrote:
> Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp>
> Signed-off-by: Anthony Liguori <aligu...@us.ibm.com>
> ---
>  hw/pci.c |   38 ++++++++++++++++++++++++++++++++++----
>  hw/pci.h |    3 +++
>  2 files changed, 37 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/pci.c b/hw/pci.c
> index 962886e..b6f58de 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -43,12 +43,14 @@
>  
>  static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
>  static char *pcibus_get_dev_path(DeviceState *dev);
> +static int pcibus_reset(BusState *qbus);
>  
>  struct BusInfo pci_bus_info = {
>      .name       = "PCI",
>      .size       = sizeof(PCIBus),
>      .print_dev  = pcibus_dev_print,
>      .get_dev_path = pcibus_get_dev_path,
> +    .reset      = pcibus_reset,
>      .props      = (Property[]) {
>          DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
>          DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
> @@ -133,7 +135,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;
>  
> @@ -161,9 +163,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

Double negation :)

> +           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.
> +         */

Is this doing anything besides give devices another way to shoot
themselves in the foot?  Handling this all in one place seems easier,
assuming everyone just calls pci_device_reset_default in the end.  Or do
you expect some devices to avoid calling pci_device_reset_default?

> +        qdev_reset_all(&dev->qdev);
> +        pci_device_reset_default(dev);
> +    }
> +}
> +
> +/*
> + * Trigger pci bus reset under a given bus.
> + * This functions emulates RST#.
> + */
> +void pci_bus_reset(PCIBus *bus)
>  {
> -    PCIBus *bus = opaque;
>      int i;
>  
>      for (i = 0; i < bus->nirq; i++) {
> @@ -176,6 +198,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;
> @@ -230,7 +261,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 7100804..280a2f8 100644
> --- a/hw/pci.h
> +++ b/hw/pci.h
> @@ -225,6 +225,9 @@ 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_bus_reset(PCIBus *bus);
> +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

Reply via email to