Patchwork [14/25] pci: factor out the logic to get pci device from address.

login
register
mail settings
Submitter Isaku Yamahata
Date Oct. 2, 2009, 10:31 a.m.
Message ID <1254479517-25845-15-git-send-email-yamahata@valinux.co.jp>
Download mbox | patch
Permalink /patch/34821/
State Superseded
Headers show

Comments

Isaku Yamahata - Oct. 2, 2009, 10:31 a.m.
factor out conversion logic from io port address into bus+dev+func
with bit shift operation and conversion bus+dev+func into pci device.
They will be used later by pcie support.
This patch also eliminates the logic duplication.

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

Patch

diff --git a/hw/pci.c b/hw/pci.c
index 7620bb5..b11f5c3 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -609,44 +609,25 @@  void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
         pci_update_mappings(d);
 }
 
-void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
+static void pci_data_write_common(PCIDevice *pci_dev,
+                                  uint32_t config_addr, uint32_t val, int len)
 {
-    PCIBus *s = opaque;
-    PCIDevice *pci_dev;
-    int config_addr, bus_num;
-
-#if 0
-    PCI_DPRINTF("pci_data_write: addr=%08"PRIx32" val=%08"PRIx32" len=%d\n",
-                addr, val, len);
-#endif
-    bus_num = (addr >> 16) & 0xff;
-    s = pci_find_bus(s, bus_num);
-    if (!s)
-        return;
-    pci_dev = s->devices[(addr >> 8) & 0xff];
+    assert(len == 1 || len == 2 || len == 4);
     if (!pci_dev)
         return;
-    config_addr = addr & 0xff;
-    PCI_DPRINTF("pci_config_write: %s: "
-                "addr=%02x val=%08"PRI32x" len=%d\n",
-                pci_dev->name, config_addr, val, len);
+
+    PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRI32x" len=%d\n",
+                __func__, pci_dev->name, config_addr, val, len);
     pci_dev->config_write(pci_dev, config_addr, val, len);
 }
 
-uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
+static uint32_t pci_data_read_common(PCIDevice *pci_dev,
+                                     uint32_t config_addr, int len)
 {
-    PCIBus *s = opaque;
-    PCIDevice *pci_dev;
-    int config_addr, bus_num;
     uint32_t val;
 
-    bus_num = (addr >> 16) & 0xff;
-    s = pci_find_bus(s, bus_num);
-    if (!s)
-        goto fail;
-    pci_dev = s->devices[(addr >> 8) & 0xff];
+    assert(len == 1 || len == 2 || len == 4);
     if (!pci_dev) {
-    fail:
         switch(len) {
         case 1:
             val = 0xff;
@@ -659,21 +640,50 @@  uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
             val = 0xffffffff;
             break;
         }
-        goto the_end;
+    } else {
+        val = pci_dev->config_read(pci_dev, config_addr, len);
+        PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRIx32" len=%d\n",
+                    __func__, pci_dev->name, config_addr, val, len);
     }
-    config_addr = addr & 0xff;
-    val = pci_dev->config_read(pci_dev, config_addr, len);
-    PCI_DPRINTF("pci_config_read: %s: "
-                "addr=%02x val=%08"PRIx32" len=%d\n",
-                pci_dev->name, config_addr, val, len);
- the_end:
+
 #if 0
-    PCI_DPRINTF("pci_data_read: addr=%08"PRIx32" val=%08"PRIx32" len=%d\n",
-                addr, val, len);
+    PCI_DPRINTF("%s: addr=%08"PRIx32" val=%08"PRIx32" len=%d\n",
+                __func__, addr, val, len);
 #endif
     return val;
 }
 
+static inline PCIDevice *pci_addr_to_dev(PCIBus *bus, uint32_t addr)
+{
+    int bus_num = (addr >> 16) & 0xff;
+    unsigned int devfn = (addr >> 8) & 0xff;
+
+    return pci_find_device(bus, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
+}
+
+static inline uint32_t pci_addr_to_config(uint32_t addr)
+{
+    return addr & 0xff;
+}
+
+void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
+{
+    PCIBus *s = opaque;
+#if 0
+    PCI_DPRINTF("pci_data_write: addr=%08"PRIx32" val=%08"PRIx32" len=%d\n",
+                addr, val, len);
+#endif
+
+    pci_data_write_common(pci_addr_to_dev(s, addr), pci_addr_to_config(addr),
+                          val, len);
+}
+
+uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
+{
+    PCIBus *s = opaque;
+    return pci_data_read_common(pci_addr_to_dev(s, addr),
+                                pci_addr_to_config(addr), len);
+}
 /***********************************************************/
 /* generic PCI irq support */