Commit f38db651 authored by Muli Ben-Yehuda's avatar Muli Ben-Yehuda Committed by Andi Kleen

[PATCH] Calgary IOMMU: consolidate per bus data structures

Move the tce_table_kva array, disabled bitmap and bus_to_phb array
into a new per bus 'struct calgary_bus_info'. Also slightly reorganize
build_tce_table and tce_table_setparms to avoid exporting bus_info to
tce.c.
Signed-off-by: default avatarMuli Ben-Yehuda <muli@il.ibm.com>
Signed-off-by: default avatarJon Mason <jdmason@us.ibm.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
parent 5f4a7a93
...@@ -111,17 +111,17 @@ static const unsigned long phb_offsets[] = { ...@@ -111,17 +111,17 @@ static const unsigned long phb_offsets[] = {
0xB000 /* PHB3 */ 0xB000 /* PHB3 */
}; };
static char bus_to_phb[MAX_PHB_BUS_NUM];
void* tce_table_kva[MAX_PHB_BUS_NUM];
unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED; unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED;
static int translate_empty_slots __read_mostly = 0; static int translate_empty_slots __read_mostly = 0;
static int calgary_detected __read_mostly = 0; static int calgary_detected __read_mostly = 0;
/* struct calgary_bus_info {
* the bitmap of PHBs the user requested that we disable void *tce_space;
* translation on. int translation_disabled;
*/ signed char phbid;
static DECLARE_BITMAP(translation_disabled, MAX_PHB_BUS_NUM); };
static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, };
static void tce_cache_blast(struct iommu_table *tbl); static void tce_cache_blast(struct iommu_table *tbl);
...@@ -149,7 +149,7 @@ static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen) ...@@ -149,7 +149,7 @@ static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen)
static inline int translate_phb(struct pci_dev* dev) static inline int translate_phb(struct pci_dev* dev)
{ {
int disabled = test_bit(dev->bus->number, translation_disabled); int disabled = bus_info[dev->bus->number].translation_disabled;
return !disabled; return !disabled;
} }
...@@ -454,7 +454,7 @@ static struct dma_mapping_ops calgary_dma_ops = { ...@@ -454,7 +454,7 @@ static struct dma_mapping_ops calgary_dma_ops = {
static inline int busno_to_phbid(unsigned char num) static inline int busno_to_phbid(unsigned char num)
{ {
return bus_to_phb[num]; return bus_info[num].phbid;
} }
static inline unsigned long split_queue_offset(unsigned char num) static inline unsigned long split_queue_offset(unsigned char num)
...@@ -631,6 +631,10 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar) ...@@ -631,6 +631,10 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar)
if (ret) if (ret)
return ret; return ret;
tbl = dev->sysdata;
tbl->it_base = (unsigned long)bus_info[dev->bus->number].tce_space;
tce_free(tbl, 0, tbl->it_size);
calgary_reserve_regions(dev); calgary_reserve_regions(dev);
/* set TARs for each PHB */ /* set TARs for each PHB */
...@@ -824,7 +828,7 @@ static int __init calgary_init(void) ...@@ -824,7 +828,7 @@ static int __init calgary_init(void)
calgary_init_one_nontraslated(dev); calgary_init_one_nontraslated(dev);
continue; continue;
} }
if (!tce_table_kva[dev->bus->number] && !translate_empty_slots) { if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots) {
pci_dev_put(dev); pci_dev_put(dev);
continue; continue;
} }
...@@ -844,7 +848,7 @@ static int __init calgary_init(void) ...@@ -844,7 +848,7 @@ static int __init calgary_init(void)
pci_dev_put(dev); pci_dev_put(dev);
continue; continue;
} }
if (!tce_table_kva[dev->bus->number] && !translate_empty_slots) if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots)
continue; continue;
calgary_disable_translation(dev); calgary_disable_translation(dev);
calgary_free_tar(dev); calgary_free_tar(dev);
...@@ -894,9 +898,8 @@ void __init detect_calgary(void) ...@@ -894,9 +898,8 @@ void __init detect_calgary(void)
for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
int dev; int dev;
struct calgary_bus_info *info = &bus_info[bus];
tce_table_kva[bus] = NULL; info->phbid = -1;
bus_to_phb[bus] = -1;
if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY)
continue; continue;
...@@ -907,12 +910,9 @@ void __init detect_calgary(void) ...@@ -907,12 +910,9 @@ void __init detect_calgary(void)
*/ */
phb = (phb + 1) % PHBS_PER_CALGARY; phb = (phb + 1) % PHBS_PER_CALGARY;
if (test_bit(bus, translation_disabled)) { if (info->translation_disabled)
printk(KERN_INFO "Calgary: translation is disabled for "
"PHB 0x%x\n", bus);
/* skip this phb, don't allocate a tbl for it */
continue; continue;
}
/* /*
* Scan the slots of the PCI bus to see if there is a device present. * Scan the slots of the PCI bus to see if there is a device present.
* The parent bus will be the zero-ith device, so start at 1. * The parent bus will be the zero-ith device, so start at 1.
...@@ -923,8 +923,8 @@ void __init detect_calgary(void) ...@@ -923,8 +923,8 @@ void __init detect_calgary(void)
tbl = alloc_tce_table(); tbl = alloc_tce_table();
if (!tbl) if (!tbl)
goto cleanup; goto cleanup;
tce_table_kva[bus] = tbl; info->tce_space = tbl;
bus_to_phb[bus] = phb; info->phbid = phb;
calgary_found = 1; calgary_found = 1;
break; break;
} }
...@@ -940,9 +940,12 @@ void __init detect_calgary(void) ...@@ -940,9 +940,12 @@ void __init detect_calgary(void)
return; return;
cleanup: cleanup:
for (--bus; bus >= 0; --bus) for (--bus; bus >= 0; --bus) {
if (tce_table_kva[bus]) struct calgary_bus_info *info = &bus_info[bus];
free_tce_table(tce_table_kva[bus]);
if (info->tce_space)
free_tce_table(info->tce_space);
}
} }
int __init calgary_iommu_init(void) int __init calgary_iommu_init(void)
...@@ -1016,7 +1019,7 @@ static int __init calgary_parse_options(char *p) ...@@ -1016,7 +1019,7 @@ static int __init calgary_parse_options(char *p)
if (bridge < MAX_PHB_BUS_NUM) { if (bridge < MAX_PHB_BUS_NUM) {
printk(KERN_INFO "Calgary: disabling " printk(KERN_INFO "Calgary: disabling "
"translation for PHB 0x%x\n", bridge); "translation for PHB 0x%x\n", bridge);
set_bit(bridge, translation_disabled); bus_info[bridge].translation_disabled = 1;
} }
} }
......
...@@ -106,14 +106,6 @@ static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl) ...@@ -106,14 +106,6 @@ static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl)
/* set the tce table size - measured in entries */ /* set the tce table size - measured in entries */
tbl->it_size = table_size_to_number_of_entries(specified_table_size); tbl->it_size = table_size_to_number_of_entries(specified_table_size);
tbl->it_base = (unsigned long)tce_table_kva[dev->bus->number];
if (!tbl->it_base) {
printk(KERN_ERR "Calgary: iommu_table_setparms: "
"no table allocated?!\n");
ret = -ENOMEM;
goto done;
}
/* /*
* number of bytes needed for the bitmap size in number of * number of bytes needed for the bitmap size in number of
* entries; we need one bit per entry * entries; we need one bit per entry
...@@ -162,8 +154,6 @@ int build_tce_table(struct pci_dev *dev, void __iomem *bbar) ...@@ -162,8 +154,6 @@ int build_tce_table(struct pci_dev *dev, void __iomem *bbar)
if (ret) if (ret)
goto free_tbl; goto free_tbl;
tce_free(tbl, 0, tbl->it_size);
tbl->bbar = bbar; tbl->bbar = bbar;
/* /*
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#ifndef _ASM_X86_64_TCE_H #ifndef _ASM_X86_64_TCE_H
#define _ASM_X86_64_TCE_H #define _ASM_X86_64_TCE_H
extern void* tce_table_kva[];
extern unsigned int specified_table_size; extern unsigned int specified_table_size;
struct iommu_table; struct iommu_table;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment