Commit 38908d74 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-acpi.bkbits.net/linux-acpi

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 03e691ed 8a0f08e2
......@@ -110,12 +110,54 @@ cyrix_get_free_region(unsigned long base, unsigned long size)
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,
unsigned long size, mtrr_type type)
{
unsigned char arr, arr_type, arr_size;
u32 cr0, ccr3;
u32 cr4 = 0;
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,
}
}
/* 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);
prepare_set();
base <<= PAGE_SHIFT;
setCx86(arr, ((unsigned char *) &base)[3]);
......@@ -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(CX86_RCR_BASE + reg, arr_type);
/* 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);
post_set();
}
typedef struct {
......@@ -210,31 +224,11 @@ arr_state_t arr_state[8] __initdata = {
unsigned char ccr_state[7] __initdata = { 0, 0, 0, 0, 0, 0, 0 };
static void __init
cyrix_arr_init_secondary(void)
static void cyrix_set_all(void)
{
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
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);
prepare_set();
/* the CCRs are not contiguous */
for (i = 0; i < 4; i++)
......@@ -245,18 +239,7 @@ cyrix_arr_init_secondary(void)
cyrix_set_arr(i, arr_state[i].base,
arr_state[i].size, arr_state[i].type);
/* 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);
post_set();
}
/*
......@@ -361,7 +344,7 @@ cyrix_arr_init(void)
static struct mtrr_ops cyrix_mtrr_ops = {
.vendor = X86_VENDOR_CYRIX,
.init = cyrix_arr_init,
.init_secondary = cyrix_arr_init_secondary,
.set_all = cyrix_set_all,
.set = cyrix_set_arr,
.get = cyrix_get_arr,
.get_free_region = cyrix_get_free_region,
......
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/mtrr.h>
......@@ -6,6 +8,90 @@
#include <asm/cpufeature.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)
/* [SUMMARY] Get a free MTRR.
......@@ -55,23 +141,104 @@ void generic_get_mtrr(unsigned int reg, unsigned long *base,
*type = base_lo & 0xff;
}
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.
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.
*/
{
u32 cr0, cr4 = 0;
u32 deftype_lo, deftype_hi;
static spinlock_t set_atomicity_lock = SPIN_LOCK_UNLOCKED;
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;
}
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) */
if ( cpu_has_pge ) {
cr4 = read_cr4();
......@@ -90,18 +257,10 @@ void generic_set_mtrr(unsigned int reg, unsigned long base,
/* Disable MTRRs, and set the default type to uncached */
wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi);
}
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));
}
static void post_set(void)
{
/* Flush caches and TLBs */
wbinvd();
......@@ -114,7 +273,57 @@ void generic_set_mtrr(unsigned int reg, unsigned long base,
/* Restore value of CR4 */
if ( cpu_has_pge )
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)
......@@ -178,7 +387,7 @@ int positive_have_wrcomb(void)
*/
struct mtrr_ops generic_mtrr_ops = {
.use_intel_if = 1,
.init_secondary = generic_init_secondary,
.set_all = generic_set_all,
.get = generic_get_mtrr,
.get_free_region = generic_get_free_region,
.set = generic_set_mtrr,
......
......@@ -163,8 +163,11 @@ static void ipi_handler(void *info)
}
/* The master has cleared me to execute */
mtrr_if->set(data->smp_reg, data->smp_base,
data->smp_size, data->smp_type);
if (data->smp_reg != ~0UL)
mtrr_if->set(data->smp_reg, data->smp_base,
data->smp_size, data->smp_type);
else
mtrr_if->set_all();
atomic_dec(&data->count);
while(atomic_read(&data->gate)) {
......@@ -243,7 +246,15 @@ static void set_mtrr(unsigned int reg, unsigned long base,
atomic_set(&data.gate,1);
/* do our MTRR business */
mtrr_if->set(reg,base,size,type);
/* 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);
/* wait for the others */
while(atomic_read(&data.count)) {
......@@ -530,6 +541,20 @@ static void __init init_ifs(void)
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
*
......@@ -537,7 +562,7 @@ static void __init init_ifs(void)
* initialized (i.e. before smp_init()).
*
*/
int __init mtrr_init(void)
static int __init mtrr_init(void)
{
init_ifs();
......@@ -608,21 +633,15 @@ int __init mtrr_init(void)
break;
}
}
printk("mtrr: v%s\n",MTRR_VERSION);
if (mtrr_if) {
set_num_var_ranges();
if (use_intel()) {
/* Only for Intel MTRRs */
get_mtrr_state();
}
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;
}
//subsys_initcall(mtrr_init);
core_initcall(mtrr_init);
......@@ -38,9 +38,10 @@ struct mtrr_ops {
u32 vendor;
u32 use_intel_if;
void (*init)(void);
void (*init_secondary)(void);
void (*set)(unsigned int reg, unsigned long base,
unsigned long size, mtrr_type type);
void (*set_all)(void);
void (*get)(unsigned int reg, unsigned long *base,
unsigned long *size, mtrr_type * type);
int (*get_free_region) (unsigned long base, unsigned long size);
......
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/mtrr.h>
#include <asm/msr.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 */
void set_mtrr_prepare_save(struct set_mtrr_context *ctxt)
......@@ -246,93 +76,3 @@ void set_mtrr_done(struct set_mtrr_context *ctxt)
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 @@
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
#include <asm/mtrr.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/smpboot.h>
......@@ -403,12 +402,6 @@ void __init smp_callin(void)
local_irq_enable();
#ifdef CONFIG_MTRR
/*
* Must be done before calibration delay is computed
*/
mtrr_init_secondary_cpu ();
#endif
/*
* Get our bogomips.
*/
......
......@@ -292,16 +292,14 @@ struct controller {
struct pci_resource *io_head;
struct pci_resource *bus_head;
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_entry2;
struct event_info event_queue[10];
struct slot *slot;
u8 next_event;
u8 interrupt;
u8 bus;
u8 device;
u8 function;
u8 bus; /* bus number for the pci hotplug controller */
u8 rev;
u8 slot_device_offset;
u8 first_slot;
......@@ -695,7 +693,8 @@ static inline int cpq_get_latch_status (struct controller *ctrl, struct slot *sl
return 1;
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));
......@@ -733,7 +732,7 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl)
DECLARE_WAITQUEUE(wait, current);
int retval = 0;
dbg(__FUNCTION__" - start\n");
dbg("%s - start\n", __FUNCTION__);
add_wait_queue(&ctrl->queue, &wait);
set_current_state(TASK_INTERRUPTIBLE);
/* 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)
if (signal_pending(current))
retval = -EINTR;
dbg(__FUNCTION__" - end\n");
dbg("%s - end\n", __FUNCTION__);
return retval;
}
......
......@@ -314,7 +314,7 @@ static int ctrl_slot_setup (struct controller * ctrl, void *smbios_start, void *
void *slot_entry= NULL;
int result;
dbg(__FUNCTION__"\n");
dbg("%s\n", __FUNCTION__);
tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
......@@ -467,7 +467,7 @@ static int ctrl_slot_cleanup (struct controller * ctrl)
//
// 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;
u32 work;
......@@ -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;
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;
......@@ -490,7 +490,6 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl
return -1;
}
for (loop = 0; loop < len; ++loop) {
tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
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
if ((tbus == bus_num) && (tdevice == dev_num)) {
*slot = tslot;
if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
if (PCIIRQRoutingInfoLength != NULL)
kfree(PCIIRQRoutingInfoLength);
return 0;
} else {
// 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
// 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
// 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) {
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.
if (((work >> 8) & 0x000000FF) == (long) bus_num) {
bridgeSlot = tslot;
......@@ -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
// 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
......@@ -592,7 +592,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
if (slot == NULL)
return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl;
if (ctrl == NULL)
......@@ -627,7 +627,7 @@ static int process_SI (struct hotplug_slot *hotplug_slot)
if (slot == NULL)
return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl;
if (ctrl == NULL)
......@@ -667,7 +667,7 @@ static int process_SS (struct hotplug_slot *hotplug_slot)
if (slot == NULL)
return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl;
if (ctrl == NULL)
......@@ -695,7 +695,7 @@ static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
struct controller *ctrl;
dbg(__FUNCTION__"\n");
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
if (slot == NULL)
return -ENODEV;
......@@ -716,7 +716,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL)
return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl;
if (ctrl == NULL)
......@@ -734,7 +734,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL)
return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl;
if (ctrl == NULL)
......@@ -752,7 +752,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL)
return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl;
if (ctrl == NULL)
......@@ -770,8 +770,8 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL)
return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl;
if (ctrl == NULL)
......@@ -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
rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
if (rc) {
err(__FUNCTION__" : pci_read_config_word failed\n");
err("%s : pci_read_config_word failed\n", __FUNCTION__);
return rc;
}
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)
ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
if (!ctrl) {
err(__FUNCTION__" : out of memory\n");
err("%s : out of memory\n", __FUNCTION__);
return -ENOMEM;
}
memset(ctrl, 0, sizeof(struct controller));
rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
if (rc) {
err(__FUNCTION__" : pci_read_config_word failed\n");
err("%s : pci_read_config_word failed\n", __FUNCTION__);
goto err_free_ctrl;
}
......@@ -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");
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->device = PCI_SLOT(pdev->devfn);
ctrl->function = PCI_FUNC(pdev->devfn);
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_waitqueue_head(&ctrl->queue);
......@@ -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 */
rc = one_time_init();
if (rc) {
goto err_free_ctrl;
goto err_free_bus;
}
dbg("pdev = %p\n", pdev);
......@@ -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)) {
err("cannot reserve MMIO region\n");
rc = -ENOMEM;
goto err_free_ctrl;
goto err_free_bus;
}
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)
// in this case it will always be called for the "base"
// bus/dev/func of a slot.
// 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);
if (rc) {
err(msg_initialization_err, rc);
......@@ -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
rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
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;
}
......@@ -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);
if (rc) {
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;
}
......@@ -1188,6 +1196,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iounmap(ctrl->hpc_reg);
err_free_mem_region:
release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
err_free_bus:
kfree(ctrl->pci_bus);
err_free_ctrl:
kfree(ctrl);
return rc;
......@@ -1328,6 +1338,8 @@ static void unload_cpqphpd(void)
kfree(tres);
}
kfree (ctrl->pci_bus);
tctrl = ctrl;
ctrl = ctrl->next;
kfree(tctrl);
......
This diff is collapsed.
......@@ -161,7 +161,7 @@ static int check_for_compaq_ROM (void *rom_start)
(temp6 == 'Q')) {
result = 1;
}
dbg (__FUNCTION__" - returned %d\n", result);
dbg ("%s - returned %d\n", __FUNCTION__, result);
return result;
}
......@@ -286,12 +286,12 @@ static u32 store_HRT (void *rom_start)
return(rc);
// 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)
return(rc);
// 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)
return(rc);
......@@ -479,8 +479,9 @@ int compaq_nvram_load (void *rom_start, struct controller *ctrl)
device = p_ev_ctrl->device;
function = p_ev_ctrl->function;
while ((bus != ctrl->bus) || (device != ctrl->device)
|| (function != ctrl->function)) {
while ((bus != ctrl->bus) ||
(device != PCI_SLOT(ctrl->pci_dev->devfn)) ||
(function != PCI_FUNC(ctrl->pci_dev->devfn))) {
nummem = p_ev_ctrl->mem_avail;
numpmem = p_ev_ctrl->p_mem_avail;
numio = p_ev_ctrl->io_avail;
......
This diff is collapsed.
......@@ -53,8 +53,9 @@ static int read_ctrl (char *buf, char **start, off_t offset, int len, int *eof,
*eof = 1;
out += sprintf(out, "hot plug ctrl Info Page\n");
out += sprintf(out, "bus = %d, device = %d, function = %d\n",ctrl->bus,
ctrl->device, ctrl->function);
out += sprintf(out, "bus = %d, device = %d, function = %d\n",
ctrl->bus, PCI_SLOT(ctrl->pci_dev->devfn),
PCI_FUNC(ctrl->pci_dev->devfn));
out += sprintf(out, "Free resources: memory\n");
index = 11;
res = ctrl->mem_head;
......@@ -104,8 +105,9 @@ static int read_dev (char *buf, char **start, off_t offset, int len, int *eof, v
*eof = 1;
out += sprintf(out, "hot plug ctrl Info Page\n");
out += sprintf(out, "bus = %d, device = %d, function = %d\n",ctrl->bus,
ctrl->device, ctrl->function);
out += sprintf(out, "bus = %d, device = %d, function = %d\n",
ctrl->bus, PCI_SLOT(ctrl->pci_dev->devfn),
PCI_FUNC(ctrl->pci_dev->devfn));
slot=ctrl->slot;
......
......@@ -39,7 +39,8 @@ extern int ibmphp_debug;
#else
#define MY_NAME THIS_MODULE->name
#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 info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
......@@ -121,6 +122,7 @@ struct scal_detail {
u8 port1_port_connect;
u8 port2_node_connect;
u8 port2_port_connect;
u8 chassis_num;
// struct list_head scal_detail_list;
};
......@@ -139,9 +141,27 @@ struct rio_detail {
u8 port1_port_connect;
u8 first_slot_num;
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 *
......@@ -153,7 +173,6 @@ struct ebda_hpc_list {
short phys_addr;
// struct list_head ebda_hpc_list;
};
/*****************************************************************
* IN HPC DATA STRUCTURE, THE ASSOCIATED SLOT AND BUS *
* STRUCTURE *
......@@ -195,6 +214,9 @@ struct wpeg_i2c_ctlr_access {
u8 i2c_addr;
};
#define HPC_DEVICE_ID 0x0246
#define HPC_SUBSYSTEM_ID 0x0247
#define HPC_PCI_OFFSET 0x40
/*************************************************************************
* RSTC DESCRIPTOR NODE *
*************************************************************************/
......@@ -215,8 +237,9 @@ struct ebda_pci_rsrc {
u8 rsrc_type;
u8 bus_num;
u8 dev_fun;
ulong start_addr;
ulong end_addr;
u32 start_addr;
u32 end_addr;
u8 marked; /* for NVRAM */
struct list_head ebda_pci_rsrc_list;
};
......@@ -248,7 +271,7 @@ struct bus_info {
***********************************************************/
extern struct list_head ibmphp_ebda_pci_rsrc_head;
extern struct list_head ibmphp_slot_head;
extern struct list_head ibmphp_res_head;
/***********************************************************
* FUNCTION PROTOTYPES *
***********************************************************/
......@@ -263,6 +286,7 @@ extern void ibmphp_free_ebda_pci_rsrc_queue (void);
extern struct bus_info *ibmphp_find_same_bus_num (u32);
extern int ibmphp_get_bus_index (u8);
extern u16 ibmphp_get_total_controllers (void);
extern int ibmphp_register_pci (void);
/* passed parameters */
#define MEM 0
......@@ -669,7 +693,7 @@ extern void ibmphp_hpc_stop_poll_thread (void);
#define PCIX66 0x05
#define PCI66 0x04
extern struct pci_ops *ibmphp_pci_root_ops;
extern struct pci_bus *ibmphp_pci_bus;
/* Variables */
......@@ -713,6 +737,7 @@ struct slot {
struct controller {
struct ebda_hpc_slot *slots;
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 ending_slot_num;
u8 revision;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -141,20 +141,5 @@ extern int pci_visit_dev (struct pci_visit *fn,
struct pci_dev_wrapped *wrapped_dev,
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
......@@ -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
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_HOTPLUG) += hotplug.o
obj-$(CONFIG_PROC_FS) += proc.o
ifndef CONFIG_SPARC64
......
......@@ -7,8 +7,8 @@
#define TRUE (!FALSE)
#endif
static void
run_sbin_hotplug(struct pci_dev *pdev, int insert)
#ifdef CONFIG_HOTPLUG
static void run_sbin_hotplug(struct pci_dev *pdev, int insert)
{
int i;
char *argv[3], *envp[8];
......@@ -45,13 +45,18 @@ run_sbin_hotplug(struct pci_dev *pdev, int insert)
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
* @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
pci_insert_device(struct pci_dev *dev, struct pci_bus *bus)
......@@ -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
*
* Delete the device structure from the device lists and
* notify userspace (/sbin/hotplug).
* Delete the device structure from the device lists,
* remove the /proc entry, and notify userspace (/sbin/hotplug).
*/
void
pci_remove_device(struct pci_dev *dev)
......@@ -94,10 +99,11 @@ pci_remove_device(struct pci_dev *dev)
#ifdef CONFIG_PROC_FS
pci_proc_detach_device(dev);
#endif
/* notify userspace of hotplug device removal */
run_sbin_hotplug(dev, FALSE);
}
#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(pci_insert_device);
EXPORT_SYMBOL(pci_remove_device);
#endif
......@@ -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
* 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);
list_add_tail(&dev->bus_list, &bus->devices);
pci_insert_device (dev, bus);
/* Fix up broken headers */
pci_fixup_device(PCI_FIXUP_HEADER, dev);
......@@ -594,4 +594,5 @@ EXPORT_SYMBOL(pci_setup_device);
EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_do_scan_bus);
EXPORT_SYMBOL(pci_scan_slot);
EXPORT_SYMBOL(pci_scan_bus);
#endif
......@@ -18,6 +18,8 @@
#define PCI_CFG_SPACE_SIZE 256
static int proc_initialized; /* = 0 */
static loff_t
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)
struct proc_dir_entry *de, *e;
char name[16];
if (!proc_initialized)
return -EACCES;
if (!(de = bus->procdir)) {
sprintf(name, "%02x", bus->number);
de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
......@@ -446,6 +451,9 @@ int pci_proc_attach_bus(struct pci_bus* bus)
{
struct proc_dir_entry *de = bus->procdir;
if (!proc_initialized)
return -EACCES;
if (!de) {
char name[16];
sprintf(name, "%02x", bus->number);
......@@ -595,6 +603,7 @@ static int __init pci_proc_init(void)
entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
if (entry)
entry->proc_fops = &proc_bus_pci_dev_operations;
proc_initialized = 1;
pci_for_each_dev(dev) {
pci_proc_attach_device(dev);
}
......
......@@ -1020,6 +1020,16 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
if (status)
return status;
/* increment urb's reference count as part of giving it to the HCD
* (which now controls it). HCD guarantees that it either returns
* an error or calls giveback(), but not both.
*/
urb = usb_get_urb (urb);
if (urb->dev == hcd->self.root_hub) {
urb->transfer_flags |= URB_NO_DMA_MAP;
return rh_urb_enqueue (hcd, urb);
}
/* lower level hcd code should use *_dma exclusively */
if (!(urb->transfer_flags & URB_NO_DMA_MAP)) {
if (usb_pipecontrol (urb->pipe))
......@@ -1038,16 +1048,7 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
: PCI_DMA_TODEVICE);
}
/* increment urb's reference count as part of giving it to the HCD
* (which now controls it). HCD guarantees that it either returns
* an error or calls giveback(), but not both.
*/
urb = usb_get_urb (urb);
if (urb->dev == hcd->self.root_hub)
status = rh_urb_enqueue (hcd, urb);
else
status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);
return status;
return hcd->driver->urb_enqueue (hcd, urb, mem_flags);
}
/*-------------------------------------------------------------------------*/
......
......@@ -27,7 +27,6 @@
/*****************************************************************************/
#define __NO_VERSION__
#include <linux/config.h>
#include <linux/module.h>
#include <linux/fs.h>
......@@ -561,35 +560,57 @@ static void put_mount (struct vfsmount **mount)
static int create_special_files (void)
{
struct dentry *parent;
int retval;
int retval = 0;
/* create the devices special file */
retval = get_mount (&usbdevice_fs_type, &usbdevfs_mount);
if (retval)
return retval;
if (retval) {
err ("Unable to get usbdevfs mount");
goto exit;
}
retval = get_mount (&usb_fs_type, &usbfs_mount);
if (retval) {
put_mount (&usbfs_mount);
return retval;
err ("Unable to get usbfs mount");
goto error_clean_usbdevfs_mount;
}
parent = usbfs_mount->mnt_sb->s_root;
devices_usbfs_dentry = fs_create_file ("devices", listmode | S_IFREG, parent,
devices_usbfs_dentry = fs_create_file ("devices",
listmode | S_IFREG, parent,
NULL, &usbdevfs_devices_fops,
listuid, listgid);
if (devices_usbfs_dentry == NULL) {
err ("Unable to create devices usbfs file");
return -ENODEV;
retval = -ENODEV;
goto error_clean_mounts;
}
parent = usbdevfs_mount->mnt_sb->s_root;
devices_usbdevfs_dentry = fs_create_file ("devices", listmode | S_IFREG, parent,
devices_usbdevfs_dentry = fs_create_file ("devices",
listmode | S_IFREG, parent,
NULL, &usbdevfs_devices_fops,
listuid, listgid);
if (devices_usbdevfs_dentry == NULL) {
err ("Unable to create devices usbfs file");
return -ENODEV;
retval = -ENODEV;
goto error_remove_file;
}
return 0;
goto exit;
error_remove_file:
fs_remove_file (devices_usbfs_dentry);
devices_usbfs_dentry = NULL;
error_clean_mounts:
put_mount (&usbfs_mount);
error_clean_usbdevfs_mount:
put_mount (&usbdevfs_mount);
exit:
return retval;
}
static void remove_special_files (void)
......
This diff is collapsed.
This diff is collapsed.
......@@ -41,14 +41,17 @@ static int check_reset_complete (
/* if reset finished and it's still not enabled -- handoff */
if (!(port_status & PORT_PE)) {
dbg ("%s port %d full speed, give to companion, 0x%x",
ehci->hcd.self.bus_name, index + 1, port_status);
hcd_to_bus (&ehci->hcd)->bus_name,
index + 1, port_status);
// what happens if HCS_N_CC(params) == 0 ?
port_status |= PORT_OWNER;
writel (port_status, &ehci->regs->port_status [index]);
} else
dbg ("%s port %d high speed", ehci->hcd.self.bus_name, index + 1);
dbg ("%s port %d high speed",
hcd_to_bus (&ehci->hcd)->bus_name,
index + 1);
return port_status;
}
......@@ -310,11 +313,13 @@ static int ehci_hub_control (
if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT
&& PORT_USB11 (temp)) {
dbg ("%s port %d low speed, give to companion",
hcd->self.bus_name, wIndex + 1);
hcd_to_bus (&ehci->hcd)->bus_name,
wIndex + 1);
temp |= PORT_OWNER;
} else {
vdbg ("%s port %d reset",
hcd->self.bus_name, wIndex + 1);
hcd_to_bus (&ehci->hcd)->bus_name,
wIndex + 1);
temp |= PORT_RESET;
temp &= ~PORT_PE;
......
This diff is collapsed.
This diff is collapsed.
......@@ -69,6 +69,8 @@ struct ehci_hcd { /* one per controller */
struct pci_pool *qtd_pool; /* one or more per qh */
struct pci_pool *itd_pool; /* itd per iso urb */
struct pci_pool *sitd_pool; /* sitd per split iso urb */
struct timer_list watchdog;
};
/* unwrap an HCD pointer to get an EHCI_HCD pointer */
......@@ -389,4 +391,26 @@ struct ehci_fstn {
union ehci_shadow fstn_next; /* ptr to periodic q entry */
} __attribute__ ((aligned (32)));
/*-------------------------------------------------------------------------*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
#define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb)
#define STUB_DEBUG_FILES
#else /* LINUX_VERSION_CODE */
static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
{ return &hcd->self; }
#define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags)
#ifndef DEBUG
#define STUB_DEBUG_FILES
#endif /* DEBUG */
#endif /* LINUX_VERSION_CODE */
/*-------------------------------------------------------------------------*/
#endif /* __LINUX_EHCI_HCD_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -774,7 +774,7 @@ ioctl_scanner(struct inode *inode, struct file *file,
if (copy_from_user(&cmsg, (void *)arg, sizeof(cmsg)))
return -EFAULT;
nb = le16_to_cpup(&cmsg.req.wLength);
nb = cmsg.req.wLength;
if (nb > sizeof(buf))
return -EINVAL;
......@@ -789,8 +789,8 @@ ioctl_scanner(struct inode *inode, struct file *file,
ret = usb_control_msg(dev, pipe, cmsg.req.bRequest,
cmsg.req.bRequestType,
le16_to_cpup(&cmsg.req.wValue),
le16_to_cpup(&cmsg.req.wIndex),
cmsg.req.wValue,
cmsg.req.wIndex,
buf, nb, HZ);
if (ret < 0) {
......
This diff is collapsed.
......@@ -230,7 +230,6 @@ struct usb_se401 {
int nullpackets;
};
static inline void usb_se401_remove_disconnected (struct usb_se401 *se401);
#endif
......
......@@ -567,6 +567,8 @@ static void kaweth_usb_receive(struct urb *urb)
return;
}
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
skb->dev = net;
eth_copy_and_sum(skb, kaweth->rx_buf + 2, pkt_len, 0);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -102,6 +102,7 @@ struct us_unusual_dev {
#define US_FL_IGNORE_SER 0x00000010 /* Ignore the serial number given */
#define US_FL_SCM_MULT_TARG 0x00000020 /* supports multiple targets */
#define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs fixing */
#define US_FL_FIX_CAPACITY 0x00000080 /* READ CAPACITY response too big */
#define US_FL_DEV_ATTACHED 0x00010000 /* is the device attached? */
#define US_FLIDX_IP_WANTED 17 /* 0x00020000 is an IRQ expected? */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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