2006-11-02 21:49:44

by Muli Ben-Yehuda

[permalink] [raw]
Subject: [PATCH 0/4] Calgary: updates for 2.6.20

Hi Andi,

Please apply these four patches to your tree for 2.6.20. The first one
is trivial, second one is a bug fix for certain configuration of x460
(and in general replaces a hack with the Right Thing(TM), third is a
cleanup and fourth is mostly for the distros but also useful in
mainline. More details available with each patch.

Thanks,
Muli


2006-11-02 21:49:45

by Muli Ben-Yehuda

[permalink] [raw]
Subject: [PATCH 1/4] Calgary: phb_shift can be int

From: Muli Ben-Yehuda <[email protected]>

Signed-off-by: Muli Ben-Yehuda <[email protected]>
Signed-off-by: Jon Mason <[email protected]>
---
arch/x86_64/kernel/pci-calgary.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
index 37a7708..31d5758 100644
--- a/arch/x86_64/kernel/pci-calgary.c
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -740,7 +740,7 @@ static void __init calgary_increase_spli
{
u64 val64;
void __iomem *target;
- unsigned long phb_shift = -1;
+ unsigned int phb_shift = ~0; /* silence gcc */
u64 mask;

switch (busno_to_phbid(busnum)) {
--
1.4.1

2006-11-02 21:50:15

by Muli Ben-Yehuda

[permalink] [raw]
Subject: [PATCH 4/4] Calgary: allow compiling Calgary in but not using it by default

From: Muli Ben-Yehuda <[email protected]>

This patch makes it possible to compile Calgary in but not use it by
default. In this mode, use 'iommu=calgary' to activate it.

Signed-off-by: Muli Ben-Yehuda <[email protected]>
Signed-off-by: Jon Mason <[email protected]>
---
Documentation/x86_64/boot-options.txt | 3 ++-
arch/x86_64/Kconfig | 11 +++++++++++
arch/x86_64/kernel/pci-calgary.c | 9 +++++++++
arch/x86_64/kernel/pci-dma.c | 5 +++++
include/asm-x86_64/calgary.h | 2 ++
5 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
index f3c57f4..5c86ed6 100644
--- a/Documentation/x86_64/boot-options.txt
+++ b/Documentation/x86_64/boot-options.txt
@@ -183,7 +183,7 @@ PCI
IOMMU

iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]][,merge]
- [,forcesac][,fullflush][,nomerge][,noaperture]
+ [,forcesac][,fullflush][,nomerge][,noaperture][,calgary]
size set size of iommu (in bytes)
noagp don't initialize the AGP driver and use full aperture.
off don't use the IOMMU
@@ -204,6 +204,7 @@ IOMMU
buffering.
nodac Forbid DMA >4GB
panic Always panic when IOMMU overflows
+ calgary Use the Calgary IOMMU if it is available

swiotlb=pages[,force]

diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 010d226..5cb509d 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -455,6 +455,17 @@ config CALGARY_IOMMU
Normally the kernel will make the right choice by itself.
If unsure, say Y.

+config CALGARY_IOMMU_ENABLED_BY_DEFAULT
+ bool "Should Calgary be enabled by default?"
+ default y
+ depends on CALGARY_IOMMU
+ help
+ Should Calgary be enabled by default? if you choose 'y', Calgary
+ will be used (if it exists). If you choose 'n', Calgary will not be
+ used even if it exists. If you choose 'n' and would like to use
+ Calgary anyway, pass 'iommu=calgary' on the kernel command line.
+ If unsure, say Y.
+
# need this always selected by IOMMU for the VIA workaround
config SWIOTLB
bool
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
index eaa8d31..16889b7 100644
--- a/arch/x86_64/kernel/pci-calgary.c
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -43,6 +43,12 @@ #include <asm/system.h>
#include <asm/dma.h>
#include <asm/rio.h>

+#ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT
+int use_calgary __read_mostly = 1;
+#else
+int use_calgary __read_mostly = 0;
+#endif /* CONFIG_CALGARY_DEFAULT_ENABLED */
+
#define PCI_DEVICE_ID_IBM_CALGARY 0x02a1
#define PCI_VENDOR_DEVICE_ID_CALGARY \
(PCI_VENDOR_ID_IBM | PCI_DEVICE_ID_IBM_CALGARY << 16)
@@ -1061,6 +1067,9 @@ void __init detect_calgary(void)
if (swiotlb || no_iommu || iommu_detected)
return;

+ if (!use_calgary)
+ return;
+
if (!early_pci_allowed())
return;

diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c
index f8d8574..683b7a5 100644
--- a/arch/x86_64/kernel/pci-dma.c
+++ b/arch/x86_64/kernel/pci-dma.c
@@ -296,6 +296,11 @@ #ifdef CONFIG_IOMMU
gart_parse_options(p);
#endif

+#ifdef CONFIG_CALGARY_IOMMU
+ if (!strncmp(p, "calgary", 7))
+ use_calgary = 1;
+#endif /* CONFIG_CALGARY_IOMMU */
+
p += strcspn(p, ",");
if (*p == ',')
++p;
diff --git a/include/asm-x86_64/calgary.h b/include/asm-x86_64/calgary.h
index 6b93f5a..7ee9006 100644
--- a/include/asm-x86_64/calgary.h
+++ b/include/asm-x86_64/calgary.h
@@ -51,6 +51,8 @@ #define TCE_TABLE_SIZE_2M 5
#define TCE_TABLE_SIZE_4M 6
#define TCE_TABLE_SIZE_8M 7

+extern int use_calgary;
+
#ifdef CONFIG_CALGARY_IOMMU
extern int calgary_iommu_init(void);
extern void detect_calgary(void);
--
1.4.1

2006-11-02 21:50:14

by Muli Ben-Yehuda

[permalink] [raw]
Subject: [PATCH 2/4] Calgary: use BIOS supplied BBARs and topology information

From: Laurent Vivier <[email protected]>

Find the BBAR register address of each Calgary using the "Extended
BIOS Data Area" rather than calculating it ourselves. Also get the bus
topology (what PHB each bus is on) from Calgary rather than
calculating it ourselves.

This patch fixes http://bugzilla.kernel.org/show_bug.cgi?id=7407.

Signed-off-by: Laurent Vivier <[email protected]>
Signed-off-by: Muli Ben-Yehuda <[email protected]>
Signed-off-by: Jon Mason <[email protected]>
---
arch/x86_64/kernel/pci-calgary.c | 161 ++++++++++++++++++++++++++++++--------
include/asm-x86_64/rio.h | 76 ++++++++++++++++++
2 files changed, 201 insertions(+), 36 deletions(-)

diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
index 31d5758..71922e0 100644
--- a/arch/x86_64/kernel/pci-calgary.c
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -41,6 +41,7 @@ #include <asm/tce.h>
#include <asm/pci-direct.h>
#include <asm/system.h>
#include <asm/dma.h>
+#include <asm/rio.h>

#define PCI_DEVICE_ID_IBM_CALGARY 0x02a1
#define PCI_VENDOR_DEVICE_ID_CALGARY \
@@ -115,14 +116,35 @@ static const unsigned long phb_offsets[]
0xB000 /* PHB3 */
};

+/* PHB debug registers */
+
+static const unsigned long phb_debug_offsets[] = {
+ 0x4000 /* PHB 0 DEBUG */,
+ 0x5000 /* PHB 1 DEBUG */,
+ 0x6000 /* PHB 2 DEBUG */,
+ 0x7000 /* PHB 3 DEBUG */
+};
+
+/*
+ * STUFF register for each debug PHB,
+ * byte 1 = start bus number, byte 2 = end bus number
+ */
+
+#define PHB_DEBUG_STUFF_OFFSET 0x0020
+
unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED;
static int translate_empty_slots __read_mostly = 0;
static int calgary_detected __read_mostly = 0;

+static struct rio_table_hdr *rio_table_hdr __initdata;
+static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata;
+static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata;
+
struct calgary_bus_info {
void *tce_space;
unsigned char translation_disabled;
signed char phbid;
+ void __iomem *bbar;
};

static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, };
@@ -475,6 +497,11 @@ static struct dma_mapping_ops calgary_dm
.unmap_sg = calgary_unmap_sg,
};

+static inline void __iomem * busno_to_bbar(unsigned char num)
+{
+ return bus_info[num].bbar;
+}
+
static inline int busno_to_phbid(unsigned char num)
{
return bus_info[num].phbid;
@@ -828,31 +855,9 @@ static void __init calgary_disable_trans
del_timer_sync(&tbl->watchdog_timer);
}

-static inline unsigned int __init locate_register_space(struct pci_dev *dev)
+static inline void __iomem * __init locate_register_space(struct pci_dev *dev)
{
- int rionodeid;
- u32 address;
-
- /*
- * Each Calgary has four busses. The first four busses (first Calgary)
- * have RIO node ID 2, then the next four (second Calgary) have RIO
- * node ID 3, the next four (third Calgary) have node ID 2 again, etc.
- * We use a gross hack - relying on the dev->bus->number ordering,
- * modulo 14 - to decide which Calgary a given bus is on. Busses 0, 1,
- * 2 and 4 are on the first Calgary (id 2), 6, 8, a and c are on the
- * second (id 3), and then it repeats modulo 14.
- */
- rionodeid = (dev->bus->number % 14 > 4) ? 3 : 2;
- /*
- * register space address calculation as follows:
- * FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase)
- * ChassisBase is always zero for x366/x260/x460
- * RioNodeId is 2 for first Calgary, 3 for second Calgary
- */
- address = START_ADDRESS -
- (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 14)) +
- (0x100000) * (rionodeid - CHASSIS_BASE);
- return address;
+ return busno_to_bbar(dev->bus->number);
}

static void __init calgary_init_one_nontraslated(struct pci_dev *dev)
@@ -864,15 +869,12 @@ static void __init calgary_init_one_nont

static int __init calgary_init_one(struct pci_dev *dev)
{
- u32 address;
void __iomem *bbar;
int ret;

BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM);

- address = locate_register_space(dev);
- /* map entire 1MB of Calgary config space */
- bbar = ioremap_nocache(address, 1024 * 1024);
+ bbar = locate_register_space(dev);
if (!bbar) {
ret = -ENODATA;
goto done;
@@ -898,6 +900,35 @@ static int __init calgary_init(void)
{
int ret = -ENODEV;
struct pci_dev *dev = NULL;
+ int rio, phb, bus;
+ void __iomem *bbar;
+ void __iomem *target;
+ u8 start_bus, end_bus;
+ u32 val;
+
+ for (rio = 0; rio < rio_table_hdr->num_rio_dev; rio++) {
+
+ if ( (rio_devs[rio]->type != COMPAT_CALGARY) &&
+ (rio_devs[rio]->type != ALT_CALGARY) )
+ continue;
+
+ /* map entire 1MB of Calgary config space */
+ bbar = ioremap_nocache(rio_devs[rio]->BBAR, 1024 * 1024);
+
+ for (phb = 0; phb < PHBS_PER_CALGARY; phb++) {
+
+ target = calgary_reg(bbar, phb_debug_offsets[phb] |
+ PHB_DEBUG_STUFF_OFFSET);
+ val = be32_to_cpu(readl(target));
+ start_bus = (u8)((val & 0x00FF0000) >> 16);
+ end_bus = (u8)((val & 0x0000FF00) >> 8);
+ for (bus = start_bus; bus <= end_bus; bus++) {
+ bus_info[bus].bbar = bbar;
+ bus_info[bus].phbid = phb;
+ }
+ }
+ }
+

do {
dev = pci_get_device(PCI_VENDOR_ID_IBM,
@@ -962,13 +993,55 @@ static inline int __init determine_tce_t
return ret;
}

+static int __init build_detail_arrays(void)
+{
+ unsigned long ptr;
+ int i, scal_detail_size, rio_detail_size;
+
+ if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){
+ printk(KERN_WARNING
+ "Calgary: MAX_NUMNODES too low! Defined as %d, "
+ "but system has %d nodes.\n",
+ MAX_NUMNODES, rio_table_hdr->num_scal_dev);
+ return -ENODEV;
+ }
+
+ switch (rio_table_hdr->version){
+ default:
+ printk(KERN_WARNING
+ "Calgary: Invalid Rio Grande Table Version: %d\n",
+ rio_table_hdr->version);
+ return -ENODEV;
+ case 2:
+ scal_detail_size = 11;
+ rio_detail_size = 13;
+ break;
+ case 3:
+ scal_detail_size = 12;
+ rio_detail_size = 15;
+ break;
+ }
+
+ ptr = ((unsigned long)rio_table_hdr) + 3;
+ for (i = 0; i < rio_table_hdr->num_scal_dev;
+ i++, ptr += scal_detail_size)
+ scal_devs[i] = (struct scal_detail *)ptr;
+
+ for (i = 0; i < rio_table_hdr->num_rio_dev;
+ i++, ptr += rio_detail_size)
+ rio_devs[i] = (struct rio_detail *)ptr;
+
+ return 0;
+}
+
void __init detect_calgary(void)
{
u32 val;
int bus;
void *tbl;
int calgary_found = 0;
- int phb = -1;
+ unsigned long ptr;
+ int offset;

/*
* if the user specified iommu=off or iommu=soft or we found
@@ -980,6 +1053,29 @@ void __init detect_calgary(void)
if (!early_pci_allowed())
return;

+ ptr = (unsigned long)phys_to_virt(get_bios_ebda());
+
+ rio_table_hdr = NULL;
+ offset = 0x180;
+ while (offset) {
+ /* The block id is stored in the 2nd word */
+ if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){
+ /* set the pointer past the offset & block id */
+ rio_table_hdr = (struct rio_table_hdr *)(ptr+offset+4);
+ break;
+ }
+ /* The next offset is stored in the 1st word. 0 means no more */
+ offset = *((unsigned short *)(ptr + offset));
+ }
+ if (!rio_table_hdr){
+ printk(KERN_ERR "Calgary: Unable to locate "
+ "Rio Grande Table in EBDA - bailing!\n");
+ return;
+ }
+
+ if (build_detail_arrays())
+ return;
+
specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE);

for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
@@ -990,12 +1086,6 @@ void __init detect_calgary(void)
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 (info->translation_disabled)
continue;

@@ -1010,7 +1100,6 @@ void __init detect_calgary(void)
if (!tbl)
goto cleanup;
info->tce_space = tbl;
- info->phbid = phb;
calgary_found = 1;
break;
}
diff --git a/include/asm-x86_64/rio.h b/include/asm-x86_64/rio.h
new file mode 100644
index 0000000..1f315c3
--- /dev/null
+++ b/include/asm-x86_64/rio.h
@@ -0,0 +1,76 @@
+/*
+ * Derived from include/asm-i386/mach-summit/mach_mpparse.h
+ * and include/asm-i386/mach-default/bios_ebda.h
+ *
+ * Author: Laurent Vivier <[email protected]>
+ *
+ */
+
+#ifndef __ASM_RIO_H
+#define __ASM_RIO_H
+
+#define RIO_TABLE_VERSION 3
+
+struct rio_table_hdr {
+ u8 version; /* Version number of this data structure */
+ u8 num_scal_dev; /* # of Scalability devices */
+ u8 num_rio_dev; /* # of RIO I/O devices */
+} __attribute__((packed));
+
+struct scal_detail {
+ u8 node_id; /* Scalability Node ID */
+ u32 CBAR; /* Address of 1MB register space */
+ u8 port0node; /* Node ID port connected to: 0xFF=None */
+ u8 port0port; /* Port num port connected to: 0,1,2, or */
+ /* 0xFF=None */
+ u8 port1node; /* Node ID port connected to: 0xFF = None */
+ u8 port1port; /* Port num port connected to: 0,1,2, or */
+ /* 0xFF=None */
+ u8 port2node; /* Node ID port connected to: 0xFF = None */
+ u8 port2port; /* Port num port connected to: 0,1,2, or */
+ /* 0xFF=None */
+ u8 chassis_num; /* 1 based Chassis number (1 = boot node) */
+} __attribute__((packed));
+
+struct rio_detail {
+ u8 node_id; /* RIO Node ID */
+ u32 BBAR; /* Address of 1MB register space */
+ u8 type; /* Type of device */
+ u8 owner_id; /* Node ID of Hurricane that owns this */
+ /* node */
+ u8 port0node; /* Node ID port connected to: 0xFF=None */
+ u8 port0port; /* Port num port connected to: 0,1,2, or */
+ /* 0xFF=None */
+ u8 port1node; /* Node ID port connected to: 0xFF=None */
+ u8 port1port; /* Port num port connected to: 0,1,2, or */
+ /* 0xFF=None */
+ u8 first_slot; /* Lowest slot number below this Calgary */
+ u8 status; /* Bit 0 = 1 : the XAPIC is used */
+ /* = 0 : the XAPIC is not used, ie: */
+ /* ints fwded to another XAPIC */
+ /* Bits1:7 Reserved */
+ u8 WP_index; /* instance index - lower ones have */
+ /* lower slot numbers/PCI bus numbers */
+ u8 chassis_num; /* 1 based Chassis number */
+} __attribute__((packed));
+
+enum {
+ HURR_SCALABILTY = 0, /* Hurricane Scalability info */
+ HURR_RIOIB = 2, /* Hurricane RIOIB info */
+ COMPAT_CALGARY = 4, /* Compatibility Calgary */
+ ALT_CALGARY = 5, /* Second Planar Calgary */
+};
+
+/*
+ * there is a real-mode segmented pointer pointing to the
+ * 4K EBDA area at 0x40E.
+ */
+
+static inline unsigned long get_bios_ebda(void)
+{
+ unsigned long address= *(unsigned short *)phys_to_virt(0x40Eul);
+ address <<= 4;
+ return address;
+}
+
+#endif /* __ASM_RIO_H */
--
1.4.1

2006-11-02 21:50:15

by Muli Ben-Yehuda

[permalink] [raw]
Subject: [PATCH 3/4] Calgary: check BBAR ioremap success when ioremapping

From: Muli Ben-Yehuda <[email protected]>

This patch cleans up the previous "Use BIOS supplied BBAR information"
patch. Mostly stylistic clenaups, but also check for ioremap failure
when we ioremap the BBAR rather than when trying to use it.

Signed-off-by: Muli Ben-Yehuda <[email protected]>
Signed-off-by: Jon Mason <[email protected]>
Acked-by: Laurent Vivier <[email protected]>
---
arch/x86_64/kernel/pci-calgary.c | 85 ++++++++++++++++++++++----------------
include/asm-x86_64/rio.h | 8 +---
2 files changed, 52 insertions(+), 41 deletions(-)

diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
index 71922e0..eaa8d31 100644
--- a/arch/x86_64/kernel/pci-calgary.c
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -138,7 +138,7 @@ static int calgary_detected __read_mostl

static struct rio_table_hdr *rio_table_hdr __initdata;
static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata;
-static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata;
+static struct rio_detail *rio_devs[MAX_NUMNODES * 4] __initdata;

struct calgary_bus_info {
void *tce_space;
@@ -855,11 +855,6 @@ static void __init calgary_disable_trans
del_timer_sync(&tbl->watchdog_timer);
}

-static inline void __iomem * __init locate_register_space(struct pci_dev *dev)
-{
- return busno_to_bbar(dev->bus->number);
-}
-
static void __init calgary_init_one_nontraslated(struct pci_dev *dev)
{
pci_dev_get(dev);
@@ -874,15 +869,10 @@ static int __init calgary_init_one(struc

BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM);

- bbar = locate_register_space(dev);
- if (!bbar) {
- ret = -ENODATA;
- goto done;
- }
-
+ bbar = busno_to_bbar(dev->bus->number);
ret = calgary_setup_tar(dev, bbar);
if (ret)
- goto iounmap;
+ goto done;

pci_dev_get(dev);
dev->bus->self = dev;
@@ -890,38 +880,39 @@ static int __init calgary_init_one(struc

return 0;

-iounmap:
- iounmap(bbar);
done:
return ret;
}

-static int __init calgary_init(void)
+static int __init calgary_locate_bbars(void)
{
- int ret = -ENODEV;
- struct pci_dev *dev = NULL;
- int rio, phb, bus;
+ int ret;
+ int rioidx, phb, bus;
void __iomem *bbar;
void __iomem *target;
+ unsigned long offset;
u8 start_bus, end_bus;
u32 val;

- for (rio = 0; rio < rio_table_hdr->num_rio_dev; rio++) {
+ ret = -ENODATA;
+ for (rioidx = 0; rioidx < rio_table_hdr->num_rio_dev; rioidx++) {
+ struct rio_detail *rio = rio_devs[rioidx];

- if ( (rio_devs[rio]->type != COMPAT_CALGARY) &&
- (rio_devs[rio]->type != ALT_CALGARY) )
+ if ((rio->type != COMPAT_CALGARY) && (rio->type != ALT_CALGARY))
continue;

/* map entire 1MB of Calgary config space */
- bbar = ioremap_nocache(rio_devs[rio]->BBAR, 1024 * 1024);
+ bbar = ioremap_nocache(rio->BBAR, 1024 * 1024);
+ if (!bbar)
+ goto error;

for (phb = 0; phb < PHBS_PER_CALGARY; phb++) {
+ offset = phb_debug_offsets[phb] | PHB_DEBUG_STUFF_OFFSET;
+ target = calgary_reg(bbar, offset);

- target = calgary_reg(bbar, phb_debug_offsets[phb] |
- PHB_DEBUG_STUFF_OFFSET);
val = be32_to_cpu(readl(target));
start_bus = (u8)((val & 0x00FF0000) >> 16);
- end_bus = (u8)((val & 0x0000FF00) >> 8);
+ end_bus = (u8)((val & 0x0000FF00) >> 8);
for (bus = start_bus; bus <= end_bus; bus++) {
bus_info[bus].bbar = bbar;
bus_info[bus].phbid = phb;
@@ -929,6 +920,25 @@ static int __init calgary_init(void)
}
}

+ return 0;
+
+error:
+ /* scan bus_info and iounmap any bbars we previously ioremap'd */
+ for (bus = 0; bus < ARRAY_SIZE(bus_info); bus++)
+ if (bus_info[bus].bbar)
+ iounmap(bbar);
+
+ return ret;
+}
+
+static int __init calgary_init(void)
+{
+ int ret;
+ struct pci_dev *dev = NULL;
+
+ ret = calgary_locate_bbars();
+ if (ret)
+ return ret;

do {
dev = pci_get_device(PCI_VENDOR_ID_IBM,
@@ -1000,18 +1010,13 @@ static int __init build_detail_arrays(vo

if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){
printk(KERN_WARNING
- "Calgary: MAX_NUMNODES too low! Defined as %d, "
+ "Calgary: MAX_NUMNODES too low! Defined as %d, "
"but system has %d nodes.\n",
MAX_NUMNODES, rio_table_hdr->num_scal_dev);
return -ENODEV;
}

switch (rio_table_hdr->version){
- default:
- printk(KERN_WARNING
- "Calgary: Invalid Rio Grande Table Version: %d\n",
- rio_table_hdr->version);
- return -ENODEV;
case 2:
scal_detail_size = 11;
rio_detail_size = 13;
@@ -1020,6 +1025,11 @@ static int __init build_detail_arrays(vo
scal_detail_size = 12;
rio_detail_size = 15;
break;
+ default:
+ printk(KERN_WARNING
+ "Calgary: Invalid Rio Grande Table Version: %d\n",
+ rio_table_hdr->version);
+ return -EPROTO;
}

ptr = ((unsigned long)rio_table_hdr) + 3;
@@ -1042,6 +1052,7 @@ void __init detect_calgary(void)
int calgary_found = 0;
unsigned long ptr;
int offset;
+ int ret;

/*
* if the user specified iommu=off or iommu=soft or we found
@@ -1061,27 +1072,29 @@ void __init detect_calgary(void)
/* The block id is stored in the 2nd word */
if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){
/* set the pointer past the offset & block id */
- rio_table_hdr = (struct rio_table_hdr *)(ptr+offset+4);
+ rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
break;
}
/* The next offset is stored in the 1st word. 0 means no more */
offset = *((unsigned short *)(ptr + offset));
}
- if (!rio_table_hdr){
+ if (!rio_table_hdr) {
printk(KERN_ERR "Calgary: Unable to locate "
"Rio Grande Table in EBDA - bailing!\n");
return;
}

- if (build_detail_arrays())
+ ret = build_detail_arrays();
+ if (ret) {
+ printk(KERN_ERR "Calgary: build_detail_arrays ret %d\n", ret);
return;
+ }

specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE);

for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
int dev;
struct calgary_bus_info *info = &bus_info[bus];
- info->phbid = -1;

if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY)
continue;
diff --git a/include/asm-x86_64/rio.h b/include/asm-x86_64/rio.h
index 1f315c3..c7350f6 100644
--- a/include/asm-x86_64/rio.h
+++ b/include/asm-x86_64/rio.h
@@ -3,7 +3,6 @@
* and include/asm-i386/mach-default/bios_ebda.h
*
* Author: Laurent Vivier <[email protected]>
- *
*/

#ifndef __ASM_RIO_H
@@ -19,7 +18,7 @@ struct rio_table_hdr {

struct scal_detail {
u8 node_id; /* Scalability Node ID */
- u32 CBAR; /* Address of 1MB register space */
+ u32 CBAR; /* Address of 1MB register space */
u8 port0node; /* Node ID port connected to: 0xFF=None */
u8 port0port; /* Port num port connected to: 0,1,2, or */
/* 0xFF=None */
@@ -34,7 +33,7 @@ struct scal_detail {

struct rio_detail {
u8 node_id; /* RIO Node ID */
- u32 BBAR; /* Address of 1MB register space */
+ u32 BBAR; /* Address of 1MB register space */
u8 type; /* Type of device */
u8 owner_id; /* Node ID of Hurricane that owns this */
/* node */
@@ -65,10 +64,9 @@ enum {
* there is a real-mode segmented pointer pointing to the
* 4K EBDA area at 0x40E.
*/
-
static inline unsigned long get_bios_ebda(void)
{
- unsigned long address= *(unsigned short *)phys_to_virt(0x40Eul);
+ unsigned long address = *(unsigned short *)phys_to_virt(0x40EUL);
address <<= 4;
return address;
}
--
1.4.1

2006-11-02 22:12:50

by David Rientjes

[permalink] [raw]
Subject: Re: [PATCH 1/4] Calgary: phb_shift can be int

On Thu, 2 Nov 2006, [email protected] wrote:

> diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
> index 37a7708..31d5758 100644
> --- a/arch/x86_64/kernel/pci-calgary.c
> +++ b/arch/x86_64/kernel/pci-calgary.c
> @@ -740,7 +740,7 @@ static void __init calgary_increase_spli
> {
> u64 val64;
> void __iomem *target;
> - unsigned long phb_shift = -1;
> + unsigned int phb_shift = ~0; /* silence gcc */
> u64 mask;
>
> switch (busno_to_phbid(busnum)) {
>

There's been a suggestion to add

#define SILENCE_GCC(x) = x

for these silencing cases with the advantage that all the cases are marked
for an easy grep and the purpose of such an initialization is known by
the code reader.

http://lkml.org/lkml/2006/10/31/106

2006-11-02 23:16:38

by Richard B. Johnson

[permalink] [raw]
Subject: Re: [PATCH 1/4] Calgary: phb_shift can be int


----- Original Message -----
From: "David Rientjes" <[email protected]>
To: <[email protected]>
Cc: <[email protected]>; <[email protected]>; <[email protected]>;
<[email protected]>
Sent: Thursday, November 02, 2006 5:12 PM
Subject: Re: [PATCH 1/4] Calgary: phb_shift can be int


> On Thu, 2 Nov 2006, [email protected] wrote:
>
>> diff --git a/arch/x86_64/kernel/pci-calgary.c
>> b/arch/x86_64/kernel/pci-calgary.c
>> index 37a7708..31d5758 100644
>> --- a/arch/x86_64/kernel/pci-calgary.c
>> +++ b/arch/x86_64/kernel/pci-calgary.c
>> @@ -740,7 +740,7 @@ static void __init calgary_increase_spli
>> {
>> u64 val64;
>> void __iomem *target;
>> - unsigned long phb_shift = -1;
>> + unsigned int phb_shift = ~0; /* silence gcc */
>> u64 mask;
>>
>> switch (busno_to_phbid(busnum)) {
>>
>
> There's been a suggestion to add
>
> #define SILENCE_GCC(x) = x

This was previously discussed. To quiet gcc warnings, one can use "var=var",
but you do not want to hide it in a macro! That hides bonafide bugs. If you
carefully review code and see that there is absolutely no possibility of
using an uninitialized variable in any execution path, then you can assign
it to itself to quiet the compiler.

>
> for these silencing cases with the advantage that all the cases are marked
> for an easy grep and the purpose of such an initialization is known by
> the code reader.
>
> http://lkml.org/lkml/2006/10/31/106
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.24 (somewhere). IT took away email
"privileges" to engineers.
New Book: http://www.AbominableFirebug.com


2006-11-02 23:20:41

by David Rientjes

[permalink] [raw]
Subject: Re: [PATCH 1/4] Calgary: phb_shift can be int

On Thu, 2 Nov 2006, Richard B. Johnson wrote:

> > > diff --git a/arch/x86_64/kernel/pci-calgary.c
> > > b/arch/x86_64/kernel/pci-calgary.c
> > > index 37a7708..31d5758 100644
> > > --- a/arch/x86_64/kernel/pci-calgary.c
> > > +++ b/arch/x86_64/kernel/pci-calgary.c
> >> @@ -740,7 +740,7 @@ static void __init calgary_increase_spli
> > > {
> > > u64 val64;
> > > void __iomem *target;
> > > - unsigned long phb_shift = -1;
> > > + unsigned int phb_shift = ~0; /* silence gcc */
> > > u64 mask;
> > >
> > > switch (busno_to_phbid(busnum)) {
> > >
> >
> > There's been a suggestion to add
> >
> > #define SILENCE_GCC(x) = x
>
> This was previously discussed. To quiet gcc warnings, one can use "var=var",
> but you do not want to hide it in a macro! That hides bonafide bugs. If you
> carefully review code and see that there is absolutely no possibility of using
> an uninitialized variable in any execution path, then you can assign it to
> itself to quiet the compiler.
>

Such as the case above.

David