Commit 8a0f08e2 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linuxusb.bkbits.net/linus-2.5

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 36b6ca01 159b0104
...@@ -161,7 +161,7 @@ KAO --> ...@@ -161,7 +161,7 @@ KAO -->
</sect1> </sect1>
<sect1><title>MTRR Handling</title> <sect1><title>MTRR Handling</title>
!Earch/i386/kernel/mtrr.c !Earch/i386/kernel/cpu/mtrr/main.c
</sect1> </sect1>
<sect1><title>PCI Support Library</title> <sect1><title>PCI Support Library</title>
!Edrivers/pci/pci.c !Edrivers/pci/pci.c
......
...@@ -80,14 +80,14 @@ would have a contended child and we had assumed that no object is its ...@@ -80,14 +80,14 @@ would have a contended child and we had assumed that no object is its
own descendent. Moreover, there is exactly one cross-directory rename own descendent. Moreover, there is exactly one cross-directory rename
(see above). (see above).
Consider the object blocking the cross-directory rename. One of Consider the object blocking the cross-directory rename. One
its descendents is locked by cross-directory rename (otherwise we would again of its descendents is locked by cross-directory rename (otherwise we
have an infinite set of of contended objects). But that means that means would again have an infinite set of of contended objects). But that
that cross-directory rename is taking locks out of order. Due to (2) the means that cross-directory rename is taking locks out of order. Due
order hadn't changed since we had acquired filesystem lock. But locking to (2) the order hadn't changed since we had acquired filesystem lock.
rules for cross-directory rename guarantee that we do not try to acquire But locking rules for cross-directory rename guarantee that we do not
lock on descendent before the lock on ancestor. Contradiction. I.e. try to acquire lock on descendent before the lock on ancestor.
deadlock is impossible. Q.E.D. Contradiction. I.e. deadlock is impossible. Q.E.D.
These operations are guaranteed to avoid loop creation. Indeed, These operations are guaranteed to avoid loop creation. Indeed,
......
...@@ -69,7 +69,7 @@ Locking change: ->s_vfs_rename_sem is taken only by cross-directory renames. ...@@ -69,7 +69,7 @@ Locking change: ->s_vfs_rename_sem is taken only by cross-directory renames.
Most likely there is no need to change anything, but if you relied on Most likely there is no need to change anything, but if you relied on
global exclusion between renames for some internal purpose - you need to global exclusion between renames for some internal purpose - you need to
change your internal locking. Otherwise exclusion warranties remain the change your internal locking. Otherwise exclusion warranties remain the
same (i.e. parents are victim are locked, etc.). same (i.e. parents and victim are locked, etc.).
--- ---
[informational] [informational]
......
...@@ -156,6 +156,7 @@ static void __init init_intel(struct cpuinfo_x86 *c) ...@@ -156,6 +156,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
} }
#endif #endif
get_model_name(c);
if (c->cpuid_level > 1) { if (c->cpuid_level > 1) {
/* supports eax=2 call */ /* supports eax=2 call */
......
...@@ -110,12 +110,54 @@ cyrix_get_free_region(unsigned long base, unsigned long size) ...@@ -110,12 +110,54 @@ cyrix_get_free_region(unsigned long base, unsigned long size)
return -ENOSPC; return -ENOSPC;
} }
static u32 cr4 = 0;
static u32 ccr3;
static void prepare_set(void)
{
u32 cr0;
/* Save value of CR4 and clear Page Global Enable (bit 7) */
if ( cpu_has_pge ) {
cr4 = read_cr4();
write_cr4(cr4 & (unsigned char) ~(1 << 7));
}
/* Disable and flush caches. Note that wbinvd flushes the TLBs as
a side-effect */
cr0 = read_cr0() | 0x40000000;
wbinvd();
write_cr0(cr0);
wbinvd();
/* Cyrix ARRs - everything else were excluded at the top */
ccr3 = getCx86(CX86_CCR3);
/* Cyrix ARRs - everything else were excluded at the top */
setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);
}
static void post_set(void)
{
/* Flush caches and TLBs */
wbinvd();
/* Cyrix ARRs - everything else was excluded at the top */
setCx86(CX86_CCR3, ccr3);
/* Enable caches */
write_cr0(read_cr0() & 0xbfffffff);
/* Restore value of CR4 */
if ( cpu_has_pge )
write_cr4(cr4);
}
static void cyrix_set_arr(unsigned int reg, unsigned long base, static void cyrix_set_arr(unsigned int reg, unsigned long base,
unsigned long size, mtrr_type type) unsigned long size, mtrr_type type)
{ {
unsigned char arr, arr_type, arr_size; unsigned char arr, arr_type, arr_size;
u32 cr0, ccr3;
u32 cr4 = 0;
arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */ arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */
...@@ -158,24 +200,7 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base, ...@@ -158,24 +200,7 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base,
} }
} }
/* Save value of CR4 and clear Page Global Enable (bit 7) */ prepare_set();
if ( cpu_has_pge ) {
cr4 = read_cr4();
write_cr4(cr4 & (unsigned char) ~(1 << 7));
}
/* Disable and flush caches. Note that wbinvd flushes the TLBs as
a side-effect */
cr0 = read_cr0() | 0x40000000;
wbinvd();
write_cr0(cr0);
wbinvd();
/* Cyrix ARRs - everything else were excluded at the top */
ccr3 = getCx86(CX86_CCR3);
/* Cyrix ARRs - everything else were excluded at the top */
setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);
base <<= PAGE_SHIFT; base <<= PAGE_SHIFT;
setCx86(arr, ((unsigned char *) &base)[3]); setCx86(arr, ((unsigned char *) &base)[3]);
...@@ -183,18 +208,7 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base, ...@@ -183,18 +208,7 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base,
setCx86(arr + 2, (((unsigned char *) &base)[1]) | arr_size); setCx86(arr + 2, (((unsigned char *) &base)[1]) | arr_size);
setCx86(CX86_RCR_BASE + reg, arr_type); setCx86(CX86_RCR_BASE + reg, arr_type);
/* Flush caches and TLBs */ post_set();
wbinvd();
/* Cyrix ARRs - everything else was excluded at the top */
setCx86(CX86_CCR3, ccr3);
/* Enable caches */
write_cr0(read_cr0() & 0xbfffffff);
/* Restore value of CR4 */
if ( cpu_has_pge )
write_cr4(cr4);
} }
typedef struct { typedef struct {
...@@ -210,31 +224,11 @@ arr_state_t arr_state[8] __initdata = { ...@@ -210,31 +224,11 @@ arr_state_t arr_state[8] __initdata = {
unsigned char ccr_state[7] __initdata = { 0, 0, 0, 0, 0, 0, 0 }; unsigned char ccr_state[7] __initdata = { 0, 0, 0, 0, 0, 0, 0 };
static void __init static void cyrix_set_all(void)
cyrix_arr_init_secondary(void)
{ {
int i; int i;
u32 cr0, ccr3, cr4 = 0;
/* flush cache and enable MAPEN */
/* Save value of CR4 and clear Page Global Enable (bit 7) */
if ( cpu_has_pge ) {
cr4 = read_cr4();
write_cr4(cr4 & (unsigned char) ~(1 << 7));
}
/* Disable and flush caches. Note that wbinvd flushes the TLBs as prepare_set();
a side-effect */
cr0 = read_cr0() | 0x40000000;
wbinvd();
write_cr0(cr0);
wbinvd();
/* Cyrix ARRs - everything else were excluded at the top */
ccr3 = getCx86(CX86_CCR3);
/* Cyrix ARRs - everything else were excluded at the top */
setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);
/* the CCRs are not contiguous */ /* the CCRs are not contiguous */
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
...@@ -245,18 +239,7 @@ cyrix_arr_init_secondary(void) ...@@ -245,18 +239,7 @@ cyrix_arr_init_secondary(void)
cyrix_set_arr(i, arr_state[i].base, cyrix_set_arr(i, arr_state[i].base,
arr_state[i].size, arr_state[i].type); arr_state[i].size, arr_state[i].type);
/* Flush caches and TLBs */ post_set();
wbinvd();
/* Cyrix ARRs - everything else was excluded at the top */
setCx86(CX86_CCR3, ccr3);
/* Enable caches */
write_cr0(read_cr0() & 0xbfffffff);
/* Restore value of CR4 */
if ( cpu_has_pge )
write_cr4(cr4);
} }
/* /*
...@@ -361,7 +344,7 @@ cyrix_arr_init(void) ...@@ -361,7 +344,7 @@ cyrix_arr_init(void)
static struct mtrr_ops cyrix_mtrr_ops = { static struct mtrr_ops cyrix_mtrr_ops = {
.vendor = X86_VENDOR_CYRIX, .vendor = X86_VENDOR_CYRIX,
.init = cyrix_arr_init, .init = cyrix_arr_init,
.init_secondary = cyrix_arr_init_secondary, .set_all = cyrix_set_all,
.set = cyrix_set_arr, .set = cyrix_set_arr,
.get = cyrix_get_arr, .get = cyrix_get_arr,
.get_free_region = cyrix_get_free_region, .get_free_region = cyrix_get_free_region,
......
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/mtrr.h> #include <asm/mtrr.h>
...@@ -6,6 +8,90 @@ ...@@ -6,6 +8,90 @@
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include "mtrr.h" #include "mtrr.h"
struct mtrr_state {
struct mtrr_var_range *var_ranges;
mtrr_type fixed_ranges[NUM_FIXED_RANGES];
unsigned char enabled;
mtrr_type def_type;
};
static unsigned long smp_changes_mask __initdata = 0;
struct mtrr_state mtrr_state = {};
/* Get the MSR pair relating to a var range */
static void __init
get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr)
{
rdmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
}
static void __init
get_fixed_ranges(mtrr_type * frs)
{
unsigned long *p = (unsigned long *) frs;
int i;
rdmsr(MTRRfix64K_00000_MSR, p[0], p[1]);
for (i = 0; i < 2; i++)
rdmsr(MTRRfix16K_80000_MSR + i, p[2 + i * 2], p[3 + i * 2]);
for (i = 0; i < 8; i++)
rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2], p[7 + i * 2]);
}
/* Grab all of the MTRR state for this CPU into *state */
void get_mtrr_state(void)
{
unsigned int i;
struct mtrr_var_range *vrs;
unsigned long lo, dummy;
if (!mtrr_state.var_ranges) {
mtrr_state.var_ranges = kmalloc(num_var_ranges * sizeof (struct mtrr_var_range),
GFP_KERNEL);
if (!mtrr_state.var_ranges)
return;
}
vrs = mtrr_state.var_ranges;
for (i = 0; i < num_var_ranges; i++)
get_mtrr_var_range(i, &vrs[i]);
get_fixed_ranges(mtrr_state.fixed_ranges);
rdmsr(MTRRdefType_MSR, lo, dummy);
mtrr_state.def_type = (lo & 0xff);
mtrr_state.enabled = (lo & 0xc00) >> 10;
}
/* Free resources associated with a struct mtrr_state */
void __init finalize_mtrr_state(void)
{
if (mtrr_state.var_ranges)
kfree(mtrr_state.var_ranges);
mtrr_state.var_ranges = NULL;
}
/* Some BIOS's are fucked and don't set all MTRRs the same! */
void __init mtrr_state_warn(void)
{
unsigned long mask = smp_changes_mask;
if (!mask)
return;
if (mask & MTRR_CHANGE_MASK_FIXED)
printk
("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
if (mask & MTRR_CHANGE_MASK_VARIABLE)
printk
("mtrr: your CPUs had inconsistent variable MTRR settings\n");
if (mask & MTRR_CHANGE_MASK_DEFTYPE)
printk
("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
printk("mtrr: probably your BIOS does not setup all CPUs\n");
}
int generic_get_free_region(unsigned long base, unsigned long size) int generic_get_free_region(unsigned long base, unsigned long size)
/* [SUMMARY] Get a free MTRR. /* [SUMMARY] Get a free MTRR.
...@@ -55,23 +141,104 @@ void generic_get_mtrr(unsigned int reg, unsigned long *base, ...@@ -55,23 +141,104 @@ void generic_get_mtrr(unsigned int reg, unsigned long *base,
*type = base_lo & 0xff; *type = base_lo & 0xff;
} }
void generic_set_mtrr(unsigned int reg, unsigned long base, static int __init set_fixed_ranges(mtrr_type * frs)
unsigned long size, mtrr_type type) {
/* [SUMMARY] Set variable MTRR register on the local CPU. unsigned long *p = (unsigned long *) frs;
<reg> The register to set. int changed = FALSE;
<base> The base address of the region. int i;
<size> The size of the region. If this is 0 the region is disabled. unsigned long lo, hi;
<type> The type of the region.
<do_safe> If TRUE, do the change safely. If FALSE, safety measures should rdmsr(MTRRfix64K_00000_MSR, lo, hi);
be done externally. if (p[0] != lo || p[1] != hi) {
[RETURNS] Nothing. wrmsr(MTRRfix64K_00000_MSR, p[0], p[1]);
changed = TRUE;
}
for (i = 0; i < 2; i++) {
rdmsr(MTRRfix16K_80000_MSR + i, lo, hi);
if (p[2 + i * 2] != lo || p[3 + i * 2] != hi) {
wrmsr(MTRRfix16K_80000_MSR + i, p[2 + i * 2],
p[3 + i * 2]);
changed = TRUE;
}
}
for (i = 0; i < 8; i++) {
rdmsr(MTRRfix4K_C0000_MSR + i, lo, hi);
if (p[6 + i * 2] != lo || p[7 + i * 2] != hi) {
wrmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2],
p[7 + i * 2]);
changed = TRUE;
}
}
return changed;
}
/* Set the MSR pair relating to a var range. Returns TRUE if
changes are made */
static int __init set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
{
unsigned int lo, hi;
int changed = FALSE;
rdmsr(MTRRphysBase_MSR(index), lo, hi);
if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
|| (vr->base_hi & 0xfUL) != (hi & 0xfUL)) {
wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
changed = TRUE;
}
rdmsr(MTRRphysMask_MSR(index), lo, hi);
if ((vr->mask_lo & 0xfffff800UL) != (lo & 0xfffff800UL)
|| (vr->mask_hi & 0xfUL) != (hi & 0xfUL)) {
wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
changed = TRUE;
}
return changed;
}
static unsigned long set_mtrr_state(u32 deftype_lo, u32 deftype_hi)
/* [SUMMARY] Set the MTRR state for this CPU.
<state> The MTRR state information to read.
<ctxt> Some relevant CPU context.
[NOTE] The CPU must already be in a safe state for MTRR changes.
[RETURNS] 0 if no changes made, else a mask indication what was changed.
*/ */
{ {
u32 cr0, cr4 = 0; unsigned int i;
u32 deftype_lo, deftype_hi; unsigned long change_mask = 0;
static spinlock_t set_atomicity_lock = SPIN_LOCK_UNLOCKED;
for (i = 0; i < num_var_ranges; i++)
if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i]))
change_mask |= MTRR_CHANGE_MASK_VARIABLE;
if (set_fixed_ranges(mtrr_state.fixed_ranges))
change_mask |= MTRR_CHANGE_MASK_FIXED;
/* Set_mtrr_restore restores the old value of MTRRdefType,
so to set it we fiddle with the saved value */
if ((deftype_lo & 0xff) != mtrr_state.def_type
|| ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) {
deftype_lo |= (mtrr_state.def_type | mtrr_state.enabled << 10);
change_mask |= MTRR_CHANGE_MASK_DEFTYPE;
}
return change_mask;
}
static u32 cr4 = 0;
static u32 deftype_lo, deftype_hi;
static void prepare_set(void)
{
u32 cr0;
/* Note that this is not ideal, since the cache is only flushed/disabled
for this CPU while the MTRRs are changed, but changing this requires
more invasive changes to the way the kernel boots */
spin_lock(&set_atomicity_lock);
/* Save value of CR4 and clear Page Global Enable (bit 7) */ /* Save value of CR4 and clear Page Global Enable (bit 7) */
if ( cpu_has_pge ) { if ( cpu_has_pge ) {
cr4 = read_cr4(); cr4 = read_cr4();
...@@ -90,18 +257,10 @@ void generic_set_mtrr(unsigned int reg, unsigned long base, ...@@ -90,18 +257,10 @@ void generic_set_mtrr(unsigned int reg, unsigned long base,
/* Disable MTRRs, and set the default type to uncached */ /* Disable MTRRs, and set the default type to uncached */
wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi); wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi);
}
if (size == 0) { static void post_set(void)
/* The invalid bit is kept in the mask, so we simply clear the {
relevant mask register to disable a range. */
wrmsr(MTRRphysMask_MSR(reg), 0, 0);
} else {
wrmsr(MTRRphysBase_MSR(reg), base << PAGE_SHIFT | type,
(base & size_and_mask) >> (32 - PAGE_SHIFT));
wrmsr(MTRRphysMask_MSR(reg), -size << PAGE_SHIFT | 0x800,
(-size & size_and_mask) >> (32 - PAGE_SHIFT));
}
/* Flush caches and TLBs */ /* Flush caches and TLBs */
wbinvd(); wbinvd();
...@@ -114,7 +273,57 @@ void generic_set_mtrr(unsigned int reg, unsigned long base, ...@@ -114,7 +273,57 @@ void generic_set_mtrr(unsigned int reg, unsigned long base,
/* Restore value of CR4 */ /* Restore value of CR4 */
if ( cpu_has_pge ) if ( cpu_has_pge )
write_cr4(cr4); write_cr4(cr4);
spin_unlock(&set_atomicity_lock);
}
static void generic_set_all(void)
{
unsigned long mask, count;
prepare_set();
/* Actually set the state */
mask = set_mtrr_state(deftype_lo,deftype_hi);
post_set();
/* Use the atomic bitops to update the global mask */
for (count = 0; count < sizeof mask * 8; ++count) {
if (mask & 0x01)
set_bit(count, &smp_changes_mask);
mask >>= 1;
}
}
static void generic_set_mtrr(unsigned int reg, unsigned long base,
unsigned long size, mtrr_type type)
/* [SUMMARY] Set variable MTRR register on the local CPU.
<reg> The register to set.
<base> The base address of the region.
<size> The size of the region. If this is 0 the region is disabled.
<type> The type of the region.
<do_safe> If TRUE, do the change safely. If FALSE, safety measures should
be done externally.
[RETURNS] Nothing.
*/
{
prepare_set();
printk("MTRR: setting reg %x\n",reg);
if (size == 0) {
/* The invalid bit is kept in the mask, so we simply clear the
relevant mask register to disable a range. */
wrmsr(MTRRphysMask_MSR(reg), 0, 0);
} else {
wrmsr(MTRRphysBase_MSR(reg), base << PAGE_SHIFT | type,
(base & size_and_mask) >> (32 - PAGE_SHIFT));
wrmsr(MTRRphysMask_MSR(reg), -size << PAGE_SHIFT | 0x800,
(-size & size_and_mask) >> (32 - PAGE_SHIFT));
}
post_set();
} }
int generic_validate_add_page(unsigned long base, unsigned long size, unsigned int type) int generic_validate_add_page(unsigned long base, unsigned long size, unsigned int type)
...@@ -178,7 +387,7 @@ int positive_have_wrcomb(void) ...@@ -178,7 +387,7 @@ int positive_have_wrcomb(void)
*/ */
struct mtrr_ops generic_mtrr_ops = { struct mtrr_ops generic_mtrr_ops = {
.use_intel_if = 1, .use_intel_if = 1,
.init_secondary = generic_init_secondary, .set_all = generic_set_all,
.get = generic_get_mtrr, .get = generic_get_mtrr,
.get_free_region = generic_get_free_region, .get_free_region = generic_get_free_region,
.set = generic_set_mtrr, .set = generic_set_mtrr,
......
...@@ -163,8 +163,11 @@ static void ipi_handler(void *info) ...@@ -163,8 +163,11 @@ static void ipi_handler(void *info)
} }
/* The master has cleared me to execute */ /* The master has cleared me to execute */
if (data->smp_reg != ~0UL)
mtrr_if->set(data->smp_reg, data->smp_base, mtrr_if->set(data->smp_reg, data->smp_base,
data->smp_size, data->smp_type); data->smp_size, data->smp_type);
else
mtrr_if->set_all();
atomic_dec(&data->count); atomic_dec(&data->count);
while(atomic_read(&data->gate)) { while(atomic_read(&data->gate)) {
...@@ -243,6 +246,14 @@ static void set_mtrr(unsigned int reg, unsigned long base, ...@@ -243,6 +246,14 @@ static void set_mtrr(unsigned int reg, unsigned long base,
atomic_set(&data.gate,1); atomic_set(&data.gate,1);
/* do our MTRR business */ /* do our MTRR business */
/* HACK!
* We use this same function to initialize the mtrrs on boot.
* The state of the boot cpu's mtrrs has been saved, and we want
* to replicate across all the APs.
* If we're doing that @reg is set to something special...
*/
if (reg != ~0UL)
mtrr_if->set(reg,base,size,type); mtrr_if->set(reg,base,size,type);
/* wait for the others */ /* wait for the others */
...@@ -530,6 +541,20 @@ static void __init init_ifs(void) ...@@ -530,6 +541,20 @@ static void __init init_ifs(void)
centaur_init_mtrr(); centaur_init_mtrr();
} }
static void init_other_cpus(void)
{
if (use_intel())
get_mtrr_state();
/* bring up the other processors */
set_mtrr(~0UL,0,0,0);
if (use_intel()) {
finalize_mtrr_state();
mtrr_state_warn();
}
}
/** /**
* mtrr_init - initialie mtrrs on the boot CPU * mtrr_init - initialie mtrrs on the boot CPU
* *
...@@ -537,7 +562,7 @@ static void __init init_ifs(void) ...@@ -537,7 +562,7 @@ static void __init init_ifs(void)
* initialized (i.e. before smp_init()). * initialized (i.e. before smp_init()).
* *
*/ */
int __init mtrr_init(void) static int __init mtrr_init(void)
{ {
init_ifs(); init_ifs();
...@@ -608,21 +633,15 @@ int __init mtrr_init(void) ...@@ -608,21 +633,15 @@ int __init mtrr_init(void)
break; break;
} }
} }
printk("mtrr: v%s\n",MTRR_VERSION);
if (mtrr_if) { if (mtrr_if) {
set_num_var_ranges(); set_num_var_ranges();
if (use_intel()) {
/* Only for Intel MTRRs */
get_mtrr_state();
}
init_table(); init_table();
init_other_cpus();
} }
#if 0
printk("mtrr: v%s Richard Gooch (rgooch@atnf.csiro.au)\n"
"mtrr: detected mtrr type: %s\n",
MTRR_VERSION, mtrr_if_name[mtrr_if]);
#endif
return mtrr_if ? -ENXIO : 0; return mtrr_if ? -ENXIO : 0;
} }
//subsys_initcall(mtrr_init); core_initcall(mtrr_init);
...@@ -38,9 +38,10 @@ struct mtrr_ops { ...@@ -38,9 +38,10 @@ struct mtrr_ops {
u32 vendor; u32 vendor;
u32 use_intel_if; u32 use_intel_if;
void (*init)(void); void (*init)(void);
void (*init_secondary)(void);
void (*set)(unsigned int reg, unsigned long base, void (*set)(unsigned int reg, unsigned long base,
unsigned long size, mtrr_type type); unsigned long size, mtrr_type type);
void (*set_all)(void);
void (*get)(unsigned int reg, unsigned long *base, void (*get)(unsigned int reg, unsigned long *base,
unsigned long *size, mtrr_type * type); unsigned long *size, mtrr_type * type);
int (*get_free_region) (unsigned long base, unsigned long size); int (*get_free_region) (unsigned long base, unsigned long size);
......
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/slab.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/mtrr.h> #include <asm/mtrr.h>
#include <asm/msr.h> #include <asm/msr.h>
#include "mtrr.h" #include "mtrr.h"
struct mtrr_state {
struct mtrr_var_range *var_ranges;
mtrr_type fixed_ranges[NUM_FIXED_RANGES];
unsigned char enabled;
mtrr_type def_type;
};
static unsigned long smp_changes_mask __initdata = 0;
struct mtrr_state mtrr_state = {};
static int __init set_fixed_ranges(mtrr_type * frs)
{
unsigned long *p = (unsigned long *) frs;
int changed = FALSE;
int i;
unsigned long lo, hi;
rdmsr(MTRRfix64K_00000_MSR, lo, hi);
if (p[0] != lo || p[1] != hi) {
wrmsr(MTRRfix64K_00000_MSR, p[0], p[1]);
changed = TRUE;
}
for (i = 0; i < 2; i++) {
rdmsr(MTRRfix16K_80000_MSR + i, lo, hi);
if (p[2 + i * 2] != lo || p[3 + i * 2] != hi) {
wrmsr(MTRRfix16K_80000_MSR + i, p[2 + i * 2],
p[3 + i * 2]);
changed = TRUE;
}
}
for (i = 0; i < 8; i++) {
rdmsr(MTRRfix4K_C0000_MSR + i, lo, hi);
if (p[6 + i * 2] != lo || p[7 + i * 2] != hi) {
wrmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2],
p[7 + i * 2]);
changed = TRUE;
}
}
return changed;
}
/* Set the MSR pair relating to a var range. Returns TRUE if
changes are made */
static int __init set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
{
unsigned int lo, hi;
int changed = FALSE;
rdmsr(MTRRphysBase_MSR(index), lo, hi);
if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
|| (vr->base_hi & 0xfUL) != (hi & 0xfUL)) {
wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
changed = TRUE;
}
rdmsr(MTRRphysMask_MSR(index), lo, hi);
if ((vr->mask_lo & 0xfffff800UL) != (lo & 0xfffff800UL)
|| (vr->mask_hi & 0xfUL) != (hi & 0xfUL)) {
wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
changed = TRUE;
}
return changed;
}
static unsigned long set_mtrr_state(u32 deftype_lo, u32 deftype_hi)
/* [SUMMARY] Set the MTRR state for this CPU.
<state> The MTRR state information to read.
<ctxt> Some relevant CPU context.
[NOTE] The CPU must already be in a safe state for MTRR changes.
[RETURNS] 0 if no changes made, else a mask indication what was changed.
*/
{
unsigned int i;
unsigned long change_mask = 0;
for (i = 0; i < num_var_ranges; i++)
if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i]))
change_mask |= MTRR_CHANGE_MASK_VARIABLE;
if (set_fixed_ranges(mtrr_state.fixed_ranges))
change_mask |= MTRR_CHANGE_MASK_FIXED;
/* Set_mtrr_restore restores the old value of MTRRdefType,
so to set it we fiddle with the saved value */
if ((deftype_lo & 0xff) != mtrr_state.def_type
|| ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) {
deftype_lo |= (mtrr_state.def_type | mtrr_state.enabled << 10);
change_mask |= MTRR_CHANGE_MASK_DEFTYPE;
}
return change_mask;
}
/* Some BIOS's are fucked and don't set all MTRRs the same! */
static void __init mtrr_state_warn(void)
{
unsigned long mask = smp_changes_mask;
if (!mask)
return;
if (mask & MTRR_CHANGE_MASK_FIXED)
printk
("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
if (mask & MTRR_CHANGE_MASK_VARIABLE)
printk
("mtrr: your CPUs had inconsistent variable MTRR settings\n");
if (mask & MTRR_CHANGE_MASK_DEFTYPE)
printk
("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
printk("mtrr: probably your BIOS does not setup all CPUs\n");
}
/* Free resources associated with a struct mtrr_state */
static void __init finalize_mtrr_state(void)
{
if (mtrr_state.var_ranges)
kfree(mtrr_state.var_ranges);
mtrr_state.var_ranges = NULL;
}
/* Get the MSR pair relating to a var range */
static void __init
get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr)
{
rdmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
}
static void __init
get_fixed_ranges(mtrr_type * frs)
{
unsigned long *p = (unsigned long *) frs;
int i;
rdmsr(MTRRfix64K_00000_MSR, p[0], p[1]);
for (i = 0; i < 2; i++)
rdmsr(MTRRfix16K_80000_MSR + i, p[2 + i * 2], p[3 + i * 2]);
for (i = 0; i < 8; i++)
rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2], p[7 + i * 2]);
}
/* Grab all of the MTRR state for this CPU into *state */
void get_mtrr_state(void)
{
unsigned int i;
struct mtrr_var_range *vrs;
unsigned long lo, dummy;
if (!mtrr_state.var_ranges) {
mtrr_state.var_ranges = kmalloc(num_var_ranges * sizeof (struct mtrr_var_range),
GFP_KERNEL);
if (!mtrr_state.var_ranges)
return;
}
vrs = mtrr_state.var_ranges;
for (i = 0; i < num_var_ranges; i++)
get_mtrr_var_range(i, &vrs[i]);
get_fixed_ranges(mtrr_state.fixed_ranges);
rdmsr(MTRRdefType_MSR, lo, dummy);
mtrr_state.def_type = (lo & 0xff);
mtrr_state.enabled = (lo & 0xc00) >> 10;
}
/* Put the processor into a state where MTRRs can be safely set */ /* Put the processor into a state where MTRRs can be safely set */
void set_mtrr_prepare_save(struct set_mtrr_context *ctxt) void set_mtrr_prepare_save(struct set_mtrr_context *ctxt)
...@@ -246,93 +76,3 @@ void set_mtrr_done(struct set_mtrr_context *ctxt) ...@@ -246,93 +76,3 @@ void set_mtrr_done(struct set_mtrr_context *ctxt)
local_irq_restore(ctxt->flags); local_irq_restore(ctxt->flags);
} }
void __init generic_init_secondary(void)
{
u32 cr0, cr4 = 0;
u32 deftype_lo, deftype_hi;
unsigned long mask, count;
/* Note that this is not ideal, since the cache is only flushed/disabled
for this CPU while the MTRRs are changed, but changing this requires
more invasive changes to the way the kernel boots */
/* Save value of CR4 and clear Page Global Enable (bit 7) */
if ( cpu_has_pge ) {
cr4 = read_cr4();
write_cr4(cr4 & (unsigned char) ~(1 << 7));
}
/* Disable and flush caches. Note that wbinvd flushes the TLBs as
a side-effect */
cr0 = read_cr0() | 0x40000000;
wbinvd();
write_cr0(cr0);
wbinvd();
/* Save MTRR state */
rdmsr(MTRRdefType_MSR, deftype_lo, deftype_hi);
/* Disable MTRRs, and set the default type to uncached */
wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi);
/* Actually set the state */
mask = set_mtrr_state(deftype_lo,deftype_hi);
/* Flush caches and TLBs */
wbinvd();
/* Intel (P6) standard MTRRs */
wrmsr(MTRRdefType_MSR, deftype_lo, deftype_hi);
/* Enable caches */
write_cr0(read_cr0() & 0xbfffffff);
/* Restore value of CR4 */
if ( cpu_has_pge )
write_cr4(cr4);
/* Use the atomic bitops to update the global mask */
for (count = 0; count < sizeof mask * 8; ++count) {
if (mask & 0x01)
set_bit(count, &smp_changes_mask);
mask >>= 1;
}
}
/**
* mtrr_init_secondary - setup AP MTRR state
*
* Yes, this code is exactly the same as the set_mtrr code, except for the
* piece in the middle - you set all the ranges at once, instead of one
* register at a time.
* Shoot me.
*/
void __init mtrr_init_secondary_cpu(void)
{
unsigned long flags;
if (!mtrr_if || !mtrr_if->init_secondary) {
/* I see no MTRRs I can support in SMP mode... */
printk("mtrr: SMP support incomplete for this vendor\n");
return;
}
local_irq_save(flags);
mtrr_if->init_secondary();
local_irq_restore(flags);
}
/**
* mtrr_final_init - finalize initialization sequence.
*/
static int __init mtrr_finalize_state(void)
{
if (use_intel()) {
finalize_mtrr_state();
mtrr_state_warn();
}
return 0;
}
arch_initcall(mtrr_finalize_state);
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mc146818rtc.h> #include <linux/mc146818rtc.h>
#include <asm/mtrr.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/smpboot.h> #include <asm/smpboot.h>
...@@ -403,12 +402,6 @@ void __init smp_callin(void) ...@@ -403,12 +402,6 @@ void __init smp_callin(void)
local_irq_enable(); local_irq_enable();
#ifdef CONFIG_MTRR
/*
* Must be done before calibration delay is computed
*/
mtrr_init_secondary_cpu ();
#endif
/* /*
* Get our bogomips. * Get our bogomips.
*/ */
......
...@@ -114,11 +114,10 @@ static int tosh_fn_status(void) ...@@ -114,11 +114,10 @@ static int tosh_fn_status(void)
if (tosh_fn!=0) { if (tosh_fn!=0) {
scan = inb(tosh_fn); scan = inb(tosh_fn);
} else { } else {
save_flags(flags); local_irq_save(flags);
cli();
outb(0x8e, 0xe4); outb(0x8e, 0xe4);
scan = inb(0xe5); scan = inb(0xe5);
restore_flags(flags); local_irq_restore(flags);
} }
return (int) scan; return (int) scan;
...@@ -141,35 +140,32 @@ static int tosh_emulate_fan(SMMRegisters *regs) ...@@ -141,35 +140,32 @@ static int tosh_emulate_fan(SMMRegisters *regs)
if (tosh_id==0xfccb) { if (tosh_id==0xfccb) {
if (eax==0xfe00) { if (eax==0xfe00) {
/* fan status */ /* fan status */
save_flags(flags); local_irq_save(flags);
cli();
outb(0xbe, 0xe4); outb(0xbe, 0xe4);
al = inb(0xe5); al = inb(0xe5);
restore_flags(flags); local_irq_restore(flags);
regs->eax = 0x00; regs->eax = 0x00;
regs->ecx = (unsigned int) (al & 0x01); regs->ecx = (unsigned int) (al & 0x01);
} }
if ((eax==0xff00) && (ecx==0x0000)) { if ((eax==0xff00) && (ecx==0x0000)) {
/* fan off */ /* fan off */
save_flags(flags); local_irq_save(flags);
cli();
outb(0xbe, 0xe4); outb(0xbe, 0xe4);
al = inb(0xe5); al = inb(0xe5);
outb(0xbe, 0xe4); outb(0xbe, 0xe4);
outb (al | 0x01, 0xe5); outb (al | 0x01, 0xe5);
restore_flags(flags); local_irq_restore(flags);
regs->eax = 0x00; regs->eax = 0x00;
regs->ecx = 0x00; regs->ecx = 0x00;
} }
if ((eax==0xff00) && (ecx==0x0001)) { if ((eax==0xff00) && (ecx==0x0001)) {
/* fan on */ /* fan on */
save_flags(flags); local_irq_save(flags);
cli();
outb(0xbe, 0xe4); outb(0xbe, 0xe4);
al = inb(0xe5); al = inb(0xe5);
outb(0xbe, 0xe4); outb(0xbe, 0xe4);
outb(al & 0xfe, 0xe5); outb(al & 0xfe, 0xe5);
restore_flags(flags); local_irq_restore(flags);
regs->eax = 0x00; regs->eax = 0x00;
regs->ecx = 0x01; regs->ecx = 0x01;
} }
...@@ -180,33 +176,30 @@ static int tosh_emulate_fan(SMMRegisters *regs) ...@@ -180,33 +176,30 @@ static int tosh_emulate_fan(SMMRegisters *regs)
if (tosh_id==0xfccc) { if (tosh_id==0xfccc) {
if (eax==0xfe00) { if (eax==0xfe00) {
/* fan status */ /* fan status */
save_flags(flags); local_irq_save(flags);
cli();
outb(0xe0, 0xe4); outb(0xe0, 0xe4);
al = inb(0xe5); al = inb(0xe5);
restore_flags(flags); local_irq_restore(flags);
regs->eax = 0x00; regs->eax = 0x00;
regs->ecx = al & 0x01; regs->ecx = al & 0x01;
} }
if ((eax==0xff00) && (ecx==0x0000)) { if ((eax==0xff00) && (ecx==0x0000)) {
/* fan off */ /* fan off */
save_flags(flags); local_irq_save(flags);
cli();
outb(0xe0, 0xe4); outb(0xe0, 0xe4);
al = inb(0xe5); al = inb(0xe5);
outw(0xe0 | ((al & 0xfe) << 8), 0xe4); outw(0xe0 | ((al & 0xfe) << 8), 0xe4);
restore_flags(flags); local_irq_restore(flags);
regs->eax = 0x00; regs->eax = 0x00;
regs->ecx = 0x00; regs->ecx = 0x00;
} }
if ((eax==0xff00) && (ecx==0x0001)) { if ((eax==0xff00) && (ecx==0x0001)) {
/* fan on */ /* fan on */
save_flags(flags); local_irq_save(flags);
cli();
outb(0xe0, 0xe4); outb(0xe0, 0xe4);
al = inb(0xe5); al = inb(0xe5);
outw(0xe0 | ((al | 0x01) << 8), 0xe4); outw(0xe0 | ((al | 0x01) << 8), 0xe4);
restore_flags(flags); local_irq_restore(flags);
regs->eax = 0x00; regs->eax = 0x00;
regs->ecx = 0x01; regs->ecx = 0x01;
} }
......
...@@ -292,16 +292,14 @@ struct controller { ...@@ -292,16 +292,14 @@ struct controller {
struct pci_resource *io_head; struct pci_resource *io_head;
struct pci_resource *bus_head; struct pci_resource *bus_head;
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
struct pci_ops *pci_ops; struct pci_bus *pci_bus;
struct proc_dir_entry* proc_entry; struct proc_dir_entry* proc_entry;
struct proc_dir_entry* proc_entry2; struct proc_dir_entry* proc_entry2;
struct event_info event_queue[10]; struct event_info event_queue[10];
struct slot *slot; struct slot *slot;
u8 next_event; u8 next_event;
u8 interrupt; u8 interrupt;
u8 bus; u8 bus; /* bus number for the pci hotplug controller */
u8 device;
u8 function;
u8 rev; u8 rev;
u8 slot_device_offset; u8 slot_device_offset;
u8 first_slot; u8 first_slot;
...@@ -695,7 +693,8 @@ static inline int cpq_get_latch_status (struct controller *ctrl, struct slot *sl ...@@ -695,7 +693,8 @@ static inline int cpq_get_latch_status (struct controller *ctrl, struct slot *sl
return 1; return 1;
hp_slot = slot->device - ctrl->slot_device_offset; hp_slot = slot->device - ctrl->slot_device_offset;
dbg(__FUNCTION__": slot->device = %d, ctrl->slot_device_offset = %d \n", slot->device, ctrl->slot_device_offset); dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d \n",
__FUNCTION__, slot->device, ctrl->slot_device_offset);
status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)); status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot));
...@@ -733,7 +732,7 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl) ...@@ -733,7 +732,7 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl)
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
int retval = 0; int retval = 0;
dbg(__FUNCTION__" - start\n"); dbg("%s - start\n", __FUNCTION__);
add_wait_queue(&ctrl->queue, &wait); add_wait_queue(&ctrl->queue, &wait);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
/* Sleep for up to 1 second to wait for the LED to change. */ /* Sleep for up to 1 second to wait for the LED to change. */
...@@ -743,7 +742,7 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl) ...@@ -743,7 +742,7 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl)
if (signal_pending(current)) if (signal_pending(current))
retval = -EINTR; retval = -EINTR;
dbg(__FUNCTION__" - end\n"); dbg("%s - end\n", __FUNCTION__);
return retval; return retval;
} }
......
...@@ -314,7 +314,7 @@ static int ctrl_slot_setup (struct controller * ctrl, void *smbios_start, void * ...@@ -314,7 +314,7 @@ static int ctrl_slot_setup (struct controller * ctrl, void *smbios_start, void *
void *slot_entry= NULL; void *slot_entry= NULL;
int result; int result;
dbg(__FUNCTION__"\n"); dbg("%s\n", __FUNCTION__);
tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR); tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
...@@ -467,7 +467,7 @@ static int ctrl_slot_cleanup (struct controller * ctrl) ...@@ -467,7 +467,7 @@ static int ctrl_slot_cleanup (struct controller * ctrl)
// //
// Output: SUCCESS or FAILURE // Output: SUCCESS or FAILURE
//============================================================================= //=============================================================================
static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *slot) static int get_slot_mapping (struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
{ {
struct irq_routing_table *PCIIRQRoutingInfoLength; struct irq_routing_table *PCIIRQRoutingInfoLength;
u32 work; u32 work;
...@@ -476,7 +476,7 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl ...@@ -476,7 +476,7 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl
u8 tbus, tdevice, tslot, bridgeSlot; u8 tbus, tdevice, tslot, bridgeSlot;
dbg(__FUNCTION__" %p, %d, %d, %p\n", ops, bus_num, dev_num, slot); dbg("%s: %p, %d, %d, %p\n", __FUNCTION__, bus, bus_num, dev_num, slot);
bridgeSlot = 0xFF; bridgeSlot = 0xFF;
...@@ -490,7 +490,6 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl ...@@ -490,7 +490,6 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl
return -1; return -1;
} }
for (loop = 0; loop < len; ++loop) { for (loop = 0; loop < len; ++loop) {
tbus = PCIIRQRoutingInfoLength->slots[loop].bus; tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3; tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
...@@ -499,7 +498,8 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl ...@@ -499,7 +498,8 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl
if ((tbus == bus_num) && (tdevice == dev_num)) { if ((tbus == bus_num) && (tdevice == dev_num)) {
*slot = tslot; *slot = tslot;
if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength ); if (PCIIRQRoutingInfoLength != NULL)
kfree(PCIIRQRoutingInfoLength);
return 0; return 0;
} else { } else {
// Didn't get a match on the target PCI device. Check if the // Didn't get a match on the target PCI device. Check if the
...@@ -508,10 +508,11 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl ...@@ -508,10 +508,11 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl
// device, I need to save the bridge's slot number. If I can't // device, I need to save the bridge's slot number. If I can't
// find an entry for the target device, I will have to assume it's // find an entry for the target device, I will have to assume it's
// on the other side of the bridge, and assign it the bridge's slot. // on the other side of the bridge, and assign it the bridge's slot.
pci_read_config_dword_nodev (ops, tbus, tdevice, 0, PCI_REVISION_ID, &work); bus->number = tbus;
pci_bus_read_config_dword (bus, PCI_DEVFN(tdevice, 0), PCI_REVISION_ID, &work);
if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) { if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
pci_read_config_dword_nodev (ops, tbus, tdevice, 0, PCI_PRIMARY_BUS, &work); pci_bus_read_config_dword (bus, PCI_DEVFN(tdevice, 0), PCI_PRIMARY_BUS, &work);
// See if bridge's secondary bus matches target bus. // See if bridge's secondary bus matches target bus.
if (((work >> 8) & 0x000000FF) == (long) bus_num) { if (((work >> 8) & 0x000000FF) == (long) bus_num) {
bridgeSlot = tslot; bridgeSlot = tslot;
...@@ -521,7 +522,6 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl ...@@ -521,7 +522,6 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl
} }
// If we got here, we didn't find an entry in the IRQ mapping table // If we got here, we didn't find an entry in the IRQ mapping table
// for the target PCI device. If we did determine that the target // for the target PCI device. If we did determine that the target
// device is on the other side of a PCI-to-PCI bridge, return the // device is on the other side of a PCI-to-PCI bridge, return the
...@@ -592,7 +592,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) ...@@ -592,7 +592,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -627,7 +627,7 @@ static int process_SI (struct hotplug_slot *hotplug_slot) ...@@ -627,7 +627,7 @@ static int process_SI (struct hotplug_slot *hotplug_slot)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -667,7 +667,7 @@ static int process_SS (struct hotplug_slot *hotplug_slot) ...@@ -667,7 +667,7 @@ static int process_SS (struct hotplug_slot *hotplug_slot)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -695,7 +695,7 @@ static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value) ...@@ -695,7 +695,7 @@ static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
struct controller *ctrl; struct controller *ctrl;
dbg(__FUNCTION__"\n"); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
...@@ -716,7 +716,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -716,7 +716,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -734,7 +734,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -734,7 +734,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -752,7 +752,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -752,7 +752,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -771,7 +771,7 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -771,7 +771,7 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -820,7 +820,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -820,7 +820,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// TODO: This code can be made to support non-Compaq or Intel subsystem IDs // TODO: This code can be made to support non-Compaq or Intel subsystem IDs
rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid); rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
if (rc) { if (rc) {
err(__FUNCTION__" : pci_read_config_word failed\n"); err("%s : pci_read_config_word failed\n", __FUNCTION__);
return rc; return rc;
} }
dbg("Subsystem Vendor ID: %x\n", subsystem_vid); dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
...@@ -831,14 +831,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -831,14 +831,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL); ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
if (!ctrl) { if (!ctrl) {
err(__FUNCTION__" : out of memory\n"); err("%s : out of memory\n", __FUNCTION__);
return -ENOMEM; return -ENOMEM;
} }
memset(ctrl, 0, sizeof(struct controller)); memset(ctrl, 0, sizeof(struct controller));
rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid); rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
if (rc) { if (rc) {
err(__FUNCTION__" : pci_read_config_word failed\n"); err("%s : pci_read_config_word failed\n", __FUNCTION__);
goto err_free_ctrl; goto err_free_ctrl;
} }
...@@ -991,12 +991,20 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -991,12 +991,20 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dbg (" pcix_support %s\n", ctrl->pcix_support == 0 ? "not supported" : "supported"); dbg (" pcix_support %s\n", ctrl->pcix_support == 0 ? "not supported" : "supported");
ctrl->pci_dev = pdev; ctrl->pci_dev = pdev;
ctrl->pci_ops = pdev->bus->ops;
/* make our own copy of the pci bus structure, as we like tweaking it a lot */
ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
if (!ctrl->pci_bus) {
err("out of memory\n");
rc = -ENOMEM;
goto err_free_ctrl;
}
memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
ctrl->bus = pdev->bus->number; ctrl->bus = pdev->bus->number;
ctrl->device = PCI_SLOT(pdev->devfn);
ctrl->function = PCI_FUNC(pdev->devfn);
ctrl->rev = rev; ctrl->rev = rev;
dbg("bus device function rev: %d %d %d %d\n", ctrl->bus, ctrl->device, ctrl->function, ctrl->rev); dbg("bus device function rev: %d %d %d %d\n", ctrl->bus,
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev);
init_MUTEX(&ctrl->crit_sect); init_MUTEX(&ctrl->crit_sect);
init_waitqueue_head(&ctrl->queue); init_waitqueue_head(&ctrl->queue);
...@@ -1004,7 +1012,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1004,7 +1012,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* initialize our threads if they haven't already been started up */ /* initialize our threads if they haven't already been started up */
rc = one_time_init(); rc = one_time_init();
if (rc) { if (rc) {
goto err_free_ctrl; goto err_free_bus;
} }
dbg("pdev = %p\n", pdev); dbg("pdev = %p\n", pdev);
...@@ -1015,7 +1023,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1015,7 +1023,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_resource_len(pdev, 0), MY_NAME)) { pci_resource_len(pdev, 0), MY_NAME)) {
err("cannot reserve MMIO region\n"); err("cannot reserve MMIO region\n");
rc = -ENOMEM; rc = -ENOMEM;
goto err_free_ctrl; goto err_free_bus;
} }
ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
...@@ -1043,7 +1051,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1043,7 +1051,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// in this case it will always be called for the "base" // in this case it will always be called for the "base"
// bus/dev/func of a slot. // bus/dev/func of a slot.
// CS: this is leveraging the PCIIRQ routing code from the kernel (pci-pc.c: get_irq_routing_table) // CS: this is leveraging the PCIIRQ routing code from the kernel (pci-pc.c: get_irq_routing_table)
rc = get_slot_mapping(ctrl->pci_ops, pdev->bus->number, (readb(ctrl->hpc_reg + SLOT_MASK) >> 4), &(ctrl->first_slot)); rc = get_slot_mapping(ctrl->pci_bus, pdev->bus->number, (readb(ctrl->hpc_reg + SLOT_MASK) >> 4), &(ctrl->first_slot));
dbg("get_slot_mapping: first_slot = %d, returned = %d\n", ctrl->first_slot, rc); dbg("get_slot_mapping: first_slot = %d, returned = %d\n", ctrl->first_slot, rc);
if (rc) { if (rc) {
err(msg_initialization_err, rc); err(msg_initialization_err, rc);
...@@ -1053,7 +1061,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1053,7 +1061,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// Store PCI Config Space for all devices on this bus // Store PCI Config Space for all devices on this bus
rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK)); rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
if (rc) { if (rc) {
err(__FUNCTION__": unable to save PCI configuration data, error %d\n", rc); err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
goto err_iounmap; goto err_iounmap;
} }
...@@ -1080,7 +1088,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1080,7 +1088,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table); rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table);
if (rc) { if (rc) {
err(msg_initialization_err, 6); err(msg_initialization_err, 6);
err(__FUNCTION__": unable to save PCI configuration data, error %d\n", rc); err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
goto err_iounmap; goto err_iounmap;
} }
...@@ -1188,6 +1196,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1188,6 +1196,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iounmap(ctrl->hpc_reg); iounmap(ctrl->hpc_reg);
err_free_mem_region: err_free_mem_region:
release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
err_free_bus:
kfree(ctrl->pci_bus);
err_free_ctrl: err_free_ctrl:
kfree(ctrl); kfree(ctrl);
return rc; return rc;
...@@ -1328,6 +1338,8 @@ static void unload_cpqphpd(void) ...@@ -1328,6 +1338,8 @@ static void unload_cpqphpd(void)
kfree(tres); kfree(tres);
} }
kfree (ctrl->pci_bus);
tctrl = ctrl; tctrl = ctrl;
ctrl = ctrl->next; ctrl = ctrl->next;
kfree(tctrl); kfree(tctrl);
......
...@@ -772,13 +772,13 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size) ...@@ -772,13 +772,13 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
return(NULL); return(NULL);
for (node = *head; node; node = node->next) { for (node = *head; node; node = node->next) {
dbg(__FUNCTION__": req_size =%x node=%p, base=%x, length=%x\n", dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
size, node, node->base, node->length); __FUNCTION__, size, node, node->base, node->length);
if (node->length < size) if (node->length < size)
continue; continue;
if (node->base & (size - 1)) { if (node->base & (size - 1)) {
dbg(__FUNCTION__": not aligned\n"); dbg("%s: not aligned\n", __FUNCTION__);
// this one isn't base aligned properly // this one isn't base aligned properly
// so we'll make a new entry and split it up // so we'll make a new entry and split it up
temp_dword = (node->base | (size-1)) + 1; temp_dword = (node->base | (size-1)) + 1;
...@@ -804,7 +804,7 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size) ...@@ -804,7 +804,7 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
// Don't need to check if too small since we already did // Don't need to check if too small since we already did
if (node->length > size) { if (node->length > size) {
dbg(__FUNCTION__": too big\n"); dbg("%s: too big\n", __FUNCTION__);
// this one is longer than we need // this one is longer than we need
// so we'll make a new entry and split it up // so we'll make a new entry and split it up
split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
...@@ -821,7 +821,7 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size) ...@@ -821,7 +821,7 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
node->next = split_node; node->next = split_node;
} // End of too big on top end } // End of too big on top end
dbg(__FUNCTION__": got one!!!\n"); dbg("%s: got one!!!\n", __FUNCTION__);
// If we got here, then it is the right size // If we got here, then it is the right size
// Now take it out of the list // Now take it out of the list
if (*head == node) { if (*head == node) {
...@@ -856,7 +856,7 @@ int cpqhp_resource_sort_and_combine(struct pci_resource **head) ...@@ -856,7 +856,7 @@ int cpqhp_resource_sort_and_combine(struct pci_resource **head)
struct pci_resource *node2; struct pci_resource *node2;
int out_of_order = 1; int out_of_order = 1;
dbg(__FUNCTION__": head = %p, *head = %p\n", head, *head); dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
if (!(*head)) if (!(*head))
return(1); return(1);
...@@ -942,7 +942,7 @@ void cpqhp_ctrl_intr(int IRQ, struct controller * ctrl, struct pt_regs *regs) ...@@ -942,7 +942,7 @@ void cpqhp_ctrl_intr(int IRQ, struct controller * ctrl, struct pt_regs *regs)
// Read to clear posted writes // Read to clear posted writes
misc = readw(ctrl->hpc_reg + MISC); misc = readw(ctrl->hpc_reg + MISC);
dbg (__FUNCTION__" - waking up\n"); dbg ("%s - waking up\n", __FUNCTION__);
wake_up_interruptible(&ctrl->queue); wake_up_interruptible(&ctrl->queue);
} }
...@@ -1382,8 +1382,8 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1382,8 +1382,8 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
struct resource_lists res_lists; struct resource_lists res_lists;
hp_slot = func->device - ctrl->slot_device_offset; hp_slot = func->device - ctrl->slot_device_offset;
dbg(__FUNCTION__": func->device, slot_offset, hp_slot = %d, %d ,%d\n", dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
func->device, ctrl->slot_device_offset, hp_slot); __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
if (ctrl->speed == 1) { if (ctrl->speed == 1) {
// Wait for exclusive access to hardware // Wait for exclusive access to hardware
...@@ -1430,55 +1430,56 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1430,55 +1430,56 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
// turn on board and blink green LED // turn on board and blink green LED
// Wait for exclusive access to hardware // Wait for exclusive access to hardware
dbg(__FUNCTION__": before down\n"); dbg("%s: before down\n", __FUNCTION__);
down(&ctrl->crit_sect); down(&ctrl->crit_sect);
dbg(__FUNCTION__": after down\n"); dbg("%s: after down\n", __FUNCTION__);
dbg(__FUNCTION__": before slot_enable\n"); dbg("%s: before slot_enable\n", __FUNCTION__);
slot_enable (ctrl, hp_slot); slot_enable (ctrl, hp_slot);
dbg(__FUNCTION__": before green_LED_blink\n"); dbg("%s: before green_LED_blink\n", __FUNCTION__);
green_LED_blink (ctrl, hp_slot); green_LED_blink (ctrl, hp_slot);
dbg(__FUNCTION__": before amber_LED_blink\n"); dbg("%s: before amber_LED_blink\n", __FUNCTION__);
amber_LED_off (ctrl, hp_slot); amber_LED_off (ctrl, hp_slot);
dbg(__FUNCTION__": before set_SOGO\n"); dbg("%s: before set_SOGO\n", __FUNCTION__);
set_SOGO(ctrl); set_SOGO(ctrl);
// Wait for SOBS to be unset // Wait for SOBS to be unset
dbg(__FUNCTION__": before wait_for_ctrl_irq\n"); dbg("%s: before wait_for_ctrl_irq\n", __FUNCTION__);
wait_for_ctrl_irq (ctrl); wait_for_ctrl_irq (ctrl);
dbg(__FUNCTION__": after wait_for_ctrl_irq\n"); dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
// Done with exclusive hardware access // Done with exclusive hardware access
dbg(__FUNCTION__": before up\n"); dbg("%s: before up\n", __FUNCTION__);
up(&ctrl->crit_sect); up(&ctrl->crit_sect);
dbg(__FUNCTION__": after up\n"); dbg("%s: after up\n", __FUNCTION__);
// Wait for ~1 second because of hot plug spec // Wait for ~1 second because of hot plug spec
dbg(__FUNCTION__": before long_delay\n"); dbg("%s: before long_delay\n", __FUNCTION__);
long_delay(1*HZ); long_delay(1*HZ);
dbg(__FUNCTION__": after long_delay\n"); dbg("%s: after long_delay\n", __FUNCTION__);
dbg(__FUNCTION__": func status = %x\n", func->status); dbg("%s: func status = %x\n", __FUNCTION__, func->status);
// Check for a power fault // Check for a power fault
if (func->status == 0xFF) { if (func->status == 0xFF) {
// power fault occurred, but it was benign // power fault occurred, but it was benign
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
dbg(__FUNCTION__": temp register set to %x by power fault\n", temp_register); dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
rc = POWER_FAILURE; rc = POWER_FAILURE;
func->status = 0; func->status = 0;
} else { } else {
// Get vendor/device ID u32 // Get vendor/device ID u32
rc = pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_VENDOR_ID, &temp_register); ctrl->pci_bus->number = func->bus;
dbg(__FUNCTION__": pci_read_config_dword returns %d\n", rc); rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), PCI_VENDOR_ID, &temp_register);
dbg(__FUNCTION__": temp_register is %x\n", temp_register); dbg("%s: pci_read_config_dword returns %d\n", __FUNCTION__, rc);
dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
if (rc != 0) { if (rc != 0) {
// Something's wrong here // Something's wrong here
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
dbg(__FUNCTION__": temp register set to %x by error\n", temp_register); dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
} }
// Preset return code. It will be changed later if things go okay. // Preset return code. It will be changed later if things go okay.
rc = NO_ADAPTER_PRESENT; rc = NO_ADAPTER_PRESENT;
...@@ -1494,7 +1495,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1494,7 +1495,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
rc = configure_new_device(ctrl, func, 0, &res_lists); rc = configure_new_device(ctrl, func, 0, &res_lists);
dbg(__FUNCTION__": back from configure_new_device\n"); dbg("%s: back from configure_new_device\n", __FUNCTION__);
ctrl->io_head = res_lists.io_head; ctrl->io_head = res_lists.io_head;
ctrl->mem_head = res_lists.mem_head; ctrl->mem_head = res_lists.mem_head;
ctrl->p_mem_head = res_lists.p_mem_head; ctrl->p_mem_head = res_lists.p_mem_head;
...@@ -1531,7 +1532,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1531,7 +1532,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
func->is_a_board = 0x01; func->is_a_board = 0x01;
//next, we will instantiate the linux pci_dev structures (with appropriate driver notification, if already present) //next, we will instantiate the linux pci_dev structures (with appropriate driver notification, if already present)
dbg(__FUNCTION__": configure linux pci_dev structure\n"); dbg("%s: configure linux pci_dev structure\n", __FUNCTION__);
index = 0; index = 0;
do { do {
new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++); new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);
...@@ -1598,7 +1599,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control ...@@ -1598,7 +1599,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control
device = func->device; device = func->device;
hp_slot = func->device - ctrl->slot_device_offset; hp_slot = func->device - ctrl->slot_device_offset;
dbg("In "__FUNCTION__", hp_slot = %d\n", hp_slot); dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
// When we get here, it is safe to change base Address Registers. // When we get here, it is safe to change base Address Registers.
// We will attempt to save the base Address Register Lengths // We will attempt to save the base Address Register Lengths
...@@ -1927,7 +1928,7 @@ void cpqhp_pushbutton_thread (unsigned long slot) ...@@ -1927,7 +1928,7 @@ void cpqhp_pushbutton_thread (unsigned long slot)
func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0); func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl); dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);
if (!func) { if (!func) {
dbg("Error! func NULL in "__FUNCTION__"\n"); dbg("Error! func NULL in %s\n", __FUNCTION__);
return ; return ;
} }
...@@ -1951,7 +1952,7 @@ void cpqhp_pushbutton_thread (unsigned long slot) ...@@ -1951,7 +1952,7 @@ void cpqhp_pushbutton_thread (unsigned long slot)
func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0); func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl); dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);
if (!func) { if (!func) {
dbg("Error! func NULL in "__FUNCTION__"\n"); dbg("Error! func NULL in %s\n", __FUNCTION__);
return ; return ;
} }
...@@ -2066,7 +2067,7 @@ int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func) ...@@ -2066,7 +2067,7 @@ int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func)
} }
if (rc) { if (rc) {
dbg(__FUNCTION__": rc = %d\n", rc); dbg("%s: rc = %d\n", __FUNCTION__, rc);
} }
if (p_slot) if (p_slot)
...@@ -2082,7 +2083,9 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func) ...@@ -2082,7 +2083,9 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
u8 index = 0; u8 index = 0;
u8 replace_flag; u8 replace_flag;
u32 rc = 0; u32 rc = 0;
unsigned int devfn;
struct slot* p_slot; struct slot* p_slot;
struct pci_bus *pci_bus = ctrl->pci_bus;
int physical_slot=0; int physical_slot=0;
device = func->device; device = func->device;
...@@ -2094,8 +2097,11 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func) ...@@ -2094,8 +2097,11 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
// Make sure there are no video controllers here // Make sure there are no video controllers here
while (func && !rc) { while (func && !rc) {
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
// Check the Class Code // Check the Class Code
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code); rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
if (rc) if (rc)
return rc; return rc;
...@@ -2104,13 +2110,13 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func) ...@@ -2104,13 +2110,13 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
rc = REMOVE_NOT_SUPPORTED; rc = REMOVE_NOT_SUPPORTED;
} else { } else {
// See if it's a bridge // See if it's a bridge
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
if (rc) if (rc)
return rc; return rc;
// If it's a bridge, check the VGA Enable bit // If it's a bridge, check the VGA Enable bit
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, &BCR); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
if (rc) if (rc)
return rc; return rc;
...@@ -2332,11 +2338,12 @@ static u32 configure_new_device (struct controller * ctrl, struct pci_func * fun ...@@ -2332,11 +2338,12 @@ static u32 configure_new_device (struct controller * ctrl, struct pci_func * fun
new_slot = func; new_slot = func;
dbg(__FUNCTION__"\n"); dbg("%s\n", __FUNCTION__);
// Check for Multi-function device // Check for Multi-function device
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0E, &temp_byte); ctrl->pci_bus->number = func->bus;
rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
if (rc) { if (rc) {
dbg(__FUNCTION__": rc = %d\n", rc); dbg("%s: rc = %d\n", __FUNCTION__, rc);
return rc; return rc;
} }
...@@ -2372,7 +2379,7 @@ static u32 configure_new_device (struct controller * ctrl, struct pci_func * fun ...@@ -2372,7 +2379,7 @@ static u32 configure_new_device (struct controller * ctrl, struct pci_func * fun
// and creates a board structure // and creates a board structure
while ((function < max_functions) && (!stop_it)) { while ((function < max_functions) && (!stop_it)) {
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, function, 0x00, &ID); pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
if (ID == 0xFFFFFFFF) { // There's nothing there. if (ID == 0xFFFFFFFF) { // There's nothing there.
function++; function++;
...@@ -2435,6 +2442,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2435,6 +2442,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
u32 temp_register; u32 temp_register;
u32 base; u32 base;
u32 ID; u32 ID;
unsigned int devfn;
struct pci_resource *mem_node; struct pci_resource *mem_node;
struct pci_resource *p_mem_node; struct pci_resource *p_mem_node;
struct pci_resource *io_node; struct pci_resource *io_node;
...@@ -2445,17 +2453,22 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2445,17 +2453,22 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
struct pci_resource *hold_bus_node; struct pci_resource *hold_bus_node;
struct irq_mapping irqs; struct irq_mapping irqs;
struct pci_func *new_slot; struct pci_func *new_slot;
struct pci_bus *pci_bus;
struct resource_lists temp_resources; struct resource_lists temp_resources;
pci_bus = ctrl->pci_bus;
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
// Check for Bridge // Check for Bridge
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &temp_byte); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
if (rc) if (rc)
return rc; return rc;
if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
// set Primary bus // set Primary bus
dbg("set Primary bus = %d\n", func->bus); dbg("set Primary bus = %d\n", func->bus);
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PRIMARY_BUS, func->bus); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
if (rc) if (rc)
return rc; return rc;
...@@ -2470,29 +2483,29 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2470,29 +2483,29 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set Secondary bus // set Secondary bus
temp_byte = bus_node->base; temp_byte = bus_node->base;
dbg("set Secondary bus = %d\n", bus_node->base); dbg("set Secondary bus = %d\n", bus_node->base);
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
if (rc) if (rc)
return rc; return rc;
// set subordinate bus // set subordinate bus
temp_byte = bus_node->base + bus_node->length - 1; temp_byte = bus_node->base + bus_node->length - 1;
dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1); dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1);
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
if (rc) if (rc)
return rc; return rc;
// set subordinate Latency Timer and base Latency Timer // set subordinate Latency Timer and base Latency Timer
temp_byte = 0x40; temp_byte = 0x40;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SEC_LATENCY_TIMER, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
if (rc) if (rc)
return rc; return rc;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_LATENCY_TIMER, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
if (rc) if (rc)
return rc; return rc;
// set Cache Line size // set Cache Line size
temp_byte = 0x08; temp_byte = 0x08;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_CACHE_LINE_SIZE, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
if (rc) if (rc)
return rc; return rc;
...@@ -2568,10 +2581,10 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2568,10 +2581,10 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set IO base and Limit registers // set IO base and Limit registers
temp_byte = io_node->base >> 8; temp_byte = io_node->base >> 8;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_BASE, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
temp_byte = (io_node->base + io_node->length - 1) >> 8; temp_byte = (io_node->base + io_node->length - 1) >> 8;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
} else { } else {
kfree(hold_IO_node); kfree(hold_IO_node);
hold_IO_node = NULL; hold_IO_node = NULL;
...@@ -2586,16 +2599,16 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2586,16 +2599,16 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set Mem base and Limit registers // set Mem base and Limit registers
temp_word = mem_node->base >> 16; temp_word = mem_node->base >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
temp_word = (mem_node->base + mem_node->length - 1) >> 16; temp_word = (mem_node->base + mem_node->length - 1) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
} else { } else {
temp_word = 0xFFFF; temp_word = 0xFFFF;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
temp_word = 0x0000; temp_word = 0x0000;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
kfree(hold_mem_node); kfree(hold_mem_node);
hold_mem_node = NULL; hold_mem_node = NULL;
...@@ -2610,16 +2623,16 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2610,16 +2623,16 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set Pre Mem base and Limit registers // set Pre Mem base and Limit registers
temp_word = p_mem_node->base >> 16; temp_word = p_mem_node->base >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16; temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
} else { } else {
temp_word = 0xFFFF; temp_word = 0xFFFF;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
temp_word = 0x0000; temp_word = 0x0000;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
kfree(hold_p_mem_node); kfree(hold_p_mem_node);
hold_p_mem_node = NULL; hold_p_mem_node = NULL;
...@@ -2635,7 +2648,9 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2635,7 +2648,9 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
irqs.barber_pole = (irqs.barber_pole + 1) & 0x03; irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
ID = 0xFFFFFFFF; ID = 0xFFFFFFFF;
pci_read_config_dword_nodev (ctrl->pci_ops, hold_bus_node->base, device, 0, 0x00, &ID); pci_bus->number = hold_bus_node->base;
pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);
pci_bus->number = func->bus;
if (ID != 0xFFFFFFFF) { // device Present if (ID != 0xFFFFFFFF) { // device Present
// Setup slot structure. // Setup slot structure.
...@@ -2703,7 +2718,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2703,7 +2718,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
temp_byte = temp_resources.bus_head->base - 1; temp_byte = temp_resources.bus_head->base - 1;
// set subordinate bus // set subordinate bus
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
if (temp_resources.bus_head->length == 0) { if (temp_resources.bus_head->length == 0) {
kfree(temp_resources.bus_head); kfree(temp_resources.bus_head);
...@@ -2724,7 +2739,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2724,7 +2739,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
hold_IO_node->base = io_node->base + io_node->length; hold_IO_node->base = io_node->base + io_node->length;
temp_byte = (hold_IO_node->base) >> 8; temp_byte = (hold_IO_node->base) >> 8;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_BASE, temp_byte); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_BASE, temp_byte);
return_resource(&(resources->io_head), io_node); return_resource(&(resources->io_head), io_node);
} }
...@@ -2742,13 +2757,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2742,13 +2757,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
func->io_head = hold_IO_node; func->io_head = hold_IO_node;
temp_byte = (io_node->base - 1) >> 8; temp_byte = (io_node->base - 1) >> 8;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
return_resource(&(resources->io_head), io_node); return_resource(&(resources->io_head), io_node);
} else { } else {
// it doesn't need any IO // it doesn't need any IO
temp_word = 0x0000; temp_word = 0x0000;
pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_LIMIT, temp_word);
return_resource(&(resources->io_head), io_node); return_resource(&(resources->io_head), io_node);
kfree(hold_IO_node); kfree(hold_IO_node);
...@@ -2774,7 +2789,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2774,7 +2789,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
hold_mem_node->base = mem_node->base + mem_node->length; hold_mem_node->base = mem_node->base + mem_node->length;
temp_word = (hold_mem_node->base) >> 16; temp_word = (hold_mem_node->base) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
return_resource(&(resources->mem_head), mem_node); return_resource(&(resources->mem_head), mem_node);
} }
...@@ -2792,14 +2807,14 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2792,14 +2807,14 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// configure end address // configure end address
temp_word = (mem_node->base - 1) >> 16; temp_word = (mem_node->base - 1) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
// Return unused resources to the pool // Return unused resources to the pool
return_resource(&(resources->mem_head), mem_node); return_resource(&(resources->mem_head), mem_node);
} else { } else {
// it doesn't need any Mem // it doesn't need any Mem
temp_word = 0x0000; temp_word = 0x0000;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
return_resource(&(resources->mem_head), mem_node); return_resource(&(resources->mem_head), mem_node);
kfree(hold_mem_node); kfree(hold_mem_node);
...@@ -2825,7 +2840,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2825,7 +2840,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
hold_p_mem_node->base = p_mem_node->base + p_mem_node->length; hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
temp_word = (hold_p_mem_node->base) >> 16; temp_word = (hold_p_mem_node->base) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
return_resource(&(resources->p_mem_head), p_mem_node); return_resource(&(resources->p_mem_head), p_mem_node);
} }
...@@ -2843,13 +2858,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2843,13 +2858,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
func->p_mem_head = hold_p_mem_node; func->p_mem_head = hold_p_mem_node;
temp_word = (p_mem_node->base - 1) >> 16; temp_word = (p_mem_node->base - 1) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
return_resource(&(resources->p_mem_head), p_mem_node); return_resource(&(resources->p_mem_head), p_mem_node);
} else { } else {
// it doesn't need any PMem // it doesn't need any PMem
temp_word = 0x0000; temp_word = 0x0000;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
return_resource(&(resources->p_mem_head), p_mem_node); return_resource(&(resources->p_mem_head), p_mem_node);
kfree(hold_p_mem_node); kfree(hold_p_mem_node);
...@@ -2870,14 +2885,14 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2870,14 +2885,14 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// enable card // enable card
command = 0x0157; // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR command = 0x0157; // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, command); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
// set Bridge Control Register // set Bridge Control Register
command = 0x07; // = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA command = 0x07; // = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, command); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
} else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) { } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
// Standard device // Standard device
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code); rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
if (class_code == PCI_BASE_CLASS_DISPLAY) { if (class_code == PCI_BASE_CLASS_DISPLAY) {
// Display (video) adapter (not supported) // Display (video) adapter (not supported)
...@@ -2887,10 +2902,10 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2887,10 +2902,10 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
for (cloop = 0x10; cloop <= 0x24; cloop += 4) { for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
dbg("CND: bus=%d, device=%d, func=%d, offset=%d\n", func->bus, func->device, func->function, cloop); dbg("CND: bus=%d, devfn=%d, offset=%d\n", pci_bus->number, devfn, cloop);
rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
rc = pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &temp_register); rc = pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp_register);
dbg("CND: base = 0x%x\n", temp_register); dbg("CND: base = 0x%x\n", temp_register);
if (temp_register) { // If this register is implemented if (temp_register) { // If this register is implemented
...@@ -2971,7 +2986,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2971,7 +2986,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
return(NOT_ENOUGH_RESOURCES); return(NOT_ENOUGH_RESOURCES);
} }
rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, base); rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, base);
// Check for 64-bit base // Check for 64-bit base
if ((temp_register & 0x07L) == 0x04) { if ((temp_register & 0x07L) == 0x04) {
...@@ -2980,13 +2995,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2980,13 +2995,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// Upper 32 bits of address always zero on today's systems // Upper 32 bits of address always zero on today's systems
// FIXME this is probably not true on Alpha and ia64??? // FIXME this is probably not true on Alpha and ia64???
base = 0; base = 0;
rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, base); rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, base);
} }
} }
} // End of base register loop } // End of base register loop
// Figure out which interrupt pin this function uses // Figure out which interrupt pin this function uses
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_INTERRUPT_PIN, &temp_byte); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_INTERRUPT_PIN, &temp_byte);
// If this function needs an interrupt and we are behind a bridge // If this function needs an interrupt and we are behind a bridge
// and the pin is tied to something that's alread mapped, // and the pin is tied to something that's alread mapped,
...@@ -2998,7 +3013,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2998,7 +3013,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03]; IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
} else { } else {
// Program IRQ based on card type // Program IRQ based on card type
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code); rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
if (class_code == PCI_BASE_CLASS_STORAGE) { if (class_code == PCI_BASE_CLASS_STORAGE) {
IRQ = cpqhp_disk_irq; IRQ = cpqhp_disk_irq;
...@@ -3008,7 +3023,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -3008,7 +3023,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
} }
// IRQ Line // IRQ Line
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_INTERRUPT_LINE, IRQ); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
if (!behind_bridge) { if (!behind_bridge) {
rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ); rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
...@@ -3022,19 +3037,19 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -3022,19 +3037,19 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// Latency Timer // Latency Timer
temp_byte = 0x40; temp_byte = 0x40;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_LATENCY_TIMER, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
// Cache Line size // Cache Line size
temp_byte = 0x08; temp_byte = 0x08;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_CACHE_LINE_SIZE, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
// disable ROM base Address // disable ROM base Address
temp_dword = 0x00L; temp_dword = 0x00L;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_ROM_ADDRESS, temp_dword); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_dword);
// enable card // enable card
temp_word = 0x0157; // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR temp_word = 0x0157; // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, temp_word);
} // End of Not-A-Bridge else } // End of Not-A-Bridge else
else { else {
// It's some strange type of PCI adapter (Cardbus?) // It's some strange type of PCI adapter (Cardbus?)
......
...@@ -161,7 +161,7 @@ static int check_for_compaq_ROM (void *rom_start) ...@@ -161,7 +161,7 @@ static int check_for_compaq_ROM (void *rom_start)
(temp6 == 'Q')) { (temp6 == 'Q')) {
result = 1; result = 1;
} }
dbg (__FUNCTION__" - returned %d\n", result); dbg ("%s - returned %d\n", __FUNCTION__, result);
return result; return result;
} }
...@@ -286,12 +286,12 @@ static u32 store_HRT (void *rom_start) ...@@ -286,12 +286,12 @@ static u32 store_HRT (void *rom_start)
return(rc); return(rc);
// The device Number // The device Number
rc = add_byte( &pFill, ctrl->device, &usedbytes, &available); rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
if (rc) if (rc)
return(rc); return(rc);
// The function Number // The function Number
rc = add_byte( &pFill, ctrl->function, &usedbytes, &available); rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
if (rc) if (rc)
return(rc); return(rc);
...@@ -479,8 +479,9 @@ int compaq_nvram_load (void *rom_start, struct controller *ctrl) ...@@ -479,8 +479,9 @@ int compaq_nvram_load (void *rom_start, struct controller *ctrl)
device = p_ev_ctrl->device; device = p_ev_ctrl->device;
function = p_ev_ctrl->function; function = p_ev_ctrl->function;
while ((bus != ctrl->bus) || (device != ctrl->device) while ((bus != ctrl->bus) ||
|| (function != ctrl->function)) { (device != PCI_SLOT(ctrl->pci_dev->devfn)) ||
(function != PCI_FUNC(ctrl->pci_dev->devfn))) {
nummem = p_ev_ctrl->mem_avail; nummem = p_ev_ctrl->mem_avail;
numpmem = p_ev_ctrl->p_mem_avail; numpmem = p_ev_ctrl->p_mem_avail;
numio = p_ev_ctrl->io_avail; numio = p_ev_ctrl->io_avail;
......
...@@ -140,7 +140,7 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct ...@@ -140,7 +140,7 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct
//We did not even find a hotplug rep of the function, create it //We did not even find a hotplug rep of the function, create it
//This code might be taken out if we can guarantee the creation of functions //This code might be taken out if we can guarantee the creation of functions
//in parallel (hotplug and Linux at the same time). //in parallel (hotplug and Linux at the same time).
dbg("@@@@@@@@@@@ cpqhp_slot_create in "__FUNCTION__"\n"); dbg("@@@@@@@@@@@ cpqhp_slot_create in %s\n", __FUNCTION__);
temp_func = cpqhp_slot_create(bus->number); temp_func = cpqhp_slot_create(bus->number);
if (temp_func == NULL) if (temp_func == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -150,8 +150,9 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct ...@@ -150,8 +150,9 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct
//Create /proc/bus/pci proc entry for this device and bus device is on //Create /proc/bus/pci proc entry for this device and bus device is on
//Notify the drivers of the change //Notify the drivers of the change
if (temp_func->pci_dev) { if (temp_func->pci_dev) {
pci_proc_attach_device(temp_func->pci_dev); // pci_insert_device (temp_func->pci_dev, bus);
pci_announce_device_to_drivers(temp_func->pci_dev); // pci_proc_attach_device(temp_func->pci_dev);
// pci_announce_device_to_drivers(temp_func->pci_dev);
} }
return 0; return 0;
...@@ -307,7 +308,7 @@ int cpqhp_unconfigure_device(struct pci_func* func) ...@@ -307,7 +308,7 @@ int cpqhp_unconfigure_device(struct pci_func* func)
memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped)); memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped)); memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
dbg(__FUNCTION__": bus/dev/func = %x/%x/%x\n",func->bus, func->device, func->function); dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
for (j=0; j<8 ; j++) { for (j=0; j<8 ; j++) {
struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j); struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j);
...@@ -326,15 +327,15 @@ int cpqhp_unconfigure_device(struct pci_func* func) ...@@ -326,15 +327,15 @@ int cpqhp_unconfigure_device(struct pci_func* func)
return rc; return rc;
} }
static int PCI_RefinedAccessConfig(struct pci_ops *ops, u8 bus, u8 device, u8 function, u8 offset, u32 *value) static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
{ {
u32 vendID = 0; u32 vendID = 0;
if (pci_read_config_dword_nodev (ops, bus, device, function, PCI_VENDOR_ID, &vendID) == -1) if (pci_bus_read_config_dword (bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
return -1; return -1;
if (vendID == 0xffffffff) if (vendID == 0xffffffff)
return -1; return -1;
return pci_read_config_dword_nodev (ops, bus, device, function, offset, value); return pci_bus_read_config_dword (bus, devfn, offset, value);
} }
...@@ -355,10 +356,10 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num) ...@@ -355,10 +356,10 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
fakedev.devfn = dev_num << 3; fakedev.devfn = dev_num << 3;
fakedev.bus = &fakebus; fakedev.bus = &fakebus;
fakebus.number = bus_num; fakebus.number = bus_num;
dbg(__FUNCTION__": dev %d, bus %d, pin %d, num %d\n", dbg("%s: dev %d, bus %d, pin %d, num %d\n",
dev_num, bus_num, int_pin, irq_num); __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num); rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
dbg(__FUNCTION__":rc %d\n", rc); dbg("%s: rc %d\n", __FUNCTION__, rc);
if (rc) if (rc)
return rc; return rc;
...@@ -392,9 +393,11 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev ...@@ -392,9 +393,11 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
u32 work; u32 work;
u8 tbus; u8 tbus;
ctrl->pci_bus->number = bus_num;
for (tdevice = 0; tdevice < 0x100; tdevice++) { for (tdevice = 0; tdevice < 0x100; tdevice++) {
//Scan for access first //Scan for access first
if (PCI_RefinedAccessConfig(ctrl->pci_ops, bus_num, tdevice >> 3, tdevice & 0x7, 0x08, &work) == -1) if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
continue; continue;
dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice); dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
//Yep we got one. Not a bridge ? //Yep we got one. Not a bridge ?
...@@ -406,12 +409,12 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev ...@@ -406,12 +409,12 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
} }
for (tdevice = 0; tdevice < 0x100; tdevice++) { for (tdevice = 0; tdevice < 0x100; tdevice++) {
//Scan for access first //Scan for access first
if (PCI_RefinedAccessConfig(ctrl->pci_ops, bus_num, tdevice >> 3, tdevice & 0x7, 0x08, &work) == -1) if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
continue; continue;
dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice); dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
//Yep we got one. bridge ? //Yep we got one. bridge ?
if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) { if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
pci_read_config_byte_nodev (ctrl->pci_ops, tbus, tdevice, 0, PCI_SECONDARY_BUS, &tbus); pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice); dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
if (PCI_ScanBusNonBridge(tbus, tdevice) == 0) if (PCI_ScanBusNonBridge(tbus, tdevice) == 0)
return 0; return 0;
...@@ -450,19 +453,20 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num ...@@ -450,19 +453,20 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
if (tslot == slot) { if (tslot == slot) {
*bus_num = tbus; *bus_num = tbus;
*dev_num = tdevice; *dev_num = tdevice;
pci_read_config_dword_nodev (ctrl->pci_ops, *bus_num, *dev_num >> 3, *dev_num & 0x7, PCI_VENDOR_ID, &work); ctrl->pci_bus->number = tbus;
pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
if (!nobridge || (work == 0xffffffff)) { if (!nobridge || (work == 0xffffffff)) {
if (PCIIRQRoutingInfoLength != NULL) if (PCIIRQRoutingInfoLength != NULL)
kfree(PCIIRQRoutingInfoLength ); kfree(PCIIRQRoutingInfoLength );
return 0; return 0;
} }
dbg("bus_num %d dev_num %d func_num %d\n", *bus_num, *dev_num >> 3, *dev_num & 0x7); dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
pci_read_config_dword_nodev (ctrl->pci_ops, *bus_num, *dev_num >> 3, *dev_num & 0x7, PCI_CLASS_REVISION, &work); pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
dbg("work >> 8 (%x) = BRIDGE (%x)\n", work >> 8, PCI_TO_PCI_BRIDGE_CLASS); dbg("work >> 8 (%x) = BRIDGE (%x)\n", work >> 8, PCI_TO_PCI_BRIDGE_CLASS);
if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) { if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
pci_read_config_byte_nodev (ctrl->pci_ops, *bus_num, *dev_num >> 3, *dev_num & 0x7, PCI_SECONDARY_BUS, &tbus); pci_bus_read_config_byte (ctrl->pci_bus, *dev_num, PCI_SECONDARY_BUS, &tbus);
dbg("Scan bus for Non Bridge: bus %d\n", tbus); dbg("Scan bus for Non Bridge: bus %d\n", tbus);
if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) { if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
*bus_num = tbus; *bus_num = tbus;
...@@ -535,17 +539,17 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) ...@@ -535,17 +539,17 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
} }
// Save PCI configuration space for all devices in supported slots // Save PCI configuration space for all devices in supported slots
ctrl->pci_bus->number = busnumber;
for (device = FirstSupported; device <= LastSupported; device++) { for (device = FirstSupported; device <= LastSupported; device++) {
ID = 0xFFFFFFFF; ID = 0xFFFFFFFF;
rc = pci_read_config_dword_nodev (ctrl->pci_ops, busnumber, device, 0, PCI_VENDOR_ID, &ID); rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
if (ID != 0xFFFFFFFF) { // device in slot if (ID != 0xFFFFFFFF) { // device in slot
rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, 0, 0x0B, &class_code); rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
if (rc) if (rc)
return rc; return rc;
rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, 0, PCI_HEADER_TYPE, &header_type); rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
if (rc) if (rc)
return rc; return rc;
...@@ -563,7 +567,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) ...@@ -563,7 +567,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // P-P Bridge if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // P-P Bridge
// Recurse the subordinate bus // Recurse the subordinate bus
// get the subordinate bus number // get the subordinate bus number
rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, function, PCI_SECONDARY_BUS, &secondary_bus); rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus);
if (rc) { if (rc) {
return rc; return rc;
} else { } else {
...@@ -572,9 +576,9 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) ...@@ -572,9 +576,9 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
// Save secondary bus cfg spc // Save secondary bus cfg spc
// with this recursive call. // with this recursive call.
rc = cpqhp_save_config(ctrl, sub_bus, 0); rc = cpqhp_save_config(ctrl, sub_bus, 0);
if (rc) if (rc)
return rc; return rc;
ctrl->pci_bus->number = busnumber;
} }
} }
...@@ -602,7 +606,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) ...@@ -602,7 +606,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function); new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
for (cloop = 0; cloop < 0x20; cloop++) { for (cloop = 0; cloop < 0x20; cloop++) {
rc = pci_read_config_dword_nodev (ctrl->pci_ops, busnumber, device, function, cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
if (rc) if (rc)
return rc; return rc;
} }
...@@ -615,15 +619,15 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) ...@@ -615,15 +619,15 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
// reading in Class Code and Header type. // reading in Class Code and Header type.
while ((function < max_functions)&&(!stop_it)) { while ((function < max_functions)&&(!stop_it)) {
rc = pci_read_config_dword_nodev (ctrl->pci_ops, busnumber, device, function, PCI_VENDOR_ID, &ID); rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
if (ID == 0xFFFFFFFF) { // nothing there. if (ID == 0xFFFFFFFF) { // nothing there.
function++; function++;
} else { // Something there } else { // Something there
rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, function, 0x0B, &class_code); rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
if (rc) if (rc)
return rc; return rc;
rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, function, PCI_HEADER_TYPE, &header_type); rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
if (rc) if (rc)
return rc; return rc;
...@@ -677,12 +681,12 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot) ...@@ -677,12 +681,12 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
ID = 0xFFFFFFFF; ID = 0xFFFFFFFF;
pci_read_config_dword_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, 0, PCI_VENDOR_ID, &ID); ctrl->pci_bus->number = new_slot->bus;
pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
if (ID != 0xFFFFFFFF) { // device in slot if (ID != 0xFFFFFFFF) { // device in slot
pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, 0, 0x0B, &class_code); pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, 0, PCI_HEADER_TYPE, &header_type);
if (header_type & 0x80) // Multi-function device if (header_type & 0x80) // Multi-function device
max_functions = 8; max_functions = 8;
...@@ -694,22 +698,22 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot) ...@@ -694,22 +698,22 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
do { do {
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
// Recurse the subordinate bus // Recurse the subordinate bus
pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, PCI_SECONDARY_BUS, &secondary_bus); pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
sub_bus = (int) secondary_bus; sub_bus = (int) secondary_bus;
// Save the config headers for the secondary bus. // Save the config headers for the secondary bus.
rc = cpqhp_save_config(ctrl, sub_bus, 0); rc = cpqhp_save_config(ctrl, sub_bus, 0);
if (rc) if (rc)
return(rc); return(rc);
ctrl->pci_bus->number = new_slot->bus;
} // End of IF } // End of IF
new_slot->status = 0; new_slot->status = 0;
for (cloop = 0; cloop < 0x20; cloop++) { for (cloop = 0; cloop < 0x20; cloop++) {
pci_read_config_dword_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
} }
function++; function++;
...@@ -720,14 +724,14 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot) ...@@ -720,14 +724,14 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
// reading in the Class Code and the Header type. // reading in the Class Code and the Header type.
while ((function < max_functions) && (!stop_it)) { while ((function < max_functions) && (!stop_it)) {
pci_read_config_dword_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, PCI_VENDOR_ID, &ID); pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
if (ID == 0xFFFFFFFF) { // nothing there. if (ID == 0xFFFFFFFF) { // nothing there.
function++; function++;
} else { // Something there } else { // Something there
pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, 0x0B, &class_code); pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, PCI_HEADER_TYPE, &header_type); pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
stop_it++; stop_it++;
} }
...@@ -763,17 +767,21 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) ...@@ -763,17 +767,21 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
u32 rc; u32 rc;
struct pci_func *next; struct pci_func *next;
int index = 0; int index = 0;
struct pci_bus *pci_bus = ctrl->pci_bus;
unsigned int devfn;
func = cpqhp_slot_find(func->bus, func->device, index++); func = cpqhp_slot_find(func->bus, func->device, index++);
while (func != NULL) { while (func != NULL) {
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
// Check for Bridge // Check for Bridge
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type); pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
// PCI-PCI Bridge // PCI-PCI Bridge
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, &secondary_bus); pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
sub_bus = (int) secondary_bus; sub_bus = (int) secondary_bus;
...@@ -787,13 +795,14 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) ...@@ -787,13 +795,14 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
next = next->next; next = next->next;
} }
pci_bus->number = func->bus;
//FIXME: this loop is duplicated in the non-bridge case. The two could be rolled together //FIXME: this loop is duplicated in the non-bridge case. The two could be rolled together
// Figure out IO and memory base lengths // Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x14; cloop += 4) { for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base); pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
if (base) { // If this register is implemented if (base) { // If this register is implemented
if (base & 0x01L) { if (base & 0x01L) {
...@@ -827,8 +836,8 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) ...@@ -827,8 +836,8 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
// Figure out IO and memory base lengths // Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x24; cloop += 4) { for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base); pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
if (base) { // If this register is implemented if (base) { // If this register is implemented
if (base & 0x01L) { if (base & 0x01L) {
...@@ -897,28 +906,31 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -897,28 +906,31 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
struct pci_resource *p_mem_node; struct pci_resource *p_mem_node;
struct pci_resource *io_node; struct pci_resource *io_node;
struct pci_resource *bus_node; struct pci_resource *bus_node;
struct pci_bus *pci_bus = ctrl->pci_bus;
unsigned int devfn;
func = cpqhp_slot_find(func->bus, func->device, index++); func = cpqhp_slot_find(func->bus, func->device, index++);
while ((func != NULL) && func->is_a_board) { while ((func != NULL) && func->is_a_board) {
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
// Save the command register // Save the command register
pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, &save_command); pci_bus_read_config_word (pci_bus, devfn, PCI_COMMAND, &save_command);
// disable card // disable card
command = 0x00; command = 0x00;
pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, command); pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
// Check for Bridge // Check for Bridge
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type); pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
// Clear Bridge Control Register // Clear Bridge Control Register
command = 0x00; command = 0x00;
pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, command); pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, &secondary_bus); pci_bus_read_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, &temp_byte);
bus_node =(struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); bus_node =(struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
if (!bus_node) if (!bus_node)
...@@ -931,9 +943,8 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -931,9 +943,8 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
func->bus_head = bus_node; func->bus_head = bus_node;
// Save IO base and Limit registers // Save IO base and Limit registers
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_BASE, &b_base); pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_BASE, &b_base);
pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_LIMIT, &b_length);
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, &b_length);
if ((b_base <= b_length) && (save_command & 0x01)) { if ((b_base <= b_length) && (save_command & 0x01)) {
io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
...@@ -946,10 +957,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -946,10 +957,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
io_node->next = func->io_head; io_node->next = func->io_head;
func->io_head = io_node; func->io_head = io_node;
} }
// Save memory base and Limit registers
pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, &w_base);
pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, &w_length); // Save memory base and Limit registers
pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
if ((w_base <= w_length) && (save_command & 0x02)) { if ((w_base <= w_length) && (save_command & 0x02)) {
mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
...@@ -962,10 +973,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -962,10 +973,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
mem_node->next = func->mem_head; mem_node->next = func->mem_head;
func->mem_head = mem_node; func->mem_head = mem_node;
} }
// Save prefetchable memory base and Limit registers
pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, &w_base);
pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, &w_length); // Save prefetchable memory base and Limit registers
pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
if ((w_base <= w_length) && (save_command & 0x02)) { if ((w_base <= w_length) && (save_command & 0x02)) {
p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
...@@ -980,12 +991,11 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -980,12 +991,11 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
} }
// Figure out IO and memory base lengths // Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x14; cloop += 4) { for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &save_base); pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
temp_register = base; temp_register = base;
...@@ -1046,12 +1056,11 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -1046,12 +1056,11 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
} else if ((header_type & 0x7F) == 0x00) { // Standard header } else if ((header_type & 0x7F) == 0x00) { // Standard header
// Figure out IO and memory base lengths // Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x24; cloop += 4) { for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &save_base); pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
temp_register = base; temp_register = base;
...@@ -1138,21 +1147,26 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func) ...@@ -1138,21 +1147,26 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
u32 temp; u32 temp;
u32 rc; u32 rc;
int index = 0; int index = 0;
struct pci_bus *pci_bus = ctrl->pci_bus;
unsigned int devfn;
func = cpqhp_slot_find(func->bus, func->device, index++); func = cpqhp_slot_find(func->bus, func->device, index++);
while (func != NULL) { while (func != NULL) {
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
// Start at the top of config space so that the control // Start at the top of config space so that the control
// registers are programmed last // registers are programmed last
for (cloop = 0x3C; cloop > 0; cloop -= 4) { for (cloop = 0x3C; cloop > 0; cloop -= 4) {
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, func->config_space[cloop >> 2]); pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]);
} }
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type); pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
// If this is a bridge device, restore subordinate devices // If this is a bridge device, restore subordinate devices
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, &secondary_bus); pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
sub_bus = (int) secondary_bus; sub_bus = (int) secondary_bus;
...@@ -1172,7 +1186,7 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func) ...@@ -1172,7 +1186,7 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
// they are the same. If not, the board is different. // they are the same. If not, the board is different.
for (cloop = 16; cloop < 40; cloop += 4) { for (cloop = 16; cloop < 40; cloop += 4) {
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &temp); pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp);
if (temp != func->config_space[cloop >> 2]) { if (temp != func->config_space[cloop >> 2]) {
dbg("Config space compare failure!!! offset = %x\n", cloop); dbg("Config space compare failure!!! offset = %x\n", cloop);
...@@ -1212,6 +1226,8 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1212,6 +1226,8 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
u32 rc; u32 rc;
struct pci_func *next; struct pci_func *next;
int index = 0; int index = 0;
struct pci_bus *pci_bus = ctrl->pci_bus;
unsigned int devfn;
if (!func->is_a_board) if (!func->is_a_board)
return(ADD_NOT_SUPPORTED); return(ADD_NOT_SUPPORTED);
...@@ -1219,7 +1235,10 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1219,7 +1235,10 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
func = cpqhp_slot_find(func->bus, func->device, index++); func = cpqhp_slot_find(func->bus, func->device, index++);
while (func != NULL) { while (func != NULL) {
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_VENDOR_ID, &temp_register); pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register);
// No adapter present // No adapter present
if (temp_register == 0xFFFFFFFF) if (temp_register == 0xFFFFFFFF)
...@@ -1229,14 +1248,14 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1229,14 +1248,14 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
return(ADAPTER_NOT_SAME); return(ADAPTER_NOT_SAME);
// Check for same revision number and class code // Check for same revision number and class code
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_CLASS_REVISION, &temp_register); pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);
// Adapter not the same // Adapter not the same
if (temp_register != func->config_space[0x08 >> 2]) if (temp_register != func->config_space[0x08 >> 2])
return(ADAPTER_NOT_SAME); return(ADAPTER_NOT_SAME);
// Check for Bridge // Check for Bridge
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type); pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
// In order to continue checking, we must program the // In order to continue checking, we must program the
...@@ -1244,7 +1263,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1244,7 +1263,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
// for it's subordinate bus(es) // for it's subordinate bus(es)
temp_register = func->config_space[0x18 >> 2]; temp_register = func->config_space[0x18 >> 2];
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PRIMARY_BUS, temp_register); pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);
secondary_bus = (temp_register >> 8) & 0xFF; secondary_bus = (temp_register >> 8) & 0xFF;
...@@ -1263,7 +1282,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1263,7 +1282,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
// Check to see if it is a standard config header // Check to see if it is a standard config header
else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) { else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
// Check subsystem vendor and ID // Check subsystem vendor and ID
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBSYSTEM_VENDOR_ID, &temp_register); pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
if (temp_register != func->config_space[0x2C >> 2]) { if (temp_register != func->config_space[0x2C >> 2]) {
// If it's a SMART-2 and the register isn't filled // If it's a SMART-2 and the register isn't filled
...@@ -1277,10 +1296,8 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1277,10 +1296,8 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
// Figure out IO and memory base lengths // Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x24; cloop += 4) { for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
if (base) { // If this register is implemented if (base) { // If this register is implemented
if (base & 0x01L) { if (base & 0x01L) {
// IO base // IO base
...@@ -1436,8 +1453,8 @@ int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start) ...@@ -1436,8 +1453,8 @@ int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start)
continue; continue;
} }
// find out if this entry is for an occupied slot // find out if this entry is for an occupied slot
pci_read_config_dword_nodev (ctrl->pci_ops, primary_bus, dev_func >> 3, dev_func & 0x07, PCI_VENDOR_ID, &temp_dword); ctrl->pci_bus->number = primary_bus;
pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
dbg("temp_D_word = %x\n", temp_dword); dbg("temp_D_word = %x\n", temp_dword);
if (temp_dword != 0xFFFFFFFF) { if (temp_dword != 0xFFFFFFFF) {
...@@ -1586,7 +1603,7 @@ int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists * ...@@ -1586,7 +1603,7 @@ int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists *
int rc = 0; int rc = 0;
struct pci_resource *node; struct pci_resource *node;
struct pci_resource *t_node; struct pci_resource *t_node;
dbg(__FUNCTION__"\n"); dbg("%s\n", __FUNCTION__);
if (!func) if (!func)
return(1); return(1);
......
...@@ -53,8 +53,9 @@ static int read_ctrl (char *buf, char **start, off_t offset, int len, int *eof, ...@@ -53,8 +53,9 @@ static int read_ctrl (char *buf, char **start, off_t offset, int len, int *eof,
*eof = 1; *eof = 1;
out += sprintf(out, "hot plug ctrl Info Page\n"); out += sprintf(out, "hot plug ctrl Info Page\n");
out += sprintf(out, "bus = %d, device = %d, function = %d\n",ctrl->bus, out += sprintf(out, "bus = %d, device = %d, function = %d\n",
ctrl->device, ctrl->function); ctrl->bus, PCI_SLOT(ctrl->pci_dev->devfn),
PCI_FUNC(ctrl->pci_dev->devfn));
out += sprintf(out, "Free resources: memory\n"); out += sprintf(out, "Free resources: memory\n");
index = 11; index = 11;
res = ctrl->mem_head; res = ctrl->mem_head;
...@@ -104,8 +105,9 @@ static int read_dev (char *buf, char **start, off_t offset, int len, int *eof, v ...@@ -104,8 +105,9 @@ static int read_dev (char *buf, char **start, off_t offset, int len, int *eof, v
*eof = 1; *eof = 1;
out += sprintf(out, "hot plug ctrl Info Page\n"); out += sprintf(out, "hot plug ctrl Info Page\n");
out += sprintf(out, "bus = %d, device = %d, function = %d\n",ctrl->bus, out += sprintf(out, "bus = %d, device = %d, function = %d\n",
ctrl->device, ctrl->function); ctrl->bus, PCI_SLOT(ctrl->pci_dev->devfn),
PCI_FUNC(ctrl->pci_dev->devfn));
slot=ctrl->slot; slot=ctrl->slot;
......
...@@ -39,7 +39,8 @@ extern int ibmphp_debug; ...@@ -39,7 +39,8 @@ extern int ibmphp_debug;
#else #else
#define MY_NAME THIS_MODULE->name #define MY_NAME THIS_MODULE->name
#endif #endif
#define debug(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0) #define debug(fmt, arg...) do { if (ibmphp_debug == 1) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
#define debug_pci(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg) #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg) #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
...@@ -121,6 +122,7 @@ struct scal_detail { ...@@ -121,6 +122,7 @@ struct scal_detail {
u8 port1_port_connect; u8 port1_port_connect;
u8 port2_node_connect; u8 port2_node_connect;
u8 port2_port_connect; u8 port2_port_connect;
u8 chassis_num;
// struct list_head scal_detail_list; // struct list_head scal_detail_list;
}; };
...@@ -139,9 +141,27 @@ struct rio_detail { ...@@ -139,9 +141,27 @@ struct rio_detail {
u8 port1_port_connect; u8 port1_port_connect;
u8 first_slot_num; u8 first_slot_num;
u8 status; u8 status;
// struct list_head rio_detail_list; u8 wpindex;
u8 chassis_num;
struct list_head rio_detail_list;
}; };
struct opt_rio {
u8 rio_type;
u8 chassis_num;
u8 first_slot_num;
u8 middle_num;
struct list_head opt_rio_list;
};
struct opt_rio_lo {
u8 rio_type;
u8 chassis_num;
u8 first_slot_num;
u8 middle_num;
u8 pack_count;
struct list_head opt_rio_lo_list;
};
/**************************************************************** /****************************************************************
* HPC DESCRIPTOR NODE * * HPC DESCRIPTOR NODE *
...@@ -153,7 +173,6 @@ struct ebda_hpc_list { ...@@ -153,7 +173,6 @@ struct ebda_hpc_list {
short phys_addr; short phys_addr;
// struct list_head ebda_hpc_list; // struct list_head ebda_hpc_list;
}; };
/***************************************************************** /*****************************************************************
* IN HPC DATA STRUCTURE, THE ASSOCIATED SLOT AND BUS * * IN HPC DATA STRUCTURE, THE ASSOCIATED SLOT AND BUS *
* STRUCTURE * * STRUCTURE *
...@@ -195,6 +214,9 @@ struct wpeg_i2c_ctlr_access { ...@@ -195,6 +214,9 @@ struct wpeg_i2c_ctlr_access {
u8 i2c_addr; u8 i2c_addr;
}; };
#define HPC_DEVICE_ID 0x0246
#define HPC_SUBSYSTEM_ID 0x0247
#define HPC_PCI_OFFSET 0x40
/************************************************************************* /*************************************************************************
* RSTC DESCRIPTOR NODE * * RSTC DESCRIPTOR NODE *
*************************************************************************/ *************************************************************************/
...@@ -215,8 +237,9 @@ struct ebda_pci_rsrc { ...@@ -215,8 +237,9 @@ struct ebda_pci_rsrc {
u8 rsrc_type; u8 rsrc_type;
u8 bus_num; u8 bus_num;
u8 dev_fun; u8 dev_fun;
ulong start_addr; u32 start_addr;
ulong end_addr; u32 end_addr;
u8 marked; /* for NVRAM */
struct list_head ebda_pci_rsrc_list; struct list_head ebda_pci_rsrc_list;
}; };
...@@ -248,7 +271,7 @@ struct bus_info { ...@@ -248,7 +271,7 @@ struct bus_info {
***********************************************************/ ***********************************************************/
extern struct list_head ibmphp_ebda_pci_rsrc_head; extern struct list_head ibmphp_ebda_pci_rsrc_head;
extern struct list_head ibmphp_slot_head; extern struct list_head ibmphp_slot_head;
extern struct list_head ibmphp_res_head;
/*********************************************************** /***********************************************************
* FUNCTION PROTOTYPES * * FUNCTION PROTOTYPES *
***********************************************************/ ***********************************************************/
...@@ -263,6 +286,7 @@ extern void ibmphp_free_ebda_pci_rsrc_queue (void); ...@@ -263,6 +286,7 @@ extern void ibmphp_free_ebda_pci_rsrc_queue (void);
extern struct bus_info *ibmphp_find_same_bus_num (u32); extern struct bus_info *ibmphp_find_same_bus_num (u32);
extern int ibmphp_get_bus_index (u8); extern int ibmphp_get_bus_index (u8);
extern u16 ibmphp_get_total_controllers (void); extern u16 ibmphp_get_total_controllers (void);
extern int ibmphp_register_pci (void);
/* passed parameters */ /* passed parameters */
#define MEM 0 #define MEM 0
...@@ -669,7 +693,7 @@ extern void ibmphp_hpc_stop_poll_thread (void); ...@@ -669,7 +693,7 @@ extern void ibmphp_hpc_stop_poll_thread (void);
#define PCIX66 0x05 #define PCIX66 0x05
#define PCI66 0x04 #define PCI66 0x04
extern struct pci_ops *ibmphp_pci_root_ops; extern struct pci_bus *ibmphp_pci_bus;
/* Variables */ /* Variables */
...@@ -713,6 +737,7 @@ struct slot { ...@@ -713,6 +737,7 @@ struct slot {
struct controller { struct controller {
struct ebda_hpc_slot *slots; struct ebda_hpc_slot *slots;
struct ebda_hpc_bus *buses; struct ebda_hpc_bus *buses;
struct pci_dev *ctrl_dev; /* in case where controller is PCI */
u8 starting_slot_num; /* starting and ending slot #'s this ctrl controls*/ u8 starting_slot_num; /* starting and ending slot #'s this ctrl controls*/
u8 ending_slot_num; u8 ending_slot_num;
u8 revision; u8 revision;
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev) #define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
#define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt) #define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
#define DRIVER_VERSION "0.3" #define DRIVER_VERSION "0.6"
#define DRIVER_DESC "IBM Hot Plug PCI Controller Driver" #define DRIVER_DESC "IBM Hot Plug PCI Controller Driver"
int ibmphp_debug; int ibmphp_debug;
...@@ -56,7 +56,7 @@ MODULE_LICENSE ("GPL"); ...@@ -56,7 +56,7 @@ MODULE_LICENSE ("GPL");
MODULE_DESCRIPTION (DRIVER_DESC); MODULE_DESCRIPTION (DRIVER_DESC);
static int *ops[MAX_OPS + 1]; static int *ops[MAX_OPS + 1];
struct pci_ops *ibmphp_pci_root_ops; struct pci_bus *ibmphp_pci_bus;
static int max_slots; static int max_slots;
static int irqs[16]; /* PIC mode IRQ's we're using so far (in case MPS tables don't provide default info for empty slots */ static int irqs[16]; /* PIC mode IRQ's we're using so far (in case MPS tables don't provide default info for empty slots */
...@@ -88,6 +88,8 @@ static inline int get_cur_bus_info (struct slot **sl) ...@@ -88,6 +88,8 @@ static inline int get_cur_bus_info (struct slot **sl)
slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED (slot_cur->busstatus); slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED (slot_cur->busstatus);
if (READ_BUS_MODE (slot_cur->ctrl)) if (READ_BUS_MODE (slot_cur->ctrl))
slot_cur->bus_on->current_bus_mode = CURRENT_BUS_MODE (slot_cur->busstatus); slot_cur->bus_on->current_bus_mode = CURRENT_BUS_MODE (slot_cur->busstatus);
else
slot_cur->bus_on->current_bus_mode = 0xFF;
debug ("busstatus = %x, bus_speed = %x, bus_mode = %x\n", slot_cur->busstatus, slot_cur->bus_on->current_speed, slot_cur->bus_on->current_bus_mode); debug ("busstatus = %x, bus_speed = %x, bus_mode = %x\n", slot_cur->busstatus, slot_cur->bus_on->current_speed, slot_cur->bus_on->current_bus_mode);
...@@ -108,11 +110,15 @@ static inline int slot_update (struct slot **sl) ...@@ -108,11 +110,15 @@ static inline int slot_update (struct slot **sl)
static int __init get_max_slots (void) static int __init get_max_slots (void)
{ {
struct slot * slot_cur;
struct list_head * tmp; struct list_head * tmp;
int slot_count = 0; u8 slot_count = 0;
list_for_each (tmp, &ibmphp_slot_head) list_for_each (tmp, &ibmphp_slot_head) {
++slot_count; slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
/* sometimes the hot-pluggable slots start with 4 (not always from 1 */
slot_count = max (slot_count, slot_cur->number);
}
return slot_count; return slot_count;
} }
...@@ -330,7 +336,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -330,7 +336,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 * value)
memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot)); memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status)); hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
if (!hpcrc) { if (!hpcrc) {
*value = SLOT_POWER (myslot.status); *value = SLOT_PWRGD (myslot.status);
rc = 0; rc = 0;
} }
} }
...@@ -395,14 +401,21 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -395,14 +401,21 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value)
rc = 0; rc = 0;
mode = pslot->supported_bus_mode; mode = pslot->supported_bus_mode;
*value = pslot->supported_speed; *value = pslot->supported_speed;
*value &= 0x0f; switch (*value) {
case BUS_SPEED_33:
break;
case BUS_SPEED_66:
if (mode == BUS_MODE_PCIX) if (mode == BUS_MODE_PCIX)
*value |= 0x80; *value += 0x01;
else if (mode == BUS_MODE_PCI) break;
*value |= 0x40; case BUS_SPEED_100:
else case BUS_SPEED_133:
*value |= 0x20; *value = pslot->supported_speed + 0x01;
break;
default:
*/ /* Note (will need to change): there would be soon 256, 512 also */
/* rc = -ENODEV;
}
} }
} else } else
rc = -ENODEV; rc = -ENODEV;
...@@ -429,14 +442,25 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -429,14 +442,25 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value)
if (!rc) { if (!rc) {
mode = pslot->bus_on->current_bus_mode; mode = pslot->bus_on->current_bus_mode;
*value = pslot->bus_on->current_speed; *value = pslot->bus_on->current_speed;
*value &= 0x0f; switch (*value) {
case BUS_SPEED_33:
break;
case BUS_SPEED_66:
if (mode == BUS_MODE_PCIX) if (mode == BUS_MODE_PCIX)
*value |= 0x80; *value += 0x01;
else if (mode == BUS_MODE_PCI) else if (mode == BUS_MODE_PCI)
*value |= 0x40; ;
else else
*value |= 0x20; *value = PCI_SPEED_UNKNOWN;
break;
case BUS_SPEED_100:
case BUS_SPEED_133:
*value += 0x01;
break;
default:
*/ /* Note of change: there would also be 256, 512 soon */
/* rc = -ENODEV;
}
} }
} }
} else } else
...@@ -454,7 +478,7 @@ static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * valu ...@@ -454,7 +478,7 @@ static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * valu
int hpcrc = 0; int hpcrc = 0;
struct slot myslot; struct slot myslot;
debug ("get_max_adapter_speed - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value); debug ("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
if (flag) if (flag)
ibmphp_lock_operations (); ibmphp_lock_operations ();
...@@ -485,17 +509,16 @@ static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * valu ...@@ -485,17 +509,16 @@ static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * valu
if (flag) if (flag)
ibmphp_unlock_operations (); ibmphp_unlock_operations ();
debug ("get_adapter_present - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value); debug ("get_max_adapter_speed_1 - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
return rc; return rc;
} }
static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value) static int get_bus_name (struct hotplug_slot *hotplug_slot, char * value)
{ {
int rc = -ENODEV; int rc = -ENODEV;
struct slot *pslot = NULL; struct slot *pslot = NULL;
struct pci_dev * dev = NULL;
debug ("get_card_bus_names - Entry hotplug_slot[%lx] \n", (ulong)hotplug_slot); debug ("get_bus_name - Entry hotplug_slot[%lx] \n", (ulong)hotplug_slot);
ibmphp_lock_operations (); ibmphp_lock_operations ();
...@@ -503,26 +526,17 @@ static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value) ...@@ -503,26 +526,17 @@ static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value)
pslot = (struct slot *) hotplug_slot->private; pslot = (struct slot *) hotplug_slot->private;
if (pslot) { if (pslot) {
rc = 0; rc = 0;
if (pslot->func) snprintf (value, 100, "Bus %x", pslot->bus);
dev = pslot->func->dev;
else
dev = pci_find_slot (pslot->bus, (pslot->device << 3) | (0x00 & 0x7));
if (dev)
snprintf (value, 100, "Bus %d : %s", pslot->bus,dev->name);
else
snprintf (value, 100, "Bus %d", pslot->bus);
} }
} else } else
rc = -ENODEV; rc = -ENODEV;
ibmphp_unlock_operations (); ibmphp_unlock_operations ();
debug ("get_card_bus_names - Exit rc[%d] value[%x]\n", rc, *value); debug ("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
return rc; return rc;
} }
*/ */
/******************************************************************************* /*******************************************************************************
* This routine will initialize the ops data structure used in the validate * This routine will initialize the ops data structure used in the validate
* function. It will also power off empty slots that are powered on since BIOS * function. It will also power off empty slots that are powered on since BIOS
...@@ -531,12 +545,14 @@ static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value) ...@@ -531,12 +545,14 @@ static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value)
static int __init init_ops (void) static int __init init_ops (void)
{ {
struct slot *slot_cur; struct slot *slot_cur;
struct list_head *tmp;
int retval; int retval;
int j;
int rc; int rc;
int j;
for (j = 0; j < MAX_OPS; j++) { for (j = 0; j < MAX_OPS; j++) {
ops[j] = (int *) kmalloc ((max_slots + 1) * sizeof (int), GFP_KERNEL); ops[j] = (int *) kmalloc ((max_slots + 1) * sizeof (int), GFP_KERNEL);
memset (ops[j], 0, (max_slots + 1) * sizeof (int));
if (!ops[j]) { if (!ops[j]) {
err ("out of system memory \n"); err ("out of system memory \n");
return -ENOMEM; return -ENOMEM;
...@@ -547,12 +563,13 @@ static int __init init_ops (void) ...@@ -547,12 +563,13 @@ static int __init init_ops (void)
ops[REMOVE][0] = 0; ops[REMOVE][0] = 0;
ops[DETAIL][0] = 0; ops[DETAIL][0] = 0;
for (j = 1; j <= max_slots; j++) { list_for_each (tmp, &ibmphp_slot_head) {
slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
slot_cur = ibmphp_get_slot_from_physical_num (j); if (!slot_cur)
return -ENODEV;
debug ("BEFORE GETTING SLOT STATUS, slot # %x\n", slot_cur->number); debug ("BEFORE GETTING SLOT STATUS, slot # %x\n", slot_cur->number);
if (slot_cur->ctrl->revision == 0xFF) if (slot_cur->ctrl->revision == 0xFF)
if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision)) if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision))
return -1; return -1;
...@@ -572,21 +589,21 @@ static int __init init_ops (void) ...@@ -572,21 +589,21 @@ static int __init init_ops (void)
debug ("status = %x, ext_status = %x\n", slot_cur->status, slot_cur->ext_status); debug ("status = %x, ext_status = %x\n", slot_cur->status, slot_cur->ext_status);
debug ("SLOT_POWER = %x, SLOT_PRESENT = %x, SLOT_LATCH = %x\n", SLOT_POWER (slot_cur->status), SLOT_PRESENT (slot_cur->status), SLOT_LATCH (slot_cur->status)); debug ("SLOT_POWER = %x, SLOT_PRESENT = %x, SLOT_LATCH = %x\n", SLOT_POWER (slot_cur->status), SLOT_PRESENT (slot_cur->status), SLOT_LATCH (slot_cur->status));
if (!(SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
/* No power, adapter, and latch closed */ /* No power, adapter, and latch closed */
ops[ADD][j] = 1; ops[ADD][slot_cur->number] = 1;
else else
ops[ADD][j] = 0; ops[ADD][slot_cur->number] = 0;
ops[DETAIL][j] = 1; ops[DETAIL][slot_cur->number] = 1;
if ((SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
/*Power,adapter,latch closed */ /*Power,adapter,latch closed */
ops[REMOVE][j] = 1; ops[REMOVE][slot_cur->number] = 1;
else else
ops[REMOVE][j] = 0; ops[REMOVE][slot_cur->number] = 0;
if ((SLOT_POWER (slot_cur->status)) && !(SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) { if ((SLOT_PWRGD (slot_cur->status)) && !(SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) {
debug ("BEFORE POWER OFF COMMAND\n"); debug ("BEFORE POWER OFF COMMAND\n");
rc = power_off (slot_cur); rc = power_off (slot_cur);
if (rc) if (rc)
...@@ -624,7 +641,7 @@ static int validate (struct slot *slot_cur, int opn) ...@@ -624,7 +641,7 @@ static int validate (struct slot *slot_cur, int opn)
if (retval) if (retval)
return retval; return retval;
if (!(SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
&& !(SLOT_LATCH (slot_cur->status))) && !(SLOT_LATCH (slot_cur->status)))
ops[ADD][number] = 1; ops[ADD][number] = 1;
else else
...@@ -632,7 +649,7 @@ static int validate (struct slot *slot_cur, int opn) ...@@ -632,7 +649,7 @@ static int validate (struct slot *slot_cur, int opn)
ops[DETAIL][number] = 1; ops[DETAIL][number] = 1;
if ((SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
&& !(SLOT_LATCH (slot_cur->status))) && !(SLOT_LATCH (slot_cur->status)))
ops[REMOVE][number] = 1; ops[REMOVE][number] = 1;
else else
...@@ -678,7 +695,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur) ...@@ -678,7 +695,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur)
} }
snprintf (buffer, 10, "%d", slot_cur->number); snprintf (buffer, 10, "%d", slot_cur->number);
info->power_status = SLOT_POWER (slot_cur->status); info->power_status = SLOT_PWRGD (slot_cur->status);
info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status); info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status);
info->latch_status = SLOT_LATCH (slot_cur->status); info->latch_status = SLOT_LATCH (slot_cur->status);
if (!SLOT_PRESENT (slot_cur->status)) { if (!SLOT_PRESENT (slot_cur->status)) {
...@@ -688,8 +705,8 @@ int ibmphp_update_slot_info (struct slot *slot_cur) ...@@ -688,8 +705,8 @@ int ibmphp_update_slot_info (struct slot *slot_cur)
info->adapter_status = 1; info->adapter_status = 1;
// get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0); // get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0);
} }
/* /* !!!!!!!!!TO DO: THIS NEEDS TO CHANGE!!!!!!!!!!!!! */
bus_speed = slot_cur->bus_on->current_speed; /* bus_speed = slot_cur->bus_on->current_speed;
bus_speed &= 0x0f; bus_speed &= 0x0f;
if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX) if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
...@@ -701,7 +718,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur) ...@@ -701,7 +718,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur)
info->cur_bus_speed_status = bus_speed; info->cur_bus_speed_status = bus_speed;
info->max_bus_speed_status = slot_cur->hotplug_slot->info->max_bus_speed_status; info->max_bus_speed_status = slot_cur->hotplug_slot->info->max_bus_speed_status;
// To do: card_bus_names // To do: bus_names
*/ */
rc = pci_hp_change_slot_info (buffer, info); rc = pci_hp_change_slot_info (buffer, info);
kfree (info); kfree (info);
...@@ -752,18 +769,6 @@ static struct pci_bus *find_bus (u8 busno) ...@@ -752,18 +769,6 @@ static struct pci_bus *find_bus (u8 busno)
return NULL; return NULL;
} }
/******************************************************************
* This function is here because we can no longer use pci_root_ops
******************************************************************/
static struct pci_ops *get_root_pci_ops (void)
{
struct pci_bus * bus;
if ((bus = find_bus (0)))
return bus->ops;
return NULL;
}
/************************************************************* /*************************************************************
* This routine frees up memory used by struct slot, including * This routine frees up memory used by struct slot, including
* the pointers to pci_func, bus, hotplug_slot, controller, * the pointers to pci_func, bus, hotplug_slot, controller,
...@@ -775,6 +780,8 @@ static void free_slots (void) ...@@ -775,6 +780,8 @@ static void free_slots (void)
struct list_head * tmp; struct list_head * tmp;
struct list_head * next; struct list_head * next;
debug ("%s -- enter\n", __FUNCTION__);
list_for_each_safe (tmp, next, &ibmphp_slot_head) { list_for_each_safe (tmp, next, &ibmphp_slot_head) {
slot_cur = list_entry (tmp, struct slot, ibm_slot_list); slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
...@@ -795,7 +802,9 @@ static void free_slots (void) ...@@ -795,7 +802,9 @@ static void free_slots (void)
ibmphp_unconfigure_card (&slot_cur, -1); /* we don't want to actually remove the resources, since free_resources will do just that */ ibmphp_unconfigure_card (&slot_cur, -1); /* we don't want to actually remove the resources, since free_resources will do just that */
kfree (slot_cur); kfree (slot_cur);
slot_cur = NULL;
} }
debug ("%s -- exit\n", __FUNCTION__);
} }
static int ibm_is_pci_dev_in_use (struct pci_dev *dev) static int ibm_is_pci_dev_in_use (struct pci_dev *dev)
...@@ -851,7 +860,7 @@ static int ibm_unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped ...@@ -851,7 +860,7 @@ static int ibm_unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped
if (temp_func) if (temp_func)
temp_func->dev = NULL; temp_func->dev = NULL;
else else
err ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn); debug ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
return 0; return 0;
} }
...@@ -954,8 +963,8 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct ...@@ -954,8 +963,8 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct
} }
if (temp_func->dev) { if (temp_func->dev) {
pci_proc_attach_device (temp_func->dev); // pci_proc_attach_device (temp_func->dev);
pci_announce_device_to_drivers (temp_func->dev); // pci_announce_device_to_drivers (temp_func->dev);
} }
return 0; return 0;
...@@ -965,6 +974,51 @@ static struct pci_visit configure_functions = { ...@@ -965,6 +974,51 @@ static struct pci_visit configure_functions = {
.visit_pci_dev =configure_visit_pci_dev, .visit_pci_dev =configure_visit_pci_dev,
}; };
/*
* The following function is to fix kernel bug regarding
* getting bus entries, here we manually add those primary
* bus entries to kernel bus structure whenever apply
*/
static u8 bus_structure_fixup (u8 busno)
{
struct pci_bus *bus;
struct pci_dev *dev;
u16 l;
if (!find_bus (busno) || !(ibmphp_find_same_bus_num (busno)))
return 1;
bus = kmalloc (sizeof (*bus), GFP_KERNEL);
if (!bus) {
err ("%s - out of memory\n", __FUNCTION__);
return 1;
}
dev = kmalloc (sizeof (*dev), GFP_KERNEL);
if (!dev) {
kfree (bus);
err ("%s - out of memory\n", __FUNCTION__);
return 1;
}
bus->number = busno;
bus->ops = ibmphp_pci_bus->ops;
dev->bus = bus;
for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
if (!pci_read_config_word (dev, PCI_VENDOR_ID, &l) && l != 0x0000 && l != 0xffff) {
debug ("%s - Inside bus_struture_fixup() \n", __FUNCTION__);
pci_scan_bus (busno, ibmphp_pci_bus->ops, NULL);
break;
}
}
kfree (dev);
kfree (bus);
return 0;
}
static int ibm_configure_device (struct pci_func *func) static int ibm_configure_device (struct pci_func *func)
{ {
unsigned char bus; unsigned char bus;
...@@ -972,6 +1026,7 @@ static int ibm_configure_device (struct pci_func *func) ...@@ -972,6 +1026,7 @@ static int ibm_configure_device (struct pci_func *func)
struct pci_bus *child; struct pci_bus *child;
struct pci_dev *temp; struct pci_dev *temp;
int rc = 0; int rc = 0;
int flag = 0; /* this is to make sure we don't double scan the bus, for bridged devices primarily */
struct pci_dev_wrapped wrapped_dev; struct pci_dev_wrapped wrapped_dev;
struct pci_bus_wrapped wrapped_bus; struct pci_bus_wrapped wrapped_bus;
...@@ -980,6 +1035,8 @@ static int ibm_configure_device (struct pci_func *func) ...@@ -980,6 +1035,8 @@ static int ibm_configure_device (struct pci_func *func)
memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped)); memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
memset (&dev0, 0, sizeof (struct pci_dev)); memset (&dev0, 0, sizeof (struct pci_dev));
if (!(bus_structure_fixup (func->busno)))
flag = 1;
if (func->dev == NULL) if (func->dev == NULL)
func->dev = pci_find_slot (func->busno, (func->device << 3) | (func->function & 0x7)); func->dev = pci_find_slot (func->busno, (func->device << 3) | (func->function & 0x7));
...@@ -995,7 +1052,7 @@ static int ibm_configure_device (struct pci_func *func) ...@@ -995,7 +1052,7 @@ static int ibm_configure_device (struct pci_func *func)
return 0; return 0;
} }
} }
if (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
pci_read_config_byte (func->dev, PCI_SECONDARY_BUS, &bus); pci_read_config_byte (func->dev, PCI_SECONDARY_BUS, &bus);
child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus); child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus);
pci_do_scan_bus (child); pci_do_scan_bus (child);
...@@ -1028,7 +1085,7 @@ static int is_bus_empty (struct slot * slot_cur) ...@@ -1028,7 +1085,7 @@ static int is_bus_empty (struct slot * slot_cur)
rc = slot_update (&tmp_slot); rc = slot_update (&tmp_slot);
if (rc) if (rc)
return 0; return 0;
if (SLOT_PRESENT (tmp_slot->status) && SLOT_POWER (tmp_slot->status)) if (SLOT_PRESENT (tmp_slot->status) && SLOT_PWRGD (tmp_slot->status))
return 0; return 0;
i++; i++;
} }
...@@ -1046,6 +1103,9 @@ static int set_bus (struct slot * slot_cur) ...@@ -1046,6 +1103,9 @@ static int set_bus (struct slot * slot_cur)
int rc; int rc;
u8 speed; u8 speed;
u8 cmd = 0x0; u8 cmd = 0x0;
const struct list_head *tmp;
struct pci_dev * dev;
int retval;
debug ("%s - entry slot # %d \n", __FUNCTION__, slot_cur->number); debug ("%s - entry slot # %d \n", __FUNCTION__, slot_cur->number);
if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) { if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) {
...@@ -1091,6 +1151,14 @@ static int set_bus (struct slot * slot_cur) ...@@ -1091,6 +1151,14 @@ static int set_bus (struct slot * slot_cur)
cmd = HPC_BUS_100PCIXMODE; cmd = HPC_BUS_100PCIXMODE;
break; break;
case BUS_SPEED_133: case BUS_SPEED_133:
/* This is to take care of the bug in CIOBX chip*/
list_for_each (tmp, &pci_devices) {
dev = (struct pci_dev *) pci_dev_g (tmp);
if (dev) {
if ((dev->vendor == 0x1166) && (dev->device == 0x0101))
ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE);
}
}
cmd = HPC_BUS_133PCIXMODE; cmd = HPC_BUS_133PCIXMODE;
break; break;
default: default:
...@@ -1103,9 +1171,17 @@ static int set_bus (struct slot * slot_cur) ...@@ -1103,9 +1171,17 @@ static int set_bus (struct slot * slot_cur)
return -ENODEV; return -ENODEV;
} }
debug ("setting bus speed for slot %d, cmd %x\n", slot_cur->number, cmd); debug ("setting bus speed for slot %d, cmd %x\n", slot_cur->number, cmd);
ibmphp_hpc_writeslot (slot_cur, cmd); retval = ibmphp_hpc_writeslot (slot_cur, cmd);
if (retval) {
err ("setting bus speed failed\n");
return retval;
}
if (CTLR_RESULT (slot_cur->ctrl->status)) {
err ("command not completed successfully in set_bus \n");
return -EIO;
}
} }
/* This is for x400, once Brandon fixes the firmware, /* This is for x440, once Brandon fixes the firmware,
will not need this delay */ will not need this delay */
long_delay (1 * HZ); long_delay (1 * HZ);
debug ("%s -Exit \n", __FUNCTION__); debug ("%s -Exit \n", __FUNCTION__);
...@@ -1128,7 +1204,7 @@ static int check_limitations (struct slot *slot_cur) ...@@ -1128,7 +1204,7 @@ static int check_limitations (struct slot *slot_cur)
for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) { for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
tmp_slot = ibmphp_get_slot_from_physical_num (i); tmp_slot = ibmphp_get_slot_from_physical_num (i);
if ((SLOT_POWER (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status))) if ((SLOT_PWRGD (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status)))
count++; count++;
} }
get_cur_bus_info (&slot_cur); get_cur_bus_info (&slot_cur);
...@@ -1384,11 +1460,15 @@ int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot) ...@@ -1384,11 +1460,15 @@ int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
debug ("DISABLING SLOT... \n"); debug ("DISABLING SLOT... \n");
if (slot_cur == NULL) if (slot_cur == NULL) {
ibmphp_unlock_operations ();
return -ENODEV; return -ENODEV;
}
if (slot_cur->ctrl == NULL) if (slot_cur->ctrl == NULL) {
ibmphp_unlock_operations ();
return -ENODEV; return -ENODEV;
}
flag = slot_cur->flag; /* to see if got here from polling */ flag = slot_cur->flag; /* to see if got here from polling */
...@@ -1463,6 +1543,7 @@ int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot) ...@@ -1463,6 +1543,7 @@ int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
return -EFAULT; return -EFAULT;
} }
if (flag)
ibmphp_update_slot_info (slot_cur); ibmphp_update_slot_info (slot_cur);
ibmphp_unlock_operations (); ibmphp_unlock_operations ();
return -EFAULT; return -EFAULT;
...@@ -1503,10 +1584,10 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { ...@@ -1503,10 +1584,10 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
.get_attention_status = get_attention_status, .get_attention_status = get_attention_status,
.get_latch_status = get_latch_status, .get_latch_status = get_latch_status,
.get_adapter_status = get_adapter_present, .get_adapter_status = get_adapter_present,
/* get_max_bus_speed_status: get_max_bus_speed, /* .get_max_bus_speed_status = get_max_bus_speed,
.get_max_adapter_speed_status = get_max_adapter_speed, .get_max_adapter_speed_status = get_max_adapter_speed,
.get_cur_bus_speed_status = get_cur_bus_speed, .get_cur_bus_speed_status = get_cur_bus_speed,
.get_card_bus_names_status = get_card_bus_names, .get_bus_name_status = get_bus_name,
*/ */
}; };
...@@ -1526,6 +1607,7 @@ static void ibmphp_unload (void) ...@@ -1526,6 +1607,7 @@ static void ibmphp_unload (void)
static int __init ibmphp_init (void) static int __init ibmphp_init (void)
{ {
struct pci_bus *bus;
int i = 0; int i = 0;
int rc = 0; int rc = 0;
...@@ -1533,11 +1615,18 @@ static int __init ibmphp_init (void) ...@@ -1533,11 +1615,18 @@ static int __init ibmphp_init (void)
info (DRIVER_DESC " version: " DRIVER_VERSION "\n"); info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
ibmphp_pci_root_ops = get_root_pci_ops (); ibmphp_pci_bus = kmalloc (sizeof (*ibmphp_pci_bus), GFP_KERNEL);
if (ibmphp_pci_root_ops == NULL) { if (!ibmphp_pci_bus) {
err ("cannot read bus operations... will not be able to read the cards. Please check your system\n"); err ("out of memory\n");
return -ENOMEM;
}
bus = find_bus (0);
if (!bus) {
err ("Can't find the root pci bus, can not continue\n");
return -ENODEV; return -ENODEV;
} }
memcpy (ibmphp_pci_bus, bus, sizeof (*ibmphp_pci_bus));
ibmphp_debug = debug; ibmphp_debug = debug;
...@@ -1560,6 +1649,11 @@ static int __init ibmphp_init (void) ...@@ -1560,6 +1649,11 @@ static int __init ibmphp_init (void)
max_slots = get_max_slots (); max_slots = get_max_slots ();
if ((rc = ibmphp_register_pci ())) {
ibmphp_unload ();
return rc;
}
if (init_ops ()) { if (init_ops ()) {
ibmphp_unload (); ibmphp_unload ();
return -ENODEV; return -ENODEV;
...@@ -1570,11 +1664,9 @@ static int __init ibmphp_init (void) ...@@ -1570,11 +1664,9 @@ static int __init ibmphp_init (void)
return -ENODEV; return -ENODEV;
} }
/* lock ourselves into memory with a module count of -1 /* if no NVRAM module selected, lock ourselves into memory with a
* so that no one can unload us. */ * module count of -1 so that no one can unload us. */
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return 0; return 0;
} }
......
...@@ -56,11 +56,17 @@ LIST_HEAD (ibmphp_slot_head); ...@@ -56,11 +56,17 @@ LIST_HEAD (ibmphp_slot_head);
/* Local variables */ /* Local variables */
static struct ebda_hpc_list *hpc_list_ptr; static struct ebda_hpc_list *hpc_list_ptr;
static struct ebda_rsrc_list *rsrc_list_ptr; static struct ebda_rsrc_list *rsrc_list_ptr;
static struct rio_table_hdr *rio_table_ptr; static struct rio_table_hdr *rio_table_ptr = NULL;
static LIST_HEAD (ebda_hpc_head); static LIST_HEAD (ebda_hpc_head);
static LIST_HEAD (bus_info_head); static LIST_HEAD (bus_info_head);
static LIST_HEAD (rio_vg_head);
static LIST_HEAD (rio_lo_head);
static LIST_HEAD (opt_vg_head);
static LIST_HEAD (opt_lo_head);
static void *io_mem; static void *io_mem;
char *chassis_str, *rxe_str, *str;
/* Local functions */ /* Local functions */
static int ebda_rsrc_controller (void); static int ebda_rsrc_controller (void);
static int ebda_rsrc_rsrc (void); static int ebda_rsrc_rsrc (void);
...@@ -125,6 +131,7 @@ static void free_ebda_hpc (struct controller *controller) ...@@ -125,6 +131,7 @@ static void free_ebda_hpc (struct controller *controller)
controller->slots = NULL; controller->slots = NULL;
kfree (controller->buses); kfree (controller->buses);
controller->buses = NULL; controller->buses = NULL;
controller->ctrl_dev = NULL;
kfree (controller); kfree (controller);
} }
...@@ -173,18 +180,77 @@ static void __init print_bus_info (void) ...@@ -173,18 +180,77 @@ static void __init print_bus_info (void)
} }
} }
static void print_ebda_pci_rsrc (void) static void print_lo_info (void)
{
struct rio_detail *ptr;
struct list_head *ptr1;
debug ("print_lo_info ---- \n");
list_for_each (ptr1, &rio_lo_head) {
ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
}
}
static void print_vg_info (void)
{
struct rio_detail *ptr;
struct list_head *ptr1;
debug ("%s --- \n", __FUNCTION__);
list_for_each (ptr1, &rio_vg_head) {
ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
}
}
static void __init print_ebda_pci_rsrc (void)
{ {
struct ebda_pci_rsrc *ptr; struct ebda_pci_rsrc *ptr;
struct list_head *ptr1; struct list_head *ptr1;
list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) { list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list); ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n", debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
__FUNCTION__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr); __FUNCTION__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
} }
} }
static void __init print_ibm_slot (void)
{
struct slot *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &ibmphp_slot_head) {
ptr = list_entry (ptr1, struct slot, ibm_slot_list);
debug ("%s - slot_number: %x \n", __FUNCTION__, ptr->number);
}
}
static void __init print_opt_vg (void)
{
struct opt_rio *ptr;
struct list_head *ptr1;
debug ("%s --- \n", __FUNCTION__);
list_for_each (ptr1, &opt_vg_head) {
ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
debug ("%s - rio_type %x \n", __FUNCTION__, ptr->rio_type);
debug ("%s - chassis_num: %x \n", __FUNCTION__, ptr->chassis_num);
debug ("%s - first_slot_num: %x \n", __FUNCTION__, ptr->first_slot_num);
debug ("%s - middle_num: %x \n", __FUNCTION__, ptr->middle_num);
}
}
static void __init print_ebda_hpc (void) static void __init print_ebda_hpc (void)
{ {
struct controller *hpc_ptr; struct controller *hpc_ptr;
...@@ -221,6 +287,7 @@ static void __init print_ebda_hpc (void) ...@@ -221,6 +287,7 @@ static void __init print_ebda_hpc (void)
break; break;
case 2: case 2:
case 4:
debug ("%s - wpegbbar: %lx\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.wpegbbar); debug ("%s - wpegbbar: %lx\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.wpegbbar);
debug ("%s - i2c_addr: %x\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.i2c_addr); debug ("%s - i2c_addr: %x\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.i2c_addr);
debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq); debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
...@@ -357,31 +424,382 @@ int __init ibmphp_access_ebda (void) ...@@ -357,31 +424,382 @@ int __init ibmphp_access_ebda (void)
rio_complete = 1; rio_complete = 1;
} }
}
if (hs_complete && rio_complete) { if (!hs_complete && !rio_complete) {
rc = ebda_rsrc_controller (); iounmap (io_mem);
return -ENODEV;
}
if (rio_table_ptr) {
if (rio_complete == 1 && rio_table_ptr->ver_num == 3) {
rc = ebda_rio_table ();
if (rc) { if (rc) {
iounmap(io_mem); iounmap (io_mem);
return rc; return rc;
} }
rc = ebda_rsrc_rsrc (); }
}
rc = ebda_rsrc_controller ();
if (rc) { if (rc) {
iounmap(io_mem); iounmap (io_mem);
return rc; return rc;
} }
rc = ebda_rio_table ();
rc = ebda_rsrc_rsrc ();
if (rc) { if (rc) {
iounmap(io_mem); iounmap (io_mem);
return rc; return rc;
} }
iounmap (io_mem); iounmap (io_mem);
return 0; return 0;
}
/*
* map info of scalability details and rio details from physical address
*/
static int __init ebda_rio_table (void)
{
u16 offset;
u8 i;
struct rio_detail *rio_detail_ptr;
offset = rio_table_ptr->offset;
offset += 12 * rio_table_ptr->scal_count;
// we do concern about rio details
for (i = 0; i < rio_table_ptr->riodev_count; i++) {
rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL);
if (!rio_detail_ptr)
return -ENOMEM;
memset (rio_detail_ptr, 0, sizeof (struct rio_detail));
rio_detail_ptr->rio_node_id = readb (io_mem + offset);
rio_detail_ptr->bbar = readl (io_mem + offset + 1);
rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
rio_detail_ptr->status = readb (io_mem + offset + 12);
rio_detail_ptr->wpindex = readb (io_mem + offset + 13);
rio_detail_ptr->chassis_num = readb (io_mem + offset + 14);
// debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
//create linked list of chassis
if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5)
list_add (&rio_detail_ptr->rio_detail_list, &rio_vg_head);
//create linked list of expansion box
else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7)
list_add (&rio_detail_ptr->rio_detail_list, &rio_lo_head);
else
// not in my concern
kfree (rio_detail_ptr);
offset += 15;
} }
print_lo_info ();
print_vg_info ();
return 0;
}
/*
* reorganizing linked list of chassis
*/
static struct opt_rio *search_opt_vg (u8 chassis_num)
{
struct opt_rio *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &opt_vg_head) {
ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
if (ptr->chassis_num == chassis_num)
return ptr;
} }
iounmap (io_mem); return NULL;
return -ENODEV;
} }
static int __init combine_wpg_for_chassis (void)
{
struct opt_rio *opt_rio_ptr = NULL;
struct rio_detail *rio_detail_ptr = NULL;
struct list_head *list_head_ptr = NULL;
list_for_each (list_head_ptr, &rio_vg_head) {
rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
if (!opt_rio_ptr) {
opt_rio_ptr = (struct opt_rio *) kmalloc (sizeof (struct opt_rio), GFP_KERNEL);
if (!opt_rio_ptr)
return -ENOMEM;
memset (opt_rio_ptr, 0, sizeof (struct opt_rio));
opt_rio_ptr->rio_type = rio_detail_ptr->rio_type;
opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num;
opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
opt_rio_ptr->middle_num = rio_detail_ptr->first_slot_num;
list_add (&opt_rio_ptr->opt_rio_list, &opt_vg_head);
} else {
opt_rio_ptr->first_slot_num = min (opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
opt_rio_ptr->middle_num = max (opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num);
}
}
print_opt_vg ();
return 0;
}
/*
* reorgnizing linked list of expansion box
*/
static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
{
struct opt_rio_lo *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &opt_lo_head) {
ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list);
if (ptr->chassis_num == chassis_num)
return ptr;
}
return NULL;
}
static int combine_wpg_for_expansion (void)
{
struct opt_rio_lo *opt_rio_lo_ptr = NULL;
struct rio_detail *rio_detail_ptr = NULL;
struct list_head *list_head_ptr = NULL;
list_for_each (list_head_ptr, &rio_lo_head) {
rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
if (!opt_rio_lo_ptr) {
opt_rio_lo_ptr = (struct opt_rio_lo *) kmalloc (sizeof (struct opt_rio_lo), GFP_KERNEL);
if (!opt_rio_lo_ptr)
return -ENOMEM;
memset (opt_rio_lo_ptr, 0, sizeof (struct opt_rio_lo));
opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type;
opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num;
opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
opt_rio_lo_ptr->middle_num = rio_detail_ptr->first_slot_num;
opt_rio_lo_ptr->pack_count = 1;
list_add (&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head);
} else {
opt_rio_lo_ptr->first_slot_num = min (opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
opt_rio_lo_ptr->middle_num = max (opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num);
opt_rio_lo_ptr->pack_count = 2;
}
}
return 0;
}
static char *convert_2digits_to_char (int var)
{
int bit;
char *str1;
str = (char *) kmalloc (3, GFP_KERNEL);
memset (str, 0, 3);
str1 = (char *) kmalloc (2, GFP_KERNEL);
memset (str, 0, 3);
bit = (int)(var / 10);
switch (bit) {
case 0:
//one digit number
*str = (char)(var + 48);
return str;
default:
//2 digits number
*str1 = (char)(bit + 48);
strncpy (str, str1, 1);
memset (str1, 0, 3);
*str1 = (char)((var % 10) + 48);
strcat (str, str1);
return str;
}
return NULL;
}
/* Since we don't know the max slot number per each chassis, hence go
* through the list of all chassis to find out the range
* Arguments: slot_num, 1st slot number of the chassis we think we are on,
* var (0 = chassis, 1 = expansion box)
*/
static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
{
struct opt_rio *opt_vg_ptr = NULL;
struct opt_rio_lo *opt_lo_ptr = NULL;
struct list_head *ptr = NULL;
int rc = 0;
if (!var) {
list_for_each (ptr, &opt_vg_head) {
opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) {
rc = -ENODEV;
break;
}
}
} else {
list_for_each (ptr, &opt_lo_head) {
opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) {
rc = -ENODEV;
break;
}
}
}
return rc;
}
static struct opt_rio_lo * find_rxe_num (u8 slot_num)
{
struct opt_rio_lo *opt_lo_ptr;
struct list_head *ptr;
list_for_each (ptr, &opt_lo_head) {
opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
//check to see if this slot_num belongs to expansion box
if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1)))
return opt_lo_ptr;
}
return NULL;
}
static struct opt_rio * find_chassis_num (u8 slot_num)
{
struct opt_rio *opt_vg_ptr;
struct list_head *ptr;
list_for_each (ptr, &opt_vg_head) {
opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
//check to see if this slot_num belongs to chassis
if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0)))
return opt_vg_ptr;
}
return NULL;
}
/* This routine will find out how many slots are in the chassis, so that
* the slot numbers for rxe100 would start from 1, and not from 7, or 6 etc
*/
static u8 calculate_first_slot (u8 slot_num)
{
u8 first_slot = 1;
struct list_head * list;
struct slot * slot_cur;
list_for_each (list, &ibmphp_slot_head) {
slot_cur = list_entry (list, struct slot, ibm_slot_list);
if (slot_cur->ctrl) {
if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num))
first_slot = slot_cur->ctrl->ending_slot_num;
}
}
return first_slot + 1;
}
static char *create_file_name (struct slot * slot_cur)
{
struct opt_rio *opt_vg_ptr = NULL;
struct opt_rio_lo *opt_lo_ptr = NULL;
char *ptr_chassis_num, *ptr_rxe_num, *ptr_slot_num;
int which = 0; /* rxe = 1, chassis = 0 */
u8 number = 1; /* either chassis or rxe # */
u8 first_slot = 1;
u8 slot_num;
u8 flag = 0;
if (!slot_cur) {
err ("Structure passed is empty \n");
return NULL;
}
slot_num = slot_cur->number;
chassis_str = (char *) kmalloc (30, GFP_KERNEL);
memset (chassis_str, 0, 30);
rxe_str = (char *) kmalloc (30, GFP_KERNEL);
memset (rxe_str, 0, 30);
ptr_chassis_num = (char *) kmalloc (3, GFP_KERNEL);
memset (ptr_chassis_num, 0, 3);
ptr_rxe_num = (char *) kmalloc (3, GFP_KERNEL);
memset (ptr_rxe_num, 0, 3);
ptr_slot_num = (char *) kmalloc (3, GFP_KERNEL);
memset (ptr_slot_num, 0, 3);
strcpy (chassis_str, "chassis");
strcpy (rxe_str, "rxe");
if (rio_table_ptr) {
if (rio_table_ptr->ver_num == 3) {
opt_vg_ptr = find_chassis_num (slot_num);
opt_lo_ptr = find_rxe_num (slot_num);
}
}
if (opt_vg_ptr) {
if (opt_lo_ptr) {
if ((slot_num - opt_vg_ptr->first_slot_num) > (slot_num - opt_lo_ptr->first_slot_num)) {
number = opt_lo_ptr->chassis_num;
first_slot = opt_lo_ptr->first_slot_num;
which = 1; /* it is RXE */
} else {
first_slot = opt_vg_ptr->first_slot_num;
number = opt_vg_ptr->chassis_num;
which = 0;
}
} else {
first_slot = opt_vg_ptr->first_slot_num;
number = opt_vg_ptr->chassis_num;
which = 0;
}
++flag;
} else if (opt_lo_ptr) {
number = opt_lo_ptr->chassis_num;
first_slot = opt_lo_ptr->first_slot_num;
which = 1;
++flag;
} else if (rio_table_ptr) {
if (rio_table_ptr->ver_num == 3) {
/* if both NULL and we DO have correct RIO table in BIOS */
return NULL;
}
}
if (!flag) {
if (slot_cur->ctrl->ctlr_type == 4) {
first_slot = calculate_first_slot (slot_num);
which = 1;
} else {
which = 0;
}
}
switch (which) {
case 0:
/* Chassis */
*ptr_chassis_num = (char)(number + 48);
strcat (chassis_str, ptr_chassis_num);
kfree (ptr_chassis_num);
strcat (chassis_str, "slot");
ptr_slot_num = convert_2digits_to_char (slot_num - first_slot + 1);
strcat (chassis_str, ptr_slot_num);
kfree (ptr_slot_num);
return chassis_str;
break;
case 1:
/* RXE */
*ptr_rxe_num = (char)(number + 48);
strcat (rxe_str, ptr_rxe_num);
kfree (ptr_rxe_num);
strcat (rxe_str, "slot");
ptr_slot_num = convert_2digits_to_char (slot_num - first_slot + 1);
strcat (rxe_str, ptr_slot_num);
kfree (ptr_slot_num);
return rxe_str;
break;
}
return NULL;
}
static struct pci_driver ibmphp_driver;
/* /*
* map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of
...@@ -400,6 +818,9 @@ static int __init ebda_rsrc_controller (void) ...@@ -400,6 +818,9 @@ static int __init ebda_rsrc_controller (void)
struct ebda_hpc_slot *slot_ptr; struct ebda_hpc_slot *slot_ptr;
struct bus_info *bus_info_ptr1, *bus_info_ptr2; struct bus_info *bus_info_ptr1, *bus_info_ptr2;
int rc; int rc;
int retval;
struct slot *slot_cur;
struct list_head *list;
addr = hpc_list_ptr->phys_addr; addr = hpc_list_ptr->phys_addr;
for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) { for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
...@@ -511,22 +932,21 @@ static int __init ebda_rsrc_controller (void) ...@@ -511,22 +932,21 @@ static int __init ebda_rsrc_controller (void)
hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1); hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);
hpc_ptr->irq = readb (io_mem + addr + 2); hpc_ptr->irq = readb (io_mem + addr + 2);
addr += 3; addr += 3;
debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n", hpc_ptr->u.pci_ctlr.bus, hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
break; break;
case 0: case 0:
hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr); hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr);
hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2); hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2);
retval = check_region (hpc_ptr->u.isa_ctlr.io_start, (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1));
if (retval)
return -ENODEV;
request_region (hpc_ptr->u.isa_ctlr.io_start, (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1), "ibmphp");
hpc_ptr->irq = readb (io_mem + addr + 4); hpc_ptr->irq = readb (io_mem + addr + 4);
addr += 5; addr += 5;
break; break;
case 2: case 2:
hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
hpc_ptr->irq = readb (io_mem + addr + 5);
addr += 6;
break;
case 4: case 4:
hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr); hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4); hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
...@@ -537,12 +957,10 @@ static int __init ebda_rsrc_controller (void) ...@@ -537,12 +957,10 @@ static int __init ebda_rsrc_controller (void)
iounmap (io_mem); iounmap (io_mem);
return -ENODEV; return -ENODEV;
} }
/* following 3 line: Now our driver only supports I2c ctlrType */
if ((hpc_ptr->ctlr_type != 2) && (hpc_ptr->ctlr_type != 4)) {
err ("Please run this driver on ibm xseries440\n ");
return -ENODEV;
}
//reorganize chassis' linked list
combine_wpg_for_chassis ();
combine_wpg_for_expansion ();
hpc_ptr->revision = 0xff; hpc_ptr->revision = 0xff;
hpc_ptr->options = 0xff; hpc_ptr->options = 0xff;
hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num; hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num;
...@@ -566,7 +984,7 @@ static int __init ebda_rsrc_controller (void) ...@@ -566,7 +984,7 @@ static int __init ebda_rsrc_controller (void)
} }
memset (hp_slot_ptr->info, 0, sizeof (struct hotplug_slot_info)); memset (hp_slot_ptr->info, 0, sizeof (struct hotplug_slot_info));
hp_slot_ptr->name = (char *) kmalloc (10, GFP_KERNEL); hp_slot_ptr->name = (char *) kmalloc (30, GFP_KERNEL);
if (!hp_slot_ptr->name) { if (!hp_slot_ptr->name) {
iounmap (io_mem); iounmap (io_mem);
kfree (hp_slot_ptr->info); kfree (hp_slot_ptr->info);
...@@ -583,9 +1001,7 @@ static int __init ebda_rsrc_controller (void) ...@@ -583,9 +1001,7 @@ static int __init ebda_rsrc_controller (void)
return -ENOMEM; return -ENOMEM;
} }
((struct slot *)hp_slot_ptr->private)->flag = TRUE; ((struct slot *)hp_slot_ptr->private)->flag = TRUE;
snprintf (hp_slot_ptr->name, 10, "%d", hpc_ptr->slots[index].slot_num);
((struct slot *) hp_slot_ptr->private)->capabilities = hpc_ptr->slots[index].slot_cap; ((struct slot *) hp_slot_ptr->private)->capabilities = hpc_ptr->slots[index].slot_cap;
if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX) if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
...@@ -617,7 +1033,6 @@ static int __init ebda_rsrc_controller (void) ...@@ -617,7 +1033,6 @@ static int __init ebda_rsrc_controller (void)
((struct slot *) hp_slot_ptr->private)->number = hpc_ptr->slots[index].slot_num; ((struct slot *) hp_slot_ptr->private)->number = hpc_ptr->slots[index].slot_num;
((struct slot *) hp_slot_ptr->private)->hotplug_slot = hp_slot_ptr; ((struct slot *) hp_slot_ptr->private)->hotplug_slot = hp_slot_ptr;
rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr); rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr);
if (rc) { if (rc) {
iounmap (io_mem); iounmap (io_mem);
...@@ -631,8 +1046,6 @@ static int __init ebda_rsrc_controller (void) ...@@ -631,8 +1046,6 @@ static int __init ebda_rsrc_controller (void)
} }
hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops; hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;
pci_hp_register (hp_slot_ptr);
// end of registering ibm slot with hotplug core // end of registering ibm slot with hotplug core
list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head); list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head);
...@@ -642,7 +1055,20 @@ static int __init ebda_rsrc_controller (void) ...@@ -642,7 +1055,20 @@ static int __init ebda_rsrc_controller (void)
list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head ); list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head );
} /* each hpc */ } /* each hpc */
list_for_each (list, &ibmphp_slot_head) {
slot_cur = list_entry (list, struct slot, ibm_slot_list);
snprintf (slot_cur->hotplug_slot->name, 30, "%s", create_file_name (slot_cur));
if (chassis_str)
kfree (chassis_str);
if (rxe_str)
kfree (rxe_str);
pci_hp_register (slot_cur->hotplug_slot);
}
print_ebda_hpc (); print_ebda_hpc ();
print_ibm_slot ();
return 0; return 0;
} }
...@@ -682,7 +1108,7 @@ static int __init ebda_rsrc_rsrc (void) ...@@ -682,7 +1108,7 @@ static int __init ebda_rsrc_rsrc (void)
addr += 6; addr += 6;
debug ("rsrc from io type ----\n"); debug ("rsrc from io type ----\n");
debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n", debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr); rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head); list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
...@@ -703,7 +1129,7 @@ static int __init ebda_rsrc_rsrc (void) ...@@ -703,7 +1129,7 @@ static int __init ebda_rsrc_rsrc (void)
addr += 10; addr += 10;
debug ("rsrc from mem or pfm ---\n"); debug ("rsrc from mem or pfm ---\n");
debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n", debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr); rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head); list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
...@@ -715,56 +1141,6 @@ static int __init ebda_rsrc_rsrc (void) ...@@ -715,56 +1141,6 @@ static int __init ebda_rsrc_rsrc (void)
return 0; return 0;
} }
/*
* map info of scalability details and rio details from physical address
*/
static int __init ebda_rio_table(void)
{
u16 offset;
u8 i;
struct scal_detail *scal_detail_ptr;
struct rio_detail *rio_detail_ptr;
offset = rio_table_ptr->offset;
for (i = 0; i < rio_table_ptr->scal_count; i++) {
scal_detail_ptr = kmalloc (sizeof (struct scal_detail), GFP_KERNEL );
if (!scal_detail_ptr )
return -ENOMEM;
memset (scal_detail_ptr, 0, sizeof (struct scal_detail) );
scal_detail_ptr->node_id = readb (io_mem + offset);
scal_detail_ptr->cbar = readl (io_mem+ offset + 1);
scal_detail_ptr->port0_node_connect = readb (io_mem + 5);
scal_detail_ptr->port0_port_connect = readb (io_mem + 6);
scal_detail_ptr->port1_node_connect = readb (io_mem + 7);
scal_detail_ptr->port1_port_connect = readb (io_mem + 8);
scal_detail_ptr->port2_node_connect = readb (io_mem + 9);
scal_detail_ptr->port2_port_connect = readb (io_mem + 10);
debug ("node_id: %x\ncbar: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nport2_node: %x\nport2_port: %x\n", scal_detail_ptr->node_id, scal_detail_ptr->cbar, scal_detail_ptr->port0_node_connect, scal_detail_ptr->port0_port_connect, scal_detail_ptr->port1_node_connect, scal_detail_ptr->port1_port_connect, scal_detail_ptr->port2_node_connect, scal_detail_ptr->port2_port_connect);
// list_add (&scal_detail_ptr->scal_detail_list, &scal_detail_head);
offset += 11;
}
for (i=0; i < rio_table_ptr->riodev_count; i++) {
rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL );
if (!rio_detail_ptr )
return -ENOMEM;
memset (rio_detail_ptr, 0, sizeof (struct rio_detail) );
rio_detail_ptr->rio_node_id = readb (io_mem + offset );
rio_detail_ptr->bbar = readl (io_mem + offset + 1);
rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
rio_detail_ptr->status = readb (io_mem + offset + 12);
debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
offset += 13;
}
return 0;
}
u16 ibmphp_get_total_controllers (void) u16 ibmphp_get_total_controllers (void)
{ {
return hpc_list_ptr->num_ctlrs; return hpc_list_ptr->num_ctlrs;
...@@ -830,32 +1206,21 @@ void ibmphp_free_bus_info_queue (void) ...@@ -830,32 +1206,21 @@ void ibmphp_free_bus_info_queue (void)
} }
} }
/*
* Calculate the total hot pluggable slots controlled by total hpcs
*/
/*
int ibmphp_get_total_hp_slots (void)
{
struct ebda_hpc *ptr;
int slot_num = 0;
ptr = ebda_hpc_head;
while (ptr != NULL) {
slot_num += ptr->slot_count;
ptr = ptr->next;
}
return slot_num;
}
*/
void ibmphp_free_ebda_hpc_queue (void) void ibmphp_free_ebda_hpc_queue (void)
{ {
struct controller *controller; struct controller *controller = NULL;
struct list_head *list; struct list_head *list;
struct list_head *next; struct list_head *next;
int pci_flag = 0;
list_for_each_safe (list, next, &ebda_hpc_head) { list_for_each_safe (list, next, &ebda_hpc_head) {
controller = list_entry (list, struct controller, ebda_hpc_list); controller = list_entry (list, struct controller, ebda_hpc_list);
if (controller->ctlr_type == 0)
release_region (controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1));
else if ((controller->ctlr_type == 1) && (!pci_flag)) {
++pci_flag;
pci_unregister_driver (&ibmphp_driver);
}
free_ebda_hpc (controller); free_ebda_hpc (controller);
} }
} }
...@@ -873,3 +1238,58 @@ void ibmphp_free_ebda_pci_rsrc_queue (void) ...@@ -873,3 +1238,58 @@ void ibmphp_free_ebda_pci_rsrc_queue (void)
} }
} }
static struct pci_device_id id_table[] __devinitdata = {
{
vendor: PCI_VENDOR_ID_IBM,
device: HPC_DEVICE_ID,
subvendor: PCI_VENDOR_ID_IBM,
subdevice: HPC_SUBSYSTEM_ID,
class: ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
}, {}
};
MODULE_DEVICE_TABLE(pci, id_table);
static int ibmphp_probe (struct pci_dev *, const struct pci_device_id *);
static struct pci_driver ibmphp_driver = {
name: "ibmphp",
id_table: id_table,
probe: ibmphp_probe,
};
int ibmphp_register_pci (void)
{
struct controller *ctrl;
struct list_head *tmp;
int rc = 0;
list_for_each (tmp, &ebda_hpc_head) {
ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
if (ctrl->ctlr_type == 1) {
rc = pci_module_init (&ibmphp_driver);
break;
}
}
return rc;
}
static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids)
{
struct controller *ctrl;
struct list_head *tmp;
debug ("inside ibmphp_probe \n");
list_for_each (tmp, &ebda_hpc_head) {
ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
if (ctrl->ctlr_type == 1) {
if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
ctrl->ctrl_dev = dev;
debug ("found device!!! \n");
debug ("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device);
return 0;
}
}
}
return -ENODEV;
}
...@@ -107,8 +107,8 @@ static struct semaphore sem_exit; // make sure polling thread goes away ...@@ -107,8 +107,8 @@ static struct semaphore sem_exit; // make sure polling thread goes away
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// local function prototypes // local function prototypes
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static u8 ctrl_read (struct controller *, void *, u8); static u8 i2c_ctrl_read (struct controller *, void *, u8);
static u8 ctrl_write (struct controller *, void *, u8, u8); static u8 i2c_ctrl_write (struct controller *, void *, u8, u8);
static u8 hpc_writecmdtoindex (u8, u8); static u8 hpc_writecmdtoindex (u8, u8);
static u8 hpc_readcmdtoindex (u8, u8); static u8 hpc_readcmdtoindex (u8, u8);
static void get_hpc_access (void); static void get_hpc_access (void);
...@@ -142,12 +142,12 @@ void __init ibmphp_hpc_initvars (void) ...@@ -142,12 +142,12 @@ void __init ibmphp_hpc_initvars (void)
} }
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
* Name: ctrl_read * Name: i2c_ctrl_read
* *
* Action: read from HPC over I2C * Action: read from HPC over I2C
* *
*---------------------------------------------------------------------*/ *---------------------------------------------------------------------*/
static u8 ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index) static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
{ {
u8 status; u8 status;
int i; int i;
...@@ -249,13 +249,13 @@ static u8 ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index) ...@@ -249,13 +249,13 @@ static u8 ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
} }
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
* Name: ctrl_write * Name: i2c_ctrl_write
* *
* Action: write to HPC over I2C * Action: write to HPC over I2C
* *
* Return 0 or error codes * Return 0 or error codes
*---------------------------------------------------------------------*/ *---------------------------------------------------------------------*/
static u8 ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd) static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd)
{ {
u8 rc; u8 rc;
void *wpg_addr; // base addr + offset void *wpg_addr; // base addr + offset
...@@ -351,6 +351,93 @@ static u8 ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 c ...@@ -351,6 +351,93 @@ static u8 ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 c
return (rc); return (rc);
} }
//------------------------------------------------------------
// Read from ISA type HPC
//------------------------------------------------------------
static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset)
{
u16 start_address;
u16 end_address;
u8 data;
start_address = ctlr_ptr->u.isa_ctlr.io_start;
end_address = ctlr_ptr->u.isa_ctlr.io_end;
data = inb (start_address + offset);
return data;
}
//--------------------------------------------------------------
// Write to ISA type HPC
//--------------------------------------------------------------
static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data)
{
u16 start_address;
u16 port_address;
start_address = ctlr_ptr->u.isa_ctlr.io_start;
port_address = start_address + (u16) offset;
outb (data, port_address);
}
static u8 pci_ctrl_read (struct controller *ctrl, u8 offset)
{
u8 data = 0x00;
debug ("inside pci_ctrl_read\n");
if (ctrl->ctrl_dev)
pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
return data;
}
static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data)
{
u8 rc = -ENODEV;
debug ("inside pci_ctrl_write\n");
if (ctrl->ctrl_dev) {
pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
rc = 0;
}
return rc;
}
static u8 ctrl_read (struct controller *ctlr, void *base, u8 offset)
{
u8 rc;
switch (ctlr->ctlr_type) {
case 0:
rc = isa_ctrl_read (ctlr, offset);
break;
case 1:
rc = pci_ctrl_read (ctlr, offset);
break;
case 2:
case 4:
rc = i2c_ctrl_read (ctlr, base, offset);
break;
default:
return -ENODEV;
}
return rc;
}
static u8 ctrl_write (struct controller *ctlr, void *base, u8 offset, u8 data)
{
u8 rc = 0;
switch (ctlr->ctlr_type) {
case 0:
isa_ctrl_write(ctlr, offset, data);
break;
case 1:
rc = pci_ctrl_write (ctlr, offset, data);
break;
case 2:
case 4:
rc = i2c_ctrl_write(ctlr, base, offset, data);
break;
default:
return -ENODEV;
}
return rc;
}
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
* Name: hpc_writecmdtoindex() * Name: hpc_writecmdtoindex()
* *
...@@ -449,7 +536,7 @@ static u8 hpc_readcmdtoindex (u8 cmd, u8 index) ...@@ -449,7 +536,7 @@ static u8 hpc_readcmdtoindex (u8 cmd, u8 index)
*---------------------------------------------------------------------*/ *---------------------------------------------------------------------*/
int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
{ {
void *wpg_bbar; void *wpg_bbar = NULL;
struct controller *ctlr_ptr; struct controller *ctlr_ptr;
struct list_head *pslotlist; struct list_head *pslotlist;
u8 index, status; u8 index, status;
...@@ -491,6 +578,7 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) ...@@ -491,6 +578,7 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// map physical address to logical address // map physical address to logical address
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE); wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
...@@ -569,7 +657,11 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) ...@@ -569,7 +657,11 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// cleanup // cleanup
//-------------------------------------------------------------------- //--------------------------------------------------------------------
iounmap (wpg_bbar); // remove physical to logical address mapping
// remove physical to logical address mapping
if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
iounmap (wpg_bbar);
free_hpc_access (); free_hpc_access ();
debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc); debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
...@@ -583,7 +675,7 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) ...@@ -583,7 +675,7 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
*---------------------------------------------------------------------*/ *---------------------------------------------------------------------*/
int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
{ {
void *wpg_bbar; void *wpg_bbar = NULL;
struct controller *ctlr_ptr; struct controller *ctlr_ptr;
u8 index, status; u8 index, status;
int busindex; int busindex;
...@@ -626,12 +718,13 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) ...@@ -626,12 +718,13 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// map physical address to logical address // map physical address to logical address
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE); wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__, debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__,
ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar, ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
ctlr_ptr->u.wpeg_ctlr.i2c_addr); ctlr_ptr->u.wpeg_ctlr.i2c_addr);
}
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// check controller status before writing // check controller status before writing
//-------------------------------------------------------------------- //--------------------------------------------------------------------
...@@ -668,7 +761,10 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) ...@@ -668,7 +761,10 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
ctlr_ptr->status = status; ctlr_ptr->status = status;
} }
// cleanup // cleanup
iounmap (wpg_bbar); // remove physical to logical address mapping
// remove physical to logical address mapping
if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
iounmap (wpg_bbar);
free_hpc_access (); free_hpc_access ();
debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc); debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
...@@ -701,6 +797,7 @@ void free_hpc_access (void) ...@@ -701,6 +797,7 @@ void free_hpc_access (void)
void ibmphp_lock_operations (void) void ibmphp_lock_operations (void)
{ {
down (&semOperations); down (&semOperations);
to_debug = TRUE;
} }
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
...@@ -710,6 +807,7 @@ void ibmphp_unlock_operations (void) ...@@ -710,6 +807,7 @@ void ibmphp_unlock_operations (void)
{ {
debug ("%s - Entry\n", __FUNCTION__); debug ("%s - Entry\n", __FUNCTION__);
up (&semOperations); up (&semOperations);
to_debug = FALSE;
debug ("%s - Exit\n", __FUNCTION__); debug ("%s - Exit\n", __FUNCTION__);
} }
...@@ -734,6 +832,9 @@ static void poll_hpc (void) ...@@ -734,6 +832,9 @@ static void poll_hpc (void)
debug ("%s - Entry\n", __FUNCTION__); debug ("%s - Entry\n", __FUNCTION__);
while (!ibmphp_shutdown) { while (!ibmphp_shutdown) {
if (ibmphp_shutdown)
break;
/* try to get the lock to do some kind of harware access */ /* try to get the lock to do some kind of harware access */
down (&semOperations); down (&semOperations);
...@@ -758,9 +859,9 @@ static void poll_hpc (void) ...@@ -758,9 +859,9 @@ static void poll_hpc (void)
} }
} }
} }
poll_state = POLL_SLOTS; ++poll_count;
poll_state = POLL_SLEEP;
break; break;
case POLL_SLOTS: case POLL_SLOTS:
list_for_each (pslotlist, &ibmphp_slot_head) { list_for_each (pslotlist, &ibmphp_slot_head) {
pslot = list_entry (pslotlist, struct slot, ibm_slot_list); pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
...@@ -772,7 +873,6 @@ static void poll_hpc (void) ...@@ -772,7 +873,6 @@ static void poll_hpc (void)
|| (myslot.ext_status != pslot->ext_status)) || (myslot.ext_status != pslot->ext_status))
process_changeinstatus (pslot, &myslot); process_changeinstatus (pslot, &myslot);
} }
ctrl_count = 0x00; ctrl_count = 0x00;
list_for_each (pslotlist, &ibmphp_slot_head) { list_for_each (pslotlist, &ibmphp_slot_head) {
if (ctrl_count >= ibmphp_get_total_controllers()) if (ctrl_count >= ibmphp_get_total_controllers())
...@@ -787,29 +887,31 @@ static void poll_hpc (void) ...@@ -787,29 +887,31 @@ static void poll_hpc (void)
} }
} }
++poll_count; ++poll_count;
if (poll_count >= POLL_LATCH_CNT) {
poll_count = 0;
poll_state = POLL_SLEEP; poll_state = POLL_SLEEP;
}
break; break;
case POLL_SLEEP: case POLL_SLEEP:
/* don't sleep with a lock on the hardware */ /* don't sleep with a lock on the hardware */
up (&semOperations); up (&semOperations);
long_delay (POLL_INTERVAL_SEC * HZ); long_delay (POLL_INTERVAL_SEC * HZ);
if (ibmphp_shutdown)
break;
down (&semOperations); down (&semOperations);
if (poll_count >= POLL_LATCH_CNT) {
poll_count = 0;
poll_state = POLL_SLOTS;
} else
poll_state = POLL_LATCH_REGISTER; poll_state = POLL_LATCH_REGISTER;
break; break;
} }
/* give up the harware semaphore */ /* give up the harware semaphore */
up (&semOperations); up (&semOperations);
/* sleep for a short time just for good measure */ /* sleep for a short time just for good measure */
set_current_state (TASK_INTERRUPTIBLE); set_current_state (TASK_INTERRUPTIBLE);
schedule_timeout (HZ/10); schedule_timeout (HZ/10);
} }
up (&sem_exit); up (&sem_exit);
debug ("%s - Exit\n", __FUNCTION__); debug ("%s - Exit\n", __FUNCTION__);
} }
...@@ -1070,15 +1172,23 @@ void __exit ibmphp_hpc_stop_poll_thread (void) ...@@ -1070,15 +1172,23 @@ void __exit ibmphp_hpc_stop_poll_thread (void)
debug ("%s - Entry\n", __FUNCTION__); debug ("%s - Entry\n", __FUNCTION__);
ibmphp_shutdown = TRUE; ibmphp_shutdown = TRUE;
debug ("before locking operations \n");
ibmphp_lock_operations (); ibmphp_lock_operations ();
debug ("after locking operations \n");
// wait for poll thread to exit // wait for poll thread to exit
debug ("before sem_exit down \n");
down (&sem_exit); down (&sem_exit);
debug ("after sem_exit down \n");
// cleanup // cleanup
debug ("before free_hpc_access \n");
free_hpc_access (); free_hpc_access ();
debug ("after free_hpc_access \n");
ibmphp_unlock_operations (); ibmphp_unlock_operations ();
debug ("after unlock operations \n");
up (&sem_exit); up (&sem_exit);
debug ("after sem exit up\n");
debug ("%s - Exit\n", __FUNCTION__); debug ("%s - Exit\n", __FUNCTION__);
} }
......
...@@ -104,11 +104,15 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) ...@@ -104,11 +104,15 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
/* For every function on the card */ /* For every function on the card */
for (function = 0x00; function < 0x08; function++) { for (function = 0x00; function < 0x08; function++) {
unsigned int devfn = PCI_DEVFN(device, function);
ibmphp_pci_bus->number = cur_func->busno;
cur_func->function = function; cur_func->function = function;
debug ("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->funcion = %x\n", cur_func->busno, device, function); debug ("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->funcion = %x\n",
cur_func->busno, cur_func->device, cur_func->function);
pci_read_config_word_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_VENDOR_ID, &vendor_id); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
debug ("vendor_id is %x\n", vendor_id); debug ("vendor_id is %x\n", vendor_id);
if (vendor_id != PCI_VENDOR_ID_NOTVALID) { if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
...@@ -122,8 +126,8 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) ...@@ -122,8 +126,8 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
* |_=> 0 = single function device, 1 = multi-function device * |_=> 0 = single function device, 1 = multi-function device
*/ */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_HEADER_TYPE, &hdr_type); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_CLASS_REVISION, &class); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
class_code = class >> 24; class_code = class >> 24;
debug ("hrd_type = %x, class = %x, class_code %x \n", hdr_type, class, class_code); debug ("hrd_type = %x, class = %x, class_code %x \n", hdr_type, class, class_code);
...@@ -195,7 +199,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) ...@@ -195,7 +199,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
goto error; goto error;
} }
pci_read_config_byte_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_SECONDARY_BUS, &sec_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
flag = FALSE; flag = FALSE;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
if (func->devices[i]) { if (func->devices[i]) {
...@@ -267,8 +271,9 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) ...@@ -267,8 +271,9 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
cleanup_count = 2; cleanup_count = 2;
goto error; goto error;
} }
debug ("cur_func->busno = %x, device = %x, function = %x\n", cur_func->busno, device, function); debug ("cur_func->busno = %x, device = %x, function = %x\n",
pci_read_config_byte_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_SECONDARY_BUS, &sec_number); cur_func->busno, device, function);
pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
debug ("after configuring bridge..., sec_number = %x\n", sec_number); debug ("after configuring bridge..., sec_number = %x\n", sec_number);
flag = FALSE; flag = FALSE;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
...@@ -361,13 +366,12 @@ static int configure_device (struct pci_func *func) ...@@ -361,13 +366,12 @@ static int configure_device (struct pci_func *func)
struct resource_node *mem[6]; struct resource_node *mem[6];
struct resource_node *mem_tmp; struct resource_node *mem_tmp;
struct resource_node *pfmem[6]; struct resource_node *pfmem[6];
u8 device; unsigned int devfn;
u8 function;
debug ("%s - inside\n", __FUNCTION__); debug ("%s - inside\n", __FUNCTION__);
device = func->device; devfn = PCI_DEVFN(func->device, func->function);
function = func->function; ibmphp_pci_bus->number = func->busno;
for (count = 0; address[count]; count++) { /* for 6 BARs */ for (count = 0; address[count]; count++) { /* for 6 BARs */
...@@ -384,8 +388,8 @@ static int configure_device (struct pci_func *func) ...@@ -384,8 +388,8 @@ static int configure_device (struct pci_func *func)
pcibios_write_config_dword(cur_func->busno, cur_func->device, pcibios_write_config_dword(cur_func->busno, cur_func->device,
PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF); PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF);
*/ */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0xFFFFFFFF); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
if (!bar[count]) /* This BAR is not implemented */ if (!bar[count]) /* This BAR is not implemented */
continue; continue;
...@@ -421,11 +425,11 @@ static int configure_device (struct pci_func *func) ...@@ -421,11 +425,11 @@ static int configure_device (struct pci_func *func)
kfree (io[count]); kfree (io[count]);
return -EIO; return -EIO;
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->io[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
/* _______________This is for debugging purposes only_____________________ */ /* _______________This is for debugging purposes only_____________________ */
debug ("b4 writing, the IO address is %x\n", func->io[count]->start); debug ("b4 writing, the IO address is %x\n", func->io[count]->start);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
debug ("after writing.... the start address is %x\n", bar[count]); debug ("after writing.... the start address is %x\n", bar[count]);
/* _________________________________________________________________________*/ /* _________________________________________________________________________*/
...@@ -484,11 +488,11 @@ static int configure_device (struct pci_func *func) ...@@ -484,11 +488,11 @@ static int configure_device (struct pci_func *func)
} }
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->pfmem[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
/*_______________This if for debugging purposes only______________________________*/ /*_______________This is for debugging purposes only______________________________*/
debug ("b4 writing, start addres is %x\n", func->pfmem[count]->start); debug ("b4 writing, start addres is %x\n", func->pfmem[count]->start);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
debug ("after writing, start address is %x\n", bar[count]); debug ("after writing, start address is %x\n", bar[count]);
/*_________________________________________________________________________________*/ /*_________________________________________________________________________________*/
...@@ -496,7 +500,7 @@ static int configure_device (struct pci_func *func) ...@@ -496,7 +500,7 @@ static int configure_device (struct pci_func *func)
debug ("inside the mem 64 case, count %d\n", count); debug ("inside the mem 64 case, count %d\n", count);
count += 1; count += 1;
/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */ /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
} }
} else { } else {
/* regular memory */ /* regular memory */
...@@ -526,10 +530,10 @@ static int configure_device (struct pci_func *func) ...@@ -526,10 +530,10 @@ static int configure_device (struct pci_func *func)
kfree (mem[count]); kfree (mem[count]);
return -EIO; return -EIO;
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->mem[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
/* _______________________This is for debugging purposes only _______________________*/ /* _______________________This is for debugging purposes only _______________________*/
debug ("b4 writing, start address is %x\n", func->mem[count]->start); debug ("b4 writing, start address is %x\n", func->mem[count]->start);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
debug ("after writing, the address is %x\n", bar[count]); debug ("after writing, the address is %x\n", bar[count]);
/* __________________________________________________________________________________*/ /* __________________________________________________________________________________*/
...@@ -538,22 +542,22 @@ static int configure_device (struct pci_func *func) ...@@ -538,22 +542,22 @@ static int configure_device (struct pci_func *func)
debug ("inside mem 64 case, reg. mem, count %d\n", count); debug ("inside mem 64 case, reg. mem, count %d\n", count);
count += 1; count += 1;
/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */ /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
} }
} }
} /* end of mem */ } /* end of mem */
} /* end of for */ } /* end of for */
func->bus = 0; /* To indicate that this is not a PPB */ func->bus = 0; /* To indicate that this is not a PPB */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_PIN, &irq); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
if ((irq > 0x00) && (irq < 0x05)) if ((irq > 0x00) && (irq < 0x05))
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_LINE, func->irq[irq - 1]); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_CACHE_LINE_SIZE, CACHE); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_LATENCY_TIMER, LATENCY); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_ROM_ADDRESS, 0x00L); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_COMMAND, DEVICEENABLE); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
return 0; return 0;
} }
...@@ -593,24 +597,23 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -593,24 +597,23 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
0 0
}; };
struct pci_func *func = *func_passed; struct pci_func *func = *func_passed;
u8 function; unsigned int devfn;
u8 device;
u8 irq; u8 irq;
int retval; int retval;
debug ("%s - enter\n", __FUNCTION__); debug ("%s - enter\n", __FUNCTION__);
function = func->function; devfn = PCI_DEVFN(func->function, func->device);
device = func->device; ibmphp_pci_bus->number = func->busno;
/* Configuring necessary info for the bridge so that we could see the devices /* Configuring necessary info for the bridge so that we could see the devices
* behind it * behind it
*/ */
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PRIMARY_BUS, func->busno); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, func->busno);
/* _____________________For debugging purposes only __________________________ /* _____________________For debugging purposes only __________________________
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PRIMARY_BUS, &pri_number); pci_bus_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
debug ("primary # written into the bridge is %x\n", pri_number); debug ("primary # written into the bridge is %x\n", pri_number);
___________________________________________________________________________*/ ___________________________________________________________________________*/
...@@ -624,23 +627,23 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -624,23 +627,23 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
debug ("after find_sec_number, the number we got is %x\n", sec_number); debug ("after find_sec_number, the number we got is %x\n", sec_number);
debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno); debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SECONDARY_BUS, sec_number); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, sec_number);
/* __________________For debugging purposes only __________________________________ /* __________________For debugging purposes only __________________________________
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SECONDARY_BUS, &sec_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
debug ("sec_number after write/read is %x\n", sec_number); debug ("sec_number after write/read is %x\n", sec_number);
________________________________________________________________________________*/ ________________________________________________________________________________*/
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SUBORDINATE_BUS, sec_number); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, sec_number);
/* __________________For debugging purposes only ____________________________________ /* __________________For debugging purposes only ____________________________________
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SUBORDINATE_BUS, &sec_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sec_number);
debug ("subordinate number after write/read is %x\n", sec_number); debug ("subordinate number after write/read is %x\n", sec_number);
__________________________________________________________________________________*/ __________________________________________________________________________________*/
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_CACHE_LINE_SIZE, CACHE); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_LATENCY_TIMER, LATENCY); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SEC_LATENCY_TIMER, LATENCY); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SEC_LATENCY_TIMER, LATENCY);
debug ("func->busno is %x\n", func->busno); debug ("func->busno is %x\n", func->busno);
debug ("sec_number after writing is %x\n", sec_number); debug ("sec_number after writing is %x\n", sec_number);
...@@ -653,8 +656,8 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -653,8 +656,8 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
/* First we need to allocate mem/io for the bridge itself in case it needs it */ /* First we need to allocate mem/io for the bridge itself in case it needs it */
for (count = 0; address[count]; count++) { /* for 2 BARs */ for (count = 0; address[count]; count++) { /* for 2 BARs */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0xFFFFFFFF); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
if (!bar[count]) { if (!bar[count]) {
/* This BAR is not implemented */ /* This BAR is not implemented */
...@@ -694,7 +697,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -694,7 +697,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
return -EIO; return -EIO;
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->io[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
} else { } else {
/* This is Memory */ /* This is Memory */
...@@ -747,13 +750,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -747,13 +750,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
} }
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->pfmem[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) { if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
/* takes up another dword */ /* takes up another dword */
count += 1; count += 1;
/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */ /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
} }
} else { } else {
...@@ -784,13 +787,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -784,13 +787,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
return -EIO; return -EIO;
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->mem[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) { if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
/* takes up another dword */ /* takes up another dword */
count += 1; count += 1;
/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */ /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
} }
} }
...@@ -802,6 +805,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -802,6 +805,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
if (amount_needed == NULL) if (amount_needed == NULL)
return -ENOMEM; return -ENOMEM;
ibmphp_pci_bus->number = func->busno;
debug ("after coming back from scan_behind_bridge\n"); debug ("after coming back from scan_behind_bridge\n");
debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct); debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct);
debug ("amount_needed->io = %x\n", amount_needed->io); debug ("amount_needed->io = %x\n", amount_needed->io);
...@@ -920,6 +924,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -920,6 +924,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
debug ("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem); debug ("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem);
if (flag_io && flag_mem && flag_pfmem) { if (flag_io && flag_mem && flag_pfmem) {
/* If on bootup, there was a bridged card in this slot,
* then card was removed and ibmphp got unloaded and loaded
* back again, there's no way for us to remove the bus
* struct, so no need to kmalloc, can use existing node
*/
bus = ibmphp_find_res_bus (sec_number);
if (!bus) {
bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL); bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
if (!bus) { if (!bus) {
err ("out of system memory \n"); err ("out of system memory \n");
...@@ -930,6 +941,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -930,6 +941,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
bus->busno = sec_number; bus->busno = sec_number;
debug ("b4 adding new bus\n"); debug ("b4 adding new bus\n");
rc = add_new_bus (bus, io, mem, pfmem, func->busno); rc = add_new_bus (bus, io, mem, pfmem, func->busno);
} else if (!(bus->rangeIO) && !(bus->rangeMem) && !(bus->rangePFMem))
rc = add_new_bus (bus, io, mem, pfmem, 0xFF);
else {
err ("expected bus structure not empty? \n");
retval = -EIO;
goto error;
}
if (rc) { if (rc) {
if (rc == -ENOMEM) { if (rc == -ENOMEM) {
ibmphp_remove_bus (bus, func->busno); ibmphp_remove_bus (bus, func->busno);
...@@ -938,8 +956,8 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -938,8 +956,8 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
retval = rc; retval = rc;
goto error; goto error;
} }
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, &io_base); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &io_base);
pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, &pfmem_base); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &pfmem_base);
if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
debug ("io 32\n"); debug ("io 32\n");
...@@ -951,73 +969,73 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -951,73 +969,73 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
} }
if (bus->noIORanges) { if (bus->noIORanges) {
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);
/* _______________This is for debugging purposes only ____________________ /* _______________This is for debugging purposes only ____________________
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, &temp); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &temp);
debug ("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8); debug ("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT, &temp); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &temp);
debug ("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8); debug ("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
________________________________________________________________________*/ ________________________________________________________________________*/
if (need_io_upper) { /* since can't support n.e.ways */ if (need_io_upper) { /* since can't support n.e.ways */
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE_UPPER16, 0x0000); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, 0x0000);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT_UPPER16, 0x0000); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, 0x0000);
} }
} else { } else {
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, 0x00); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT, 0x00); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00);
} }
if (bus->noMemRanges) { if (bus->noMemRanges) {
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16);
/* ____________________This is for debugging purposes only ________________________ /* ____________________This is for debugging purposes only ________________________
pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_BASE, &temp); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &temp);
debug ("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16); debug ("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_LIMIT, &temp); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &temp);
debug ("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16); debug ("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
__________________________________________________________________________________*/ __________________________________________________________________________________*/
} else { } else {
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_BASE, 0xffff); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0xffff);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_LIMIT, 0x0000); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000);
} }
if (bus->noPFMemRanges) { if (bus->noPFMemRanges) {
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16);
/* __________________________This is for debugging purposes only _______________________ /* __________________________This is for debugging purposes only _______________________
pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, &temp); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &temp);
debug ("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16); debug ("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_LIMIT, &temp); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &temp);
debug ("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16); debug ("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
______________________________________________________________________________________*/ ______________________________________________________________________________________*/
if (need_pfmem_upper) { /* since can't support n.e.ways */ if (need_pfmem_upper) { /* since can't support n.e.ways */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_BASE_UPPER32, 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, 0x00000000);
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_LIMIT_UPPER32, 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, 0x00000000);
} }
} else { } else {
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, 0xffff); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0xffff);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_LIMIT, 0x0000); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000);
} }
debug ("b4 writing control information\n"); debug ("b4 writing control information\n");
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_PIN, &irq); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
if ((irq > 0x00) && (irq < 0x05)) if ((irq > 0x00) && (irq < 0x05))
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_LINE, func->irq[irq - 1]); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
/* /*
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, ctrl); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, ctrl);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR);
*/ */
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_COMMAND, DEVICEENABLE); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, 0x07); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, 0x07);
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
if (amount_needed->devices[i]) { if (amount_needed->devices[i]) {
debug ("device where devices[i] is 1 = %x\n", i); debug ("device where devices[i] is 1 = %x\n", i);
...@@ -1073,6 +1091,7 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno) ...@@ -1073,6 +1091,7 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
u16 vendor_id; u16 vendor_id;
u8 hdr_type; u8 hdr_type;
u8 device, function; u8 device, function;
unsigned int devfn;
int howmany = 0; /*this is to see if there are any devices behind the bridge */ int howmany = 0; /*this is to see if there are any devices behind the bridge */
u32 bar[6], class; u32 bar[6], class;
...@@ -1092,20 +1111,23 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno) ...@@ -1092,20 +1111,23 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
return NULL; return NULL;
memset (amount, 0, sizeof (struct res_needed)); memset (amount, 0, sizeof (struct res_needed));
ibmphp_pci_bus->number = busno;
debug ("the bus_no behind the bridge is %x\n", busno); debug ("the bus_no behind the bridge is %x\n", busno);
debug ("scanning devices behind the bridge...\n"); debug ("scanning devices behind the bridge...\n");
for (device = 0; device < 32; device++) { for (device = 0; device < 32; device++) {
amount->devices[device] = 0; amount->devices[device] = 0;
for (function = 0; function < 8; function++) { for (function = 0; function < 8; function++) {
devfn = PCI_DEVFN(device, function);
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_VENDOR_ID, &vendor_id); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
if (vendor_id != PCI_VENDOR_ID_NOTVALID) { if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
/* found correct device!!! */ /* found correct device!!! */
howmany++; howmany++;
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_HEADER_TYPE, &hdr_type); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_CLASS_REVISION, &class); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
debug ("hdr_type behind the bridge is %x\n", hdr_type); debug ("hdr_type behind the bridge is %x\n", hdr_type);
if (hdr_type & PCI_HEADER_TYPE_BRIDGE) { if (hdr_type & PCI_HEADER_TYPE_BRIDGE) {
...@@ -1132,14 +1154,14 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno) ...@@ -1132,14 +1154,14 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
for (count = 0; address[count]; count++) { for (count = 0; address[count]; count++) {
/* for 6 BARs */ /* for 6 BARs */
/* /*
pci_read_config_byte_nodev(ibmphp_pci_root_ops, busno, device, function, address[count], &tmp); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, address[count], &tmp);
if (tmp & 0x01) // IO if (tmp & 0x01) // IO
pci_write_config_dword_nodev(ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFD); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFD);
else // MEMORY else // MEMORY
pci_write_config_dword_nodev(ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFF); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
*/ */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFF); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
debug ("what is bar[count]? %x, count = %d\n", bar[count], count); debug ("what is bar[count]? %x, count = %d\n", bar[count], count);
...@@ -1223,6 +1245,7 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function) ...@@ -1223,6 +1245,7 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
u32 temp_end; u32 temp_end;
u32 size; u32 size;
u32 tmp_address; u32 tmp_address;
unsigned int devfn;
debug ("%s - enter\n", __FUNCTION__); debug ("%s - enter\n", __FUNCTION__);
...@@ -1232,14 +1255,16 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function) ...@@ -1232,14 +1255,16 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
return -EINVAL; return -EINVAL;
} }
devfn = PCI_DEVFN(device, function);
ibmphp_pci_bus->number = busno;
for (count = 0; address[count]; count++) { /* for 6 BARs */ for (count = 0; address[count]; count++) { /* for 6 BARs */
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &start_address); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
/* We can do this here, b/c by that time the device driver of the card has been stopped */ /* We can do this here, b/c by that time the device driver of the card has been stopped */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFF); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &size); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &size);
pci_write_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], start_address); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], start_address);
debug ("start_address is %x\n", start_address); debug ("start_address is %x\n", start_address);
debug ("busno, device, function %x %x %x\n", busno, device, function); debug ("busno, device, function %x %x %x\n", busno, device, function);
...@@ -1336,13 +1361,16 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function) ...@@ -1336,13 +1361,16 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_1,
0 0
}; };
unsigned int devfn;
devfn = PCI_DEVFN(device, function);
ibmphp_pci_bus->number = busno;
bus_no = (int) busno; bus_no = (int) busno;
debug ("busno is %x\n", busno); debug ("busno is %x\n", busno);
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PRIMARY_BUS, &pri_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
debug ("%s - busno = %x, primary_number = %x\n", __FUNCTION__, busno, pri_number); debug ("%s - busno = %x, primary_number = %x\n", __FUNCTION__, busno, pri_number);
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SECONDARY_BUS, &sec_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
debug ("sec_number is %x\n", sec_number); debug ("sec_number is %x\n", sec_number);
sec_no = (int) sec_number; sec_no = (int) sec_number;
pri_no = (int) pri_number; pri_no = (int) pri_number;
...@@ -1351,10 +1379,10 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function) ...@@ -1351,10 +1379,10 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
return -EINVAL; return -EINVAL;
} }
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SECONDARY_BUS, &sec_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
sec_no = (int) sec_no; sec_no = (int) sec_no;
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SUBORDINATE_BUS, &sub_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sub_number);
sub_no = (int) sub_number; sub_no = (int) sub_number;
debug ("sub_no is %d, sec_no is %d\n", sub_no, sec_no); debug ("sub_no is %d, sec_no is %d\n", sub_no, sec_no);
if (sec_no != sub_number) { if (sec_no != sub_number) {
...@@ -1374,7 +1402,7 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function) ...@@ -1374,7 +1402,7 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
for (count = 0; address[count]; count++) { for (count = 0; address[count]; count++) {
/* for 2 BARs */ /* for 2 BARs */
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &start_address); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
if (!start_address) { if (!start_address) {
/* This BAR is not implemented */ /* This BAR is not implemented */
...@@ -1447,6 +1475,7 @@ static int unconfigure_boot_card (struct slot *slot_cur) ...@@ -1447,6 +1475,7 @@ static int unconfigure_boot_card (struct slot *slot_cur)
u8 busno; u8 busno;
u8 function; u8 function;
int rc; int rc;
unsigned int devfn;
u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */ u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */
debug ("%s - enter\n", __FUNCTION__); debug ("%s - enter\n", __FUNCTION__);
...@@ -1457,8 +1486,10 @@ static int unconfigure_boot_card (struct slot *slot_cur) ...@@ -1457,8 +1486,10 @@ static int unconfigure_boot_card (struct slot *slot_cur)
debug ("b4 for loop, device is %x\n", device); debug ("b4 for loop, device is %x\n", device);
/* For every function on the card */ /* For every function on the card */
for (function = 0x0; function < 0x08; function++) { for (function = 0x0; function < 0x08; function++) {
devfn = PCI_DEVFN(device, function);
ibmphp_pci_bus->number = busno;
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_VENDOR_ID, &vendor_id); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
if (vendor_id != PCI_VENDOR_ID_NOTVALID) { if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
/* found correct device!!! */ /* found correct device!!! */
...@@ -1471,8 +1502,8 @@ static int unconfigure_boot_card (struct slot *slot_cur) ...@@ -1471,8 +1502,8 @@ static int unconfigure_boot_card (struct slot *slot_cur)
* |_=> 0 = single function device, 1 = multi-function device * |_=> 0 = single function device, 1 = multi-function device
*/ */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_HEADER_TYPE, &hdr_type); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_CLASS_REVISION, &class); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
debug ("hdr_type %x, class %x\n", hdr_type, class); debug ("hdr_type %x, class %x\n", hdr_type, class);
class >>= 8; /* to take revision out, class = class.subclass.prog i/f */ class >>= 8; /* to take revision out, class = class.subclass.prog i/f */
...@@ -1579,7 +1610,6 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end) ...@@ -1579,7 +1610,6 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
} }
if (sl->func) { if (sl->func) {
debug ("do we come in here? \n");
cur_func = sl->func; cur_func = sl->func;
while (cur_func) { while (cur_func) {
/* TO DO: WILL MOST LIKELY NEED TO GET RID OF THE BUS STRUCTURE FROM RESOURCES AS WELL */ /* TO DO: WILL MOST LIKELY NEED TO GET RID OF THE BUS STRUCTURE FROM RESOURCES AS WELL */
...@@ -1619,6 +1649,7 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end) ...@@ -1619,6 +1649,7 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
sl->func = NULL; sl->func = NULL;
*slot_cur = sl; *slot_cur = sl;
debug ("%s - exit\n", __FUNCTION__);
return 0; return 0;
} }
...@@ -1638,6 +1669,7 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r ...@@ -1638,6 +1669,7 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
struct bus_node *cur_bus = NULL; struct bus_node *cur_bus = NULL;
/* Trying to find the parent bus number */ /* Trying to find the parent bus number */
if (parent_busno != 0xFF) {
cur_bus = ibmphp_find_res_bus (parent_busno); cur_bus = ibmphp_find_res_bus (parent_busno);
if (!cur_bus) { if (!cur_bus) {
err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n"); err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
...@@ -1645,7 +1677,7 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r ...@@ -1645,7 +1677,7 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
} }
list_add (&bus->bus_list, &cur_bus->bus_list); list_add (&bus->bus_list, &cur_bus->bus_list);
}
if (io) { if (io) {
io_range = kmalloc (sizeof (struct range_node), GFP_KERNEL); io_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
if (!io_range) { if (!io_range) {
...@@ -1698,6 +1730,7 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno) ...@@ -1698,6 +1730,7 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno)
int min, max; int min, max;
u8 busno; u8 busno;
struct bus_info *bus; struct bus_info *bus;
struct bus_node *bus_cur;
bus = ibmphp_find_same_bus_num (primary_busno); bus = ibmphp_find_same_bus_num (primary_busno);
if (!bus) { if (!bus) {
...@@ -1712,7 +1745,12 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno) ...@@ -1712,7 +1745,12 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno)
} }
busno = (u8) (slotno - (u8) min); busno = (u8) (slotno - (u8) min);
busno += primary_busno + 0x01; busno += primary_busno + 0x01;
if (!ibmphp_find_res_bus (busno)) bus_cur = ibmphp_find_res_bus (busno);
/* either there is no such bus number, or there are no ranges, which
* can only happen if we removed the bridged device in previous load
* of the driver, and now only have the skeleton bus struct
*/
if ((!bus_cur) || (!(bus_cur->rangeIO) && !(bus_cur->rangeMem) && !(bus_cur->rangePFMem)))
return busno; return busno;
return 0xff; return 0xff;
} }
......
...@@ -45,11 +45,17 @@ static void fix_resources (struct bus_node *); ...@@ -45,11 +45,17 @@ static void fix_resources (struct bus_node *);
static inline struct bus_node *find_bus_wprev (u8, struct bus_node **, u8); static inline struct bus_node *find_bus_wprev (u8, struct bus_node **, u8);
static LIST_HEAD(gbuses); static LIST_HEAD(gbuses);
LIST_HEAD(ibmphp_res_head);
static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr) static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr, u8 busno, int flag)
{ {
struct bus_node * newbus; struct bus_node * newbus;
if (!(curr) && !(flag)) {
err ("NULL pointer passed \n");
return NULL;
}
newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL); newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
if (!newbus) { if (!newbus) {
err ("out of system memory \n"); err ("out of system memory \n");
...@@ -57,6 +63,9 @@ static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr) ...@@ -57,6 +63,9 @@ static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr)
} }
memset (newbus, 0, sizeof (struct bus_node)); memset (newbus, 0, sizeof (struct bus_node));
if (flag)
newbus->busno = busno;
else
newbus->busno = curr->bus_num; newbus->busno = curr->bus_num;
list_add_tail (&newbus->bus_list, &gbuses); list_add_tail (&newbus->bus_list, &gbuses);
return newbus; return newbus;
...@@ -64,7 +73,14 @@ static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr) ...@@ -64,7 +73,14 @@ static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr)
static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * curr) static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * curr)
{ {
struct resource_node *rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL); struct resource_node *rs;
if (!curr) {
err ("NULL passed to allocate \n");
return NULL;
}
rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
if (!rs) { if (!rs) {
err ("out of system memory \n"); err ("out of system memory \n");
return NULL; return NULL;
...@@ -299,7 +315,7 @@ int __init ibmphp_rsrc_init (void) ...@@ -299,7 +315,7 @@ int __init ibmphp_rsrc_init (void)
* actually appears... * actually appears...
*/ */
if (ibmphp_add_resource (new_mem) < 0) { if (ibmphp_add_resource (new_mem) < 0) {
newbus = alloc_error_bus (curr); newbus = alloc_error_bus (curr, 0, 0);
if (!newbus) if (!newbus)
return -ENOMEM; return -ENOMEM;
newbus->firstMem = new_mem; newbus->firstMem = new_mem;
...@@ -316,7 +332,7 @@ int __init ibmphp_rsrc_init (void) ...@@ -316,7 +332,7 @@ int __init ibmphp_rsrc_init (void)
new_pfmem->type = PFMEM; new_pfmem->type = PFMEM;
new_pfmem->fromMem = FALSE; new_pfmem->fromMem = FALSE;
if (ibmphp_add_resource (new_pfmem) < 0) { if (ibmphp_add_resource (new_pfmem) < 0) {
newbus = alloc_error_bus (curr); newbus = alloc_error_bus (curr, 0, 0);
if (!newbus) if (!newbus)
return -ENOMEM; return -ENOMEM;
newbus->firstPFMem = new_pfmem; newbus->firstPFMem = new_pfmem;
...@@ -340,7 +356,7 @@ int __init ibmphp_rsrc_init (void) ...@@ -340,7 +356,7 @@ int __init ibmphp_rsrc_init (void)
* range actually appears... * range actually appears...
*/ */
if (ibmphp_add_resource (new_io) < 0) { if (ibmphp_add_resource (new_io) < 0) {
newbus = alloc_error_bus (curr); newbus = alloc_error_bus (curr, 0, 0);
if (!newbus) if (!newbus)
return -ENOMEM; return -ENOMEM;
newbus->firstIO = new_io; newbus->firstIO = new_io;
...@@ -352,8 +368,6 @@ int __init ibmphp_rsrc_init (void) ...@@ -352,8 +368,6 @@ int __init ibmphp_rsrc_init (void)
} }
} }
debug ("after the while loop in rsrc_init \n");
list_for_each (tmp, &gbuses) { list_for_each (tmp, &gbuses) {
bus_cur = list_entry (tmp, struct bus_node, bus_list); bus_cur = list_entry (tmp, struct bus_node, bus_list);
/* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */ /* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */
...@@ -361,11 +375,9 @@ int __init ibmphp_rsrc_init (void) ...@@ -361,11 +375,9 @@ int __init ibmphp_rsrc_init (void)
if (rc) if (rc)
return rc; return rc;
} }
debug ("b4 once_over in rsrc_init \n");
rc = once_over (); /* This is to align ranges (so no -1) */ rc = once_over (); /* This is to align ranges (so no -1) */
if (rc) if (rc)
return rc; return rc;
debug ("after once_over in rsrc_init \n");
return 0; return 0;
} }
...@@ -580,7 +592,7 @@ static void fix_resources (struct bus_node *bus_cur) ...@@ -580,7 +592,7 @@ static void fix_resources (struct bus_node *bus_cur)
* based on their resource type and sorted by their starting addresses. It assigns * based on their resource type and sorted by their starting addresses. It assigns
* the ptrs to next and nextRange if needed. * the ptrs to next and nextRange if needed.
* *
* Input: 3 diff. resources (nulled out if not needed) * Input: resource ptr
* Output: ptrs assigned (to the node) * Output: ptrs assigned (to the node)
* 0 or -1 * 0 or -1
*******************************************************************************/ *******************************************************************************/
...@@ -594,11 +606,16 @@ int ibmphp_add_resource (struct resource_node *res) ...@@ -594,11 +606,16 @@ int ibmphp_add_resource (struct resource_node *res)
debug ("%s - enter\n", __FUNCTION__); debug ("%s - enter\n", __FUNCTION__);
if (!res) {
err ("NULL passed to add \n");
return -ENODEV;
}
bus_cur = find_bus_wprev (res->busno, NULL, 0); bus_cur = find_bus_wprev (res->busno, NULL, 0);
if (!bus_cur) { if (!bus_cur) {
/* didn't find a bus, smth's wrong!!! */ /* didn't find a bus, smth's wrong!!! */
err ("no bus in the system, either pci_dev's wrong or allocation failed\n"); debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");
return -ENODEV; return -ENODEV;
} }
...@@ -769,6 +786,11 @@ int ibmphp_remove_resource (struct resource_node *res) ...@@ -769,6 +786,11 @@ int ibmphp_remove_resource (struct resource_node *res)
struct resource_node *mem_cur; struct resource_node *mem_cur;
char * type = ""; char * type = "";
if (!res) {
err ("resource to remove is NULL \n");
return -ENODEV;
}
bus_cur = find_bus_wprev (res->busno, NULL, 0); bus_cur = find_bus_wprev (res->busno, NULL, 0);
if (!bus_cur) { if (!bus_cur) {
...@@ -797,7 +819,6 @@ int ibmphp_remove_resource (struct resource_node *res) ...@@ -797,7 +819,6 @@ int ibmphp_remove_resource (struct resource_node *res)
res_prev = NULL; res_prev = NULL;
while (res_cur) { while (res_cur) {
/* ???????????DO WE _NEED_ TO BE CHECKING FOR END AS WELL?????????? */
if ((res_cur->start == res->start) && (res_cur->end == res->end)) if ((res_cur->start == res->start) && (res_cur->end == res->end))
break; break;
res_prev = res_cur; res_prev = res_cur;
...@@ -981,7 +1002,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) ...@@ -981,7 +1002,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
if (!bus_cur) { if (!bus_cur) {
/* didn't find a bus, smth's wrong!!! */ /* didn't find a bus, smth's wrong!!! */
err ("no bus in the system, either pci_dev's wrong or allocation failed \n"); debug ("no bus in the system, either pci_dev's wrong or allocation failed \n");
return -EINVAL; return -EINVAL;
} }
...@@ -1340,7 +1361,7 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno) ...@@ -1340,7 +1361,7 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
prev_bus = find_bus_wprev (parent_busno, NULL, 0); prev_bus = find_bus_wprev (parent_busno, NULL, 0);
if (!prev_bus) { if (!prev_bus) {
err ("something terribly wrong. Cannot find parent bus to the one to remove\n"); debug ("something terribly wrong. Cannot find parent bus to the one to remove\n");
return -ENODEV; return -ENODEV;
} }
...@@ -1467,13 +1488,18 @@ static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev) ...@@ -1467,13 +1488,18 @@ static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
/* /*
* find the resource node in the bus * find the resource node in the bus
* Input: Resource needed, start address of the resource, type or resource * Input: Resource needed, start address of the resource, type of resource
*/ */
int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag) int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag)
{ {
struct resource_node *res_cur = NULL; struct resource_node *res_cur = NULL;
char * type = ""; char * type = "";
if (!bus) {
err ("The bus passed in NULL to find resource \n");
return -ENODEV;
}
switch (flag) { switch (flag) {
case IO: case IO:
res_cur = bus->firstIO; res_cur = bus->firstIO;
...@@ -1514,11 +1540,11 @@ int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resour ...@@ -1514,11 +1540,11 @@ int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resour
res_cur = res_cur->next; res_cur = res_cur->next;
} }
if (!res_cur) { if (!res_cur) {
err ("SOS...cannot find %s resource in the bus. \n", type); debug ("SOS...cannot find %s resource in the bus. \n", type);
return -EINVAL; return -EINVAL;
} }
} else { } else {
err ("SOS... cannot find %s resource in the bus. \n", type); debug ("SOS... cannot find %s resource in the bus. \n", type);
return -EINVAL; return -EINVAL;
} }
} }
...@@ -1757,6 +1783,8 @@ void ibmphp_print_test (void) ...@@ -1757,6 +1783,8 @@ void ibmphp_print_test (void)
struct resource_node *res; struct resource_node *res;
struct list_head *tmp; struct list_head *tmp;
debug_pci ("*****************START**********************\n");
if ((!list_empty(&gbuses)) && flags) { if ((!list_empty(&gbuses)) && flags) {
err ("The GBUSES is not NULL?!?!?!?!?\n"); err ("The GBUSES is not NULL?!?!?!?!?\n");
return; return;
...@@ -1764,50 +1792,50 @@ void ibmphp_print_test (void) ...@@ -1764,50 +1792,50 @@ void ibmphp_print_test (void)
list_for_each (tmp, &gbuses) { list_for_each (tmp, &gbuses) {
bus_cur = list_entry (tmp, struct bus_node, bus_list); bus_cur = list_entry (tmp, struct bus_node, bus_list);
debug ("This is bus # %d. There are \n", bus_cur->busno); debug_pci ("This is bus # %d. There are \n", bus_cur->busno);
debug ("IORanges = %d\t", bus_cur->noIORanges); debug_pci ("IORanges = %d\t", bus_cur->noIORanges);
debug ("MemRanges = %d\t", bus_cur->noMemRanges); debug_pci ("MemRanges = %d\t", bus_cur->noMemRanges);
debug ("PFMemRanges = %d\n", bus_cur->noPFMemRanges); debug_pci ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
debug ("The IO Ranges are as follows:\n"); debug_pci ("The IO Ranges are as follows:\n");
if (bus_cur->rangeIO) { if (bus_cur->rangeIO) {
range = bus_cur->rangeIO; range = bus_cur->rangeIO;
for (i = 0; i < bus_cur->noIORanges; i++) { for (i = 0; i < bus_cur->noIORanges; i++) {
debug ("rangeno is %d\n", range->rangeno); debug_pci ("rangeno is %d\n", range->rangeno);
debug ("[%x - %x]\n", range->start, range->end); debug_pci ("[%x - %x]\n", range->start, range->end);
range = range->next; range = range->next;
} }
} }
debug ("The Mem Ranges are as follows:\n"); debug_pci ("The Mem Ranges are as follows:\n");
if (bus_cur->rangeMem) { if (bus_cur->rangeMem) {
range = bus_cur->rangeMem; range = bus_cur->rangeMem;
for (i = 0; i < bus_cur->noMemRanges; i++) { for (i = 0; i < bus_cur->noMemRanges; i++) {
debug ("rangeno is %d\n", range->rangeno); debug_pci ("rangeno is %d\n", range->rangeno);
debug ("[%x - %x]\n", range->start, range->end); debug_pci ("[%x - %x]\n", range->start, range->end);
range = range->next; range = range->next;
} }
} }
debug ("The PFMem Ranges are as follows:\n"); debug_pci ("The PFMem Ranges are as follows:\n");
if (bus_cur->rangePFMem) { if (bus_cur->rangePFMem) {
range = bus_cur->rangePFMem; range = bus_cur->rangePFMem;
for (i = 0; i < bus_cur->noPFMemRanges; i++) { for (i = 0; i < bus_cur->noPFMemRanges; i++) {
debug ("rangeno is %d\n", range->rangeno); debug_pci ("rangeno is %d\n", range->rangeno);
debug ("[%x - %x]\n", range->start, range->end); debug_pci ("[%x - %x]\n", range->start, range->end);
range = range->next; range = range->next;
} }
} }
debug ("The resources on this bus are as follows\n"); debug_pci ("The resources on this bus are as follows\n");
debug ("IO...\n"); debug_pci ("IO...\n");
if (bus_cur->firstIO) { if (bus_cur->firstIO) {
res = bus_cur->firstIO; res = bus_cur->firstIO;
while (res) { while (res) {
debug ("The range # is %d\n", res->rangeno); debug_pci ("The range # is %d\n", res->rangeno);
debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
debug ("[%x - %x], len=%x\n", res->start, res->end, res->len); debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
if (res->next) if (res->next)
res = res->next; res = res->next;
else if (res->nextRange) else if (res->nextRange)
...@@ -1816,13 +1844,13 @@ void ibmphp_print_test (void) ...@@ -1816,13 +1844,13 @@ void ibmphp_print_test (void)
break; break;
} }
} }
debug ("Mem...\n"); debug_pci ("Mem...\n");
if (bus_cur->firstMem) { if (bus_cur->firstMem) {
res = bus_cur->firstMem; res = bus_cur->firstMem;
while (res) { while (res) {
debug ("The range # is %d\n", res->rangeno); debug_pci ("The range # is %d\n", res->rangeno);
debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
debug ("[%x - %x], len=%x\n", res->start, res->end, res->len); debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
if (res->next) if (res->next)
res = res->next; res = res->next;
else if (res->nextRange) else if (res->nextRange)
...@@ -1831,13 +1859,13 @@ void ibmphp_print_test (void) ...@@ -1831,13 +1859,13 @@ void ibmphp_print_test (void)
break; break;
} }
} }
debug ("PFMem...\n"); debug_pci ("PFMem...\n");
if (bus_cur->firstPFMem) { if (bus_cur->firstPFMem) {
res = bus_cur->firstPFMem; res = bus_cur->firstPFMem;
while (res) { while (res) {
debug ("The range # is %d\n", res->rangeno); debug_pci ("The range # is %d\n", res->rangeno);
debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
debug ("[%x - %x], len=%x\n", res->start, res->end, res->len); debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
if (res->next) if (res->next)
res = res->next; res = res->next;
else if (res->nextRange) else if (res->nextRange)
...@@ -1847,23 +1875,53 @@ void ibmphp_print_test (void) ...@@ -1847,23 +1875,53 @@ void ibmphp_print_test (void)
} }
} }
debug ("PFMemFromMem...\n"); debug_pci ("PFMemFromMem...\n");
if (bus_cur->firstPFMemFromMem) { if (bus_cur->firstPFMemFromMem) {
res = bus_cur->firstPFMemFromMem; res = bus_cur->firstPFMemFromMem;
while (res) { while (res) {
debug ("The range # is %d\n", res->rangeno); debug_pci ("The range # is %d\n", res->rangeno);
debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
debug ("[%x - %x], len=%x\n", res->start, res->end, res->len); debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
res = res->next; res = res->next;
} }
} }
} }
debug_pci ("***********************END***********************\n");
}
int static range_exists_already (struct range_node * range, struct bus_node * bus_cur, u8 type)
{
struct range_node * range_cur = NULL;
switch (type) {
case IO:
range_cur = bus_cur->rangeIO;
break;
case MEM:
range_cur = bus_cur->rangeMem;
break;
case PFMEM:
range_cur = bus_cur->rangePFMem;
break;
default:
err ("wrong type passed to find out if range already exists \n");
return -ENODEV;
}
while (range_cur) {
if ((range_cur->start == range->start) && (range_cur->end == range->end))
return 1;
range_cur = range_cur->next;
}
return 0;
} }
/* This routine will read the windows for any PPB we have and update the /* This routine will read the windows for any PPB we have and update the
* range info for the secondary bus, and will also input this info into * range info for the secondary bus, and will also input this info into
* primary bus, since BIOS doesn't. This is for PPB that are in the system * primary bus, since BIOS doesn't. This is for PPB that are in the system
* on bootup * on bootup. For bridged cards that were added during previous load of the
* driver, only the ranges and the bus structure are added, the devices are
* added from NVRAM
* Input: primary busno * Input: primary busno
* Returns: none * Returns: none
* Note: this function doesn't take into account IO restrictions etc, * Note: this function doesn't take into account IO restrictions etc,
...@@ -1874,7 +1932,7 @@ void ibmphp_print_test (void) ...@@ -1874,7 +1932,7 @@ void ibmphp_print_test (void)
*/ */
static int __init update_bridge_ranges (struct bus_node **bus) static int __init update_bridge_ranges (struct bus_node **bus)
{ {
u8 sec_busno, device, function, busno, hdr_type, start_io_address, end_io_address; u8 sec_busno, device, function, hdr_type, start_io_address, end_io_address;
u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address; u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address;
u32 start_address, end_address, upper_start, upper_end; u32 start_address, end_address, upper_start, upper_end;
struct bus_node *bus_sec; struct bus_node *bus_sec;
...@@ -1883,19 +1941,24 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -1883,19 +1941,24 @@ static int __init update_bridge_ranges (struct bus_node **bus)
struct resource_node *mem; struct resource_node *mem;
struct resource_node *pfmem; struct resource_node *pfmem;
struct range_node *range; struct range_node *range;
unsigned int devfn;
bus_cur = *bus; bus_cur = *bus;
busno = bus_cur->busno; if (!bus_cur)
return -ENODEV;
ibmphp_pci_bus->number = bus_cur->busno;
debug ("inside %s \n", __FUNCTION__); debug ("inside %s \n", __FUNCTION__);
debug ("bus_cur->busno = %x\n", bus_cur->busno); debug ("bus_cur->busno = %x\n", bus_cur->busno);
for (device = 0; device < 32; device++) { for (device = 0; device < 32; device++) {
for (function = 0x00; function < 0x08; function++) { for (function = 0x00; function < 0x08; function++) {
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_VENDOR_ID, &vendor_id); devfn = PCI_DEVFN(device, function);
pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
if (vendor_id != PCI_VENDOR_ID_NOTVALID) { if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
/* found correct device!!! */ /* found correct device!!! */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_HEADER_TYPE, &hdr_type); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
switch (hdr_type) { switch (hdr_type) {
case PCI_HEADER_TYPE_NORMAL: case PCI_HEADER_TYPE_NORMAL:
...@@ -1914,21 +1977,25 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -1914,21 +1977,25 @@ static int __init update_bridge_ranges (struct bus_node **bus)
temp++; temp++;
} }
*/ */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SECONDARY_BUS, &sec_busno); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_busno);
bus_sec = find_bus_wprev (sec_busno, NULL, 0); bus_sec = find_bus_wprev (sec_busno, NULL, 0);
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_BASE, &start_io_address); /* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_LIMIT, &end_io_address); if (!bus_sec) {
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_BASE_UPPER16, &upper_io_start); bus_sec = alloc_error_bus (NULL, sec_busno, 1);
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_LIMIT_UPPER16, &upper_io_end); /* the rest will be populated during NVRAM call */
return 0;
}
pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &start_io_address);
pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &end_io_address);
pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, &upper_io_start);
pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, &upper_io_end);
start_address = (start_io_address & PCI_IO_RANGE_MASK) << 8; start_address = (start_io_address & PCI_IO_RANGE_MASK) << 8;
start_address |= (upper_io_start << 16); start_address |= (upper_io_start << 16);
end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8; end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8;
end_address |= (upper_io_end << 16); end_address |= (upper_io_end << 16);
if ((start_address) && (start_address <= end_address)) { if ((start_address) && (start_address <= end_address)) {
range = kmalloc (sizeof (struct range_node), GFP_KERNEL); range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
if (!range) { if (!range) {
err ("out of system memory \n"); err ("out of system memory \n");
return -ENOMEM; return -ENOMEM;
...@@ -1937,17 +2004,23 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -1937,17 +2004,23 @@ static int __init update_bridge_ranges (struct bus_node **bus)
range->start = start_address; range->start = start_address;
range->end = end_address + 0xfff; range->end = end_address + 0xfff;
if (bus_sec->noIORanges > 0) if (bus_sec->noIORanges > 0) {
if (!range_exists_already (range, bus_sec, IO)) {
add_range (IO, range, bus_sec); add_range (IO, range, bus_sec);
else { ++bus_sec->noIORanges;
} else {
kfree (range);
range = NULL;
}
} else {
/* 1st IO Range on the bus */ /* 1st IO Range on the bus */
range->rangeno = 1; range->rangeno = 1;
bus_sec->rangeIO = range; bus_sec->rangeIO = range;
}
++bus_sec->noIORanges; ++bus_sec->noIORanges;
}
fix_resources (bus_sec); fix_resources (bus_sec);
if (ibmphp_find_resource (bus_cur, start_address, &io, IO)) {
io = kmalloc (sizeof (struct resource_node), GFP_KERNEL); io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
if (!io) { if (!io) {
kfree (range); kfree (range);
...@@ -1961,12 +2034,12 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -1961,12 +2034,12 @@ static int __init update_bridge_ranges (struct bus_node **bus)
io->start = start_address; io->start = start_address;
io->end = end_address + 0xfff; io->end = end_address + 0xfff;
io->len = io->end - io->start + 1; io->len = io->end - io->start + 1;
ibmphp_add_resource (io); ibmphp_add_resource (io);
} }
}
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_MEMORY_BASE, &start_mem_address); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &start_mem_address);
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_MEMORY_LIMIT, &end_mem_address); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &end_mem_address);
start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16; start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16; end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
...@@ -1982,17 +2055,24 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -1982,17 +2055,24 @@ static int __init update_bridge_ranges (struct bus_node **bus)
range->start = start_address; range->start = start_address;
range->end = end_address + 0xfffff; range->end = end_address + 0xfffff;
if (bus_sec->noMemRanges > 0) if (bus_sec->noMemRanges > 0) {
if (!range_exists_already (range, bus_sec, MEM)) {
add_range (MEM, range, bus_sec); add_range (MEM, range, bus_sec);
else { ++bus_sec->noMemRanges;
} else {
kfree (range);
range = NULL;
}
} else {
/* 1st Mem Range on the bus */ /* 1st Mem Range on the bus */
range->rangeno = 1; range->rangeno = 1;
bus_sec->rangeMem = range; bus_sec->rangeMem = range;
++bus_sec->noMemRanges;
} }
++bus_sec->noMemRanges;
fix_resources (bus_sec); fix_resources (bus_sec);
if (ibmphp_find_resource (bus_cur, start_address, &mem, MEM)) {
mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL); mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
if (!mem) { if (!mem) {
kfree (range); kfree (range);
...@@ -2008,10 +2088,11 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -2008,10 +2088,11 @@ static int __init update_bridge_ranges (struct bus_node **bus)
mem->len = mem->end - mem->start + 1; mem->len = mem->end - mem->start + 1;
ibmphp_add_resource (mem); ibmphp_add_resource (mem);
} }
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_MEMORY_BASE, &start_mem_address); }
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_MEMORY_LIMIT, &end_mem_address); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &start_mem_address);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_BASE_UPPER32, &upper_start); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &end_mem_address);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_LIMIT_UPPER32, &upper_end); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, &upper_start);
pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, &upper_end);
start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16; start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16; end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
#if BITS_PER_LONG == 64 #if BITS_PER_LONG == 64
...@@ -2030,17 +2111,23 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -2030,17 +2111,23 @@ static int __init update_bridge_ranges (struct bus_node **bus)
range->start = start_address; range->start = start_address;
range->end = end_address + 0xfffff; range->end = end_address + 0xfffff;
if (bus_sec->noPFMemRanges > 0) if (bus_sec->noPFMemRanges > 0) {
if (!range_exists_already (range, bus_sec, PFMEM)) {
add_range (PFMEM, range, bus_sec); add_range (PFMEM, range, bus_sec);
else { ++bus_sec->noPFMemRanges;
} else {
kfree (range);
range = NULL;
}
} else {
/* 1st PFMem Range on the bus */ /* 1st PFMem Range on the bus */
range->rangeno = 1; range->rangeno = 1;
bus_sec->rangePFMem = range; bus_sec->rangePFMem = range;
++bus_sec->noPFMemRanges;
} }
++bus_sec->noPFMemRanges;
fix_resources (bus_sec); fix_resources (bus_sec);
if (ibmphp_find_resource (bus_cur, start_address, &pfmem, PFMEM)) {
pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL); pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
if (!pfmem) { if (!pfmem) {
kfree (range); kfree (range);
...@@ -2055,8 +2142,10 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -2055,8 +2142,10 @@ static int __init update_bridge_ranges (struct bus_node **bus)
pfmem->end = end_address + 0xfffff; pfmem->end = end_address + 0xfffff;
pfmem->len = pfmem->end - pfmem->start + 1; pfmem->len = pfmem->end - pfmem->start + 1;
pfmem->fromMem = FALSE; pfmem->fromMem = FALSE;
ibmphp_add_resource (pfmem); ibmphp_add_resource (pfmem);
} }
}
break; break;
} /* end of switch */ } /* end of switch */
} /* end if vendor */ } /* end if vendor */
......
...@@ -141,20 +141,5 @@ extern int pci_visit_dev (struct pci_visit *fn, ...@@ -141,20 +141,5 @@ extern int pci_visit_dev (struct pci_visit *fn,
struct pci_dev_wrapped *wrapped_dev, struct pci_dev_wrapped *wrapped_dev,
struct pci_bus_wrapped *wrapped_parent); struct pci_bus_wrapped *wrapped_parent);
extern int pci_read_config_byte_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u8 *val);
extern int pci_read_config_word_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u16 *val);
extern int pci_read_config_dword_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u32 *val);
extern int pci_write_config_byte_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u8 val);
extern int pci_write_config_word_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u16 val);
extern int pci_write_config_dword_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u32 val);
#endif #endif
...@@ -6,10 +6,8 @@ export-objs := access.o hotplug.o pci-driver.o pci.o pool.o \ ...@@ -6,10 +6,8 @@ export-objs := access.o hotplug.o pci-driver.o pci.o pool.o \
probe.o proc.o search.o compat.o probe.o proc.o search.o compat.o
obj-y += access.o probe.o pci.o pool.o quirks.o \ obj-y += access.o probe.o pci.o pool.o quirks.o \
compat.o names.o pci-driver.o search.o compat.o names.o pci-driver.o search.o hotplug.o
obj-$(CONFIG_PM) += power.o obj-$(CONFIG_PM) += power.o
obj-$(CONFIG_HOTPLUG) += hotplug.o
obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_PROC_FS) += proc.o
ifndef CONFIG_SPARC64 ifndef CONFIG_SPARC64
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
#define TRUE (!FALSE) #define TRUE (!FALSE)
#endif #endif
static void #ifdef CONFIG_HOTPLUG
run_sbin_hotplug(struct pci_dev *pdev, int insert) static void run_sbin_hotplug(struct pci_dev *pdev, int insert)
{ {
int i; int i;
char *argv[3], *envp[8]; char *argv[3], *envp[8];
...@@ -45,13 +45,18 @@ run_sbin_hotplug(struct pci_dev *pdev, int insert) ...@@ -45,13 +45,18 @@ run_sbin_hotplug(struct pci_dev *pdev, int insert)
call_usermodehelper (argv [0], argv, envp); call_usermodehelper (argv [0], argv, envp);
} }
#else
static void run_sbin_hotplug(struct pci_dev *pdev, int insert) { }
#endif
/** /**
* pci_insert_device - insert a hotplug device * pci_insert_device - insert a pci device
* @dev: the device to insert * @dev: the device to insert
* @bus: where to insert it * @bus: where to insert it
* *
* Add a new device to the device lists and notify userspace (/sbin/hotplug). * Link the device to both the global PCI device chain and the
* per-bus list of devices, add the /proc entry, and notify
* userspace (/sbin/hotplug).
*/ */
void void
pci_insert_device(struct pci_dev *dev, struct pci_bus *bus) pci_insert_device(struct pci_dev *dev, struct pci_bus *bus)
...@@ -78,11 +83,11 @@ pci_free_resources(struct pci_dev *dev) ...@@ -78,11 +83,11 @@ pci_free_resources(struct pci_dev *dev)
} }
/** /**
* pci_remove_device - remove a hotplug device * pci_remove_device - remove a pci device
* @dev: the device to remove * @dev: the device to remove
* *
* Delete the device structure from the device lists and * Delete the device structure from the device lists,
* notify userspace (/sbin/hotplug). * remove the /proc entry, and notify userspace (/sbin/hotplug).
*/ */
void void
pci_remove_device(struct pci_dev *dev) pci_remove_device(struct pci_dev *dev)
...@@ -94,10 +99,11 @@ pci_remove_device(struct pci_dev *dev) ...@@ -94,10 +99,11 @@ pci_remove_device(struct pci_dev *dev)
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
pci_proc_detach_device(dev); pci_proc_detach_device(dev);
#endif #endif
/* notify userspace of hotplug device removal */ /* notify userspace of hotplug device removal */
run_sbin_hotplug(dev, FALSE); run_sbin_hotplug(dev, FALSE);
} }
#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(pci_insert_device); EXPORT_SYMBOL(pci_insert_device);
EXPORT_SYMBOL(pci_remove_device); EXPORT_SYMBOL(pci_remove_device);
#endif
...@@ -479,10 +479,10 @@ struct pci_dev * __devinit pci_scan_slot(struct pci_dev *temp) ...@@ -479,10 +479,10 @@ struct pci_dev * __devinit pci_scan_slot(struct pci_dev *temp)
/* /*
* Link the device to both the global PCI device chain and * Link the device to both the global PCI device chain and
* the per-bus list of devices. * the per-bus list of devices and call /sbin/hotplug if we
* should.
*/ */
list_add_tail(&dev->global_list, &pci_devices); pci_insert_device (dev, bus);
list_add_tail(&dev->bus_list, &bus->devices);
/* Fix up broken headers */ /* Fix up broken headers */
pci_fixup_device(PCI_FIXUP_HEADER, dev); pci_fixup_device(PCI_FIXUP_HEADER, dev);
...@@ -594,4 +594,5 @@ EXPORT_SYMBOL(pci_setup_device); ...@@ -594,4 +594,5 @@ EXPORT_SYMBOL(pci_setup_device);
EXPORT_SYMBOL(pci_add_new_bus); EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_do_scan_bus); EXPORT_SYMBOL(pci_do_scan_bus);
EXPORT_SYMBOL(pci_scan_slot); EXPORT_SYMBOL(pci_scan_slot);
EXPORT_SYMBOL(pci_scan_bus);
#endif #endif
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#define PCI_CFG_SPACE_SIZE 256 #define PCI_CFG_SPACE_SIZE 256
static int proc_initialized; /* = 0 */
static loff_t static loff_t
proc_bus_pci_lseek(struct file *file, loff_t off, int whence) proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
{ {
...@@ -410,6 +412,9 @@ int pci_proc_attach_device(struct pci_dev *dev) ...@@ -410,6 +412,9 @@ int pci_proc_attach_device(struct pci_dev *dev)
struct proc_dir_entry *de, *e; struct proc_dir_entry *de, *e;
char name[16]; char name[16];
if (!proc_initialized)
return -EACCES;
if (!(de = bus->procdir)) { if (!(de = bus->procdir)) {
sprintf(name, "%02x", bus->number); sprintf(name, "%02x", bus->number);
de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir); de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
...@@ -446,6 +451,9 @@ int pci_proc_attach_bus(struct pci_bus* bus) ...@@ -446,6 +451,9 @@ int pci_proc_attach_bus(struct pci_bus* bus)
{ {
struct proc_dir_entry *de = bus->procdir; struct proc_dir_entry *de = bus->procdir;
if (!proc_initialized)
return -EACCES;
if (!de) { if (!de) {
char name[16]; char name[16];
sprintf(name, "%02x", bus->number); sprintf(name, "%02x", bus->number);
...@@ -595,6 +603,7 @@ static int __init pci_proc_init(void) ...@@ -595,6 +603,7 @@ static int __init pci_proc_init(void)
entry = create_proc_entry("devices", 0, proc_bus_pci_dir); entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
if (entry) if (entry)
entry->proc_fops = &proc_bus_pci_dev_operations; entry->proc_fops = &proc_bus_pci_dev_operations;
proc_initialized = 1;
pci_for_each_dev(dev) { pci_for_each_dev(dev) {
pci_proc_attach_device(dev); pci_proc_attach_device(dev);
} }
......
...@@ -115,13 +115,6 @@ static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {;} ...@@ -115,13 +115,6 @@ static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {;}
# endif # endif
/* The following functions are for initialisation: don't use them! */
extern int mtrr_init (void);
# if defined(CONFIG_SMP) && defined(CONFIG_MTRR)
extern void mtrr_init_boot_cpu (void);
extern void mtrr_init_secondary_cpu (void);
# endif
#endif #endif
#endif /* _LINUX_MTRR_H */ #endif /* _LINUX_MTRR_H */
...@@ -634,7 +634,6 @@ void pci_insert_device(struct pci_dev *, struct pci_bus *); ...@@ -634,7 +634,6 @@ void pci_insert_device(struct pci_dev *, struct pci_bus *);
void pci_remove_device(struct pci_dev *); void pci_remove_device(struct pci_dev *);
struct pci_driver *pci_dev_driver(const struct pci_dev *); struct pci_driver *pci_dev_driver(const struct pci_dev *);
const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev); const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
void pci_announce_device_to_drivers(struct pci_dev *);
unsigned int pci_do_scan_bus(struct pci_bus *bus); unsigned int pci_do_scan_bus(struct pci_bus *bus);
struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr); struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
......
...@@ -38,10 +38,6 @@ ...@@ -38,10 +38,6 @@
#include <asm/s390mach.h> #include <asm/s390mach.h>
#endif #endif
#ifdef CONFIG_MTRR
# include <asm/mtrr.h>
#endif
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
#include <asm/smp.h> #include <asm/smp.h>
#endif #endif
...@@ -490,15 +486,6 @@ static void __init do_initcalls(void) ...@@ -490,15 +486,6 @@ static void __init do_initcalls(void)
*/ */
static void __init do_basic_setup(void) static void __init do_basic_setup(void)
{ {
#if defined(CONFIG_MTRR) /* Do this after SMP initialization */
/*
* We should probably create some architecture-dependent "fixup after
* everything is up" style function where this would belong better
* than in init/main.c..
*/
mtrr_init();
#endif
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
sysctl_init(); sysctl_init();
#endif #endif
......
...@@ -1220,6 +1220,7 @@ int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs) ...@@ -1220,6 +1220,7 @@ int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs)
#endif #endif
EXPORT_SYMBOL(recalc_sigpending);
EXPORT_SYMBOL(dequeue_signal); EXPORT_SYMBOL(dequeue_signal);
EXPORT_SYMBOL(flush_signals); EXPORT_SYMBOL(flush_signals);
EXPORT_SYMBOL(force_sig); EXPORT_SYMBOL(force_sig);
......
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