diff mbox

[v2,4/8] pci: make pci_device_reset() aware of qdev.

Message ID 2f375d90b4ba1b3da1b47d4ba302911d390d44e2.1280973617.git.yamahata@valinux.co.jp
State New
Headers show

Commit Message

Isaku Yamahata Aug. 5, 2010, 2:09 a.m. UTC
Make pci_device_reset handle qdevfied device and non-converted device
diff mbox

Patch

differently.
Later they will be handled differently.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
 hw/pci.c |   35 +++++++++++++++++++++++++++++++++--
 hw/pci.h |    1 +
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 6a614d1..c48bb3e 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -130,8 +130,7 @@  static void pci_update_irq_status(PCIDevice *dev)
     }
 }
 
-/* Reset the device in response to RST# signal. */
-void pci_device_reset(PCIDevice *dev)
+void pci_device_reset_default(PCIDevice *dev)
 {
     int r;
 
@@ -159,6 +158,38 @@  void pci_device_reset(PCIDevice *dev)
     pci_update_mappings(dev);
 }
 
+/* Reset the device in response to RST# signal. */
+void pci_device_reset(PCIDevice *dev)
+{
+    if (!dev->qdev.info || !dev->qdev.info->reset) {
+        /* for not qdevified device or reset isn't implemented property.
+         * So take care of them in PCI generic layer.
+         */
+        pci_device_reset_default(dev);
+        return;
+    }
+
+    /*
+     * There are two paths to reset pci device. Each resets does partially.
+     * qemu_system_reset()
+     *  -> pci_device_reset() with bus
+     *     -> pci_device_reset_default() which resets pci common part.
+     *  -> DeviceState::reset: each device specific reset hanlder
+     *     which resets device specific part.
+     *
+     * TODO:
+     * It requires two execution paths to reset the device fully.
+     * It is confusing and prone to error. Each device should know all
+     * its states.
+     * So move this part to each device specific callback.
+     */
+
+    /* For now qdev_reset() is called directly by qemu_system_reset() */
+    /* qdev_reset(&dev->qdev); */
+
+    pci_device_reset_default(dev);
+}
+
 /*
  * Trigger pci bus reset under a given bus.
  * This functions emulates RST#.
diff --git a/hw/pci.h b/hw/pci.h
index be05662..ce1feb4 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -210,6 +210,7 @@  PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min);
 
 void pci_bus_reset(PCIBus *bus);
 void pci_device_reset(PCIDevice *dev);
+void pci_device_reset_default(PCIDevice *dev);
 
 void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                   void *irq_opaque, int nirq);