Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 32893
b: refs/heads/master
c: d2105b1
h: refs/heads/master
i:
  32891: 6545c8c
v: v3
  • Loading branch information
Jon Mason authored and Linus Torvalds committed Jul 30, 2006
1 parent 6bffdd1 commit 74319f0
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 41 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 089bbbcb36979166131868a89ca5f4e695d6637d
refs/heads/master: d2105b10fe0f460c388fe4e09226313f519d8c00
76 changes: 44 additions & 32 deletions trunk/arch/x86_64/kernel/pci-calgary.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@
#define CSR_AGENT_MASK 0xffe0ffff

#define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */
#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * 2) /* max dev->bus->number */
#define MAX_NUM_CHASSIS 8 /* max number of chassis */
#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) /* max dev->bus->number */
#define PHBS_PER_CALGARY 4

/* register offsets in Calgary's internal register space */
Expand All @@ -110,7 +111,8 @@ static const unsigned long phb_offsets[] = {
0xB000 /* PHB3 */
};

void* tce_table_kva[MAX_NUM_OF_PHBS * MAX_NUMNODES];
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;
static int translate_empty_slots __read_mostly = 0;
static int calgary_detected __read_mostly = 0;
Expand All @@ -119,7 +121,7 @@ static int calgary_detected __read_mostly = 0;
* the bitmap of PHBs the user requested that we disable
* translation on.
*/
static DECLARE_BITMAP(translation_disabled, MAX_NUMNODES * MAX_PHB_BUS_NUM);
static DECLARE_BITMAP(translation_disabled, MAX_PHB_BUS_NUM);

static void tce_cache_blast(struct iommu_table *tbl);

Expand Down Expand Up @@ -452,7 +454,7 @@ static struct dma_mapping_ops calgary_dma_ops = {

static inline int busno_to_phbid(unsigned char num)
{
return bus_to_phb(num) % PHBS_PER_CALGARY;
return bus_to_phb[num];
}

static inline unsigned long split_queue_offset(unsigned char num)
Expand Down Expand Up @@ -812,7 +814,7 @@ static int __init calgary_init(void)
int i, ret = -ENODEV;
struct pci_dev *dev = NULL;

for (i = 0; i < num_online_nodes() * MAX_NUM_OF_PHBS; i++) {
for (i = 0; i < MAX_PHB_BUS_NUM; i++) {
dev = pci_get_device(PCI_VENDOR_ID_IBM,
PCI_DEVICE_ID_IBM_CALGARY,
dev);
Expand All @@ -822,7 +824,7 @@ static int __init calgary_init(void)
calgary_init_one_nontraslated(dev);
continue;
}
if (!tce_table_kva[i] && !translate_empty_slots) {
if (!tce_table_kva[dev->bus->number] && !translate_empty_slots) {
pci_dev_put(dev);
continue;
}
Expand All @@ -842,7 +844,7 @@ static int __init calgary_init(void)
pci_dev_put(dev);
continue;
}
if (!tce_table_kva[i] && !translate_empty_slots)
if (!tce_table_kva[dev->bus->number] && !translate_empty_slots)
continue;
calgary_disable_translation(dev);
calgary_free_tar(dev);
Expand Down Expand Up @@ -876,9 +878,10 @@ static inline int __init determine_tce_table_size(u64 ram)
void __init detect_calgary(void)
{
u32 val;
int bus, table_idx;
int bus;
void *tbl;
int detected = 0;
int calgary_found = 0;
int phb = -1;

/*
* if the user specified iommu=off or iommu=soft or we found
Expand All @@ -889,37 +892,46 @@ void __init detect_calgary(void)

specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE);

for (bus = 0, table_idx = 0;
bus < num_online_nodes() * MAX_PHB_BUS_NUM;
bus++) {
for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
int dev;

tce_table_kva[bus] = NULL;
bus_to_phb[bus] = -1;

if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY)
continue;

/*
* There are 4 PHBs per Calgary chip. Set phb to which phb (0-3)
* it is connected to releative to the clagary chip.
*/
phb = (phb + 1) % PHBS_PER_CALGARY;

if (test_bit(bus, 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 */
tce_table_kva[table_idx] = NULL;
table_idx++;
continue;
}
/*
* scan the first slot of the PCI bus to see if there
* are any devices 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.
*/
val = read_pci_config(bus, 1, 0, 0);
if (val != 0xffffffff || translate_empty_slots) {
tbl = alloc_tce_table();
if (!tbl)
goto cleanup;
detected = 1;
} else
tbl = NULL;

tce_table_kva[table_idx] = tbl;
table_idx++;
for (dev = 1; dev < 8; dev++) {
val = read_pci_config(bus, dev, 0, 0);
if (val != 0xffffffff || translate_empty_slots) {
tbl = alloc_tce_table();
if (!tbl)
goto cleanup;
tce_table_kva[bus] = tbl;
bus_to_phb[bus] = phb;
calgary_found = 1;
break;
}
}
}

if (detected) {
if (calgary_found) {
iommu_detected = 1;
calgary_detected = 1;
printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected. "
Expand All @@ -928,9 +940,9 @@ void __init detect_calgary(void)
return;

cleanup:
for (--table_idx; table_idx >= 0; --table_idx)
if (tce_table_kva[table_idx])
free_tce_table(tce_table_kva[table_idx]);
for (--bus; bus >= 0; --bus)
if (tce_table_kva[bus])
free_tce_table(tce_table_kva[bus]);
}

int __init calgary_iommu_init(void)
Expand Down Expand Up @@ -1001,7 +1013,7 @@ static int __init calgary_parse_options(char *p)
if (p == endp)
break;

if (bridge < (num_online_nodes() * MAX_PHB_BUS_NUM)) {
if (bridge < MAX_PHB_BUS_NUM) {
printk(KERN_INFO "Calgary: disabling "
"translation for PHB 0x%x\n", bridge);
set_bit(bridge, translation_disabled);
Expand Down
4 changes: 1 addition & 3 deletions trunk/arch/x86_64/kernel/tce.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ static inline unsigned int table_size_to_number_of_entries(unsigned char size)
static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl)
{
unsigned int bitmapsz;
unsigned int tce_table_index;
unsigned long bmppages;
int ret;

Expand All @@ -105,8 +104,7 @@ static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl)
/* set the tce table size - measured in entries */
tbl->it_size = table_size_to_number_of_entries(specified_table_size);

tce_table_index = bus_to_phb(tbl->it_busno);
tbl->it_base = (unsigned long)tce_table_kva[tce_table_index];
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");
Expand Down
5 changes: 0 additions & 5 deletions trunk/include/asm-x86_64/calgary.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,4 @@ static inline int calgary_iommu_init(void) { return 1; }
static inline void detect_calgary(void) { return; }
#endif

static inline unsigned int bus_to_phb(unsigned char busno)
{
return ((busno % 15 == 0) ? 0 : busno / 2 + 1);
}

#endif /* _ASM_X86_64_CALGARY_H */

0 comments on commit 74319f0

Please sign in to comment.