[SeaBIOS] [PATCH 7/8] Convert pciinit.c to use standard list manipulation code.

Kevin O'Connor kevin at koconnor.net
Sun Jun 9 04:23:19 CEST 2013


Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/pciinit.c | 64 ++++++++++++++++++++++++++++-------------------------------
 1 file changed, 30 insertions(+), 34 deletions(-)

diff --git a/src/pciinit.c b/src/pciinit.c
index bb9355f..446dddf 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -13,7 +13,8 @@
 #include "config.h" // CONFIG_*
 #include "memmap.h" // add_e820
 #include "paravirt.h" // RamSize
-#include "dev-q35.h"
+#include "dev-q35.h" // Q35_HOST_BRIDGE_PCIEXBAR_ADDR
+#include "list.h" // struct hlist_node
 
 /* PM Timer ticks per second (HZ) */
 #define PM_TIMER_FREQUENCY  3579545
@@ -47,13 +48,13 @@ struct pci_region_entry {
     u64 align;
     int is64;
     enum pci_region_type type;
-    struct pci_region_entry *next;
+    struct hlist_node node;
 };
 
 struct pci_region {
     /* pci region assignments */
     u64 base;
-    struct pci_region_entry *list;
+    struct hlist_head list;
 };
 
 struct pci_bus {
@@ -539,30 +540,30 @@ static int pci_bios_bridge_region_is64(struct pci_region *r,
     }
     if ((pmem & PCI_PREF_RANGE_TYPE_MASK) != PCI_PREF_RANGE_TYPE_64)
        return 0;
-    struct pci_region_entry *entry = r->list;
-    while (entry) {
+    struct pci_region_entry *entry;
+    hlist_for_each_entry(entry, &r->list, node) {
         if (!entry->is64)
             return 0;
-        entry = entry->next;
     }
     return 1;
 }
 
 static u64 pci_region_align(struct pci_region *r)
 {
-    if (!r->list)
-        return 1;
-    // The first entry in the sorted list has the largest alignment
-    return r->list->align;
+    struct pci_region_entry *entry;
+    hlist_for_each_entry(entry, &r->list, node) {
+        // The first entry in the sorted list has the largest alignment
+        return entry->align;
+    }
+    return 1;
 }
 
 static u64 pci_region_sum(struct pci_region *r)
 {
-    struct pci_region_entry *entry = r->list;
     u64 sum = 0;
-    while (entry) {
+    struct pci_region_entry *entry;
+    hlist_for_each_entry(entry, &r->list, node) {
         sum += entry->size;
-        entry = entry->next;
     }
     return sum;
 }
@@ -570,18 +571,14 @@ static u64 pci_region_sum(struct pci_region *r)
 static void pci_region_migrate_64bit_entries(struct pci_region *from,
                                              struct pci_region *to)
 {
-    struct pci_region_entry **pprev = &from->list, **last = &to->list;
-    while (*pprev) {
-        struct pci_region_entry *entry = *pprev;
-        if (!entry->is64) {
-            pprev = &entry->next;
+    struct hlist_node **pprev, **last = &to->list.first;
+    struct pci_region_entry *entry;
+    hlist_for_each_entry_safe(entry, pprev, &from->list, node) {
+        if (!entry->is64)
             continue;
-        }
         // Move from source list to destination list.
-        *pprev = entry->next;
-        entry->next = NULL;
-        *last = entry;
-        last = &entry->next;
+        hlist_del(&entry->node);
+        hlist_add(&entry->node, last);
     }
 }
 
@@ -602,14 +599,13 @@ pci_region_create_entry(struct pci_bus *bus, struct pci_device *dev,
     entry->is64 = is64;
     entry->type = type;
     // Insert into list in sorted order.
-    struct pci_region_entry **pprev;
-    for (pprev = &bus->r[type].list; *pprev; pprev = &(*pprev)->next) {
-        struct pci_region_entry *pos = *pprev;
+    struct hlist_node **pprev;
+    struct pci_region_entry *pos;
+    hlist_for_each_entry_safe(pos, pprev, &bus->r[type].list, node) {
         if (pos->align < align || (pos->align == align && pos->size < size))
             break;
     }
-    entry->next = *pprev;
-    *pprev = entry;
+    hlist_add(&entry->node, pprev);
     return entry;
 }
 
@@ -748,17 +744,17 @@ pci_region_map_one_entry(struct pci_region_entry *entry, u64 addr)
 
 static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r)
 {
-    struct pci_region_entry *entry = r->list;
-    while (entry) {
+    struct hlist_node **pprev;
+    struct pci_region_entry *entry;
+    hlist_for_each_entry_safe(entry, pprev, &r->list, node) {
         u64 addr = r->base;
         r->base += entry->size;
         if (entry->bar == -1)
             // Update bus base address if entry is a bridge region
             busses[entry->dev->secondary_bus].r[entry->type].base = addr;
         pci_region_map_one_entry(entry, addr);
-        struct pci_region_entry *next = entry->next;
+        hlist_del(&entry->node);
         free(entry);
-        entry = next;
     }
 }
 
@@ -766,8 +762,8 @@ static void pci_bios_map_devices(struct pci_bus *busses)
 {
     if (pci_bios_init_root_regions(busses)) {
         struct pci_region r64_mem, r64_pref;
-        r64_mem.list = NULL;
-        r64_pref.list = NULL;
+        r64_mem.list.first = NULL;
+        r64_pref.list.first = NULL;
         pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_MEM],
                                          &r64_mem);
         pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_PREFMEM],
-- 
1.7.11.7




More information about the SeaBIOS mailing list