/* kmem_cache to get tables with 128 byte alignement */
 extern struct kmem_cache *amd_iommu_irq_cache;
 
+/* Make iterating over all pci segment easier */
+#define for_each_pci_segment(pci_seg) \
+       list_for_each_entry((pci_seg), &amd_iommu_pci_seg_list, list)
+#define for_each_pci_segment_safe(pci_seg, next) \
+       list_for_each_entry_safe((pci_seg), (next), &amd_iommu_pci_seg_list, list)
 /*
  * Make iterating over all IOMMUs easier
  */
        unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
 };
 
+/*
+ * This structure contains information about one PCI segment in the system.
+ */
+struct amd_iommu_pci_seg {
+       /* List with all PCI segments in the system */
+       struct list_head list;
+
+       /* PCI segment number */
+       u16 id;
+};
+
 /*
  * Structure where we save information about one hardware AMD IOMMU in the
  * system.
        u16 cap_ptr;
 
        /* pci domain of this IOMMU */
-       u16 pci_seg;
+       struct amd_iommu_pci_seg *pci_seg;
 
        /* start of exclusion range of that IOMMU */
        u64 exclusion_start;
 extern struct list_head hpet_map;
 extern struct list_head acpihid_map;
 
+/*
+ * List with all PCI segments in the system. This list is not locked because
+ * it is only written at driver initialization time
+ */
+extern struct list_head amd_iommu_pci_seg_list;
+
 /*
  * List with all IOMMUs in the system. This list is not locked because it is
  * only written and read at driver initialization or suspend time
 
 LIST_HEAD(amd_iommu_unity_map);                /* a list of required unity mappings
                                           we find in ACPI */
 
+LIST_HEAD(amd_iommu_pci_seg_list);     /* list of all PCI segments */
 LIST_HEAD(amd_iommu_list);             /* list of all AMD IOMMUs in the
                                           system */
 
        return 0;
 }
 
+/* Allocate PCI segment data structure */
+static struct amd_iommu_pci_seg *__init alloc_pci_segment(u16 id)
+{
+       struct amd_iommu_pci_seg *pci_seg;
+
+       pci_seg = kzalloc(sizeof(struct amd_iommu_pci_seg), GFP_KERNEL);
+       if (pci_seg == NULL)
+               return NULL;
+
+       pci_seg->id = id;
+       list_add_tail(&pci_seg->list, &amd_iommu_pci_seg_list);
+
+       return pci_seg;
+}
+
+static struct amd_iommu_pci_seg *__init get_pci_segment(u16 id)
+{
+       struct amd_iommu_pci_seg *pci_seg;
+
+       for_each_pci_segment(pci_seg) {
+               if (pci_seg->id == id)
+                       return pci_seg;
+       }
+
+       return alloc_pci_segment(id);
+}
+
+static void __init free_pci_segments(void)
+{
+       struct amd_iommu_pci_seg *pci_seg, *next;
+
+       for_each_pci_segment_safe(pci_seg, next) {
+               list_del(&pci_seg->list);
+               kfree(pci_seg);
+       }
+}
+
 static void __init free_iommu_one(struct amd_iommu *iommu)
 {
        free_cwwb_sem(iommu);
  */
 static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
 {
+       struct amd_iommu_pci_seg *pci_seg;
        int ret;
 
+       pci_seg = get_pci_segment(h->pci_seg);
+       if (pci_seg == NULL)
+               return -ENOMEM;
+       iommu->pci_seg = pci_seg;
+
        raw_spin_lock_init(&iommu->lock);
        iommu->cmd_sem_val = 0;
 
         */
        iommu->devid   = h->devid;
        iommu->cap_ptr = h->cap_ptr;
-       iommu->pci_seg = h->pci_seg;
        iommu->mmio_phys = h->mmio_phys;
 
        switch (h->type) {
        amd_iommu_dev_table = NULL;
 
        free_iommu_all();
+       free_pci_segments();
 }
 
 /* SB IOAPIC is always on this device in AMD systems */