summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2002-09-11 15:53:48 +1000
committerAnton Blanchard <anton@samba.org>2002-09-11 15:53:48 +1000
commit98398ebac81a1beb9342bec4fc36d6b9185249c0 (patch)
treeb79be2e9a19a1e1a70e5e797040a9fd558c009ea
parent09b1ed32b4aefc85e11c1dbdd66569cf1276a59d (diff)
parented245b591594a32d5ca1ee7d1285fef1d51f14ba (diff)
Merge samba.org:/scratch/anton/linux-2.5
into samba.org:/scratch/anton/linux-2.5_bar
-rw-r--r--arch/i386/kernel/acpi.c10
-rw-r--r--arch/i386/kernel/cpu/mtrr/cyrix.c117
-rw-r--r--arch/i386/kernel/cpu/mtrr/generic.c263
-rw-r--r--arch/i386/kernel/cpu/mtrr/main.c47
-rw-r--r--arch/i386/kernel/cpu/mtrr/mtrr.h3
-rw-r--r--arch/i386/kernel/cpu/mtrr/state.c260
-rw-r--r--arch/i386/kernel/smpboot.c7
-rw-r--r--arch/i386/kernel/time.c13
-rw-r--r--drivers/acpi/Config.in145
-rw-r--r--drivers/acpi/ac.c2
-rw-r--r--drivers/acpi/acpi_ksyms.c2
-rw-r--r--drivers/acpi/battery.c4
-rw-r--r--drivers/acpi/bus.c6
-rw-r--r--drivers/acpi/button.c1
-rw-r--r--drivers/acpi/debugger/Makefile9
-rw-r--r--drivers/acpi/debugger/dbcmds.c1114
-rw-r--r--drivers/acpi/debugger/dbdisply.c859
-rw-r--r--drivers/acpi/debugger/dbexec.c405
-rw-r--r--drivers/acpi/debugger/dbfileio.c399
-rw-r--r--drivers/acpi/debugger/dbhistry.c189
-rw-r--r--drivers/acpi/debugger/dbinput.c892
-rw-r--r--drivers/acpi/debugger/dbstats.c459
-rw-r--r--drivers/acpi/debugger/dbutils.c380
-rw-r--r--drivers/acpi/debugger/dbxface.c388
-rw-r--r--drivers/acpi/include/acpiosxf.h20
-rw-r--r--drivers/acpi/kdb/README.txt36
-rw-r--r--drivers/acpi/kdb/kdbm_acpi.c54
-rw-r--r--drivers/acpi/osl.c53
-rw-r--r--drivers/acpi/pci_irq.c2
-rw-r--r--drivers/acpi/pci_link.c12
-rw-r--r--drivers/acpi/pci_root.c4
-rw-r--r--drivers/acpi/system.c2
-rw-r--r--drivers/acpi/toshiba_acpi.c129
-rw-r--r--drivers/cdrom/cdrom.c2
-rw-r--r--drivers/hotplug/cpqphp.h13
-rw-r--r--drivers/hotplug/cpqphp_core.c70
-rw-r--r--drivers/hotplug/cpqphp_ctrl.c181
-rw-r--r--drivers/hotplug/cpqphp_nvram.c11
-rw-r--r--drivers/hotplug/cpqphp_pci.c185
-rw-r--r--drivers/hotplug/cpqphp_proc.c10
-rw-r--r--drivers/hotplug/ibmphp.h39
-rw-r--r--drivers/hotplug/ibmphp_core.c276
-rw-r--r--drivers/hotplug/ibmphp_ebda.c636
-rw-r--r--drivers/hotplug/ibmphp_hpc.c260
-rw-r--r--drivers/hotplug/ibmphp_pci.c268
-rw-r--r--drivers/hotplug/ibmphp_res.c335
-rw-r--r--drivers/hotplug/pci_hotplug.h15
-rw-r--r--drivers/pci/Makefile4
-rw-r--r--drivers/pci/hotplug.c22
-rw-r--r--drivers/pci/probe.c7
-rw-r--r--drivers/pci/proc.c9
-rw-r--r--drivers/usb/core/hcd.c21
-rw-r--r--drivers/usb/core/inode.c43
-rw-r--r--drivers/usb/host/ehci-dbg.c141
-rw-r--r--drivers/usb/host/ehci-hcd.c101
-rw-r--r--drivers/usb/host/ehci-hub.c13
-rw-r--r--drivers/usb/host/ehci-q.c107
-rw-r--r--drivers/usb/host/ehci-sched.c32
-rw-r--r--drivers/usb/host/ehci.h24
-rw-r--r--drivers/usb/host/ohci-dbg.c256
-rw-r--r--drivers/usb/host/ohci-hcd.c79
-rw-r--r--drivers/usb/host/ohci-mem.c27
-rw-r--r--drivers/usb/host/ohci-q.c314
-rw-r--r--drivers/usb/host/ohci.h27
-rw-r--r--drivers/usb/host/uhci-hcd.c187
-rw-r--r--drivers/usb/host/uhci-hcd.h43
-rw-r--r--drivers/usb/image/scanner.c6
-rw-r--r--drivers/usb/media/se401.c128
-rw-r--r--drivers/usb/media/se401.h1
-rw-r--r--drivers/usb/net/kaweth.c2
-rw-r--r--drivers/usb/net/pegasus.h6
-rw-r--r--drivers/usb/net/usbnet.c5
-rw-r--r--drivers/usb/storage/protocol.c69
-rw-r--r--drivers/usb/storage/transport.c3
-rw-r--r--drivers/usb/storage/unusual_devs.h14
-rw-r--r--drivers/usb/storage/usb.c8
-rw-r--r--drivers/usb/storage/usb.h1
-rw-r--r--fs/udf/udfdecl.h2
-rw-r--r--fs/ufs/super.c2
-rw-r--r--include/asm-i386/mtrr.h7
-rw-r--r--include/linux/acpi.h4
-rw-r--r--include/linux/pci.h1
-rw-r--r--include/linux/time.h2
-rw-r--r--include/linux/timex.h25
-rw-r--r--init/main.c13
-rw-r--r--kernel/time.c16
-rw-r--r--kernel/timer.c26
87 files changed, 3180 insertions, 7205 deletions
diff --git a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c
index 78f89522b95a..e2d1ffb97f89 100644
--- a/arch/i386/kernel/acpi.c
+++ b/arch/i386/kernel/acpi.c
@@ -166,6 +166,7 @@ acpi_parse_lapic_addr_ovr (
return 0;
}
+#ifndef CONFIG_ACPI_HT_ONLY
static int __init
acpi_parse_lapic_nmi (
@@ -185,12 +186,16 @@ acpi_parse_lapic_nmi (
return 0;
}
+#endif /*CONFIG_ACPI_HT_ONLY*/
+
#endif /*CONFIG_X86_LOCAL_APIC*/
#ifdef CONFIG_X86_IO_APIC
int acpi_ioapic;
+#ifndef CONFIG_ACPI_HT_ONLY
+
static int __init
acpi_parse_ioapic (
acpi_table_entry_header *header)
@@ -251,6 +256,7 @@ acpi_parse_nmi_src (
return 0;
}
+#endif /*!CONFIG_ACPI_HT_ONLY*/
#endif /*CONFIG_X86_IO_APIC*/
@@ -361,18 +367,21 @@ acpi_boot_init (
return result;
}
+#ifndef CONFIG_ACPI_HT_ONLY
result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi);
if (result < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
/* TBD: Cleanup to allow fallback to MPS */
return result;
}
+#endif /*!CONFIG_ACPI_HT_ONLY*/
acpi_lapic = 1;
#endif /*CONFIG_X86_LOCAL_APIC*/
#ifdef CONFIG_X86_IO_APIC
+#ifndef CONFIG_ACPI_HT_ONLY
/*
* I/O APIC
@@ -410,6 +419,7 @@ acpi_boot_init (
acpi_ioapic = 1;
+#endif /*!CONFIG_ACPI_HT_ONLY*/
#endif /*CONFIG_X86_IO_APIC*/
#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/i386/kernel/cpu/mtrr/cyrix.c b/arch/i386/kernel/cpu/mtrr/cyrix.c
index ace423c0a83c..30e1d3aac5bc 100644
--- a/arch/i386/kernel/cpu/mtrr/cyrix.c
+++ b/arch/i386/kernel/cpu/mtrr/cyrix.c
@@ -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,
diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c
index e33831835119..eeefde58dcc1 100644
--- a/arch/i386/kernel/cpu/mtrr/generic.c
+++ b/arch/i386/kernel/cpu/mtrr/generic.c
@@ -1,3 +1,5 @@
+#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,
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c
index 8f0d8a3c8bd7..aa091d2c5db7 100644
--- a/arch/i386/kernel/cpu/mtrr/main.c
+++ b/arch/i386/kernel/cpu/mtrr/main.c
@@ -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);
diff --git a/arch/i386/kernel/cpu/mtrr/mtrr.h b/arch/i386/kernel/cpu/mtrr/mtrr.h
index 5c1aa8ab552e..363a5b14acdc 100644
--- a/arch/i386/kernel/cpu/mtrr/mtrr.h
+++ b/arch/i386/kernel/cpu/mtrr/mtrr.h
@@ -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);
diff --git a/arch/i386/kernel/cpu/mtrr/state.c b/arch/i386/kernel/cpu/mtrr/state.c
index a2eef500f7bc..3d32fbf35284 100644
--- a/arch/i386/kernel/cpu/mtrr/state.c
+++ b/arch/i386/kernel/cpu/mtrr/state.c
@@ -1,180 +1,10 @@
#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);
-
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 936ee9e5fbb2..dc115fbe7492 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -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.
*/
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index a32314075d1d..ae3e803a5368 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -115,7 +115,7 @@ static inline unsigned long do_fast_gettimeoffset(void)
return delay_at_last_interrupt + edx;
}
-#define TICK_SIZE tick
+#define TICK_SIZE (tick_nsec / 1000)
spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
EXPORT_SYMBOL(i8253_lock);
@@ -280,7 +280,7 @@ void do_gettimeofday(struct timeval *tv)
usec += lost * (1000000 / HZ);
}
sec = xtime.tv_sec;
- usec += xtime.tv_usec;
+ usec += (xtime.tv_nsec / 1000);
read_unlock_irqrestore(&xtime_lock, flags);
while (usec >= 1000000) {
@@ -309,7 +309,8 @@ void do_settimeofday(struct timeval *tv)
tv->tv_sec--;
}
- xtime = *tv;
+ xtime.tv_sec = tv->tv_sec;
+ xtime.tv_nsec = (tv->tv_usec * 1000);
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
@@ -437,8 +438,8 @@ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg
*/
if ((time_status & STA_UNSYNC) == 0 &&
xtime.tv_sec > last_rtc_update + 660 &&
- xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
- xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+ (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
+ (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
@@ -655,7 +656,7 @@ void __init time_init(void)
extern int x86_udelay_tsc;
xtime.tv_sec = get_cmos_time();
- xtime.tv_usec = 0;
+ xtime.tv_nsec = 0;
/*
* If we have APM enabled or the CPU clock speed is variable
diff --git a/drivers/acpi/Config.in b/drivers/acpi/Config.in
index 4017cca560b4..bc38750060c4 100644
--- a/drivers/acpi/Config.in
+++ b/drivers/acpi/Config.in
@@ -2,91 +2,78 @@
# ACPI Configuration
#
-if [ "$CONFIG_X86" = "y" ]; then
-
- mainmenu_option next_comment
- comment 'ACPI Support'
- bool 'ACPI Support' CONFIG_ACPI
- if [ "$CONFIG_ACPI" = "y" ]; then
- if [ "$CONFIG_X86_LOCAL_APIC" = "y" ]; then
- bool 'CPU Enumeration Only' CONFIG_ACPI_HT_ONLY
- fi
+mainmenu_option next_comment
+comment 'ACPI Support'
- if [ "$CONFIG_ACPI_HT_ONLY" = "y" ]; then
- define_bool CONFIG_ACPI_BOOT y
- else
- define_bool CONFIG_ACPI_BOOT y
- define_bool CONFIG_ACPI_BUS y
- define_bool CONFIG_ACPI_INTERPRETER y
- define_bool CONFIG_ACPI_EC y
- define_bool CONFIG_ACPI_POWER y
- if [ "$CONFIG_PCI" = "y" ]; then
- define_bool CONFIG_ACPI_PCI y
- fi
- define_bool CONFIG_ACPI_SLEEP $CONFIG_SOFTWARE_SUSPEND
- define_bool CONFIG_ACPI_SYSTEM y
- tristate ' AC Adapter' CONFIG_ACPI_AC
- tristate ' Battery' CONFIG_ACPI_BATTERY
- tristate ' Button' CONFIG_ACPI_BUTTON
- tristate ' Fan' CONFIG_ACPI_FAN
- tristate ' Processor' CONFIG_ACPI_PROCESSOR
- dep_tristate ' Thermal Zone' CONFIG_ACPI_THERMAL $CONFIG_ACPI_PROCESSOR
- if [ "$CONFIG_NUMA" = "y" ]; then
- dep_bool ' NUMA support' CONFIG_ACPI_NUMA $CONFIG_NUMA
+if [ "$CONFIG_X86" = "y" ]; then
+ bool 'ACPI Support' CONFIG_ACPI
+ if [ "$CONFIG_ACPI" = "y" ]; then
+ if [ "$CONFIG_X86_LOCAL_APIC" = "y" ]; then
+ bool 'CPU Enumeration Only' CONFIG_ACPI_HT_ONLY
fi
- tristate ' Toshiba Laptop Extras' CONFIG_ACPI_TOSHIBA
- bool ' Debug Statements' CONFIG_ACPI_DEBUG
- fi
- fi
- endmenu
+ define_bool CONFIG_ACPI_BOOT y
-fi
+ if [ "$CONFIG_ACPI_HT_ONLY" != "y" ]; then
+ tristate ' AC Adapter' CONFIG_ACPI_AC
+ tristate ' Battery' CONFIG_ACPI_BATTERY
+ tristate ' Button' CONFIG_ACPI_BUTTON
+ tristate ' Fan' CONFIG_ACPI_FAN
+ tristate ' Processor' CONFIG_ACPI_PROCESSOR
+ dep_tristate ' Thermal Zone' CONFIG_ACPI_THERMAL $CONFIG_ACPI_PROCESSOR
+ if [ "$CONFIG_NUMA" = "y" ]; then
+ dep_bool ' NUMA support' CONFIG_ACPI_NUMA $CONFIG_NUMA
+ fi
+ tristate ' Toshiba Laptop Extras' CONFIG_ACPI_TOSHIBA
+ bool ' Debug Statements' CONFIG_ACPI_DEBUG
+ define_bool CONFIG_ACPI_BOOT y
+ define_bool CONFIG_ACPI_BUS y
+ define_bool CONFIG_ACPI_INTERPRETER y
+ define_bool CONFIG_ACPI_EC y
+ define_bool CONFIG_ACPI_POWER y
+ define_bool CONFIG_ACPI_PCI $CONFIG_PCI
+ define_bool CONFIG_ACPI_SLEEP $CONFIG_SOFTWARE_SUSPEND
+ define_bool CONFIG_ACPI_SYSTEM y
+ fi
+ fi
+fi
if [ "$CONFIG_IA64" = "y" ]; then
+ if [ "$CONFIG_IA64_SGI_SN" = "y" ]; then
+ define_bool CONFIG_ACPI y
+ define_bool CONFIG_ACPI_EFI y
+ define_bool CONFIG_ACPI_BOOT y
+ define_bool CONFIG_ACPI_BUS n
+ define_bool CONFIG_ACPI_INTERPRETER n
+ define_bool CONFIG_ACPI_PCI n
+ define_bool CONFIG_ACPI_POWER n
+ define_bool CONFIG_ACPI_SYSTEM n
+ define_bool CONFIG_ACPI_BUTTON n
+ define_bool CONFIG_ACPI_FAN n
+ define_bool CONFIG_ACPI_PROCESSOR n
+ define_bool CONFIG_ACPI_THERMAL n
+ define_bool CONFIG_ACPI_NUMA y
+ fi
- if [ "$CONFIG_IA64_SGI_SN" = "y" ]; then
- mainmenu_option next_comment
- comment 'ACPI Support'
- define_bool CONFIG_ACPI y
- define_bool CONFIG_ACPI_EFI y
- define_bool CONFIG_ACPI_BOOT y
- define_bool CONFIG_ACPI_BUS n
- define_bool CONFIG_ACPI_INTERPRETER n
- define_bool CONFIG_ACPI_PCI n
- define_bool CONFIG_ACPI_POWER n
- define_bool CONFIG_ACPI_SYSTEM n
- define_bool CONFIG_ACPI_BUTTON n
- define_bool CONFIG_ACPI_FAN n
- define_bool CONFIG_ACPI_PROCESSOR n
- define_bool CONFIG_ACPI_THERMAL n
- define_bool CONFIG_ACPI_NUMA y
- endmenu
- fi
-
- if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
- mainmenu_option next_comment
- comment 'ACPI Support'
- if [ "$CONFIG_PCI" = "y" ]; then
- define_bool CONFIG_ACPI_PCI y
- fi
- define_bool CONFIG_ACPI y
- define_bool CONFIG_ACPI_EFI y
- define_bool CONFIG_ACPI_BOOT y
- define_bool CONFIG_ACPI_BUS y
- define_bool CONFIG_ACPI_INTERPRETER y
- define_bool CONFIG_ACPI_POWER y
- define_bool CONFIG_ACPI_SYSTEM y
- tristate ' Button' CONFIG_ACPI_BUTTON
- tristate ' Fan' CONFIG_ACPI_FAN
- tristate ' Processor' CONFIG_ACPI_PROCESSOR
- dep_tristate ' Thermal Zone' CONFIG_ACPI_THERMAL $CONFIG_ACPI_PROCESSOR
- if [ "$CONFIG_NUMA" = "y" ]; then
- dep_bool ' NUMA support' CONFIG_ACPI_NUMA $CONFIG_NUMA
- fi
- bool ' Debug Statements' CONFIG_ACPI_DEBUG
- endmenu
- fi
-
+ if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
+ tristate ' Button' CONFIG_ACPI_BUTTON
+ tristate ' Fan' CONFIG_ACPI_FAN
+ tristate ' Processor' CONFIG_ACPI_PROCESSOR
+ dep_tristate ' Thermal Zone' CONFIG_ACPI_THERMAL $CONFIG_ACPI_PROCESSOR
+ if [ "$CONFIG_NUMA" = "y" ]; then
+ dep_bool ' NUMA support' CONFIG_ACPI_NUMA $CONFIG_NUMA
+ fi
+ bool ' Debug Statements' CONFIG_ACPI_DEBUG
+ define_bool CONFIG_ACPI_PCI $CONFIG_PCI
+ define_bool CONFIG_ACPI y
+ define_bool CONFIG_ACPI_EFI y
+ define_bool CONFIG_ACPI_BOOT y
+ define_bool CONFIG_ACPI_BUS y
+ define_bool CONFIG_ACPI_INTERPRETER y
+ define_bool CONFIG_ACPI_POWER y
+ define_bool CONFIG_ACPI_SYSTEM y
+ fi
fi
+
+endmenu
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index c9faecf0e450..e4acfd8b1b35 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -51,7 +51,7 @@ static struct acpi_driver acpi_ac_driver = {
.class = ACPI_AC_CLASS,
.ids = ACPI_AC_HID,
.ops = {
- .add = acpi_ac_add,
+ .add = acpi_ac_add,
.remove = acpi_ac_remove,
},
};
diff --git a/drivers/acpi/acpi_ksyms.c b/drivers/acpi/acpi_ksyms.c
index 91e2ac7835cc..ea2a02fc5794 100644
--- a/drivers/acpi/acpi_ksyms.c
+++ b/drivers/acpi/acpi_ksyms.c
@@ -114,6 +114,7 @@ EXPORT_SYMBOL(acpi_evaluate_reference);
#ifdef CONFIG_ACPI_BUS
EXPORT_SYMBOL(acpi_fadt);
+EXPORT_SYMBOL(acpi_walk_namespace);
EXPORT_SYMBOL(acpi_root_dir);
EXPORT_SYMBOL(acpi_bus_get_device);
EXPORT_SYMBOL(acpi_bus_get_status);
@@ -127,4 +128,3 @@ EXPORT_SYMBOL(acpi_bus_scan);
EXPORT_SYMBOL(acpi_init);
#endif /*CONFIG_ACPI_BUS*/
-
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 6a096d8c1463..53aeed0c0dc5 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -162,7 +162,7 @@ acpi_battery_get_info (
}
end:
- kfree(buffer.pointer);
+ acpi_os_free(buffer.pointer);
if (!result)
(*bif) = (struct acpi_battery_info *) data.pointer;
@@ -223,7 +223,7 @@ acpi_battery_get_status (
}
end:
- kfree(buffer.pointer);
+ acpi_os_free(buffer.pointer);
if (!result)
(*bst) = (struct acpi_battery_status *) data.pointer;
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 7e37a2500026..e5f08346cd84 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -32,7 +32,9 @@
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/proc_fs.h>
+#ifdef CONFIG_X86
#include <asm/mpspec.h>
+#endif
#include "acpi_bus.h"
#include "acpi_drivers.h"
#include "include/acinterp.h" /* for acpi_ex_eisa_id_to_string() */
@@ -665,7 +667,7 @@ acpi_bus_generate_event (
if (!event_is_open)
return_VALUE(0);
- event = kmalloc(sizeof(struct acpi_bus_event), GFP_KERNEL);
+ event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
if (!event)
return_VALUE(-ENOMEM);
@@ -1967,11 +1969,13 @@ acpi_bus_init (void)
goto error1;
}
+#ifdef CONFIG_X86
/* Ensure the SCI is set to level-triggered, active-low */
if (acpi_ioapic)
mp_override_legacy_irq(acpi_fadt.sci_int, 3, 3, acpi_fadt.sci_int);
else
eisa_set_level_irq(acpi_fadt.sci_int);
+#endif
status = acpi_enable_subsystem(ACPI_FULL_INITIALIZATION);
if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index cdd6c926ea5c..594149498463 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -70,7 +70,6 @@ struct acpi_button {
static struct proc_dir_entry *acpi_button_dir = NULL;
-
static int
acpi_button_read_info (
char *page,
diff --git a/drivers/acpi/debugger/Makefile b/drivers/acpi/debugger/Makefile
deleted file mode 100644
index ec9debb42a26..000000000000
--- a/drivers/acpi/debugger/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Makefile for all Linux ACPI interpreter subdirectories
-#
-
-obj-$(CONFIG_ACPI_INTERPRETER) := $(patsubst %.c,%.o,$(wildcard *.c))
-
-EXTRA_CFLAGS += $(ACPI_CFLAGS)
-
-include $(TOPDIR)/Rules.make
diff --git a/drivers/acpi/debugger/dbcmds.c b/drivers/acpi/debugger/dbcmds.c
deleted file mode 100644
index 274a18d86787..000000000000
--- a/drivers/acpi/debugger/dbcmds.c
+++ /dev/null
@@ -1,1114 +0,0 @@
-/*******************************************************************************
- *
- * Module Name: dbcmds - debug commands and output routines
- * $Revision: 87 $
- *
- ******************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2002, R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "acpi.h"
-#include "acdispat.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acevents.h"
-#include "acdebug.h"
-#include "acresrc.h"
-#include "acdisasm.h"
-
-#ifdef ACPI_DEBUGGER
-
-#define _COMPONENT ACPI_CA_DEBUGGER
- ACPI_MODULE_NAME ("dbcmds")
-
-
-/*
- * Arguments for the Objects command
- * These object types map directly to the ACPI_TYPES
- */
-
-static ARGUMENT_INFO acpi_db_object_types [] =
-{ {"ANY"},
- {"NUMBERS"},
- {"STRINGS"},
- {"BUFFERS"},
- {"PACKAGES"},
- {"FIELDS"},
- {"DEVICES"},
- {"EVENTS"},
- {"METHODS"},
- {"MUTEXES"},
- {"REGIONS"},
- {"POWERRESOURCES"},
- {"PROCESSORS"},
- {"THERMALZONES"},
- {"BUFFERFIELDS"},
- {"DDBHANDLES"},
- {NULL} /* Must be null terminated */
-};
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_walk_for_references
- *
- * PARAMETERS: Callback from Walk_namespace
- *
- * RETURN: Status
- *
- * DESCRIPTION: Check if this namespace object refers to the target object
- * that is passed in as the context value.
- *
- * Note: Currently doesn't check subobjects within the Node's object
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_walk_for_references (
- acpi_handle obj_handle,
- u32 nesting_level,
- void *context,
- void **return_value)
-{
- acpi_operand_object *obj_desc = (acpi_operand_object *) context;
- acpi_namespace_node *node = (acpi_namespace_node *) obj_handle;
-
-
- /* Check for match against the namespace node itself */
-
- if (node == (void *) obj_desc) {
- acpi_os_printf ("Object is a Node [%4.4s]\n", node->name.ascii);
- }
-
- /* Check for match against the object attached to the node */
-
- if (acpi_ns_get_attached_object (node) == obj_desc) {
- acpi_os_printf ("Reference at Node->Object %p [%4.4s]\n", node, node->name.ascii);
- }
-
- return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_find_references
- *
- * PARAMETERS: Object_arg - String with hex value of the object
- *
- * RETURN: None
- *
- * DESCRIPTION: Search namespace for all references to the input object
- *
- ******************************************************************************/
-
-void
-acpi_db_find_references (
- NATIVE_CHAR *object_arg)
-{
- acpi_operand_object *obj_desc;
-
-
- /* Convert string to object pointer */
-
- obj_desc = ACPI_TO_POINTER (ACPI_STRTOUL (object_arg, NULL, 16));
-
- /* Search all nodes in namespace */
-
- (void) acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
- acpi_db_walk_for_references, (void *) obj_desc, NULL);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_locks
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Display information about internal mutexes.
- *
- ******************************************************************************/
-
-void
-acpi_db_display_locks (void)
-{
- u32 i;
-
-
- for (i = 0; i < MAX_MTX; i++) {
- acpi_os_printf ("%26s : %s\n", acpi_ut_get_mutex_name (i),
- acpi_gbl_acpi_mutex_info[i].owner_id == ACPI_MUTEX_NOT_ACQUIRED
- ? "Locked" : "Unlocked");
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_table_info
- *
- * PARAMETERS: Table_arg - String with name of table to be displayed
- *
- * RETURN: None
- *
- * DESCRIPTION: Display information about loaded tables. Current
- * implementation displays all loaded tables.
- *
- ******************************************************************************/
-
-void
-acpi_db_display_table_info (
- NATIVE_CHAR *table_arg)
-{
- u32 i;
-
-
- for (i = 0; i < NUM_ACPI_TABLES; i++) {
- if (acpi_gbl_acpi_tables[i].pointer) {
- acpi_os_printf ("%s at %p length %X\n", acpi_gbl_acpi_table_data[i].name,
- acpi_gbl_acpi_tables[i].pointer, acpi_gbl_acpi_tables[i].length);
- }
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_unload_acpi_table
- *
- * PARAMETERS: Table_arg - Name of the table to be unloaded
- * Instance_arg - Which instance of the table to unload (if
- * there are multiple tables of the same type)
- *
- * RETURN: Nonde
- *
- * DESCRIPTION: Unload an ACPI table.
- * Instance is not implemented
- *
- ******************************************************************************/
-
-void
-acpi_db_unload_acpi_table (
- NATIVE_CHAR *table_arg,
- NATIVE_CHAR *instance_arg)
-{
- u32 i;
- acpi_status status;
-
-
- /* Search all tables for the target type */
-
- for (i = 0; i < NUM_ACPI_TABLES; i++) {
- if (!ACPI_STRNCMP (table_arg, acpi_gbl_acpi_table_data[i].signature,
- acpi_gbl_acpi_table_data[i].sig_length)) {
- /* Found the table, unload it */
-
- status = acpi_unload_table (i);
- if (ACPI_SUCCESS (status)) {
- acpi_os_printf ("[%s] unloaded and uninstalled\n", table_arg);
- }
- else {
- acpi_os_printf ("%s, while unloading [%s]\n",
- acpi_format_exception (status), table_arg);
- }
-
- return;
- }
- }
-
- acpi_os_printf ("Unknown table type [%s]\n", table_arg);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_set_method_breakpoint
- *
- * PARAMETERS: Location - AML offset of breakpoint
- * Walk_state - Current walk info
- * Op - Current Op (from parse walk)
- *
- * RETURN: None
- *
- * DESCRIPTION: Set a breakpoint in a control method at the specified
- * AML offset
- *
- ******************************************************************************/
-
-void
-acpi_db_set_method_breakpoint (
- NATIVE_CHAR *location,
- acpi_walk_state *walk_state,
- acpi_parse_object *op)
-{
- u32 address;
-
-
- if (!op) {
- acpi_os_printf ("There is no method currently executing\n");
- return;
- }
-
- /* Get and verify the breakpoint address */
-
- address = ACPI_STRTOUL (location, NULL, 16);
- if (address <= op->common.aml_offset) {
- acpi_os_printf ("Breakpoint %X is beyond current address %X\n", address, op->common.aml_offset);
- }
-
- /* Save breakpoint in current walk */
-
- walk_state->user_breakpoint = address;
- acpi_os_printf ("Breakpoint set at AML offset %X\n", address);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_set_method_call_breakpoint
- *
- * PARAMETERS: Op - Current Op (from parse walk)
- *
- * RETURN: None
- *
- * DESCRIPTION: Set a breakpoint in a control method at the specified
- * AML offset
- *
- ******************************************************************************/
-
-void
-acpi_db_set_method_call_breakpoint (
- acpi_parse_object *op)
-{
-
-
- if (!op) {
- acpi_os_printf ("There is no method currently executing\n");
- return;
- }
-
-
- acpi_gbl_step_to_next_call = TRUE;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_disassemble_aml
- *
- * PARAMETERS: Statements - Number of statements to disassemble
- * Op - Current Op (from parse walk)
- *
- * RETURN: None
- *
- * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
- * of statements specified.
- *
- ******************************************************************************/
-
-void
-acpi_db_disassemble_aml (
- NATIVE_CHAR *statements,
- acpi_parse_object *op)
-{
- u32 num_statements = 8;
-
-
- if (!op) {
- acpi_os_printf ("There is no method currently executing\n");
- return;
- }
-
- if (statements) {
- num_statements = ACPI_STRTOUL (statements, NULL, 0);
- }
-
- acpi_dm_disassemble (NULL, op, num_statements);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_dump_namespace
- *
- * PARAMETERS: Start_arg - Node to begin namespace dump
- * Depth_arg - Maximum tree depth to be dumped
- *
- * RETURN: None
- *
- * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
- * with type and other information.
- *
- ******************************************************************************/
-
-void
-acpi_db_dump_namespace (
- NATIVE_CHAR *start_arg,
- NATIVE_CHAR *depth_arg)
-{
- acpi_handle subtree_entry = acpi_gbl_root_node;
- u32 max_depth = ACPI_UINT32_MAX;
-
-
- /* No argument given, just start at the root and dump entire namespace */
-
- if (start_arg) {
- /* Check if numeric argument, must be a Node */
-
- if ((start_arg[0] >= 0x30) && (start_arg[0] <= 0x39)) {
- subtree_entry = ACPI_TO_POINTER (ACPI_STRTOUL (start_arg, NULL, 16));
- if (!acpi_os_readable (subtree_entry, sizeof (acpi_namespace_node))) {
- acpi_os_printf ("Address %p is invalid in this address space\n", subtree_entry);
- return;
- }
-
- if (ACPI_GET_DESCRIPTOR_TYPE (subtree_entry) != ACPI_DESC_TYPE_NAMED) {
- acpi_os_printf ("Address %p is not a valid Named object\n", subtree_entry);
- return;
- }
- }
-
- /* Alpha argument */
-
- else {
- /* The parameter is a name string that must be resolved to a Named obj*/
-
- subtree_entry = acpi_db_local_ns_lookup (start_arg);
- if (!subtree_entry) {
- subtree_entry = acpi_gbl_root_node;
- }
- }
-
- /* Now we can check for the depth argument */
-
- if (depth_arg) {
- max_depth = ACPI_STRTOUL (depth_arg, NULL, 0);
- }
- }
-
- acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT);
- acpi_os_printf ("ACPI Namespace (from %p subtree):\n", subtree_entry);
-
- /* Display the subtree */
-
- acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT);
- acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth, ACPI_UINT32_MAX, subtree_entry);
- acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_dump_namespace_by_owner
- *
- * PARAMETERS: Owner_arg - Owner ID whose nodes will be displayed
- * Depth_arg - Maximum tree depth to be dumped
- *
- * RETURN: None
- *
- * DESCRIPTION: Dump elements of the namespace that are owned by the Owner_id.
- *
- ******************************************************************************/
-
-void
-acpi_db_dump_namespace_by_owner (
- NATIVE_CHAR *owner_arg,
- NATIVE_CHAR *depth_arg)
-{
- acpi_handle subtree_entry = acpi_gbl_root_node;
- u32 max_depth = ACPI_UINT32_MAX;
- u16 owner_id;
-
-
- owner_id = (u16) ACPI_STRTOUL (owner_arg, NULL, 0);
-
- /* Now we can check for the depth argument */
-
- if (depth_arg) {
- max_depth = ACPI_STRTOUL (depth_arg, NULL, 0);
- }
-
- acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT);
- acpi_os_printf ("ACPI Namespace by owner %X:\n", owner_id);
-
- /* Display the subtree */
-
- acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT);
- acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth, owner_id, subtree_entry);
- acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_send_notify
- *
- * PARAMETERS: Name - Name of ACPI object to send the notify to
- * Value - Value of the notify to send.
- *
- * RETURN: None
- *
- * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
- * named object as an ACPI notify.
- *
- ******************************************************************************/
-
-void
-acpi_db_send_notify (
- NATIVE_CHAR *name,
- u32 value)
-{
- acpi_namespace_node *node;
- acpi_status status;
-
-
- /* Translate name to an Named object */
-
- node = acpi_db_local_ns_lookup (name);
- if (!node) {
- return;
- }
-
- /* Decode Named object type */
-
- switch (node->type) {
- case ACPI_TYPE_DEVICE:
- case ACPI_TYPE_THERMAL:
-
- /* Send the notify */
-
- status = acpi_ev_queue_notify_request (node, value);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could not queue notify\n");
- }
- break;
-
- default:
- acpi_os_printf ("Named object is not a device or a thermal object\n");
- break;
- }
-
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_set_method_data
- *
- * PARAMETERS: Type_arg - L for local, A for argument
- * Index_arg - which one
- * Value_arg - Value to set.
- *
- * RETURN: None
- *
- * DESCRIPTION: Set a local or argument for the running control method.
- * NOTE: only object supported is Number.
- *
- ******************************************************************************/
-
-void
-acpi_db_set_method_data (
- NATIVE_CHAR *type_arg,
- NATIVE_CHAR *index_arg,
- NATIVE_CHAR *value_arg)
-{
- NATIVE_CHAR type;
- u32 index;
- u32 value;
- acpi_walk_state *walk_state;
- acpi_operand_object *obj_desc;
- acpi_status status;
-
-
- /* Validate Type_arg */
-
- ACPI_STRUPR (type_arg);
- type = type_arg[0];
- if ((type != 'L') &&
- (type != 'A')) {
- acpi_os_printf ("Invalid SET operand: %s\n", type_arg);
- return;
- }
-
- /* Get the index and value */
-
- index = ACPI_STRTOUL (index_arg, NULL, 16);
- value = ACPI_STRTOUL (value_arg, NULL, 16);
-
- walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
- if (!walk_state) {
- acpi_os_printf ("There is no method currently executing\n");
- return;
- }
-
-
- /* Create and initialize the new object */
-
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
- if (!obj_desc) {
- acpi_os_printf ("Could not create an internal object\n");
- return;
- }
-
- obj_desc->integer.value = value;
-
-
- /* Store the new object into the target */
-
- switch (type) {
- case 'A':
-
- /* Set a method argument */
-
- if (index > MTH_MAX_ARG) {
- acpi_os_printf ("Arg%d - Invalid argument name\n", index);
- return;
- }
-
- status = acpi_ds_store_object_to_local (AML_ARG_OP, index, obj_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- return;
- }
-
- obj_desc = walk_state->arguments[index].object;
-
- acpi_os_printf ("Arg%d: ", index);
- acpi_db_display_internal_object (obj_desc, walk_state);
- break;
-
- case 'L':
-
- /* Set a method local */
-
- if (index > MTH_MAX_LOCAL) {
- acpi_os_printf ("Local%d - Invalid local variable name\n", index);
- return;
- }
-
- status = acpi_ds_store_object_to_local (AML_LOCAL_OP, index, obj_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- return;
- }
-
- obj_desc = walk_state->local_variables[index].object;
-
- acpi_os_printf ("Local%d: ", index);
- acpi_db_display_internal_object (obj_desc, walk_state);
- break;
-
- default:
- break;
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_walk_for_specific_objects
- *
- * PARAMETERS: Callback from Walk_namespace
- *
- * RETURN: Status
- *
- * DESCRIPTION: Display short info about objects in the namespace
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_walk_for_specific_objects (
- acpi_handle obj_handle,
- u32 nesting_level,
- void *context,
- void **return_value)
-{
- acpi_operand_object *obj_desc;
- acpi_status status;
- acpi_buffer buffer;
-
-
- obj_desc = acpi_ns_get_attached_object ((acpi_namespace_node *) obj_handle);
-
- /* Get and display the full pathname to this object */
-
- buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
- status = acpi_ns_handle_to_pathname (obj_handle, &buffer);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could Not get pathname for object %p\n", obj_handle);
- return (AE_OK);
- }
-
- acpi_os_printf ("%32s", buffer.pointer);
- ACPI_MEM_FREE (buffer.pointer);
-
-
- /* Display short information about the object */
-
- if (obj_desc) {
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
- case ACPI_TYPE_METHOD:
- acpi_os_printf (" #Args %d Concurrency %X", obj_desc->method.param_count, obj_desc->method.concurrency);
- break;
-
- case ACPI_TYPE_INTEGER:
- acpi_os_printf (" Value %X", obj_desc->integer.value);
- break;
-
- case ACPI_TYPE_STRING:
- acpi_os_printf (" \"%s\"", obj_desc->string.pointer);
- break;
-
- case ACPI_TYPE_REGION:
- acpi_os_printf (" Space_id %X Address %X Length %X", obj_desc->region.space_id, obj_desc->region.address, obj_desc->region.length);
- break;
-
- case ACPI_TYPE_PACKAGE:
- acpi_os_printf (" #Elements %X", obj_desc->package.count);
- break;
-
- case ACPI_TYPE_BUFFER:
- acpi_os_printf (" Length %X", obj_desc->buffer.length);
- break;
-
- default:
- /* Ignore other object types */
- break;
- }
- }
-
- acpi_os_printf ("\n");
- return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_objects
- *
- * PARAMETERS: Obj_type_arg - Type of object to display
- * Display_count_arg - Max depth to display
- *
- * RETURN: None
- *
- * DESCRIPTION: Display objects in the namespace of the requested type
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_display_objects (
- NATIVE_CHAR *obj_type_arg,
- NATIVE_CHAR *display_count_arg)
-{
- acpi_object_type type;
-
-
- /* Get the object type */
-
- type = acpi_db_match_argument (obj_type_arg, acpi_db_object_types);
- if (type == ACPI_TYPE_NOT_FOUND) {
- acpi_os_printf ("Invalid or unsupported argument\n");
- return (AE_OK);
- }
-
- acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT);
- acpi_os_printf ("Objects of type [%s] defined in the current ACPI Namespace: \n",
- acpi_ut_get_type_name (type));
-
- acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT);
-
- /* Walk the namespace from the root */
-
- (void) acpi_walk_namespace (type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
- acpi_db_walk_for_specific_objects, (void *) &type, NULL);
-
- acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
- return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_walk_and_match_name
- *
- * PARAMETERS: Callback from Walk_namespace
- *
- * RETURN: Status
- *
- * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
- * are supported -- '?' matches any character.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_walk_and_match_name (
- acpi_handle obj_handle,
- u32 nesting_level,
- void *context,
- void **return_value)
-{
- acpi_status status;
- NATIVE_CHAR *requested_name = (NATIVE_CHAR *) context;
- u32 i;
- acpi_buffer buffer;
-
-
- /* Check for a name match */
-
- for (i = 0; i < 4; i++) {
- /* Wildcard support */
-
- if ((requested_name[i] != '?') &&
- (requested_name[i] != ((acpi_namespace_node *) obj_handle)->name.ascii[i])) {
- /* No match, just exit */
-
- return (AE_OK);
- }
- }
-
-
- /* Get the full pathname to this object */
-
- buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
- status = acpi_ns_handle_to_pathname (obj_handle, &buffer);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could Not get pathname for object %p\n", obj_handle);
- }
- else {
- acpi_os_printf ("%32s (%p) - %s\n", buffer.pointer, obj_handle,
- acpi_ut_get_type_name (((acpi_namespace_node *) obj_handle)->type));
- ACPI_MEM_FREE (buffer.pointer);
- }
-
- return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_find_name_in_namespace
- *
- * PARAMETERS: Name_arg - The 4-character ACPI name to find.
- * wildcards are supported.
- *
- * RETURN: None
- *
- * DESCRIPTION: Search the namespace for a given name (with wildcards)
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_find_name_in_namespace (
- NATIVE_CHAR *name_arg)
-{
-
- if (ACPI_STRLEN (name_arg) > 4) {
- acpi_os_printf ("Name must be no longer than 4 characters\n");
- return (AE_OK);
- }
-
- /* Walk the namespace from the root */
-
- (void) acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
- acpi_db_walk_and_match_name, name_arg, NULL);
-
- acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
- return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_set_scope
- *
- * PARAMETERS: Name - New scope path
- *
- * RETURN: Status
- *
- * DESCRIPTION: Set the "current scope" as maintained by this utility.
- * The scope is used as a prefix to ACPI paths.
- *
- ******************************************************************************/
-
-void
-acpi_db_set_scope (
- NATIVE_CHAR *name)
-{
- acpi_status status;
- acpi_namespace_node *node;
-
-
- if (!name || name[0] == 0) {
- acpi_os_printf ("Current scope: %s\n", acpi_gbl_db_scope_buf);
- return;
- }
-
- acpi_db_prep_namestring (name);
-
-
- if (name[0] == '\\') {
- /* Validate new scope from the root */
-
- status = acpi_ns_get_node_by_path (name, acpi_gbl_root_node, ACPI_NS_NO_UPSEARCH, &node);
- if (ACPI_FAILURE (status)) {
- goto error_exit;
- }
-
- ACPI_STRCPY (acpi_gbl_db_scope_buf, name);
- ACPI_STRCAT (acpi_gbl_db_scope_buf, "\\");
- }
- else {
- /* Validate new scope relative to old scope */
-
- status = acpi_ns_get_node_by_path (name, acpi_gbl_db_scope_node, ACPI_NS_NO_UPSEARCH, &node);
- if (ACPI_FAILURE (status)) {
- goto error_exit;
- }
-
- ACPI_STRCAT (acpi_gbl_db_scope_buf, name);
- ACPI_STRCAT (acpi_gbl_db_scope_buf, "\\");
- }
-
- acpi_gbl_db_scope_node = node;
- acpi_os_printf ("New scope: %s\n", acpi_gbl_db_scope_buf);
- return;
-
-
-error_exit:
-
- acpi_os_printf ("Could not attach scope: %s, %s\n", name, acpi_format_exception (status));
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_resources
- *
- * PARAMETERS: Object_arg - String with hex value of the object
- *
- * RETURN: None
- *
- * DESCRIPTION:
- *
- ******************************************************************************/
-
-void
-acpi_db_display_resources (
- NATIVE_CHAR *object_arg)
-{
-#if ACPI_MACHINE_WIDTH != 16
-
- acpi_operand_object *obj_desc;
- acpi_status status;
- acpi_buffer return_obj;
-
-
- acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT);
- acpi_dbg_level |= ACPI_LV_RESOURCES;
-
- /* Convert string to object pointer */
-
- obj_desc = ACPI_TO_POINTER (ACPI_STRTOUL (object_arg, NULL, 16));
-
- /* Prepare for a return object of arbitrary size */
-
- return_obj.pointer = acpi_gbl_db_buffer;
- return_obj.length = ACPI_DEBUG_BUFFER_SIZE;
-
- /* _PRT */
-
- acpi_os_printf ("Evaluating _PRT\n");
-
- status = acpi_evaluate_object (obj_desc, "_PRT", NULL, &return_obj);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could not obtain _PRT: %s\n", acpi_format_exception (status));
- goto get_crs;
- }
-
- return_obj.pointer = acpi_gbl_db_buffer;
- return_obj.length = ACPI_DEBUG_BUFFER_SIZE;
-
- status = acpi_get_irq_routing_table (obj_desc, &return_obj);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Get_irq_routing_table failed: %s\n", acpi_format_exception (status));
- }
-
- else {
- acpi_rs_dump_irq_list ((u8 *) acpi_gbl_db_buffer);
- }
-
-
- /* _CRS */
-
-get_crs:
- acpi_os_printf ("Evaluating _CRS\n");
-
- return_obj.pointer = acpi_gbl_db_buffer;
- return_obj.length = ACPI_DEBUG_BUFFER_SIZE;
-
- status = acpi_evaluate_object (obj_desc, "_CRS", NULL, &return_obj);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could not obtain _CRS: %s\n", acpi_format_exception (status));
- goto get_prs;
- }
-
- return_obj.pointer = acpi_gbl_db_buffer;
- return_obj.length = ACPI_DEBUG_BUFFER_SIZE;
-
- status = acpi_get_current_resources (obj_desc, &return_obj);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Acpi_get_current_resources failed: %s\n", acpi_format_exception (status));
- goto get_prs;
- }
-
- else {
- acpi_rs_dump_resource_list (ACPI_CAST_PTR (acpi_resource, acpi_gbl_db_buffer));
- }
-
- status = acpi_set_current_resources (obj_desc, &return_obj);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Acpi_set_current_resources failed: %s\n", acpi_format_exception (status));
- goto get_prs;
- }
-
-
- /* _PRS */
-
-get_prs:
- acpi_os_printf ("Evaluating _PRS\n");
-
- return_obj.pointer = acpi_gbl_db_buffer;
- return_obj.length = ACPI_DEBUG_BUFFER_SIZE;
-
- status = acpi_evaluate_object (obj_desc, "_PRS", NULL, &return_obj);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could not obtain _PRS: %s\n", acpi_format_exception (status));
- goto cleanup;
- }
-
- return_obj.pointer = acpi_gbl_db_buffer;
- return_obj.length = ACPI_DEBUG_BUFFER_SIZE;
-
- status = acpi_get_possible_resources (obj_desc, &return_obj);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Acpi_get_possible_resources failed: %s\n", acpi_format_exception (status));
- }
-
- else {
- acpi_rs_dump_resource_list (ACPI_CAST_PTR (acpi_resource, acpi_gbl_db_buffer));
- }
-
-
-cleanup:
-
- acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
- return;
-#endif
-
-}
-
-
-typedef struct
-{
- u32 nodes;
- u32 objects;
-} ACPI_INTEGRITY_INFO;
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_integrity_walk
- *
- * PARAMETERS: Callback from Walk_namespace
- *
- * RETURN: Status
- *
- * DESCRIPTION: Examine one NS node for valid values.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_integrity_walk (
- acpi_handle obj_handle,
- u32 nesting_level,
- void *context,
- void **return_value)
-{
- ACPI_INTEGRITY_INFO *info = (ACPI_INTEGRITY_INFO *) context;
- acpi_namespace_node *node = (acpi_namespace_node *) obj_handle;
- acpi_operand_object *object;
-
-
- info->nodes++;
- if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
- acpi_os_printf ("Invalid Descriptor Type for Node %p, Type = %X\n",
- node, ACPI_GET_DESCRIPTOR_TYPE (node));
- }
-
- if (node->type > INTERNAL_TYPE_MAX) {
- acpi_os_printf ("Invalid Object Type for Node %p, Type = %X\n",
- node, node->type);
- }
-
- if (!acpi_ut_valid_acpi_name (node->name.integer)) {
- acpi_os_printf ("Invalid Acpi_name for Node %p\n", node);
- }
-
- object = acpi_ns_get_attached_object (node);
- if (object) {
- info->objects++;
- if (ACPI_GET_DESCRIPTOR_TYPE (object) != ACPI_DESC_TYPE_OPERAND) {
- acpi_os_printf ("Invalid Descriptor Type for Object %p, Type = %X\n",
- object, ACPI_GET_DESCRIPTOR_TYPE (object));
- }
- }
-
-
- return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_check_integrity
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Check entire namespace for data structure integrity
- *
- ******************************************************************************/
-
-void
-acpi_db_check_integrity (void)
-{
- ACPI_INTEGRITY_INFO info = {0,0};
-
- /* Search all nodes in namespace */
-
- (void) acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
- acpi_db_integrity_walk, (void *) &info, NULL);
-
- acpi_os_printf ("Verified %d namespace nodes with %d Objects\n", info.nodes, info.objects);
-
-}
-
-#endif /* ACPI_DEBUGGER */
diff --git a/drivers/acpi/debugger/dbdisply.c b/drivers/acpi/debugger/dbdisply.c
deleted file mode 100644
index 61c55d28a531..000000000000
--- a/drivers/acpi/debugger/dbdisply.c
+++ /dev/null
@@ -1,859 +0,0 @@
-/*******************************************************************************
- *
- * Module Name: dbdisply - debug display commands
- * $Revision: 78 $
- *
- ******************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2002, R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "acpi.h"
-#include "amlcode.h"
-#include "acdispat.h"
-#include "acnamesp.h"
-#include "acparser.h"
-#include "acinterp.h"
-#include "acdebug.h"
-
-
-#ifdef ACPI_DEBUGGER
-
-
-#define _COMPONENT ACPI_CA_DEBUGGER
- ACPI_MODULE_NAME ("dbdisply")
-
-
-/******************************************************************************
- *
- * FUNCTION: Acpi_db_get_pointer
- *
- * PARAMETERS: Target - Pointer to string to be converted
- *
- * RETURN: Converted pointer
- *
- * DESCRIPTION: Convert an ascii pointer value to a real value
- *
- *****************************************************************************/
-
-void *
-acpi_db_get_pointer (
- void *target)
-{
- void *obj_ptr;
-
-
-#if ACPI_MACHINE_WIDTH == 16
-#include <stdio.h>
-
- /* Have to handle 16-bit pointers of the form segment:offset */
-
- if (!sscanf (target, "%p", &obj_ptr)) {
- acpi_os_printf ("Invalid pointer: %s\n", target);
- return (NULL);
- }
-
-#else
-
- /* Simple flat pointer */
-
- obj_ptr = ACPI_TO_POINTER (ACPI_STRTOUL (target, NULL, 16));
-#endif
-
- return (obj_ptr);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_dump_parser_descriptor
- *
- * PARAMETERS: Op - A parser Op descriptor
- *
- * RETURN: None
- *
- * DESCRIPTION: Display a formatted parser object
- *
- ******************************************************************************/
-
-void
-acpi_db_dump_parser_descriptor (
- acpi_parse_object *op)
-{
- const acpi_opcode_info *info;
-
-
- info = acpi_ps_get_opcode_info (op->common.aml_opcode);
-
- acpi_os_printf ("Parser Op Descriptor:\n");
- acpi_os_printf ("%20.20s : %4.4X\n", "Opcode", op->common.aml_opcode);
-
- ACPI_DEBUG_ONLY_MEMBERS (acpi_os_printf ("%20.20s : %s\n", "Opcode Name", info->name));
-
- acpi_os_printf ("%20.20s : %p\n", "Value/Arg_list", op->common.value.arg);
- acpi_os_printf ("%20.20s : %p\n", "Parent", op->common.parent);
- acpi_os_printf ("%20.20s : %p\n", "Next_op", op->common.next);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_decode_and_display_object
- *
- * PARAMETERS: Target - String with object to be displayed. Names
- * and hex pointers are supported.
- * Output_type - Byte, Word, Dword, or Qword (B|W|D|Q)
- *
- * RETURN: None
- *
- * DESCRIPTION: Display a formatted ACPI object
- *
- ******************************************************************************/
-
-void
-acpi_db_decode_and_display_object (
- NATIVE_CHAR *target,
- NATIVE_CHAR *output_type)
-{
- void *obj_ptr;
- acpi_namespace_node *node;
- acpi_operand_object *obj_desc;
- u32 display = DB_BYTE_DISPLAY;
- NATIVE_CHAR buffer[80];
- acpi_buffer ret_buf;
- acpi_status status;
- u32 size;
-
-
- if (!target) {
- return;
- }
-
- /* Decode the output type */
-
- if (output_type) {
- ACPI_STRUPR (output_type);
- if (output_type[0] == 'W') {
- display = DB_WORD_DISPLAY;
- }
- else if (output_type[0] == 'D') {
- display = DB_DWORD_DISPLAY;
- }
- else if (output_type[0] == 'Q') {
- display = DB_QWORD_DISPLAY;
- }
- }
-
- ret_buf.length = sizeof (buffer);
- ret_buf.pointer = buffer;
-
- /* Differentiate between a number and a name */
-
- if ((target[0] >= 0x30) && (target[0] <= 0x39)) {
- obj_ptr = acpi_db_get_pointer (target);
- if (!acpi_os_readable (obj_ptr, 16)) {
- acpi_os_printf ("Address %p is invalid in this address space\n", obj_ptr);
- return;
- }
-
- /* Decode the object type */
-
- switch (ACPI_GET_DESCRIPTOR_TYPE (obj_ptr)) {
- case ACPI_DESC_TYPE_NAMED:
-
- /* This is a namespace Node */
-
- if (!acpi_os_readable (obj_ptr, sizeof (acpi_namespace_node))) {
- acpi_os_printf ("Cannot read entire Named object at address %p\n", obj_ptr);
- return;
- }
-
- node = obj_ptr;
- goto dump_nte;
-
-
- case ACPI_DESC_TYPE_OPERAND:
-
- /* This is a ACPI OPERAND OBJECT */
-
- if (!acpi_os_readable (obj_ptr, sizeof (acpi_operand_object))) {
- acpi_os_printf ("Cannot read entire ACPI object at address %p\n", obj_ptr);
- return;
- }
-
- acpi_ut_dump_buffer (obj_ptr, sizeof (acpi_operand_object), display, ACPI_UINT32_MAX);
- acpi_ex_dump_object_descriptor (obj_ptr, 1);
- break;
-
-
- case ACPI_DESC_TYPE_PARSER:
-
- /* This is a Parser Op object */
-
- if (!acpi_os_readable (obj_ptr, sizeof (acpi_parse_object))) {
- acpi_os_printf ("Cannot read entire Parser object at address %p\n", obj_ptr);
- return;
- }
-
- acpi_ut_dump_buffer (obj_ptr, sizeof (acpi_parse_object), display, ACPI_UINT32_MAX);
- acpi_db_dump_parser_descriptor ((acpi_parse_object *) obj_ptr);
- break;
-
-
- default:
-
- /* Is not a recognizeable object */
-
- size = 16;
- if (acpi_os_readable (obj_ptr, 64)) {
- size = 64;
- }
-
- /* Just dump some memory */
-
- acpi_ut_dump_buffer (obj_ptr, size, display, ACPI_UINT32_MAX);
- break;
- }
-
- return;
- }
-
- /* The parameter is a name string that must be resolved to a Named obj */
-
- node = acpi_db_local_ns_lookup (target);
- if (!node) {
- return;
- }
-
-
-dump_nte:
- /* Now dump the Named obj */
-
- status = acpi_get_name (node, ACPI_FULL_PATHNAME, &ret_buf);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could not convert name to pathname\n");
- }
-
- else {
- acpi_os_printf ("Object (%p) Pathname: %s\n", node, ret_buf.pointer);
- }
-
- if (!acpi_os_readable (node, sizeof (acpi_namespace_node))) {
- acpi_os_printf ("Invalid Named object at address %p\n", node);
- return;
- }
-
- acpi_ut_dump_buffer ((void *) node, sizeof (acpi_namespace_node), display, ACPI_UINT32_MAX);
- acpi_ex_dump_node (node, 1);
-
- obj_desc = acpi_ns_get_attached_object (node);
- if (obj_desc) {
- acpi_os_printf ("\nAttached Object (%p):\n", obj_desc);
- if (!acpi_os_readable (obj_desc, sizeof (acpi_operand_object))) {
- acpi_os_printf ("Invalid internal ACPI Object at address %p\n", obj_desc);
- return;
- }
-
- acpi_ut_dump_buffer ((void *) obj_desc, sizeof (acpi_operand_object), display, ACPI_UINT32_MAX);
- acpi_ex_dump_object_descriptor (obj_desc, 1);
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_decode_internal_object
- *
- * PARAMETERS: Obj_desc - Object to be displayed
- *
- * RETURN: None
- *
- * DESCRIPTION: Short display of an internal object. Numbers and Strings.
- *
- ******************************************************************************/
-
-void
-acpi_db_decode_internal_object (
- acpi_operand_object *obj_desc)
-{
- u32 i;
-
-
- if (!obj_desc) {
- acpi_os_printf (" Uninitialized\n");
- return;
- }
-
- if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
- acpi_os_printf ("%p", obj_desc);
- return;
- }
-
- acpi_os_printf (" %s", acpi_ut_get_object_type_name (obj_desc));
-
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
- case ACPI_TYPE_INTEGER:
-
- acpi_os_printf (" %8.8X%8.8X", ACPI_HIDWORD (obj_desc->integer.value),
- ACPI_LODWORD (obj_desc->integer.value));
- break;
-
-
- case ACPI_TYPE_STRING:
-
- acpi_os_printf ("(%d) \"%.24s",
- obj_desc->string.length, obj_desc->string.pointer);
-
- if (obj_desc->string.length > 24)
- {
- acpi_os_printf ("...");
- }
- else
- {
- acpi_os_printf ("\"");
- }
- break;
-
-
- case ACPI_TYPE_BUFFER:
-
- acpi_os_printf ("(%d)", obj_desc->buffer.length);
- for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) {
- acpi_os_printf (" %2.2X", obj_desc->buffer.pointer[i]);
- }
- break;
-
-
- default:
-
- acpi_os_printf ("%p", obj_desc);
- break;
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_decode_node
- *
- * PARAMETERS: Node - Object to be displayed
- *
- * RETURN: None
- *
- * DESCRIPTION: Short display of a namespace node
- *
- ******************************************************************************/
-
-void
-acpi_db_decode_node (
- acpi_namespace_node *node)
-{
-
-
- acpi_os_printf ("<Node> Name %4.4s Type-%s",
- node->name.ascii, acpi_ut_get_type_name (node->type));
-
- if (node->flags & ANOBJ_METHOD_ARG) {
- acpi_os_printf (" [Method Arg]");
- }
- if (node->flags & ANOBJ_METHOD_LOCAL) {
- acpi_os_printf (" [Method Local]");
- }
-
- acpi_db_decode_internal_object (acpi_ns_get_attached_object (node));
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_internal_object
- *
- * PARAMETERS: Obj_desc - Object to be displayed
- * Walk_state - Current walk state
- *
- * RETURN: None
- *
- * DESCRIPTION: Short display of an internal object
- *
- ******************************************************************************/
-
-void
-acpi_db_display_internal_object (
- acpi_operand_object *obj_desc,
- acpi_walk_state *walk_state)
-{
- u8 type;
-
-
- acpi_os_printf ("%p ", obj_desc);
-
- if (!obj_desc) {
- acpi_os_printf ("<Null_obj>\n");
- return;
- }
-
- /* Decode the object type */
-
- switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
- case ACPI_DESC_TYPE_PARSER:
-
- acpi_os_printf ("<Parser> ");
- break;
-
-
- case ACPI_DESC_TYPE_NAMED:
-
- acpi_db_decode_node ((acpi_namespace_node *) obj_desc);
- break;
-
-
- case ACPI_DESC_TYPE_OPERAND:
-
- type = ACPI_GET_OBJECT_TYPE (obj_desc);
- if (type > INTERNAL_TYPE_MAX) {
- acpi_os_printf (" Type %hX [Invalid Type]", type);
- return;
- }
-
- /* Decode the ACPI object type */
-
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
- case INTERNAL_TYPE_REFERENCE:
-
- switch (obj_desc->reference.opcode) {
- case AML_LOCAL_OP:
-
- acpi_os_printf ("[Local%d] ", obj_desc->reference.offset);
- if (walk_state) {
- obj_desc = walk_state->local_variables[obj_desc->reference.offset].object;
- acpi_os_printf ("%p", obj_desc);
- acpi_db_decode_internal_object (obj_desc);
- }
- break;
-
-
- case AML_ARG_OP:
-
- acpi_os_printf ("[Arg%d] ", obj_desc->reference.offset);
- if (walk_state) {
- obj_desc = walk_state->arguments[obj_desc->reference.offset].object;
- acpi_os_printf ("%p", obj_desc);
- acpi_db_decode_internal_object (obj_desc);
- }
- break;
-
-
- case AML_DEBUG_OP:
-
- acpi_os_printf ("[Debug] ");
- break;
-
-
- case AML_INDEX_OP:
-
- acpi_os_printf ("[Index] ");
- acpi_db_decode_internal_object (obj_desc->reference.object);
- break;
-
-
- case AML_REF_OF_OP:
-
- acpi_os_printf ("[Reference] ");
-
- /* Reference can be to a Node or an Operand object */
-
- switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc->reference.object)) {
- case ACPI_DESC_TYPE_NAMED:
- acpi_db_decode_node (obj_desc->reference.object);
- break;
-
- case ACPI_DESC_TYPE_OPERAND:
- acpi_db_decode_internal_object (obj_desc->reference.object);
- break;
-
- default:
- break;
- }
- break;
-
-
- default:
-
- acpi_os_printf ("Unknown Reference opcode %X\n",
- obj_desc->reference.opcode);
- break;
- }
- break;
-
- default:
-
- acpi_os_printf ("<Obj> ");
- acpi_os_printf (" ");
- acpi_db_decode_internal_object (obj_desc);
- break;
- }
- break;
-
-
- default:
-
- acpi_os_printf ("<Not a valid ACPI Object Descriptor> ");
- break;
- }
-
- acpi_os_printf ("\n");
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_method_info
- *
- * PARAMETERS: Start_op - Root of the control method parse tree
- *
- * RETURN: None
- *
- * DESCRIPTION: Display information about the current method
- *
- ******************************************************************************/
-
-void
-acpi_db_display_method_info (
- acpi_parse_object *start_op)
-{
- acpi_walk_state *walk_state;
- acpi_operand_object *obj_desc;
- acpi_namespace_node *node;
- acpi_parse_object *root_op;
- acpi_parse_object *op;
- const acpi_opcode_info *op_info;
- u32 num_ops = 0;
- u32 num_operands = 0;
- u32 num_operators = 0;
- u32 num_remaining_ops = 0;
- u32 num_remaining_operands = 0;
- u32 num_remaining_operators = 0;
- u32 num_args;
- u32 concurrency;
- u8 count_remaining = FALSE;
-
-
- walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
- if (!walk_state) {
- acpi_os_printf ("There is no method currently executing\n");
- return;
- }
-
- obj_desc = walk_state->method_desc;
- node = walk_state->method_node;
-
- num_args = obj_desc->method.param_count;
- concurrency = obj_desc->method.concurrency;
-
- acpi_os_printf ("Currently executing control method is [%4.4s]\n", node->name.ascii);
- acpi_os_printf ("%X arguments, max concurrency = %X\n", num_args, concurrency);
-
-
- root_op = start_op;
- while (root_op->common.parent) {
- root_op = root_op->common.parent;
- }
-
- op = root_op;
-
- while (op) {
- if (op == start_op) {
- count_remaining = TRUE;
- }
-
- num_ops++;
- if (count_remaining) {
- num_remaining_ops++;
- }
-
- /* Decode the opcode */
-
- op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
- switch (op_info->class) {
- case AML_CLASS_ARGUMENT:
- if (count_remaining) {
- num_remaining_operands++;
- }
-
- num_operands++;
- break;
-
- case AML_CLASS_UNKNOWN:
- /* Bad opcode or ASCII character */
-
- continue;
-
- default:
- if (count_remaining) {
- num_remaining_operators++;
- }
-
- num_operators++;
- break;
- }
-
- op = acpi_ps_get_depth_next (start_op, op);
- }
-
- acpi_os_printf ("Method contains: %X AML Opcodes - %X Operators, %X Operands\n",
- num_ops, num_operators, num_operands);
-
- acpi_os_printf ("Remaining to execute: %X AML Opcodes - %X Operators, %X Operands\n",
- num_remaining_ops, num_remaining_operators, num_remaining_operands);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_locals
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Display all locals for the currently running control method
- *
- ******************************************************************************/
-
-void
-acpi_db_display_locals (void)
-{
- u32 i;
- acpi_walk_state *walk_state;
- acpi_operand_object *obj_desc;
- acpi_namespace_node *node;
-
-
- walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
- if (!walk_state) {
- acpi_os_printf ("There is no method currently executing\n");
- return;
- }
-
- obj_desc = walk_state->method_desc;
- node = walk_state->method_node;
- acpi_os_printf ("Local Variables for method [%4.4s]:\n", node->name.ascii);
-
- for (i = 0; i < MTH_NUM_LOCALS; i++) {
- obj_desc = walk_state->local_variables[i].object;
- acpi_os_printf ("Local%d: ", i);
- acpi_db_display_internal_object (obj_desc, walk_state);
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_arguments
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Display all arguments for the currently running control method
- *
- ******************************************************************************/
-
-void
-acpi_db_display_arguments (void)
-{
- u32 i;
- acpi_walk_state *walk_state;
- acpi_operand_object *obj_desc;
- u32 num_args;
- u32 concurrency;
- acpi_namespace_node *node;
-
-
- walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
- if (!walk_state) {
- acpi_os_printf ("There is no method currently executing\n");
- return;
- }
-
- obj_desc = walk_state->method_desc;
- node = walk_state->method_node;
-
- num_args = obj_desc->method.param_count;
- concurrency = obj_desc->method.concurrency;
-
- acpi_os_printf ("Method [%4.4s] has %X arguments, max concurrency = %X\n",
- node->name.ascii, num_args, concurrency);
-
- for (i = 0; i < num_args; i++) {
- obj_desc = walk_state->arguments[i].object;
- acpi_os_printf ("Arg%d: ", i);
- acpi_db_display_internal_object (obj_desc, walk_state);
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_results
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Display current contents of a method result stack
- *
- ******************************************************************************/
-
-void
-acpi_db_display_results (void)
-{
- u32 i;
- acpi_walk_state *walk_state;
- acpi_operand_object *obj_desc;
- u32 num_results = 0;
- acpi_namespace_node *node;
-
-
- walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
- if (!walk_state) {
- acpi_os_printf ("There is no method currently executing\n");
- return;
- }
-
- obj_desc = walk_state->method_desc;
- node = walk_state->method_node;
-
- if (walk_state->results) {
- num_results = walk_state->results->results.num_results;
- }
-
- acpi_os_printf ("Method [%4.4s] has %X stacked result objects\n",
- node->name.ascii, num_results);
-
- for (i = 0; i < num_results; i++) {
- obj_desc = walk_state->results->results.obj_desc[i];
- acpi_os_printf ("Result%d: ", i);
- acpi_db_display_internal_object (obj_desc, walk_state);
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_calling_tree
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Display current calling tree of nested control methods
- *
- ******************************************************************************/
-
-void
-acpi_db_display_calling_tree (void)
-{
- acpi_walk_state *walk_state;
- acpi_namespace_node *node;
-
-
- walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
- if (!walk_state) {
- acpi_os_printf ("There is no method currently executing\n");
- return;
- }
-
- node = walk_state->method_node;
- acpi_os_printf ("Current Control Method Call Tree\n");
-
- while (walk_state) {
- node = walk_state->method_node;
-
- acpi_os_printf (" [%4.4s]\n", node->name.ascii);
-
- walk_state = walk_state->next;
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_result_object
- *
- * PARAMETERS: Obj_desc - Object to be displayed
- * Walk_state - Current walk state
- *
- * RETURN: None
- *
- * DESCRIPTION: Display the result of an AML opcode
- *
- * Note: Curently only displays the result object if we are single stepping.
- * However, this output may be useful in other contexts and could be enabled
- * to do so if needed.
- *
- ******************************************************************************/
-
-void
-acpi_db_display_result_object (
- acpi_operand_object *obj_desc,
- acpi_walk_state *walk_state)
-{
-
- /* Only display if single stepping */
-
- if (!acpi_gbl_cm_single_step) {
- return;
- }
-
- acpi_os_printf ("Result_obj: ");
- acpi_db_display_internal_object (obj_desc, walk_state);
- acpi_os_printf ("\n");
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_argument_object
- *
- * PARAMETERS: Obj_desc - Object to be displayed
- * Walk_state - Current walk state
- *
- * RETURN: None
- *
- * DESCRIPTION: Display the result of an AML opcode
- *
- ******************************************************************************/
-
-void
-acpi_db_display_argument_object (
- acpi_operand_object *obj_desc,
- acpi_walk_state *walk_state)
-{
-
- if (!acpi_gbl_cm_single_step) {
- return;
- }
-
- acpi_os_printf ("Arg_obj: ");
- acpi_db_display_internal_object (obj_desc, walk_state);
-}
-
-#endif /* ACPI_DEBUGGER */
-
diff --git a/drivers/acpi/debugger/dbexec.c b/drivers/acpi/debugger/dbexec.c
deleted file mode 100644
index 9d5b9dd7c05d..000000000000
--- a/drivers/acpi/debugger/dbexec.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*******************************************************************************
- *
- * Module Name: dbexec - debugger control method execution
- * $Revision: 44 $
- *
- ******************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2002, R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "acpi.h"
-#include "acdebug.h"
-
-#ifdef ACPI_DEBUGGER
-
-#define _COMPONENT ACPI_CA_DEBUGGER
- ACPI_MODULE_NAME ("dbexec")
-
-
-static acpi_db_method_info acpi_gbl_db_method_info;
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_execute_method
- *
- * PARAMETERS: Info - Valid info segment
- * Return_obj - Where to put return object
- *
- * RETURN: Status
- *
- * DESCRIPTION: Execute a control method.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_execute_method (
- acpi_db_method_info *info,
- acpi_buffer *return_obj)
-{
- acpi_status status;
- acpi_object_list param_objects;
- acpi_object params[MTH_NUM_ARGS];
- u32 i;
-
-
- if (acpi_gbl_db_output_to_file && !acpi_dbg_level) {
- acpi_os_printf ("Warning: debug output is not enabled!\n");
- }
-
- /* Are there arguments to the method? */
-
- if (info->args && info->args[0]) {
- for (i = 0; info->args[i] && i < MTH_NUM_ARGS; i++) {
- params[i].type = ACPI_TYPE_INTEGER;
- params[i].integer.value = ACPI_STRTOUL (info->args[i], NULL, 16);
- }
-
- param_objects.pointer = params;
- param_objects.count = i;
- }
- else {
- /* Setup default parameters */
-
- params[0].type = ACPI_TYPE_INTEGER;
- params[0].integer.value = 0x01020304;
-
- params[1].type = ACPI_TYPE_STRING;
- params[1].string.length = 12;
- params[1].string.pointer = "AML Debugger";
-
- param_objects.pointer = params;
- param_objects.count = 2;
- }
-
- /* Prepare for a return object of arbitrary size */
-
- return_obj->pointer = acpi_gbl_db_buffer;
- return_obj->length = ACPI_DEBUG_BUFFER_SIZE;
-
- /* Do the actual method execution */
-
- status = acpi_evaluate_object (NULL, info->pathname, &param_objects, return_obj);
-
- acpi_gbl_cm_single_step = FALSE;
- acpi_gbl_method_executing = FALSE;
-
- return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_execute_setup
- *
- * PARAMETERS: Info - Valid method info
- *
- * RETURN: Status
- *
- * DESCRIPTION: Setup info segment prior to method execution
- *
- ******************************************************************************/
-
-void
-acpi_db_execute_setup (
- acpi_db_method_info *info)
-{
-
- /* Catenate the current scope to the supplied name */
-
- info->pathname[0] = 0;
- if ((info->name[0] != '\\') &&
- (info->name[0] != '/')) {
- ACPI_STRCAT (info->pathname, acpi_gbl_db_scope_buf);
- }
-
- ACPI_STRCAT (info->pathname, info->name);
- acpi_db_prep_namestring (info->pathname);
-
- acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT);
- acpi_os_printf ("Executing %s\n", info->pathname);
-
- if (info->flags & EX_SINGLE_STEP) {
- acpi_gbl_cm_single_step = TRUE;
- acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
- }
-
- else {
- /* No single step, allow redirection to a file */
-
- acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT);
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_get_outstanding_allocations
- *
- * PARAMETERS: None
- *
- * RETURN: Current global allocation count minus cache entries
- *
- * DESCRIPTION: Determine the current number of "outstanding" allocations --
- * those allocations that have not been freed and also are not
- * in one of the various object caches.
- *
- ******************************************************************************/
-
-u32
-acpi_db_get_outstanding_allocations (
- void)
-{
- u32 outstanding = 0;
-
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- u32 i;
-
-
- for (i = ACPI_MEM_LIST_FIRST_CACHE_LIST; i < ACPI_NUM_MEM_LISTS; i++) {
- outstanding += (acpi_gbl_memory_lists[i].total_allocated -
- acpi_gbl_memory_lists[i].total_freed -
- acpi_gbl_memory_lists[i].cache_depth);
- }
-#endif
-
- return (outstanding);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_execute
- *
- * PARAMETERS: Name - Name of method to execute
- * Args - Parameters to the method
- * Flags - single step/no single step
- *
- * RETURN: Status
- *
- * DESCRIPTION: Execute a control method. Name is relative to the current
- * scope.
- *
- ******************************************************************************/
-
-void
-acpi_db_execute (
- NATIVE_CHAR *name,
- NATIVE_CHAR **args,
- u32 flags)
-{
- acpi_status status;
- acpi_buffer return_obj;
-
-
-#ifdef ACPI_DEBUG_OUTPUT
- u32 previous_allocations;
- u32 allocations;
-
-
- /* Memory allocation tracking */
-
- previous_allocations = acpi_db_get_outstanding_allocations ();
-#endif
-
- acpi_gbl_db_method_info.name = name;
- acpi_gbl_db_method_info.args = args;
- acpi_gbl_db_method_info.flags = flags;
-
- return_obj.pointer = NULL;
- return_obj.length = ACPI_ALLOCATE_BUFFER;
-
- acpi_db_execute_setup (&acpi_gbl_db_method_info);
- status = acpi_db_execute_method (&acpi_gbl_db_method_info, &return_obj);
-
- /*
- * Allow any handlers in separate threads to complete.
- * (Such as Notify handlers invoked from AML executed above).
- */
- acpi_os_sleep (0, 10);
-
-
-#ifdef ACPI_DEBUG_OUTPUT
-
- /* Memory allocation tracking */
-
- allocations = acpi_db_get_outstanding_allocations () - previous_allocations;
-
- acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT);
-
- if (allocations > 0) {
- acpi_os_printf ("Outstanding: %ld allocations after execution\n",
- allocations);
- }
-#endif
-
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Execution of %s failed with status %s\n",
- acpi_gbl_db_method_info.pathname, acpi_format_exception (status));
- }
-
- else {
- /* Display a return object, if any */
-
- if (return_obj.length) {
- acpi_os_printf ("Execution of %s returned object %p Buflen %X\n",
- acpi_gbl_db_method_info.pathname, return_obj.pointer, return_obj.length);
- acpi_db_dump_object (return_obj.pointer, 1);
- }
- else {
- acpi_os_printf ("No return object from execution of %s\n",
- acpi_gbl_db_method_info.pathname);
- }
- }
-
- acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_method_thread
- *
- * PARAMETERS: Context - Execution info segment
- *
- * RETURN: None
- *
- * DESCRIPTION: Debugger execute thread. Waits for a command line, then
- * simply dispatches it.
- *
- ******************************************************************************/
-
-void ACPI_SYSTEM_XFACE
-acpi_db_method_thread (
- void *context)
-{
- acpi_status status;
- acpi_db_method_info *info = context;
- u32 i;
- acpi_buffer return_obj;
-
-
- for (i = 0; i < info->num_loops; i++) {
- status = acpi_db_execute_method (info, &return_obj);
- if (ACPI_SUCCESS (status)) {
- if (return_obj.length) {
- acpi_os_printf ("Execution of %s returned object %p Buflen %X\n",
- info->pathname, return_obj.pointer, return_obj.length);
- acpi_db_dump_object (return_obj.pointer, 1);
- }
- }
- }
-
- /* Signal our completion */
-
- status = acpi_os_signal_semaphore (info->thread_gate, 1);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could not signal debugger semaphore\n");
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_create_execution_threads
- *
- * PARAMETERS: Num_threads_arg - Number of threads to create
- * Num_loops_arg - Loop count for the thread(s)
- * Method_name_arg - Control method to execute
- *
- * RETURN: None
- *
- * DESCRIPTION: Create threads to execute method(s)
- *
- ******************************************************************************/
-
-void
-acpi_db_create_execution_threads (
- NATIVE_CHAR *num_threads_arg,
- NATIVE_CHAR *num_loops_arg,
- NATIVE_CHAR *method_name_arg)
-{
- acpi_status status;
- u32 num_threads;
- u32 num_loops;
- u32 i;
- acpi_handle thread_gate;
-
-
- /* Get the arguments */
-
- num_threads = ACPI_STRTOUL (num_threads_arg, NULL, 0);
- num_loops = ACPI_STRTOUL (num_loops_arg, NULL, 0);
-
- if (!num_threads || !num_loops) {
- acpi_os_printf ("Bad argument: Threads %X, Loops %X\n", num_threads, num_loops);
- return;
- }
-
- /* Create the synchronization semaphore */
-
- status = acpi_os_create_semaphore (1, 0, &thread_gate);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could not create semaphore, %s\n", acpi_format_exception (status));
- return;
- }
-
- /* Setup the context to be passed to each thread */
-
- acpi_gbl_db_method_info.name = method_name_arg;
- acpi_gbl_db_method_info.args = NULL;
- acpi_gbl_db_method_info.flags = 0;
- acpi_gbl_db_method_info.num_loops = num_loops;
- acpi_gbl_db_method_info.thread_gate = thread_gate;
-
- acpi_db_execute_setup (&acpi_gbl_db_method_info);
-
- /* Create the threads */
-
- acpi_os_printf ("Creating %X threads to execute %X times each\n", num_threads, num_loops);
-
- for (i = 0; i < (num_threads); i++) {
- status = acpi_os_queue_for_execution (OSD_PRIORITY_MED, acpi_db_method_thread, &acpi_gbl_db_method_info);
- if (ACPI_FAILURE (status)) {
- break;
- }
- }
-
- /* Wait for all threads to complete */
-
- i = num_threads;
- while (i) /* Brain damage for OSD implementations that only support wait of 1 unit */ {
- status = acpi_os_wait_semaphore (thread_gate, 1, WAIT_FOREVER);
- i--;
- }
-
- /* Cleanup and exit */
-
- (void) acpi_os_delete_semaphore (thread_gate);
-
- acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT);
- acpi_os_printf ("All threads (%X) have completed\n", num_threads);
- acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
-}
-
-
-#endif /* ACPI_DEBUGGER */
-
-
diff --git a/drivers/acpi/debugger/dbfileio.c b/drivers/acpi/debugger/dbfileio.c
deleted file mode 100644
index 79e8b92843b5..000000000000
--- a/drivers/acpi/debugger/dbfileio.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*******************************************************************************
- *
- * Module Name: dbfileio - Debugger file I/O commands. These can't usually
- * be used when running the debugger in Ring 0 (Kernel mode)
- * $Revision: 68 $
- *
- ******************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2002, R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "acpi.h"
-#include "acdebug.h"
-#include "acnamesp.h"
-#include "actables.h"
-
-#if (defined ACPI_DEBUGGER || defined ACPI_DISASSEMBLER)
-
-#define _COMPONENT ACPI_CA_DEBUGGER
- ACPI_MODULE_NAME ("dbfileio")
-
-
-/*
- * NOTE: this is here for lack of a better place. It is used in all
- * flavors of the debugger, need LCD file
- */
-#ifdef ACPI_APPLICATION
-#include <stdio.h>
-FILE *acpi_gbl_debug_file = NULL;
-#endif
-
-
-acpi_table_header *acpi_gbl_db_table_ptr = NULL;
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_match_argument
- *
- * PARAMETERS: User_argument - User command line
- * Arguments - Array of commands to match against
- *
- * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found
- *
- * DESCRIPTION: Search command array for a command match
- *
- ******************************************************************************/
-
-acpi_object_type
-acpi_db_match_argument (
- NATIVE_CHAR *user_argument,
- ARGUMENT_INFO *arguments)
-{
- u32 i;
-
-
- if (!user_argument || user_argument[0] == 0) {
- return (ACPI_TYPE_NOT_FOUND);
- }
-
- for (i = 0; arguments[i].name; i++) {
- if (ACPI_STRSTR (arguments[i].name, user_argument) == arguments[i].name) {
- return (i);
- }
- }
-
- /* Argument not recognized */
-
- return (ACPI_TYPE_NOT_FOUND);
-}
-
-
-#ifdef ACPI_DEBUGGER
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_close_debug_file
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: If open, close the current debug output file
- *
- ******************************************************************************/
-
-void
-acpi_db_close_debug_file (
- void)
-{
-
-#ifdef ACPI_APPLICATION
-
- if (acpi_gbl_debug_file) {
- fclose (acpi_gbl_debug_file);
- acpi_gbl_debug_file = NULL;
- acpi_gbl_db_output_to_file = FALSE;
- acpi_os_printf ("Debug output file %s closed\n", acpi_gbl_db_debug_filename);
- }
-#endif
-
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_open_debug_file
- *
- * PARAMETERS: Name - Filename to open
- *
- * RETURN: Status
- *
- * DESCRIPTION: Open a file where debug output will be directed.
- *
- ******************************************************************************/
-
-void
-acpi_db_open_debug_file (
- NATIVE_CHAR *name)
-{
-
-#ifdef ACPI_APPLICATION
-
- acpi_db_close_debug_file ();
- acpi_gbl_debug_file = fopen (name, "w+");
- if (acpi_gbl_debug_file) {
- acpi_os_printf ("Debug output file %s opened\n", name);
- ACPI_STRCPY (acpi_gbl_db_debug_filename, name);
- acpi_gbl_db_output_to_file = TRUE;
- }
- else {
- acpi_os_printf ("Could not open debug file %s\n", name);
- }
-
-#endif
-}
-#endif
-
-
-#ifdef ACPI_APPLICATION
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_load_table
- *
- * PARAMETERS: fp - File that contains table
- * Table_ptr - Return value, buffer with table
- * Table_lenght - Return value, length of table
- *
- * RETURN: Status
- *
- * DESCRIPTION: Load the DSDT from the file pointer
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_db_load_table(
- FILE *fp,
- acpi_table_header **table_ptr,
- u32 *table_length)
-{
- acpi_table_header table_header;
- u8 *aml_start;
- u32 aml_length;
- u32 actual;
- acpi_status status;
-
-
- /* Read the table header */
-
- if (fread (&table_header, 1, sizeof (table_header), fp) != sizeof (acpi_table_header)) {
- acpi_os_printf ("Couldn't read the table header\n");
- return (AE_BAD_SIGNATURE);
- }
-
-
- /* Validate the table header/length */
-
- status = acpi_tb_validate_table_header (&table_header);
- if ((ACPI_FAILURE (status)) ||
- (table_header.length > 0x800000)) /* 8 Mbyte should be enough */ {
- acpi_os_printf ("Table header is invalid!\n");
- return (AE_ERROR);
- }
-
-
- /* We only support a limited number of table types */
-
- if (ACPI_STRNCMP ((char *) table_header.signature, DSDT_SIG, 4) &&
- ACPI_STRNCMP ((char *) table_header.signature, PSDT_SIG, 4) &&
- ACPI_STRNCMP ((char *) table_header.signature, SSDT_SIG, 4)) {
- acpi_os_printf ("Table signature is invalid\n");
- ACPI_DUMP_BUFFER (&table_header, sizeof (acpi_table_header));
- return (AE_ERROR);
- }
-
- /* Allocate a buffer for the table */
-
- *table_length = table_header.length;
- *table_ptr = acpi_os_allocate ((size_t) *table_length);
- if (!*table_ptr) {
- acpi_os_printf ("Could not allocate memory for ACPI table %4.4s (size=%X)\n",
- table_header.signature, table_header.length);
- return (AE_NO_MEMORY);
- }
-
-
- aml_start = (u8 *) *table_ptr + sizeof (table_header);
- aml_length = *table_length - sizeof (table_header);
-
- /* Copy the header to the buffer */
-
- ACPI_MEMCPY (*table_ptr, &table_header, sizeof (table_header));
-
- /* Get the rest of the table */
-
- actual = fread (aml_start, 1, (size_t) aml_length, fp);
- if (actual == aml_length) {
- return (AE_OK);
- }
-
- if (actual > 0) {
- acpi_os_printf ("Warning - reading table, asked for %X got %X\n", aml_length, actual);
- return (AE_OK);
- }
-
-
- acpi_os_printf ("Error - could not read the table file\n");
- acpi_os_free (*table_ptr);
- *table_ptr = NULL;
- *table_length = 0;
-
- return (AE_ERROR);
-}
-#endif
-
-
-/*******************************************************************************
- *
- * FUNCTION: Ae_local_load_table
- *
- * PARAMETERS: Table_ptr - pointer to a buffer containing the entire
- * table to be loaded
- *
- * RETURN: Status
- *
- * DESCRIPTION: This function is called to load a table from the caller's
- * buffer. The buffer must contain an entire ACPI Table including
- * a valid header. The header fields will be verified, and if it
- * is determined that the table is invalid, the call will fail.
- *
- * If the call fails an appropriate status will be returned.
- *
- ******************************************************************************/
-
-acpi_status
-ae_local_load_table (
- acpi_table_header *table_ptr)
-{
- acpi_status status;
- acpi_table_desc table_info;
-
-
- ACPI_FUNCTION_TRACE ("Ae_local_load_table");
-
- if (!table_ptr) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- table_info.pointer = table_ptr;
- status = acpi_tb_recognize_table (&table_info, ACPI_TABLE_SECONDARY);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
-
- /* Install the new table into the local data structures */
-
- status = acpi_tb_install_table (&table_info);
- if (ACPI_FAILURE (status)) {
- /* Free table allocated by Acpi_tb_get_table */
-
- acpi_tb_delete_single_table (&table_info);
- return_ACPI_STATUS (status);
- }
-
-
-#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
- status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node);
- if (ACPI_FAILURE (status)) {
- /* Uninstall table and free the buffer */
-
- acpi_tb_delete_acpi_table (ACPI_TABLE_DSDT);
- return_ACPI_STATUS (status);
- }
-#endif
-
- return_ACPI_STATUS (status);
-}
-
-
-#ifdef ACPI_APPLICATION
-acpi_status
-acpi_db_get_acpi_table (
- NATIVE_CHAR *filename)
-{
- FILE *fp;
- u32 table_length;
- acpi_status status;
-
- /* Open the file */
-
- fp = fopen (filename, "rb");
- if (!fp) {
- acpi_os_printf ("Could not open file %s\n", filename);
- return (AE_ERROR);
- }
-
-
- /* Get the entire file */
-
- fprintf (stderr, "Loading Acpi table from file %s\n", filename);
- status = acpi_db_load_table (fp, &acpi_gbl_db_table_ptr, &table_length);
- fclose(fp);
-
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Couldn't get table from the file\n");
- return (status);
- }
-
- return (AE_OK);
- }
-#endif
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_load_acpi_table
- *
- * PARAMETERS: Filname - File where table is located
- *
- * RETURN: Status
- *
- * DESCRIPTION: Load an ACPI table from a file
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_load_acpi_table (
- NATIVE_CHAR *filename) {
-#ifdef ACPI_APPLICATION
- acpi_status status;
-
-
- status = acpi_db_get_acpi_table (filename);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
-
- /* Attempt to recognize and install the table */
-
- status = ae_local_load_table (acpi_gbl_db_table_ptr);
- if (ACPI_FAILURE (status)) {
- if (status == AE_ALREADY_EXISTS) {
- acpi_os_printf ("Table %4.4s is already installed\n",
- acpi_gbl_db_table_ptr->signature);
- }
- else {
- acpi_os_printf ("Could not install table, %s\n",
- acpi_format_exception (status));
- }
-
- return (status);
- }
-
- fprintf (stderr, "Acpi table [%4.4s] successfully installed and loaded\n",
- acpi_gbl_db_table_ptr->signature);
-
- acpi_gbl_acpi_hardware_present = FALSE;
-
-#endif /* ACPI_APPLICATION */
- return (AE_OK);
-}
-
-
-#endif /* ACPI_DEBUGGER */
-
diff --git a/drivers/acpi/debugger/dbhistry.c b/drivers/acpi/debugger/dbhistry.c
deleted file mode 100644
index 6a5e6879b5fb..000000000000
--- a/drivers/acpi/debugger/dbhistry.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/******************************************************************************
- *
- * Module Name: dbhistry - debugger HISTORY command
- * $Revision: 25 $
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2002, R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "acpi.h"
-#include "acdebug.h"
-
-#ifdef ACPI_DEBUGGER
-
-#define _COMPONENT ACPI_CA_DEBUGGER
- ACPI_MODULE_NAME ("dbhistry")
-
-
-#define HI_NO_HISTORY 0
-#define HI_RECORD_HISTORY 1
-#define HISTORY_SIZE 20
-
-
-typedef struct history_info
-{
- NATIVE_CHAR command[80];
- u32 cmd_num;
-
-} HISTORY_INFO;
-
-
-static HISTORY_INFO acpi_gbl_history_buffer[HISTORY_SIZE];
-static u16 acpi_gbl_lo_history = 0;
-static u16 acpi_gbl_num_history = 0;
-static u16 acpi_gbl_next_history_index = 0;
-static u32 acpi_gbl_next_cmd_num = 1;
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_add_to_history
- *
- * PARAMETERS: Command_line - Command to add
- *
- * RETURN: None
- *
- * DESCRIPTION: Add a command line to the history buffer.
- *
- ******************************************************************************/
-
-void
-acpi_db_add_to_history (
- NATIVE_CHAR *command_line)
-{
-
- /* Put command into the next available slot */
-
- ACPI_STRCPY (acpi_gbl_history_buffer[acpi_gbl_next_history_index].command, command_line);
-
- acpi_gbl_history_buffer[acpi_gbl_next_history_index].cmd_num = acpi_gbl_next_cmd_num;
-
- /* Adjust indexes */
-
- if ((acpi_gbl_num_history == HISTORY_SIZE) &&
- (acpi_gbl_next_history_index == acpi_gbl_lo_history)) {
- acpi_gbl_lo_history++;
- if (acpi_gbl_lo_history >= HISTORY_SIZE) {
- acpi_gbl_lo_history = 0;
- }
- }
-
- acpi_gbl_next_history_index++;
- if (acpi_gbl_next_history_index >= HISTORY_SIZE) {
- acpi_gbl_next_history_index = 0;
- }
-
- acpi_gbl_next_cmd_num++;
- if (acpi_gbl_num_history < HISTORY_SIZE) {
- acpi_gbl_num_history++;
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_history
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Display the contents of the history buffer
- *
- ******************************************************************************/
-
-void
-acpi_db_display_history (void)
-{
- NATIVE_UINT i;
- u16 history_index;
-
-
- history_index = acpi_gbl_lo_history;
-
- /* Dump entire history buffer */
-
- for (i = 0; i < acpi_gbl_num_history; i++) {
- acpi_os_printf ("%ld %s\n", acpi_gbl_history_buffer[history_index].cmd_num,
- acpi_gbl_history_buffer[history_index].command);
-
- history_index++;
- if (history_index >= HISTORY_SIZE) {
- history_index = 0;
- }
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_get_from_history
- *
- * PARAMETERS: Command_num_arg - String containing the number of the
- * command to be retrieved
- *
- * RETURN: None
- *
- * DESCRIPTION: Get a command from the history buffer
- *
- ******************************************************************************/
-
-NATIVE_CHAR *
-acpi_db_get_from_history (
- NATIVE_CHAR *command_num_arg)
-{
- NATIVE_UINT i;
- u16 history_index;
- u32 cmd_num;
-
-
- if (command_num_arg == NULL) {
- cmd_num = acpi_gbl_next_cmd_num - 1;
- }
-
- else {
- cmd_num = ACPI_STRTOUL (command_num_arg, NULL, 0);
- }
-
- /* Search history buffer */
-
- history_index = acpi_gbl_lo_history;
- for (i = 0; i < acpi_gbl_num_history; i++) {
- if (acpi_gbl_history_buffer[history_index].cmd_num == cmd_num) {
- /* Found the commnad, return it */
-
- return (acpi_gbl_history_buffer[history_index].command);
- }
-
-
- history_index++;
- if (history_index >= HISTORY_SIZE) {
- history_index = 0;
- }
- }
-
- acpi_os_printf ("Invalid history number: %d\n", history_index);
- return (NULL);
-}
-
-
-#endif /* ACPI_DEBUGGER */
-
diff --git a/drivers/acpi/debugger/dbinput.c b/drivers/acpi/debugger/dbinput.c
deleted file mode 100644
index 24eb73621f08..000000000000
--- a/drivers/acpi/debugger/dbinput.c
+++ /dev/null
@@ -1,892 +0,0 @@
-/*******************************************************************************
- *
- * Module Name: dbinput - user front-end to the AML debugger
- * $Revision: 87 $
- *
- ******************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2002, R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "acpi.h"
-#include "acdebug.h"
-
-
-#ifdef ACPI_DEBUGGER
-
-#define _COMPONENT ACPI_CA_DEBUGGER
- ACPI_MODULE_NAME ("dbinput")
-
-
-/*
- * Top-level debugger commands.
- *
- * This list of commands must match the string table below it
- */
-enum acpi_ex_debugger_commands
-{
- CMD_NOT_FOUND = 0,
- CMD_NULL,
- CMD_ALLOCATIONS,
- CMD_ARGS,
- CMD_ARGUMENTS,
- CMD_BREAKPOINT,
- CMD_CALL,
- CMD_CLOSE,
- CMD_DEBUG,
- CMD_DUMP,
- CMD_ENABLEACPI,
- CMD_EVENT,
- CMD_EXECUTE,
- CMD_EXIT,
- CMD_FIND,
- CMD_GO,
- CMD_HELP,
- CMD_HELP2,
- CMD_HISTORY,
- CMD_HISTORY_EXE,
- CMD_HISTORY_LAST,
- CMD_INFORMATION,
- CMD_INTEGRITY,
- CMD_INTO,
- CMD_LEVEL,
- CMD_LIST,
- CMD_LOAD,
- CMD_LOCALS,
- CMD_LOCKS,
- CMD_METHODS,
- CMD_NAMESPACE,
- CMD_NOTIFY,
- CMD_OBJECT,
- CMD_OPEN,
- CMD_OWNER,
- CMD_PREFIX,
- CMD_QUIT,
- CMD_REFERENCES,
- CMD_RESOURCES,
- CMD_RESULTS,
- CMD_SET,
- CMD_STATS,
- CMD_STOP,
- CMD_TABLES,
- CMD_TERMINATE,
- CMD_THREADS,
- CMD_TREE,
- CMD_UNLOAD
-};
-
-#define CMD_FIRST_VALID 2
-
-
-static const COMMAND_INFO acpi_gbl_db_commands[] =
-{ {"<NOT FOUND>", 0},
- {"<NULL>", 0},
- {"ALLOCATIONS", 0},
- {"ARGS", 0},
- {"ARGUMENTS", 0},
- {"BREAKPOINT", 1},
- {"CALL", 0},
- {"CLOSE", 0},
- {"DEBUG", 1},
- {"DUMP", 1},
- {"ENABLEACPI", 0},
- {"EVENT", 1},
- {"EXECUTE", 1},
- {"EXIT", 0},
- {"FIND", 1},
- {"GO", 0},
- {"HELP", 0},
- {"?", 0},
- {"HISTORY", 0},
- {"!", 1},
- {"!!", 0},
- {"INFORMATION", 0},
- {"INTEGRITY", 0},
- {"INTO", 0},
- {"LEVEL", 0},
- {"LIST", 0},
- {"LOAD", 1},
- {"LOCALS", 0},
- {"LOCKS", 0},
- {"METHODS", 0},
- {"NAMESPACE", 0},
- {"NOTIFY", 2},
- {"OBJECT", 1},
- {"OPEN", 1},
- {"OWNER", 1},
- {"PREFIX", 0},
- {"QUIT", 0},
- {"REFERENCES", 1},
- {"RESOURCES", 1},
- {"RESULTS", 0},
- {"SET", 3},
- {"STATS", 0},
- {"STOP", 0},
- {"TABLES", 0},
- {"TERMINATE", 0},
- {"THREADS", 3},
- {"TREE", 0},
- {"UNLOAD", 1},
- {NULL, 0}
-};
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_help
- *
- * PARAMETERS: Help_type - Subcommand (optional)
- *
- * RETURN: None
- *
- * DESCRIPTION: Print a usage message.
- *
- ******************************************************************************/
-
-void
-acpi_db_display_help (
- NATIVE_CHAR *help_type)
-{
-
-
- /* No parameter, just give the overview */
-
- if (!help_type)
- {
- acpi_os_printf ("ACPI CA Debugger Commands\n\n");
- acpi_os_printf ("The following classes of commands are available. Help is available for\n");
- acpi_os_printf ("each class by entering \"Help <Class_name>\"\n\n");
- acpi_os_printf (" [GENERAL] General-Purpose Commands\n");
- acpi_os_printf (" [NAMESPACE] Namespace Access Commands\n");
- acpi_os_printf (" [METHOD] Control Method Execution Commands\n");
- acpi_os_printf (" [FILE] File I/O Commands\n");
- return;
-
- }
-
- /*
- * Parameter is the command class
- *
- * The idea here is to keep each class of commands smaller than a screenful
- */
- switch (help_type[0])
- {
- case 'G':
- acpi_os_printf ("\nGeneral-Purpose Commands\n\n");
- acpi_os_printf ("Allocations Display list of current memory allocations\n");
- acpi_os_printf ("Dump <Address>|<Namepath>\n");
- acpi_os_printf (" [Byte|Word|Dword|Qword] Display ACPI objects or memory\n");
- acpi_os_printf ("Enable_acpi Enable ACPI (hardware) mode\n");
- acpi_os_printf ("Help This help screen\n");
- acpi_os_printf ("History Display command history buffer\n");
- acpi_os_printf ("Level [<Debug_level>] [console] Get/Set debug level for file or console\n");
- acpi_os_printf ("Locks Current status of internal mutexes\n");
- acpi_os_printf ("Quit or Exit Exit this command\n");
- acpi_os_printf ("Stats [Allocations|Memory|Misc\n");
- acpi_os_printf (" |Objects|Tables] Display namespace and memory statistics\n");
- acpi_os_printf ("Tables Display info about loaded ACPI tables\n");
- acpi_os_printf ("Unload <Table_sig> [Instance] Unload an ACPI table\n");
- acpi_os_printf ("! <Command_number> Execute command from history buffer\n");
- acpi_os_printf ("!! Execute last command again\n");
- return;
-
- case 'N':
- acpi_os_printf ("\nNamespace Access Commands\n\n");
- acpi_os_printf ("Debug <Namepath> [Arguments] Single Step a control method\n");
- acpi_os_printf ("Event <F|G> <Value> Generate Acpi_event (Fixed/GPE)\n");
- acpi_os_printf ("Execute <Namepath> [Arguments] Execute control method\n");
- acpi_os_printf ("Find <Name> (? is wildcard) Find ACPI name(s) with wildcards\n");
- acpi_os_printf ("Method Display list of loaded control methods\n");
- acpi_os_printf ("Namespace [<Addr>|<Path>] [Depth] Display loaded namespace tree/subtree\n");
- acpi_os_printf ("Notify <Name_path> <Value> Send a notification\n");
- acpi_os_printf ("Objects <Object_type> Display all objects of the given type\n");
- acpi_os_printf ("Owner <Owner_id> [Depth] Display loaded namespace by object owner\n");
- acpi_os_printf ("Prefix [<Name_path>] Set or Get current execution prefix\n");
- acpi_os_printf ("References <Addr> Find all references to object at addr\n");
- acpi_os_printf ("Resources xxx Get and display resources\n");
- acpi_os_printf ("Terminate Delete namespace and all internal objects\n");
- acpi_os_printf ("Thread <Threads><Loops><Name_path> Spawn threads to execute method(s)\n");
- return;
-
- case 'M':
- acpi_os_printf ("\nControl Method Execution Commands\n\n");
- acpi_os_printf ("Arguments (or Args) Display method arguments\n");
- acpi_os_printf ("Breakpoint <Aml_offset> Set an AML execution breakpoint\n");
- acpi_os_printf ("Call Run to next control method invocation\n");
- acpi_os_printf ("Go Allow method to run to completion\n");
- acpi_os_printf ("Information Display info about the current method\n");
- acpi_os_printf ("Into Step into (not over) a method call\n");
- acpi_os_printf ("List [# of Aml Opcodes] Display method ASL statements\n");
- acpi_os_printf ("Locals Display method local variables\n");
- acpi_os_printf ("Results Display method result stack\n");
- acpi_os_printf ("Set <A|L> <#> <Value> Set method data (Arguments/Locals)\n");
- acpi_os_printf ("Stop Terminate control method\n");
- acpi_os_printf ("Tree Display control method calling tree\n");
- acpi_os_printf ("<Enter> Single step next AML opcode (over calls)\n");
- return;
-
- case 'F':
- acpi_os_printf ("\nFile I/O Commands\n\n");
- acpi_os_printf ("Close Close debug output file\n");
- acpi_os_printf ("Open <Output Filename> Open a file for debug output\n");
- acpi_os_printf ("Load <Input Filename> Load ACPI table from a file\n");
- return;
-
- default:
- acpi_os_printf ("Unrecognized Command Class: %X\n", help_type);
- return;
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_get_next_token
- *
- * PARAMETERS: String - Command buffer
- * Next - Return value, end of next token
- *
- * RETURN: Pointer to the start of the next token.
- *
- * DESCRIPTION: Command line parsing. Get the next token on the command line
- *
- ******************************************************************************/
-
-NATIVE_CHAR *
-acpi_db_get_next_token (
- NATIVE_CHAR *string,
- NATIVE_CHAR **next)
-{
- NATIVE_CHAR *start;
-
-
- /* At end of buffer? */
-
- if (!string || !(*string))
- {
- return (NULL);
- }
-
- /* Get rid of any spaces at the beginning */
-
- if (*string == ' ')
- {
- while (*string && (*string == ' '))
- {
- string++;
- }
-
- if (!(*string))
- {
- return (NULL);
- }
- }
-
- start = string;
-
- /* Find end of token */
-
- while (*string && (*string != ' '))
- {
- string++;
- }
-
- if (!(*string))
- {
- *next = NULL;
- }
- else
- {
- *string = 0;
- *next = string + 1;
- }
-
- return (start);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_get_line
- *
- * PARAMETERS: Input_buffer - Command line buffer
- *
- * RETURN: None
- *
- * DESCRIPTION: Get the next command line from the user. Gets entire line
- * up to the next newline
- *
- ******************************************************************************/
-
-u32
-acpi_db_get_line (
- NATIVE_CHAR *input_buffer)
-{
- u32 i;
- u32 count;
- NATIVE_CHAR *next;
- NATIVE_CHAR *this;
-
-
- ACPI_STRCPY (acpi_gbl_db_parsed_buf, input_buffer);
- ACPI_STRUPR (acpi_gbl_db_parsed_buf);
-
- this = acpi_gbl_db_parsed_buf;
- for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
- {
- acpi_gbl_db_args[i] = acpi_db_get_next_token (this, &next);
- if (!acpi_gbl_db_args[i])
- {
- break;
- }
-
- this = next;
- }
-
- /* Uppercase the actual command */
-
- if (acpi_gbl_db_args[0])
- {
- ACPI_STRUPR (acpi_gbl_db_args[0]);
- }
-
- count = i;
- if (count)
- {
- count--; /* Number of args only */
- }
-
- return (count);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_match_command
- *
- * PARAMETERS: User_command - User command line
- *
- * RETURN: Index into command array, -1 if not found
- *
- * DESCRIPTION: Search command array for a command match
- *
- ******************************************************************************/
-
-u32
-acpi_db_match_command (
- NATIVE_CHAR *user_command)
-{
- u32 i;
-
-
- if (!user_command || user_command[0] == 0)
- {
- return (CMD_NULL);
- }
-
- for (i = CMD_FIRST_VALID; acpi_gbl_db_commands[i].name; i++)
- {
- if (ACPI_STRSTR (acpi_gbl_db_commands[i].name, user_command) ==
- acpi_gbl_db_commands[i].name)
- {
- return (i);
- }
- }
-
- /* Command not recognized */
-
- return (CMD_NOT_FOUND);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_command_dispatch
- *
- * PARAMETERS: Input_buffer - Command line buffer
- * Walk_state - Current walk
- * Op - Current (executing) parse op
- *
- * RETURN: Status
- *
- * DESCRIPTION: Command dispatcher. Called from two places:
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_command_dispatch (
- NATIVE_CHAR *input_buffer,
- acpi_walk_state *walk_state,
- acpi_parse_object *op)
-{
- u32 temp;
- u32 command_index;
- u32 param_count;
- NATIVE_CHAR *command_line;
- acpi_status status = AE_CTRL_TRUE;
-
-
- /* If Acpi_terminate has been called, terminate this thread */
-
- if (acpi_gbl_db_terminate_threads)
- {
- return (AE_CTRL_TERMINATE);
- }
-
- param_count = acpi_db_get_line (input_buffer);
- command_index = acpi_db_match_command (acpi_gbl_db_args[0]);
- temp = 0;
-
- /* Verify that we have the minimum number of params */
-
- if (param_count < acpi_gbl_db_commands[command_index].min_args)
- {
- acpi_os_printf ("%d parameters entered, [%s] requires %d parameters\n",
- param_count, acpi_gbl_db_commands[command_index].name, acpi_gbl_db_commands[command_index].min_args);
- return (AE_CTRL_TRUE);
- }
-
- /* Decode and dispatch the command */
-
- switch (command_index)
- {
- case CMD_NULL:
- if (op)
- {
- return (AE_OK);
- }
- break;
-
- case CMD_ALLOCATIONS:
-
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- acpi_ut_dump_allocations ((u32) -1, NULL);
-#endif
- break;
-
- case CMD_ARGS:
- case CMD_ARGUMENTS:
- acpi_db_display_arguments ();
- break;
-
- case CMD_BREAKPOINT:
- acpi_db_set_method_breakpoint (acpi_gbl_db_args[1], walk_state, op);
- break;
-
- case CMD_CALL:
- acpi_db_set_method_call_breakpoint (op);
- status = AE_OK;
- break;
-
- case CMD_CLOSE:
- acpi_db_close_debug_file ();
- break;
-
- case CMD_DEBUG:
- acpi_db_execute (acpi_gbl_db_args[1], &acpi_gbl_db_args[2], EX_SINGLE_STEP);
- break;
-
- case CMD_DUMP:
- acpi_db_decode_and_display_object (acpi_gbl_db_args[1], acpi_gbl_db_args[2]);
- break;
-
- case CMD_ENABLEACPI:
- status = acpi_enable();
- if (ACPI_FAILURE(status))
- {
- acpi_os_printf("Acpi_enable failed (Status=%X)\n", status);
- return (status);
- }
- break;
-
- case CMD_EVENT:
- acpi_os_printf ("Event command not implemented\n");
- break;
-
- case CMD_EXECUTE:
- acpi_db_execute (acpi_gbl_db_args[1], &acpi_gbl_db_args[2], EX_NO_SINGLE_STEP);
- break;
-
- case CMD_FIND:
- status = acpi_db_find_name_in_namespace (acpi_gbl_db_args[1]);
- break;
-
- case CMD_GO:
- acpi_gbl_cm_single_step = FALSE;
- return (AE_OK);
-
- case CMD_HELP:
- case CMD_HELP2:
- acpi_db_display_help (acpi_gbl_db_args[1]);
- break;
-
- case CMD_HISTORY:
- acpi_db_display_history ();
- break;
-
- case CMD_HISTORY_EXE:
- command_line = acpi_db_get_from_history (acpi_gbl_db_args[1]);
- if (!command_line)
- {
- return (AE_CTRL_TRUE);
- }
-
- status = acpi_db_command_dispatch (command_line, walk_state, op);
- if (ACPI_SUCCESS (status))
- {
- status = AE_CTRL_TRUE;
- }
- return (status);
-
- case CMD_HISTORY_LAST:
- command_line = acpi_db_get_from_history (NULL);
- if (!command_line)
- {
- return (AE_CTRL_TRUE);
- }
-
- status = acpi_db_command_dispatch (command_line, walk_state, op);
- if (ACPI_SUCCESS (status))
- {
- status = AE_CTRL_TRUE;
- }
- return (status);
-
- case CMD_INFORMATION:
- acpi_db_display_method_info (op);
- break;
-
- case CMD_INTEGRITY:
- acpi_db_check_integrity ();
- break;
-
- case CMD_INTO:
- if (op)
- {
- acpi_gbl_cm_single_step = TRUE;
- return (AE_OK);
- }
- break;
-
- case CMD_LEVEL:
- if (param_count == 0)
- {
- acpi_os_printf ("Current debug level for file output is: %8.8lX\n", acpi_gbl_db_debug_level);
- acpi_os_printf ("Current debug level for console output is: %8.8lX\n", acpi_gbl_db_console_debug_level);
- }
- else if (param_count == 2)
- {
- temp = acpi_gbl_db_console_debug_level;
- acpi_gbl_db_console_debug_level = ACPI_STRTOUL (acpi_gbl_db_args[1], NULL, 16);
- acpi_os_printf ("Debug Level for console output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_console_debug_level);
- }
- else
- {
- temp = acpi_gbl_db_debug_level;
- acpi_gbl_db_debug_level = ACPI_STRTOUL (acpi_gbl_db_args[1], NULL, 16);
- acpi_os_printf ("Debug Level for file output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_debug_level);
- }
- break;
-
- case CMD_LIST:
- acpi_db_disassemble_aml (acpi_gbl_db_args[1], op);
- break;
-
- case CMD_LOAD:
- status = acpi_db_load_acpi_table (acpi_gbl_db_args[1]);
- if (ACPI_FAILURE (status))
- {
- return (status);
- }
- break;
-
- case CMD_LOCKS:
- acpi_db_display_locks ();
- break;
-
- case CMD_LOCALS:
- acpi_db_display_locals ();
- break;
-
- case CMD_METHODS:
- status = acpi_db_display_objects ("METHOD", acpi_gbl_db_args[1]);
- break;
-
- case CMD_NAMESPACE:
- acpi_db_dump_namespace (acpi_gbl_db_args[1], acpi_gbl_db_args[2]);
- break;
-
- case CMD_NOTIFY:
- temp = ACPI_STRTOUL (acpi_gbl_db_args[2], NULL, 0);
- acpi_db_send_notify (acpi_gbl_db_args[1], temp);
- break;
-
- case CMD_OBJECT:
- ACPI_STRUPR (acpi_gbl_db_args[1]);
- status = acpi_db_display_objects (acpi_gbl_db_args[1], acpi_gbl_db_args[2]);
- break;
-
- case CMD_OPEN:
- acpi_db_open_debug_file (acpi_gbl_db_args[1]);
- break;
-
- case CMD_OWNER:
- acpi_db_dump_namespace_by_owner (acpi_gbl_db_args[1], acpi_gbl_db_args[2]);
- break;
-
- case CMD_PREFIX:
- acpi_db_set_scope (acpi_gbl_db_args[1]);
- break;
-
- case CMD_REFERENCES:
- acpi_db_find_references (acpi_gbl_db_args[1]);
- break;
-
- case CMD_RESOURCES:
- acpi_db_display_resources (acpi_gbl_db_args[1]);
- break;
-
- case CMD_RESULTS:
- acpi_db_display_results ();
- break;
-
- case CMD_SET:
- acpi_db_set_method_data (acpi_gbl_db_args[1], acpi_gbl_db_args[2], acpi_gbl_db_args[3]);
- break;
-
- case CMD_STATS:
- status = acpi_db_display_statistics (acpi_gbl_db_args[1]);
- break;
-
- case CMD_STOP:
- return (AE_NOT_IMPLEMENTED);
-
- case CMD_TABLES:
- acpi_db_display_table_info (acpi_gbl_db_args[1]);
- break;
-
- case CMD_TERMINATE:
- acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT);
- acpi_ut_subsystem_shutdown ();
-
- /* TBD: [Restructure] Need some way to re-initialize without re-creating the semaphores! */
-
- /* Acpi_initialize (NULL); */
- break;
-
- case CMD_THREADS:
- acpi_db_create_execution_threads (acpi_gbl_db_args[1], acpi_gbl_db_args[2], acpi_gbl_db_args[3]);
- break;
-
- case CMD_TREE:
- acpi_db_display_calling_tree ();
- break;
-
- case CMD_UNLOAD:
- acpi_db_unload_acpi_table (acpi_gbl_db_args[1], acpi_gbl_db_args[2]);
- break;
-
- case CMD_EXIT:
- case CMD_QUIT:
- if (op)
- {
- acpi_os_printf ("Method execution terminated\n");
- return (AE_CTRL_TERMINATE);
- }
-
- if (!acpi_gbl_db_output_to_file)
- {
- acpi_dbg_level = DEBUG_DEFAULT;
- }
-
- /* Shutdown */
-
- /* Acpi_ut_subsystem_shutdown (); */
- acpi_db_close_debug_file ();
-
- acpi_gbl_db_terminate_threads = TRUE;
-
- return (AE_CTRL_TERMINATE);
-
- case CMD_NOT_FOUND:
- default:
- acpi_os_printf ("Unknown Command\n");
- return (AE_CTRL_TRUE);
- }
-
-
- /* Add all commands that come here to the history buffer */
-
- acpi_db_add_to_history (input_buffer);
- return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_execute_thread
- *
- * PARAMETERS: Context - Not used
- *
- * RETURN: None
- *
- * DESCRIPTION: Debugger execute thread. Waits for a command line, then
- * simply dispatches it.
- *
- ******************************************************************************/
-
-void ACPI_SYSTEM_XFACE
-acpi_db_execute_thread (
- void *context)
-{
- acpi_status status = AE_OK;
- acpi_status Mstatus;
-
-
- while (status != AE_CTRL_TERMINATE)
- {
- acpi_gbl_method_executing = FALSE;
- acpi_gbl_step_to_next_call = FALSE;
-
- Mstatus = acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY);
- if (ACPI_FAILURE (Mstatus))
- {
- return;
- }
-
- status = acpi_db_command_dispatch (acpi_gbl_db_line_buf, NULL, NULL);
-
- Mstatus = acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
- if (ACPI_FAILURE (Mstatus))
- {
- return;
- }
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_single_thread
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Debugger execute thread. Waits for a command line, then
- * simply dispatches it.
- *
- ******************************************************************************/
-
-void
-acpi_db_single_thread (
- void)
-{
-
- acpi_gbl_method_executing = FALSE;
- acpi_gbl_step_to_next_call = FALSE;
-
- (void) acpi_db_command_dispatch (acpi_gbl_db_line_buf, NULL, NULL);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_user_commands
- *
- * PARAMETERS: Prompt - User prompt (depends on mode)
- * Op - Current executing parse op
- *
- * RETURN: None
- *
- * DESCRIPTION: Command line execution for the AML debugger. Commands are
- * matched and dispatched here.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_user_commands (
- NATIVE_CHAR prompt,
- acpi_parse_object *op)
-{
- acpi_status status = AE_OK;
-
-
- /* TBD: [Restructure] Need a separate command line buffer for step mode */
-
- while (!acpi_gbl_db_terminate_threads)
- {
- /* Force output to console until a command is entered */
-
- acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
-
- /* Different prompt if method is executing */
-
- if (!acpi_gbl_method_executing)
- {
- acpi_os_printf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
- }
- else
- {
- acpi_os_printf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
- }
-
- /* Get the user input line */
-
- (void) acpi_os_get_line (acpi_gbl_db_line_buf);
-
- /* Check for single or multithreaded debug */
-
- if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED)
- {
- /*
- * Signal the debug thread that we have a command to execute,
- * and wait for the command to complete.
- */
- status = acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_READY);
- if (ACPI_FAILURE (status))
- {
- return (status);
- }
-
- status = acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
- if (ACPI_FAILURE (status))
- {
- return (status);
- }
- }
- else
- {
- /* Just call to the command line interpreter */
-
- acpi_db_single_thread ();
- }
- }
-
- /*
- * Only this thread (the original thread) should actually terminate the subsystem,
- * because all the semaphores are deleted during termination
- */
- status = acpi_terminate ();
- return (status);
-}
-
-
-#endif /* ACPI_DEBUGGER */
-
diff --git a/drivers/acpi/debugger/dbstats.c b/drivers/acpi/debugger/dbstats.c
deleted file mode 100644
index 32ba47dd4c86..000000000000
--- a/drivers/acpi/debugger/dbstats.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*******************************************************************************
- *
- * Module Name: dbstats - Generation and display of ACPI table statistics
- * $Revision: 61 $
- *
- ******************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2002, R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <acpi.h>
-#include <acdebug.h>
-#include <acnamesp.h>
-
-#ifdef ACPI_DEBUGGER
-
-#define _COMPONENT ACPI_CA_DEBUGGER
- ACPI_MODULE_NAME ("dbstats")
-
-/*
- * Statistics subcommands
- */
-static ARGUMENT_INFO acpi_db_stat_types [] =
-{ {"ALLOCATIONS"},
- {"OBJECTS"},
- {"MEMORY"},
- {"MISC"},
- {"TABLES"},
- {"SIZES"},
- {"STACK"},
- {NULL} /* Must be null terminated */
-};
-
-#define CMD_STAT_ALLOCATIONS 0
-#define CMD_STAT_OBJECTS 1
-#define CMD_STAT_MEMORY 2
-#define CMD_STAT_MISC 3
-#define CMD_STAT_TABLES 4
-#define CMD_STAT_SIZES 5
-#define CMD_STAT_STACK 6
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_enumerate_object
- *
- * PARAMETERS: Obj_desc - Object to be counted
- *
- * RETURN: None
- *
- * DESCRIPTION: Add this object to the global counts, by object type.
- * Limited recursion handles subobjects and packages, and this
- * is probably acceptable within the AML debugger only.
- *
- ******************************************************************************/
-
-void
-acpi_db_enumerate_object (
- acpi_operand_object *obj_desc)
-{
- u32 i;
-
-
- if (!obj_desc)
- {
- return;
- }
-
-
- /* Enumerate this object first */
-
- acpi_gbl_num_objects++;
-
- if (ACPI_GET_OBJECT_TYPE (obj_desc) > INTERNAL_TYPE_NODE_MAX)
- {
- acpi_gbl_obj_type_count_misc++;
- }
- else
- {
- acpi_gbl_obj_type_count [ACPI_GET_OBJECT_TYPE (obj_desc)]++;
- }
-
- /* Count the sub-objects */
-
- switch (ACPI_GET_OBJECT_TYPE (obj_desc))
- {
- case ACPI_TYPE_PACKAGE:
- for (i = 0; i < obj_desc->package.count; i++)
- {
- acpi_db_enumerate_object (obj_desc->package.elements[i]);
- }
- break;
-
- case ACPI_TYPE_DEVICE:
- acpi_db_enumerate_object (obj_desc->device.sys_handler);
- acpi_db_enumerate_object (obj_desc->device.drv_handler);
- acpi_db_enumerate_object (obj_desc->device.addr_handler);
- break;
-
- case ACPI_TYPE_BUFFER_FIELD:
- if (acpi_ns_get_secondary_object (obj_desc))
- {
- acpi_gbl_obj_type_count [ACPI_TYPE_BUFFER_FIELD]++;
- }
- break;
-
- case ACPI_TYPE_REGION:
- acpi_gbl_obj_type_count [INTERNAL_TYPE_REGION_FIELD ]++;
- acpi_db_enumerate_object (obj_desc->region.addr_handler);
- break;
-
- case ACPI_TYPE_POWER:
- acpi_db_enumerate_object (obj_desc->power_resource.sys_handler);
- acpi_db_enumerate_object (obj_desc->power_resource.drv_handler);
- break;
-
- case ACPI_TYPE_PROCESSOR:
- acpi_db_enumerate_object (obj_desc->processor.sys_handler);
- acpi_db_enumerate_object (obj_desc->processor.drv_handler);
- acpi_db_enumerate_object (obj_desc->processor.addr_handler);
- break;
-
- case ACPI_TYPE_THERMAL:
- acpi_db_enumerate_object (obj_desc->thermal_zone.sys_handler);
- acpi_db_enumerate_object (obj_desc->thermal_zone.drv_handler);
- acpi_db_enumerate_object (obj_desc->thermal_zone.addr_handler);
- break;
-
- default:
- break;
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_classify_one_object
- *
- * PARAMETERS: Callback for Walk_namespace
- *
- * RETURN: Status
- *
- * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
- * the parent namespace node.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_classify_one_object (
- acpi_handle obj_handle,
- u32 nesting_level,
- void *context,
- void **return_value)
-{
- acpi_namespace_node *node;
- acpi_operand_object *obj_desc;
- u32 type;
-
-
- acpi_gbl_num_nodes++;
-
- node = (acpi_namespace_node *) obj_handle;
- obj_desc = acpi_ns_get_attached_object (node);
-
- acpi_db_enumerate_object (obj_desc);
-
- type = node->type;
- if (type > INTERNAL_TYPE_NODE_MAX)
- {
- acpi_gbl_node_type_count_misc++;
- }
-
- else
- {
- acpi_gbl_node_type_count [type]++;
- }
-
- return AE_OK;
-
-
- /* TBD: These need to be counted during the initial parsing phase */
- /*
- if (Acpi_ps_is_named_op (Op->Opcode))
- {
- Num_nodes++;
- }
-
- if (Is_method)
- {
- Num_method_elements++;
- }
-
- Num_grammar_elements++;
- Op = Acpi_ps_get_depth_next (Root, Op);
-
- Size_of_parse_tree = (Num_grammar_elements - Num_method_elements) * (u32) sizeof (acpi_parse_object);
- Size_of_method_trees = Num_method_elements * (u32) sizeof (acpi_parse_object);
- Size_of_node_entries = Num_nodes * (u32) sizeof (acpi_namespace_node);
- Size_of_acpi_objects = Num_nodes * (u32) sizeof (acpi_operand_object);
-
- */
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_count_namespace_objects
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Count and classify the entire namespace, including all
- * namespace nodes and attached objects.
- *
- ******************************************************************************/
-
-void
-acpi_db_count_namespace_objects (
- void)
-{
- u32 i;
-
-
- acpi_gbl_num_nodes = 0;
- acpi_gbl_num_objects = 0;
-
- acpi_gbl_obj_type_count_misc = 0;
- for (i = 0; i < (INTERNAL_TYPE_NODE_MAX -1); i++)
- {
- acpi_gbl_obj_type_count [i] = 0;
- acpi_gbl_node_type_count [i] = 0;
- }
-
- (void) acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
- FALSE, acpi_db_classify_one_object, NULL, NULL);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_display_statistics
- *
- * PARAMETERS: Type_arg - Subcommand
- *
- * RETURN: Status
- *
- * DESCRIPTION: Display various statistics
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_display_statistics (
- NATIVE_CHAR *type_arg)
-{
- u32 i;
- u32 type;
- u32 size;
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- u32 outstanding;
-#endif
-
-
- if (!acpi_gbl_DSDT)
- {
- acpi_os_printf ("*** Warning: There is no DSDT loaded\n");
- }
-
- if (!type_arg)
- {
- acpi_os_printf ("The following subcommands are available:\n ALLOCATIONS, OBJECTS, MEMORY, MISC, SIZES, TABLES\n");
- return (AE_OK);
- }
-
- ACPI_STRUPR (type_arg);
- type = acpi_db_match_argument (type_arg, acpi_db_stat_types);
- if (type == (u32) -1)
- {
- acpi_os_printf ("Invalid or unsupported argument\n");
- return (AE_OK);
- }
-
-
- switch (type)
- {
- case CMD_STAT_ALLOCATIONS:
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- acpi_ut_dump_allocation_info ();
-#endif
- break;
-
- case CMD_STAT_TABLES:
-
- acpi_os_printf ("ACPI Table Information:\n\n");
- if (acpi_gbl_DSDT)
- {
- acpi_os_printf ("DSDT Length:................% 7ld (%X)\n", acpi_gbl_DSDT->length, acpi_gbl_DSDT->length);
- }
- break;
-
- case CMD_STAT_OBJECTS:
-
- acpi_db_count_namespace_objects ();
-
- acpi_os_printf ("\nObjects defined in the current namespace:\n\n");
-
- acpi_os_printf ("%16.16s % 10.10s % 10.10s\n", "ACPI_TYPE", "NODES", "OBJECTS");
-
- for (i = 0; i < INTERNAL_TYPE_NODE_MAX; i++)
- {
- acpi_os_printf ("%16.16s % 10ld% 10ld\n", acpi_ut_get_type_name (i),
- acpi_gbl_node_type_count [i], acpi_gbl_obj_type_count [i]);
- }
- acpi_os_printf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
- acpi_gbl_node_type_count_misc, acpi_gbl_obj_type_count_misc);
-
- acpi_os_printf ("%16.16s % 10ld% 10ld\n", "TOTALS:",
- acpi_gbl_num_nodes, acpi_gbl_num_objects);
- break;
-
- case CMD_STAT_MEMORY:
-
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- acpi_os_printf ("\n----Object and Cache Statistics---------------------------------------------\n");
-
- for (i = 0; i < ACPI_NUM_MEM_LISTS; i++)
- {
- acpi_os_printf ("\n%s\n", acpi_gbl_memory_lists[i].list_name);
-
- if (acpi_gbl_memory_lists[i].max_cache_depth > 0)
- {
- acpi_os_printf (" Cache: [Depth Max Avail Size] % 7d % 7d % 7d % 7d B\n",
- acpi_gbl_memory_lists[i].cache_depth,
- acpi_gbl_memory_lists[i].max_cache_depth,
- acpi_gbl_memory_lists[i].max_cache_depth - acpi_gbl_memory_lists[i].cache_depth,
- (acpi_gbl_memory_lists[i].cache_depth * acpi_gbl_memory_lists[i].object_size));
-
- acpi_os_printf (" Cache: [Requests Hits Misses Obj_size] % 7d % 7d % 7d % 7d B\n",
- acpi_gbl_memory_lists[i].cache_requests,
- acpi_gbl_memory_lists[i].cache_hits,
- acpi_gbl_memory_lists[i].cache_requests - acpi_gbl_memory_lists[i].cache_hits,
- acpi_gbl_memory_lists[i].object_size);
- }
-
- outstanding = acpi_gbl_memory_lists[i].total_allocated -
- acpi_gbl_memory_lists[i].total_freed -
- acpi_gbl_memory_lists[i].cache_depth;
-
- if (acpi_gbl_memory_lists[i].object_size)
- {
- size = ACPI_ROUND_UP_TO_1K (outstanding * acpi_gbl_memory_lists[i].object_size);
- }
- else
- {
- size = ACPI_ROUND_UP_TO_1K (acpi_gbl_memory_lists[i].current_total_size);
- }
-
- acpi_os_printf (" Mem: [Alloc Free Outstanding Size] % 7d % 7d % 7d % 7d Kb\n",
- acpi_gbl_memory_lists[i].total_allocated,
- acpi_gbl_memory_lists[i].total_freed,
- outstanding, size);
- }
-#endif
-
- break;
-
- case CMD_STAT_MISC:
-
- acpi_os_printf ("\nMiscellaneous Statistics:\n\n");
- acpi_os_printf ("Calls to Acpi_ps_find:.. ........% 7ld\n", acpi_gbl_ps_find_count);
- acpi_os_printf ("Calls to Acpi_ns_lookup:..........% 7ld\n", acpi_gbl_ns_lookup_count);
-
- acpi_os_printf ("\n");
-
- acpi_os_printf ("Mutex usage:\n\n");
- for (i = 0; i < NUM_MTX; i++)
- {
- acpi_os_printf ("%-28s: % 7ld\n", acpi_ut_get_mutex_name (i), acpi_gbl_acpi_mutex_info[i].use_count);
- }
- break;
-
-
- case CMD_STAT_SIZES:
-
- acpi_os_printf ("\nInternal object sizes:\n\n");
-
- acpi_os_printf ("Common %3d\n", sizeof (ACPI_OBJECT_COMMON));
- acpi_os_printf ("Number %3d\n", sizeof (ACPI_OBJECT_INTEGER));
- acpi_os_printf ("String %3d\n", sizeof (ACPI_OBJECT_STRING));
- acpi_os_printf ("Buffer %3d\n", sizeof (ACPI_OBJECT_BUFFER));
- acpi_os_printf ("Package %3d\n", sizeof (ACPI_OBJECT_PACKAGE));
- acpi_os_printf ("Buffer_field %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD));
- acpi_os_printf ("Device %3d\n", sizeof (ACPI_OBJECT_DEVICE));
- acpi_os_printf ("Event %3d\n", sizeof (ACPI_OBJECT_EVENT));
- acpi_os_printf ("Method %3d\n", sizeof (ACPI_OBJECT_METHOD));
- acpi_os_printf ("Mutex %3d\n", sizeof (ACPI_OBJECT_MUTEX));
- acpi_os_printf ("Region %3d\n", sizeof (ACPI_OBJECT_REGION));
- acpi_os_printf ("Power_resource %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE));
- acpi_os_printf ("Processor %3d\n", sizeof (ACPI_OBJECT_PROCESSOR));
- acpi_os_printf ("Thermal_zone %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE));
- acpi_os_printf ("Region_field %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD));
- acpi_os_printf ("Bank_field %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD));
- acpi_os_printf ("Index_field %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD));
- acpi_os_printf ("Reference %3d\n", sizeof (ACPI_OBJECT_REFERENCE));
- acpi_os_printf ("Notify_handler %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER));
- acpi_os_printf ("Addr_handler %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER));
- acpi_os_printf ("Extra %3d\n", sizeof (ACPI_OBJECT_EXTRA));
- acpi_os_printf ("Data %3d\n", sizeof (ACPI_OBJECT_DATA));
-
- acpi_os_printf ("\n");
-
- acpi_os_printf ("Parse_object %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON));
- acpi_os_printf ("Parse_object_named %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED));
- acpi_os_printf ("Parse_object_asl %3d\n", sizeof (ACPI_PARSE_OBJ_ASL));
- acpi_os_printf ("Operand_object %3d\n", sizeof (acpi_operand_object));
- acpi_os_printf ("Namespace_node %3d\n", sizeof (acpi_namespace_node));
-
- break;
-
-
- case CMD_STAT_STACK:
-#if defined(ACPI_DEBUG_OUTPUT)
-
- size = (u32) (acpi_gbl_entry_stack_pointer - acpi_gbl_lowest_stack_pointer);
-
- acpi_os_printf ("\nSubsystem Stack Usage:\n\n");
- acpi_os_printf ("Entry Stack Pointer %X\n", acpi_gbl_entry_stack_pointer);
- acpi_os_printf ("Lowest Stack Pointer %X\n", acpi_gbl_lowest_stack_pointer);
- acpi_os_printf ("Stack Use %X (%d)\n", size, size);
- acpi_os_printf ("Deepest Procedure Nesting %d\n", acpi_gbl_deepest_nesting);
-#endif
- break;
-
- default:
- break;
- }
-
- acpi_os_printf ("\n");
- return (AE_OK);
-}
-
-
-#endif /* ACPI_DEBUGGER */
diff --git a/drivers/acpi/debugger/dbutils.c b/drivers/acpi/debugger/dbutils.c
deleted file mode 100644
index 72539e36eaa1..000000000000
--- a/drivers/acpi/debugger/dbutils.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*******************************************************************************
- *
- * Module Name: dbutils - AML debugger utilities
- * $Revision: 56 $
- *
- ******************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2002, R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acdebug.h"
-#include "acdispat.h"
-
-
-#ifdef ACPI_DEBUGGER
-
-#define _COMPONENT ACPI_CA_DEBUGGER
- ACPI_MODULE_NAME ("dbutils")
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_set_output_destination
- *
- * PARAMETERS: Output_flags - Current flags word
- *
- * RETURN: None
- *
- * DESCRIPTION: Set the current destination for debugger output. Alos sets
- * the debug output level accordingly.
- *
- ******************************************************************************/
-
-void
-acpi_db_set_output_destination (
- u32 output_flags)
-{
-
- acpi_gbl_db_output_flags = (u8) output_flags;
-
- if ((output_flags & ACPI_DB_REDIRECTABLE_OUTPUT) && acpi_gbl_db_output_to_file) {
- acpi_dbg_level = acpi_gbl_db_debug_level;
- }
- else {
- acpi_dbg_level = acpi_gbl_db_console_debug_level;
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_dump_buffer
- *
- * PARAMETERS: Address - Pointer to the buffer
- *
- * RETURN: None
- *
- * DESCRIPTION: Print a portion of a buffer
- *
- ******************************************************************************/
-
-void
-acpi_db_dump_buffer (
- u32 address)
-{
-
- acpi_os_printf ("\nLocation %X:\n", address);
-
- acpi_dbg_level |= ACPI_LV_TABLES;
- acpi_ut_dump_buffer (ACPI_TO_POINTER (address), 64, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_dump_object
- *
- * PARAMETERS: Obj_desc - External ACPI object to dump
- * Level - Nesting level.
- *
- * RETURN: None
- *
- * DESCRIPTION: Dump the contents of an ACPI external object
- *
- ******************************************************************************/
-
-void
-acpi_db_dump_object (
- acpi_object *obj_desc,
- u32 level)
-{
- u32 i;
-
-
- if (!obj_desc) {
- acpi_os_printf ("[Null Object]\n");
- return;
- }
-
- for (i = 0; i < level; i++) {
- acpi_os_printf (" ");
- }
-
- switch (obj_desc->type) {
- case ACPI_TYPE_ANY:
-
- acpi_os_printf ("[Object Reference] = %p\n", obj_desc->reference.handle);
- break;
-
-
- case ACPI_TYPE_INTEGER:
-
- acpi_os_printf ("[Integer] = %8.8X%8.8X\n",
- ACPI_HIDWORD (obj_desc->integer.value),
- ACPI_LODWORD (obj_desc->integer.value));
- break;
-
-
- case ACPI_TYPE_STRING:
-
- acpi_os_printf ("[String] Value: ");
- for (i = 0; i < obj_desc->string.length; i++) {
- acpi_os_printf ("%c", obj_desc->string.pointer[i]);
- }
- acpi_os_printf ("\n");
- break;
-
-
- case ACPI_TYPE_BUFFER:
-
- acpi_os_printf ("[Buffer] Length %.2X = ", obj_desc->buffer.length);
- acpi_ut_dump_buffer ((u8 *) obj_desc->buffer.pointer, obj_desc->buffer.length, DB_DWORD_DISPLAY, _COMPONENT);
- break;
-
-
- case ACPI_TYPE_PACKAGE:
-
- acpi_os_printf ("[Package] Contains %d Elements: \n", obj_desc->package.count);
-
- for (i = 0; i < obj_desc->package.count; i++) {
- acpi_db_dump_object (&obj_desc->package.elements[i], level+1);
- }
- break;
-
-
- case INTERNAL_TYPE_REFERENCE:
-
- acpi_os_printf ("[Object Reference] = %p\n", obj_desc->reference.handle);
- break;
-
-
- case ACPI_TYPE_PROCESSOR:
-
- acpi_os_printf ("[Processor]\n");
- break;
-
-
- case ACPI_TYPE_POWER:
-
- acpi_os_printf ("[Power Resource]\n");
- break;
-
-
- default:
-
- acpi_os_printf ("[Unknown Type] %X \n", obj_desc->type);
- break;
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_prep_namestring
- *
- * PARAMETERS: Name - String to prepare
- *
- * RETURN: None
- *
- * DESCRIPTION: Translate all forward slashes and dots to backslashes.
- *
- ******************************************************************************/
-
-void
-acpi_db_prep_namestring (
- NATIVE_CHAR *name)
-{
-
-
- if (!name) {
- return;
- }
-
- ACPI_STRUPR (name);
-
- /* Convert a leading forward slash to a backslash */
-
- if (*name == '/') {
- *name = '\\';
- }
-
- /* Ignore a leading backslash, this is the root prefix */
-
- if (*name == '\\') {
- name++;
- }
-
- /* Convert all slash path separators to dots */
-
- while (*name) {
- if ((*name == '/') ||
- (*name == '\\')) {
- *name = '.';
- }
-
- name++;
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_second_pass_parse
- *
- * PARAMETERS: Root - Root of the parse tree
- *
- * RETURN: Status
- *
- * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until
- * second pass to parse the control methods
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_second_pass_parse (
- acpi_parse_object *root)
-{
- acpi_parse_object *op = root;
- acpi_parse_object *method;
- acpi_parse_object *search_op;
- acpi_parse_object *start_op;
- acpi_status status = AE_OK;
- u32 base_aml_offset;
- acpi_walk_state *walk_state;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- acpi_os_printf ("Pass two parse ....\n");
-
- while (op) {
- if (op->common.aml_opcode == AML_METHOD_OP) {
- method = op;
-
- /* Create a new walk state for the parse */
-
- walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT,
- NULL, NULL, NULL);
- if (!walk_state) {
- return (AE_NO_MEMORY);
- }
-
- /* Init the Walk State */
-
- walk_state->parser_state.aml =
- walk_state->parser_state.aml_start = method->named.data;
- walk_state->parser_state.aml_end =
- walk_state->parser_state.pkg_end = method->named.data + method->named.length;
- walk_state->parser_state.start_scope = op;
-
- walk_state->descending_callback = acpi_ds_load1_begin_op;
- walk_state->ascending_callback = acpi_ds_load1_end_op;
-
- /* Perform the AML parse */
-
- status = acpi_ps_parse_aml (walk_state);
-
- base_aml_offset = (method->common.value.arg)->common.aml_offset + 1;
- start_op = (method->common.value.arg)->common.next;
- search_op = start_op;
-
- while (search_op) {
- search_op->common.aml_offset += base_aml_offset;
- search_op = acpi_ps_get_depth_next (start_op, search_op);
- }
- }
-
- if (op->common.aml_opcode == AML_REGION_OP) {
- /* TBD: [Investigate] this isn't quite the right thing to do! */
- /*
- *
- * Method = (ACPI_DEFERRED_OP *) Op;
- * Status = Acpi_ps_parse_aml (Op, Method->Body, Method->Body_length);
- */
- }
-
- if (ACPI_FAILURE (status)) {
- break;
- }
-
- op = acpi_ps_get_depth_next (root, op);
- }
-
- return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_local_ns_lookup
- *
- * PARAMETERS: Name - Name to lookup
- *
- * RETURN: Pointer to a namespace node
- *
- * DESCRIPTION: Lookup a name in the ACPI namespace
- *
- * Note: Currently begins search from the root. Could be enhanced to use
- * the current prefix (scope) node as the search beginning point.
- *
- ******************************************************************************/
-
-acpi_namespace_node *
-acpi_db_local_ns_lookup (
- NATIVE_CHAR *name)
-{
- NATIVE_CHAR *internal_path;
- acpi_status status;
- acpi_namespace_node *node = NULL;
-
-
- acpi_db_prep_namestring (name);
-
- /* Build an internal namestring */
-
- status = acpi_ns_internalize_name (name, &internal_path);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Invalid namestring: %s\n", name);
- return (NULL);
- }
-
- /*
- * Lookup the name.
- * (Uses root node as the search starting point)
- */
- status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
- ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &node);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could not locate name: %s %s\n", name, acpi_format_exception (status));
- }
-
- ACPI_MEM_FREE (internal_path);
- return (node);
-}
-
-
-#endif /* ACPI_DEBUGGER */
-
-
diff --git a/drivers/acpi/debugger/dbxface.c b/drivers/acpi/debugger/dbxface.c
deleted file mode 100644
index c2945fa1eaf8..000000000000
--- a/drivers/acpi/debugger/dbxface.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/*******************************************************************************
- *
- * Module Name: dbxface - AML Debugger external interfaces
- * $Revision: 64 $
- *
- ******************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2002, R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "acpi.h"
-#include "amlcode.h"
-#include "acdebug.h"
-#include "acdisasm.h"
-
-
-#ifdef ACPI_DEBUGGER
-
-#define _COMPONENT ACPI_CA_DEBUGGER
- ACPI_MODULE_NAME ("dbxface")
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_single_step
- *
- * PARAMETERS: Walk_state - Current walk
- * Op - Current executing op
- * Opcode_class - Class of the current AML Opcode
- *
- * RETURN: Status
- *
- * DESCRIPTION: Called just before execution of an AML opcode.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_single_step (
- acpi_walk_state *walk_state,
- acpi_parse_object *op,
- u32 opcode_class)
-{
- acpi_parse_object *next;
- acpi_status status = AE_OK;
- u32 original_debug_level;
- acpi_parse_object *display_op;
- acpi_parse_object *parent_op;
-
-
- ACPI_FUNCTION_ENTRY ();
-
- /* Check for single-step breakpoint */
-
- if (walk_state->method_breakpoint &&
- (walk_state->method_breakpoint <= op->common.aml_offset)) {
- /* Check if the breakpoint has been reached or passed */
- /* Hit the breakpoint, resume single step, reset breakpoint */
-
- acpi_os_printf ("***Break*** at AML offset %X\n", op->common.aml_offset);
- acpi_gbl_cm_single_step = TRUE;
- acpi_gbl_step_to_next_call = FALSE;
- walk_state->method_breakpoint = 0;
- }
-
- /* Check for user breakpoint (Must be on exact Aml offset) */
-
- else if (walk_state->user_breakpoint &&
- (walk_state->user_breakpoint == op->common.aml_offset)) {
- acpi_os_printf ("***User_breakpoint*** at AML offset %X\n", op->common.aml_offset);
- acpi_gbl_cm_single_step = TRUE;
- acpi_gbl_step_to_next_call = FALSE;
- walk_state->method_breakpoint = 0;
- }
-
-
- /*
- * Check if this is an opcode that we are interested in --
- * namely, opcodes that have arguments
- */
- if (op->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
- return (AE_OK);
- }
-
- switch (opcode_class) {
- case AML_CLASS_UNKNOWN:
- case AML_CLASS_ARGUMENT: /* constants, literals, etc. do nothing */
- return (AE_OK);
-
- default:
- /* All other opcodes -- continue */
- break;
- }
-
- /*
- * Under certain debug conditions, display this opcode and its operands
- */
- if ((acpi_gbl_db_output_to_file) ||
- (acpi_gbl_cm_single_step) ||
- (acpi_dbg_level & ACPI_LV_PARSE)) {
- if ((acpi_gbl_db_output_to_file) ||
- (acpi_dbg_level & ACPI_LV_PARSE)) {
- acpi_os_printf ("\n[Aml_debug] Next AML Opcode to execute:\n");
- }
-
- /*
- * Display this op (and only this op - zero out the NEXT field temporarily,
- * and disable parser trace output for the duration of the display because
- * we don't want the extraneous debug output)
- */
- original_debug_level = acpi_dbg_level;
- acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
- next = op->common.next;
- op->common.next = NULL;
-
-
- display_op = op;
- parent_op = op->common.parent;
- if (parent_op) {
- if ((walk_state->control_state) &&
- (walk_state->control_state->common.state == ACPI_CONTROL_PREDICATE_EXECUTING)) {
- /*
- * We are executing the predicate of an IF or WHILE statement
- * Search upwards for the containing IF or WHILE so that the
- * entire predicate can be displayed.
- */
- while (parent_op) {
- if ((parent_op->common.aml_opcode == AML_IF_OP) ||
- (parent_op->common.aml_opcode == AML_WHILE_OP)) {
- display_op = parent_op;
- break;
- }
- parent_op = parent_op->common.parent;
- }
- }
- else {
- while (parent_op) {
- if ((parent_op->common.aml_opcode == AML_IF_OP) ||
- (parent_op->common.aml_opcode == AML_ELSE_OP) ||
- (parent_op->common.aml_opcode == AML_SCOPE_OP) ||
- (parent_op->common.aml_opcode == AML_METHOD_OP) ||
- (parent_op->common.aml_opcode == AML_WHILE_OP)) {
- break;
- }
- display_op = parent_op;
- parent_op = parent_op->common.parent;
- }
- }
- }
-
- /* Now we can display it */
-
- acpi_dm_disassemble (walk_state, display_op, ACPI_UINT32_MAX);
-
- if ((op->common.aml_opcode == AML_IF_OP) ||
- (op->common.aml_opcode == AML_WHILE_OP)) {
- if (walk_state->control_state->common.value) {
- acpi_os_printf ("Predicate = [True], IF block was executed\n");
- }
- else {
- acpi_os_printf ("Predicate = [False], Skipping IF block\n");
- }
- }
-
- else if (op->common.aml_opcode == AML_ELSE_OP) {
- acpi_os_printf ("Predicate = [False], ELSE block was executed\n");
- }
-
- /* Restore everything */
-
- op->common.next = next;
- acpi_os_printf ("\n\n");
- acpi_dbg_level = original_debug_level;
- }
-
- /* If we are not single stepping, just continue executing the method */
-
- if (!acpi_gbl_cm_single_step) {
- return (AE_OK);
- }
-
- /*
- * If we are executing a step-to-call command,
- * Check if this is a method call.
- */
- if (acpi_gbl_step_to_next_call) {
- if (op->common.aml_opcode != AML_INT_METHODCALL_OP) {
- /* Not a method call, just keep executing */
-
- return (AE_OK);
- }
-
- /* Found a method call, stop executing */
-
- acpi_gbl_step_to_next_call = FALSE;
- }
-
- /*
- * If the next opcode is a method call, we will "step over" it
- * by default.
- */
- if (op->common.aml_opcode == AML_INT_METHODCALL_OP) {
- acpi_gbl_cm_single_step = FALSE; /* No more single step while executing called method */
-
- /* Set the breakpoint on/before the call, it will stop execution as soon as we return */
-
- walk_state->method_breakpoint = 1; /* Must be non-zero! */
- }
-
-
- /* TBD: [Investigate] what are the namespace locking issues here */
-
- /* Acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */
-
- /* Go into the command loop and await next user command */
-
- acpi_gbl_method_executing = TRUE;
- status = AE_CTRL_TRUE;
- while (status == AE_CTRL_TRUE) {
- if (acpi_gbl_debugger_configuration == DEBUGGER_MULTI_THREADED) {
- /* Handshake with the front-end that gets user command lines */
-
- status = acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
- status = acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
- }
-
- else {
- /* Single threaded, we must get a command line ourselves */
-
- /* Force output to console until a command is entered */
-
- acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
-
- /* Different prompt if method is executing */
-
- if (!acpi_gbl_method_executing) {
- acpi_os_printf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
- }
- else {
- acpi_os_printf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
- }
-
- /* Get the user input line */
-
- (void) acpi_os_get_line (acpi_gbl_db_line_buf);
- }
-
- status = acpi_db_command_dispatch (acpi_gbl_db_line_buf, walk_state, op);
- }
-
- /* Acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */
-
- /* User commands complete, continue execution of the interrupted method */
-
- return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_initialize
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Init and start debugger
- *
- ******************************************************************************/
-
-acpi_status
-acpi_db_initialize (void)
-{
- acpi_status status;
-
-
- /* Init globals */
-
- acpi_gbl_db_buffer = NULL;
- acpi_gbl_db_filename = NULL;
- acpi_gbl_db_output_to_file = FALSE;
-
- acpi_gbl_db_debug_level = ACPI_LV_VERBOSITY2;
- acpi_gbl_db_console_debug_level = NORMAL_DEFAULT | ACPI_LV_TABLES;
- acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
-
- acpi_gbl_db_opt_tables = FALSE;
- acpi_gbl_db_opt_disasm = FALSE;
- acpi_gbl_db_opt_stats = FALSE;
- acpi_gbl_db_opt_verbose = TRUE;
- acpi_gbl_db_opt_ini_methods = TRUE;
-
- acpi_gbl_db_buffer = acpi_os_allocate (ACPI_DEBUG_BUFFER_SIZE);
- if (!acpi_gbl_db_buffer) {
- return (AE_NO_MEMORY);
- }
- ACPI_MEMSET (acpi_gbl_db_buffer, 0, ACPI_DEBUG_BUFFER_SIZE);
-
- /* Initial scope is the root */
-
- acpi_gbl_db_scope_buf [0] = '\\';
- acpi_gbl_db_scope_buf [1] = 0;
- acpi_gbl_db_scope_node = acpi_gbl_root_node;
-
- /*
- * If configured for multi-thread support, the debug executor runs in
- * a separate thread so that the front end can be in another address
- * space, environment, or even another machine.
- */
- if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
- /* These were created with one unit, grab it */
-
- status = acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could not get debugger mutex\n");
- return (status);
- }
- status = acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could not get debugger mutex\n");
- return (status);
- }
-
- /* Create the debug execution thread to execute commands */
-
- status = acpi_os_queue_for_execution (0, acpi_db_execute_thread, NULL);
- if (ACPI_FAILURE (status)) {
- acpi_os_printf ("Could not start debugger thread\n");
- return (status);
- }
- }
-
- if (!acpi_gbl_db_opt_verbose) {
- acpi_gbl_db_opt_disasm = TRUE;
- acpi_gbl_db_opt_stats = FALSE;
- }
-
- return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_db_terminate
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Stop debugger
- *
- ******************************************************************************/
-
-void
-acpi_db_terminate (void)
-{
-
- if (acpi_gbl_db_table_ptr) {
- acpi_os_free (acpi_gbl_db_table_ptr);
- }
- if (acpi_gbl_db_buffer) {
- acpi_os_free (acpi_gbl_db_buffer);
- }
-}
-
-
-#endif /* ACPI_DEBUGGER */
diff --git a/drivers/acpi/include/acpiosxf.h b/drivers/acpi/include/acpiosxf.h
index b6cac89b91b9..d6df38a20ed2 100644
--- a/drivers/acpi/include/acpiosxf.h
+++ b/drivers/acpi/include/acpiosxf.h
@@ -261,10 +261,6 @@ acpi_os_writable (
void *pointer,
u32 length);
-u32
-acpi_os_get_timer (
- void);
-
acpi_status
acpi_os_signal (
u32 function,
@@ -284,10 +280,6 @@ acpi_os_vprintf (
const NATIVE_CHAR *format,
va_list args);
-void
-acpi_os_redirect_output (
- void *destination);
-
/*
* Debug input
@@ -298,16 +290,4 @@ acpi_os_get_line (
NATIVE_CHAR *buffer);
-/*
- * Debug
- */
-
-void
-acpi_os_dbg_assert(
- void *failed_assertion,
- void *file_name,
- u32 line_number,
- NATIVE_CHAR *message);
-
-
#endif /* __ACPIOSXF_H__ */
diff --git a/drivers/acpi/kdb/README.txt b/drivers/acpi/kdb/README.txt
deleted file mode 100644
index 700c6b237386..000000000000
--- a/drivers/acpi/kdb/README.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-Using the ACPI debugger with kdb
---------------------------------
-
-ACPI CA includes a full-featured debugger, which allows the examination of
-a running system's ACPI tables, as well as running and stepping through
-control methods.
-
-Configuration
--------------
-1) Edit the main acpi Makefile. On the ACPI_CFLAGS line, remove the '#', thus
- enabling the debugger.
-
-2) Download the latest kdb patch from:
-
- ftp://oss.sgi.com/www/projects/kdb/download/ix86/
-
- Follow the instructions at http://oss.sgi.com/projects/kdb/ on how to
- install the patch and configure KDB.
-
-3) This would probably be a good time to recompile the kernel, and make sure
- kdb works (Hitting the Pause key should drop you into it. Type "go" to exit
- it.
-
-4) The kdb <--> ACPI debugger interface is a module. Type "make modules", and
- it will be built and placed in drivers/acpi/kdb.
-
-5) Change to that directory and type "insmod kdbm_acpi.o". This loads the
- module we just built.
-
-6) Break back into kdb. If you type help, you should now see "acpi" listed as
- a command, at the bottom.
-
-7) Type "acpi". You are now in the ACPI debugger. While hosted by kdb, it is
- wholly separate, and has many ACPI-specific commands. Type "?" or "help"
- to get a listing of the command categories, and then "help <category>" for
- a list of commands and their descriptions
diff --git a/drivers/acpi/kdb/kdbm_acpi.c b/drivers/acpi/kdb/kdbm_acpi.c
deleted file mode 100644
index e14ea39b9546..000000000000
--- a/drivers/acpi/kdb/kdbm_acpi.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * kdbm_acpi.c - kdb debugger module interface for ACPI debugger
- *
- * Copyright (C) 2000 Andrew Grover
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/types.h>
-#include <linux/kdb.h>
-#include <linux/module.h>
-
-#include "acpi.h"
-#include "acdebug.h"
-
-extern int acpi_in_debugger;
-
-static int
-kdbm_acpi(int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- acpi_in_debugger = 1;
-
- acpi_db_user_commands(DB_COMMAND_PROMPT, NULL);
-
- acpi_in_debugger = 0;
-
- return 0;
-}
-
-int
-init_module(void)
-{
- kdb_register("acpi", kdbm_acpi, "", "Enter ACPI debugger", 0);
-
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- kdb_unregister("acpi");
-}
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 62e85d568255..6e663fa8694b 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -134,16 +134,6 @@ acpi_os_allocate(ACPI_SIZE size)
return kmalloc(size, GFP_KERNEL);
}
-void *
-acpi_os_callocate(ACPI_SIZE size)
-{
- void *ptr = acpi_os_allocate(size);
- if (ptr)
- memset(ptr, 0, size);
-
- return ptr;
-}
-
void
acpi_os_free(void *ptr)
{
@@ -523,37 +513,6 @@ acpi_os_read_pci_configuration (
#endif /*CONFIG_ACPI_PCI*/
-acpi_status
-acpi_os_load_module (
- char *module_name)
-{
- ACPI_FUNCTION_TRACE ("os_load_module");
-
- if (!module_name)
- return_ACPI_STATUS (AE_BAD_PARAMETER);
-
- if (request_module(module_name) < 0) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to load module [%s].\n", module_name));
- return_ACPI_STATUS (AE_ERROR);
- }
-
- return_ACPI_STATUS (AE_OK);
-}
-
-acpi_status
-acpi_os_unload_module (
- char *module_name)
-{
- if (!module_name)
- return AE_BAD_PARAMETER;
-
- /* TODO: How on Linux? */
- /* this is done automatically for all modules with
- use_count = 0, I think. see: MOD_INC_USE_COUNT -ASG */
-
- return AE_OK;
-}
-
/*
* See acpi_os_queue_for_execution()
@@ -695,9 +654,10 @@ acpi_os_create_semaphore(
ACPI_FUNCTION_TRACE ("os_create_semaphore");
- sem = acpi_os_callocate(sizeof(struct semaphore));
+ sem = acpi_os_allocate(sizeof(struct semaphore));
if (!sem)
return_ACPI_STATUS (AE_NO_MEMORY);
+ memset(sem, 0, sizeof(struct semaphore));
sema_init(sem, initial_units);
@@ -913,12 +873,3 @@ acpi_os_signal (
return AE_OK;
}
-
-acpi_status
-acpi_os_breakpoint(NATIVE_CHAR *msg)
-{
- acpi_os_printf("breakpoint: %s", msg);
-
- return AE_OK;
-}
-
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 5d5edb42f24c..847b5938ce79 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -288,7 +288,7 @@ acpi_pci_irq_derive (
while (!irq && (bridge = bridge->bus->self)) {
pin = (pin + PCI_SLOT(bridge->devfn)) % 4;
irq = acpi_pci_irq_lookup(0, bridge->bus->number, PCI_SLOT(bridge->devfn), pin);
- };
+ }
if (!irq) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to derive IRQ for device %s\n", dev->slot_name));
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index b94b85b1cea4..4389f1d64bb8 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -54,12 +54,12 @@ static int acpi_pci_link_add (struct acpi_device *device);
static int acpi_pci_link_remove (struct acpi_device *device, int type);
static struct acpi_driver acpi_pci_link_driver = {
- .name = ACPI_PCI_LINK_DRIVER_NAME,
- .class = ACPI_PCI_LINK_CLASS,
- .ids = ACPI_PCI_LINK_HID,
- .ops = {
- .add = acpi_pci_link_add,
- .remove = acpi_pci_link_remove,
+ .name = ACPI_PCI_LINK_DRIVER_NAME,
+ .class = ACPI_PCI_LINK_CLASS,
+ .ids = ACPI_PCI_LINK_HID,
+ .ops = {
+ .add = acpi_pci_link_add,
+ .remove = acpi_pci_link_remove,
},
};
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index a56fedea61b4..57f235dbd102 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -51,8 +51,8 @@ static struct acpi_driver acpi_pci_root_driver = {
.class = ACPI_PCI_ROOT_CLASS,
.ids = ACPI_PCI_ROOT_HID,
.ops = {
- .add = acpi_pci_root_add,
- .remove = acpi_pci_root_remove,
+ .add = acpi_pci_root_add,
+ .remove = acpi_pci_root_remove,
},
};
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 68f71d76df6b..c62fa049ced3 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -23,8 +23,6 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-#define ACPI_C
-
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index 48f3b32dbfa9..4c7590389282 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -26,15 +26,15 @@
* Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse
* engineering the Windows drivers
* Yasushi Nagato - changes for linux kernel 2.4 -> 2.5
+ * Rob Miller - TV out and hotkeys help
*
*
* TODO
- * provide version info in proc
- * add Fn key status
*
*/
-#define TOSHIBA_ACPI_VERSION "0.12"
+#define TOSHIBA_ACPI_VERSION "0.13"
+#define PROC_INTERFACE_VERSION 1
#include <linux/kernel.h>
#include <linux/module.h>
@@ -43,9 +43,10 @@
#include <linux/proc_fs.h>
#include <linux/version.h>
-#define KERNEL24 (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0))
+#include <acconfig.h>
+#define OLD_ACPI_INTERFACE (ACPI_CA_VERSION < 0x20020000)
-#if KERNEL24
+#if OLD_ACPI_INTERFACE
#include <acpi.h>
extern struct proc_dir_entry* bm_proc_root;
#define acpi_root_dir bm_proc_root
@@ -82,10 +83,13 @@ MODULE_LICENSE("GPL");
#define HCI_SUCCESS 0x0000
#define HCI_FAILURE 0x1000
#define HCI_NOT_SUPPORTED 0x8000
+#define HCI_EMPTY 0x8c00
/* registers */
#define HCI_FAN 0x0004
+#define HCI_SYSTEM_EVENT 0x0016
#define HCI_VIDEO_OUT 0x001c
+#define HCI_HOTKEY_EVENT 0x001e
#define HCI_LCD_BRIGHTNESS 0x002a
/* field definitions */
@@ -94,6 +98,7 @@ MODULE_LICENSE("GPL");
#define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS)
#define HCI_VIDEO_OUT_LCD 0x1
#define HCI_VIDEO_OUT_CRT 0x2
+#define HCI_VIDEO_OUT_TV 0x4
/* utility
*/
@@ -104,6 +109,23 @@ _set_bit(u32* word, u32 mask, int value)
*word = (*word & ~mask) | (mask * value);
}
+/* an sscanf that takes explicit string length */
+static int
+snscanf(const char* str, int n, const char* format, ...)
+{
+ va_list args;
+ int result;
+ char* str2 = kmalloc(n + 1, GFP_KERNEL);
+ if (str2 == 0) return 0;
+ strncpy(str2, str, n);
+ str2[n] = 0;
+ va_start(args, format);
+ result = vsscanf(str2, format, args);
+ va_end(args);
+ kfree(str2);
+ return result;
+}
+
/* This is the common code at the end of every proc read handler. I don't
* understand it yet.
*/
@@ -226,14 +248,15 @@ hci_read1(u32 reg, u32* out1, u32* result)
#define PROC_LCD "lcd"
#define PROC_VIDEO "video"
#define PROC_FAN "fan"
+#define PROC_KEYS "keys"
+#define PROC_VERSION "version"
static struct proc_dir_entry* toshiba_proc_dir = NULL;
static int force_fan;
+static int last_key_event;
+static int key_event_valid;
/* proc file handlers
- *
- * WARNING: The write handlers are using sscanf on non-zero-terminated
- * buffers. This may result in memory reads past the buffer bounds.
*/
static int
@@ -270,7 +293,7 @@ proc_write_lcd(struct file* file, const char* buffer, unsigned long count,
u32 hci_result;
/* ISSUE: %i doesn't work with hex values as advertised */
- if (sscanf(buffer, " brightness : %i", &value) == 1 &&
+ if (snscanf(buffer, count, " brightness : %i", &value) == 1 &&
value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
value = value << HCI_LCD_BRIGHTNESS_SHIFT;
hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result);
@@ -297,8 +320,10 @@ proc_read_video(char* page, char** start, off_t off, int count, int* eof,
if (hci_result == HCI_SUCCESS) {
int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0;
int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0;
+ int is_tv = (value & HCI_VIDEO_OUT_TV ) ? 1 : 0;
p += sprintf(p, "lcd_out: %d\n", is_lcd);
p += sprintf(p, "crt_out: %d\n", is_crt);
+ p += sprintf(p, "tv_out: %d\n", is_tv);
} else {
p += sprintf(p, "ERROR\n");
goto end;
@@ -316,15 +341,18 @@ proc_write_video(struct file* file, const char* buffer, unsigned long count,
const char* buffer_end = buffer + count;
int lcd_out = -1;
int crt_out = -1;
+ int tv_out = -1;
u32 hci_result;
int video_out;
/* scan expression. Multiple expressions may be delimited with ; */
do {
- if (sscanf(buffer, " lcd_out : %i", &value) == 1)
+ if (snscanf(buffer, count, " lcd_out : %i", &value) == 1)
lcd_out = value & 1;
- else if (sscanf(buffer, " crt_out : %i", &value) == 1)
+ else if (snscanf(buffer, count, " crt_out : %i", &value) == 1)
crt_out = value & 1;
+ else if (snscanf(buffer, count, " tv_out : %i", &value) == 1)
+ tv_out = value & 1;
/* advance to one character past the next ; */
do ++buffer;
while ((buffer < buffer_end) && (*(buffer-1) != ';'));
@@ -337,6 +365,8 @@ proc_write_video(struct file* file, const char* buffer, unsigned long count,
_set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out);
if (crt_out != -1)
_set_bit(&new_video_out, HCI_VIDEO_OUT_CRT, crt_out);
+ if (tv_out != -1)
+ _set_bit(&new_video_out, HCI_VIDEO_OUT_TV, tv_out);
/* To avoid unnecessary video disruption, only write the new
* video setting if something changed. */
if (new_video_out != video_out)
@@ -376,7 +406,7 @@ proc_write_fan(struct file* file, const char* buffer, unsigned long count,
int value;
u32 hci_result;
- if (sscanf(buffer, " force_on : %i", &value) == 1 &&
+ if (snscanf(buffer, count, " force_on : %i", &value) == 1 &&
value >= 0 && value <= 1) {
hci_write1(HCI_FAN, value, &hci_result);
if (hci_result != HCI_SUCCESS)
@@ -390,6 +420,68 @@ proc_write_fan(struct file* file, const char* buffer, unsigned long count,
return count;
}
+static int
+proc_read_keys(char* page, char** start, off_t off, int count, int* eof,
+ void* context)
+{
+ char* p = page;
+ u32 hci_result;
+ u32 value;
+
+ if (off != 0) goto end;
+
+ if (!key_event_valid) {
+ hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result);
+ if (hci_result == HCI_SUCCESS) {
+ key_event_valid = 1;
+ last_key_event = value;
+ } else if (hci_result == HCI_EMPTY) {
+ /* better luck next time */
+ } else {
+ p += sprintf(p, "ERROR\n");
+ goto end;
+ }
+ }
+
+ p += sprintf(p, "hotkey_ready: %d\n", key_event_valid);
+ p += sprintf(p, "hotkey: 0x%04x\n", last_key_event);
+
+end:
+ return end_proc_read(p, page, off, count, start, eof);
+}
+
+static int
+proc_write_keys(struct file* file, const char* buffer, unsigned long count,
+ void* data)
+{
+ int value;
+
+ if (snscanf(buffer, count, " hotkey_ready : %i", &value) == 1 &&
+ value == 0) {
+ key_event_valid = 0;
+ } else {
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static int
+proc_read_version(char* page, char** start, off_t off, int count, int* eof,
+ void* context)
+{
+ char* p = page;
+
+ if (off != 0) goto end;
+
+ p += sprintf(p, "driver: %s\n", TOSHIBA_ACPI_VERSION);
+ p += sprintf(p, "proc_interface: %d\n",
+ PROC_INTERFACE_VERSION);
+
+end:
+ return end_proc_read(p, page, off, count, start, eof);
+}
+
/* proc and module init
*/
@@ -410,6 +502,13 @@ add_device(void)
toshiba_proc_dir, proc_read_fan, 0);
if (proc) proc->write_proc = proc_write_fan;
+ proc = create_proc_read_entry(PROC_KEYS, S_IFREG | S_IRUGO | S_IWUSR,
+ toshiba_proc_dir, proc_read_keys, 0);
+ if (proc) proc->write_proc = proc_write_keys;
+
+ proc = create_proc_read_entry(PROC_VERSION, S_IFREG | S_IRUGO | S_IWUSR,
+ toshiba_proc_dir, proc_read_version, 0);
+
return(AE_OK);
}
@@ -419,6 +518,8 @@ remove_device(void)
remove_proc_entry(PROC_LCD, toshiba_proc_dir);
remove_proc_entry(PROC_VIDEO, toshiba_proc_dir);
remove_proc_entry(PROC_FAN, toshiba_proc_dir);
+ remove_proc_entry(PROC_KEYS, toshiba_proc_dir);
+ remove_proc_entry(PROC_VERSION, toshiba_proc_dir);
return(AE_OK);
}
@@ -437,6 +538,10 @@ toshiba_acpi_init(void)
printk("Toshiba Laptop ACPI Extras version %s\n", TOSHIBA_ACPI_VERSION);
force_fan = 0;
+ key_event_valid = 0;
+
+ /* enable event fifo */
+ hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir);
if (!toshiba_proc_dir) {
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 6101e17ebe13..b3e37b7e66b2 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -266,8 +266,8 @@
#include <linux/proc_fs.h>
#include <linux/blkpg.h>
#include <linux/init.h>
+#include <linux/fcntl.h>
-#include <asm/fcntl.h>
#include <asm/uaccess.h>
/* used to tell the module to turn on full debugging messages */
diff --git a/drivers/hotplug/cpqphp.h b/drivers/hotplug/cpqphp.h
index 618bf2c739d2..18f99fad6989 100644
--- a/drivers/hotplug/cpqphp.h
+++ b/drivers/hotplug/cpqphp.h
@@ -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;
}
diff --git a/drivers/hotplug/cpqphp_core.c b/drivers/hotplug/cpqphp_core.c
index f7b5a5b6930c..aec0ecc145bc 100644
--- a/drivers/hotplug/cpqphp_core.c
+++ b/drivers/hotplug/cpqphp_core.c
@@ -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 @@ err_iounmap:
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);
diff --git a/drivers/hotplug/cpqphp_ctrl.c b/drivers/hotplug/cpqphp_ctrl.c
index f14f6dabe0b4..e30b88ac17f6 100644
--- a/drivers/hotplug/cpqphp_ctrl.c
+++ b/drivers/hotplug/cpqphp_ctrl.c
@@ -772,13 +772,13 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
return(NULL);
for (node = *head; node; node = node->next) {
- dbg(__FUNCTION__": req_size =%x node=%p, base=%x, length=%x\n",
- size, node, node->base, node->length);
+ dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
+ __FUNCTION__, size, node, node->base, node->length);
if (node->length < size)
continue;
if (node->base & (size - 1)) {
- dbg(__FUNCTION__": not aligned\n");
+ dbg("%s: not aligned\n", __FUNCTION__);
// this one isn't base aligned properly
// so we'll make a new entry and split it up
temp_dword = (node->base | (size-1)) + 1;
@@ -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
if (node->length > size) {
- dbg(__FUNCTION__": too big\n");
+ dbg("%s: too big\n", __FUNCTION__);
// this one is longer than we need
// so we'll make a new entry and split it up
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)
node->next = split_node;
} // 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
// Now take it out of the list
if (*head == node) {
@@ -856,7 +856,7 @@ int cpqhp_resource_sort_and_combine(struct pci_resource **head)
struct pci_resource *node2;
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))
return(1);
@@ -942,7 +942,7 @@ void cpqhp_ctrl_intr(int IRQ, struct controller * ctrl, struct pt_regs *regs)
// Read to clear posted writes
misc = readw(ctrl->hpc_reg + MISC);
- dbg (__FUNCTION__" - waking up\n");
+ dbg ("%s - waking up\n", __FUNCTION__);
wake_up_interruptible(&ctrl->queue);
}
@@ -1382,8 +1382,8 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
struct resource_lists res_lists;
hp_slot = func->device - ctrl->slot_device_offset;
- dbg(__FUNCTION__": func->device, slot_offset, hp_slot = %d, %d ,%d\n",
- func->device, ctrl->slot_device_offset, hp_slot);
+ dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
+ __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
if (ctrl->speed == 1) {
// Wait for exclusive access to hardware
@@ -1430,55 +1430,56 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
// turn on board and blink green LED
// Wait for exclusive access to hardware
- dbg(__FUNCTION__": before down\n");
+ dbg("%s: before down\n", __FUNCTION__);
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);
- dbg(__FUNCTION__": before green_LED_blink\n");
+ dbg("%s: before green_LED_blink\n", __FUNCTION__);
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);
- dbg(__FUNCTION__": before set_SOGO\n");
+ dbg("%s: before set_SOGO\n", __FUNCTION__);
set_SOGO(ctrl);
// 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);
- dbg(__FUNCTION__": after wait_for_ctrl_irq\n");
+ dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
// Done with exclusive hardware access
- dbg(__FUNCTION__": before up\n");
+ dbg("%s: before up\n", __FUNCTION__);
up(&ctrl->crit_sect);
- dbg(__FUNCTION__": after up\n");
+ dbg("%s: after up\n", __FUNCTION__);
// 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);
- 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
if (func->status == 0xFF) {
// power fault occurred, but it was benign
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;
func->status = 0;
} else {
// 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);
- dbg(__FUNCTION__": pci_read_config_dword returns %d\n", rc);
- dbg(__FUNCTION__": temp_register is %x\n", temp_register);
+ ctrl->pci_bus->number = func->bus;
+ rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), PCI_VENDOR_ID, &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) {
// Something's wrong here
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.
rc = NO_ADAPTER_PRESENT;
@@ -1494,7 +1495,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
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->mem_head = res_lists.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)
func->is_a_board = 0x01;
//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;
do {
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
device = func->device;
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.
// We will attempt to save the base Address Register Lengths
@@ -1927,7 +1928,7 @@ void cpqhp_pushbutton_thread (unsigned long slot)
func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);
if (!func) {
- dbg("Error! func NULL in "__FUNCTION__"\n");
+ dbg("Error! func NULL in %s\n", __FUNCTION__);
return ;
}
@@ -1951,7 +1952,7 @@ void cpqhp_pushbutton_thread (unsigned long slot)
func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);
if (!func) {
- dbg("Error! func NULL in "__FUNCTION__"\n");
+ dbg("Error! func NULL in %s\n", __FUNCTION__);
return ;
}
@@ -2066,7 +2067,7 @@ int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func)
}
if (rc) {
- dbg(__FUNCTION__": rc = %d\n", rc);
+ dbg("%s: rc = %d\n", __FUNCTION__, rc);
}
if (p_slot)
@@ -2082,7 +2083,9 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
u8 index = 0;
u8 replace_flag;
u32 rc = 0;
+ unsigned int devfn;
struct slot* p_slot;
+ struct pci_bus *pci_bus = ctrl->pci_bus;
int physical_slot=0;
device = func->device;
@@ -2094,8 +2097,11 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
// Make sure there are no video controllers here
while (func && !rc) {
+ pci_bus->number = func->bus;
+ devfn = PCI_DEVFN(func->device, func->function);
+
// 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)
return rc;
@@ -2104,13 +2110,13 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
rc = REMOVE_NOT_SUPPORTED;
} else {
// 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)
return rc;
// If it's a bridge, check the VGA Enable bit
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)
return rc;
@@ -2332,11 +2338,12 @@ static u32 configure_new_device (struct controller * ctrl, struct pci_func * fun
new_slot = func;
- dbg(__FUNCTION__"\n");
+ dbg("%s\n", __FUNCTION__);
// 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) {
- dbg(__FUNCTION__": rc = %d\n", rc);
+ dbg("%s: rc = %d\n", __FUNCTION__, rc);
return rc;
}
@@ -2372,7 +2379,7 @@ static u32 configure_new_device (struct controller * ctrl, struct pci_func * fun
// and creates a board structure
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.
function++;
@@ -2435,6 +2442,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
u32 temp_register;
u32 base;
u32 ID;
+ unsigned int devfn;
struct pci_resource *mem_node;
struct pci_resource *p_mem_node;
struct pci_resource *io_node;
@@ -2445,17 +2453,22 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
struct pci_resource *hold_bus_node;
struct irq_mapping irqs;
struct pci_func *new_slot;
+ struct pci_bus *pci_bus;
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
- 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)
return rc;
if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
// set Primary 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)
return rc;
@@ -2470,29 +2483,29 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set Secondary bus
temp_byte = 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)
return rc;
// set subordinate bus
temp_byte = 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)
return rc;
// set subordinate Latency Timer and base Latency Timer
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)
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)
return rc;
// set Cache Line size
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)
return rc;
@@ -2568,10 +2581,10 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set IO base and Limit registers
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;
- 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 {
kfree(hold_IO_node);
hold_IO_node = NULL;
@@ -2586,16 +2599,16 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set Mem base and Limit registers
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;
- 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 {
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;
- 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);
hold_mem_node = NULL;
@@ -2610,16 +2623,16 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set Pre Mem base and Limit registers
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;
- 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 {
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;
- 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);
hold_p_mem_node = NULL;
@@ -2635,7 +2648,9 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
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
// Setup slot structure.
@@ -2703,7 +2718,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
temp_byte = temp_resources.bus_head->base - 1;
// 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) {
kfree(temp_resources.bus_head);
@@ -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;
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);
}
@@ -2742,13 +2757,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
func->io_head = hold_IO_node;
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);
} else {
// it doesn't need any IO
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);
kfree(hold_IO_node);
@@ -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;
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);
}
@@ -2792,14 +2807,14 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// configure end address
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_resource(&(resources->mem_head), mem_node);
} else {
// it doesn't need any Mem
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);
kfree(hold_mem_node);
@@ -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;
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);
}
@@ -2843,13 +2858,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
func->p_mem_head = hold_p_mem_node;
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);
} else {
// it doesn't need any PMem
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);
kfree(hold_p_mem_node);
@@ -2870,14 +2885,14 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// enable card
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
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) {
// 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) {
// Display (video) adapter (not supported)
@@ -2887,10 +2902,10 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF;
- dbg("CND: bus=%d, device=%d, func=%d, offset=%d\n", func->bus, func->device, func->function, cloop);
- rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
+ dbg("CND: bus=%d, devfn=%d, offset=%d\n", pci_bus->number, devfn, cloop);
+ 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);
if (temp_register) { // If this register is implemented
@@ -2971,7 +2986,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
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
if ((temp_register & 0x07L) == 0x04) {
@@ -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
// FIXME this is probably not true on Alpha and ia64???
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
// 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
// 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
IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
} else {
// 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) {
IRQ = cpqhp_disk_irq;
@@ -3008,7 +3023,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
}
// 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) {
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
// Latency Timer
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
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
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
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
else {
// It's some strange type of PCI adapter (Cardbus?)
diff --git a/drivers/hotplug/cpqphp_nvram.c b/drivers/hotplug/cpqphp_nvram.c
index aafe9ee3aaa1..08dca3fba90c 100644
--- a/drivers/hotplug/cpqphp_nvram.c
+++ b/drivers/hotplug/cpqphp_nvram.c
@@ -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;
diff --git a/drivers/hotplug/cpqphp_pci.c b/drivers/hotplug/cpqphp_pci.c
index d8c65c5af128..8b9b16589f3b 100644
--- a/drivers/hotplug/cpqphp_pci.c
+++ b/drivers/hotplug/cpqphp_pci.c
@@ -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
//This code might be taken out if we can guarantee the creation of functions
//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);
if (temp_func == NULL)
return -ENOMEM;
@@ -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
//Notify the drivers of the change
if (temp_func->pci_dev) {
- pci_proc_attach_device(temp_func->pci_dev);
- pci_announce_device_to_drivers(temp_func->pci_dev);
+// pci_insert_device (temp_func->pci_dev, bus);
+// pci_proc_attach_device(temp_func->pci_dev);
+// pci_announce_device_to_drivers(temp_func->pci_dev);
}
return 0;
@@ -307,7 +308,7 @@ int cpqhp_unconfigure_device(struct pci_func* func)
memset(&wrapped_dev, 0, sizeof(struct pci_dev_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++) {
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)
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;
- 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;
if (vendID == 0xffffffff)
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)
fakedev.devfn = dev_num << 3;
fakedev.bus = &fakebus;
fakebus.number = bus_num;
- dbg(__FUNCTION__": dev %d, bus %d, pin %d, num %d\n",
- dev_num, bus_num, int_pin, irq_num);
+ dbg("%s: dev %d, bus %d, pin %d, num %d\n",
+ __FUNCTION__, dev_num, bus_num, int_pin, 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)
return rc;
@@ -392,9 +393,11 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
u32 work;
u8 tbus;
+ ctrl->pci_bus->number = bus_num;
+
for (tdevice = 0; tdevice < 0x100; tdevice++) {
//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;
dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
//Yep we got one. Not a bridge ?
@@ -406,12 +409,12 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
}
for (tdevice = 0; tdevice < 0x100; tdevice++) {
//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;
dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
//Yep we got one. bridge ?
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);
if (PCI_ScanBusNonBridge(tbus, tdevice) == 0)
return 0;
@@ -450,19 +453,20 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
if (tslot == slot) {
*bus_num = tbus;
*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 (PCIIRQRoutingInfoLength != NULL)
kfree(PCIIRQRoutingInfoLength );
return 0;
}
- dbg("bus_num %d dev_num %d func_num %d\n", *bus_num, *dev_num >> 3, *dev_num & 0x7);
- pci_read_config_dword_nodev (ctrl->pci_ops, *bus_num, *dev_num >> 3, *dev_num & 0x7, PCI_CLASS_REVISION, &work);
+ dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
+ 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);
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);
if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
*bus_num = tbus;
@@ -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
-
+ ctrl->pci_bus->number = busnumber;
for (device = FirstSupported; device <= LastSupported; device++) {
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
- 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)
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)
return rc;
@@ -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
// Recurse the subordinate bus
// 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) {
return rc;
} else {
@@ -572,9 +576,9 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
// Save secondary bus cfg spc
// with this recursive call.
rc = cpqhp_save_config(ctrl, sub_bus, 0);
-
if (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)
new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
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)
return rc;
}
@@ -615,15 +619,15 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
// reading in Class Code and Header type.
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.
function++;
} 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)
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)
return rc;
@@ -677,12 +681,12 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
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
- pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, 0, 0x0B, &class_code);
-
- pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, 0, PCI_HEADER_TYPE, &header_type);
+ 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);
if (header_type & 0x80) // Multi-function device
max_functions = 8;
@@ -694,22 +698,22 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
do {
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
// 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;
// Save the config headers for the secondary bus.
rc = cpqhp_save_config(ctrl, sub_bus, 0);
-
if (rc)
return(rc);
+ ctrl->pci_bus->number = new_slot->bus;
} // End of IF
new_slot->status = 0;
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++;
@@ -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.
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.
function++;
} 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++;
}
@@ -763,17 +767,21 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
u32 rc;
struct pci_func *next;
int index = 0;
+ struct pci_bus *pci_bus = ctrl->pci_bus;
+ unsigned int devfn;
func = cpqhp_slot_find(func->bus, func->device, index++);
while (func != NULL) {
+ pci_bus->number = func->bus;
+ devfn = PCI_DEVFN(func->device, func->function);
// 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
- 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;
@@ -787,13 +795,14 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
next = next->next;
}
+ pci_bus->number = func->bus;
//FIXME: this loop is duplicated in the non-bridge case. The two could be rolled together
// Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
temp_register = 0xFFFFFFFF;
- pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
- pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
+ pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+ pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
if (base) { // If this register is implemented
if (base & 0x01L) {
@@ -827,8 +836,8 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
// Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF;
- pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
- pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
+ pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+ pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
if (base) { // If this register is implemented
if (base & 0x01L) {
@@ -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 *io_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++);
while ((func != NULL) && func->is_a_board) {
+ pci_bus->number = func->bus;
+ devfn = PCI_DEVFN(func->device, func->function);
+
// 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
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
- 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
// Clear Bridge Control Register
command = 0x00;
- pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, command);
-
- pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, &secondary_bus);
-
- pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, &temp_byte);
+ 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_bus_read_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
bus_node =(struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
if (!bus_node)
@@ -931,9 +943,8 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
func->bus_head = bus_node;
// 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_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, &b_length);
+ 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);
if ((b_base <= b_length) && (save_command & 0x01)) {
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)
io_node->next = func->io_head;
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)) {
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)
mem_node->next = func->mem_head;
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)) {
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)
}
// Figure out IO and memory base lengths
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;
- pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
-
- pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
+ pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+ pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
temp_register = base;
@@ -1046,12 +1056,11 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
} else if ((header_type & 0x7F) == 0x00) { // Standard header
// Figure out IO and memory base lengths
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;
- pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
-
- pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
+ pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+ pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
temp_register = base;
@@ -1138,21 +1147,26 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
u32 temp;
u32 rc;
int index = 0;
+ struct pci_bus *pci_bus = ctrl->pci_bus;
+ unsigned int devfn;
func = cpqhp_slot_find(func->bus, func->device, index++);
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
// registers are programmed last
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 ((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;
@@ -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.
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]) {
dbg("Config space compare failure!!! offset = %x\n", cloop);
@@ -1212,6 +1226,8 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
u32 rc;
struct pci_func *next;
int index = 0;
+ struct pci_bus *pci_bus = ctrl->pci_bus;
+ unsigned int devfn;
if (!func->is_a_board)
return(ADD_NOT_SUPPORTED);
@@ -1219,7 +1235,10 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
func = cpqhp_slot_find(func->bus, func->device, index++);
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
if (temp_register == 0xFFFFFFFF)
@@ -1229,14 +1248,14 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
return(ADAPTER_NOT_SAME);
// 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
if (temp_register != func->config_space[0x08 >> 2])
return(ADAPTER_NOT_SAME);
// 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
// In order to continue checking, we must program the
@@ -1244,7 +1263,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
// for it's subordinate bus(es)
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;
@@ -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
else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
// 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 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)
// Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF;
- pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
-
- pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
-
+ pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+ pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
if (base) { // If this register is implemented
if (base & 0x01L) {
// IO base
@@ -1436,8 +1453,8 @@ int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start)
continue;
}
// 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);
if (temp_dword != 0xFFFFFFFF) {
@@ -1586,7 +1603,7 @@ int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists *
int rc = 0;
struct pci_resource *node;
struct pci_resource *t_node;
- dbg(__FUNCTION__"\n");
+ dbg("%s\n", __FUNCTION__);
if (!func)
return(1);
diff --git a/drivers/hotplug/cpqphp_proc.c b/drivers/hotplug/cpqphp_proc.c
index 64b3461a6e20..8912f881664a 100644
--- a/drivers/hotplug/cpqphp_proc.c
+++ b/drivers/hotplug/cpqphp_proc.c
@@ -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;
diff --git a/drivers/hotplug/ibmphp.h b/drivers/hotplug/ibmphp.h
index ca8e5044c622..fc899b307834 100644
--- a/drivers/hotplug/ibmphp.h
+++ b/drivers/hotplug/ibmphp.h
@@ -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;
diff --git a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c
index 87234e42f58e..5113d30f93f1 100644
--- a/drivers/hotplug/ibmphp_core.c
+++ b/drivers/hotplug/ibmphp_core.c
@@ -44,7 +44,7 @@
#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 DRIVER_VERSION "0.3"
+#define DRIVER_VERSION "0.6"
#define DRIVER_DESC "IBM Hot Plug PCI Controller Driver"
int ibmphp_debug;
@@ -56,7 +56,7 @@ MODULE_LICENSE ("GPL");
MODULE_DESCRIPTION (DRIVER_DESC);
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 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)
slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED (slot_cur->busstatus);
if (READ_BUS_MODE (slot_cur->ctrl))
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);
@@ -108,11 +110,15 @@ static inline int slot_update (struct slot **sl)
static int __init get_max_slots (void)
{
+ struct slot * slot_cur;
struct list_head * tmp;
- int slot_count = 0;
+ u8 slot_count = 0;
- list_for_each (tmp, &ibmphp_slot_head)
- ++slot_count;
+ list_for_each (tmp, &ibmphp_slot_head) {
+ 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;
}
@@ -330,7 +336,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 * value)
memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
if (!hpcrc) {
- *value = SLOT_POWER (myslot.status);
+ *value = SLOT_PWRGD (myslot.status);
rc = 0;
}
}
@@ -394,15 +400,22 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value)
if (pslot) {
rc = 0;
mode = pslot->supported_bus_mode;
- *value = pslot->supported_speed;
- *value &= 0x0f;
-
- if (mode == BUS_MODE_PCIX)
- *value |= 0x80;
- else if (mode == BUS_MODE_PCI)
- *value |= 0x40;
- else
- *value |= 0x20;
+ *value = pslot->supported_speed;
+ switch (*value) {
+ case BUS_SPEED_33:
+ break;
+ case BUS_SPEED_66:
+ if (mode == BUS_MODE_PCIX)
+ *value += 0x01;
+ break;
+ case BUS_SPEED_100:
+ case BUS_SPEED_133:
+ *value = pslot->supported_speed + 0x01;
+ break;
+ default:
+*/ /* Note (will need to change): there would be soon 256, 512 also */
+/* rc = -ENODEV;
+ }
}
} else
rc = -ENODEV;
@@ -429,14 +442,25 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value)
if (!rc) {
mode = pslot->bus_on->current_bus_mode;
*value = pslot->bus_on->current_speed;
- *value &= 0x0f;
-
- if (mode == BUS_MODE_PCIX)
- *value |= 0x80;
- else if (mode == BUS_MODE_PCI)
- *value |= 0x40;
- else
- *value |= 0x20;
+ switch (*value) {
+ case BUS_SPEED_33:
+ break;
+ case BUS_SPEED_66:
+ if (mode == BUS_MODE_PCIX)
+ *value += 0x01;
+ else if (mode == BUS_MODE_PCI)
+ ;
+ else
+ *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
@@ -454,7 +478,7 @@ static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * valu
int hpcrc = 0;
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)
ibmphp_lock_operations ();
@@ -485,17 +509,16 @@ static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * valu
if (flag)
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;
}
-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;
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 ();
@@ -503,26 +526,17 @@ static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value)
pslot = (struct slot *) hotplug_slot->private;
if (pslot) {
rc = 0;
- if (pslot->func)
- 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);
-
-
+ snprintf (value, 100, "Bus %x", pslot->bus);
}
} else
rc = -ENODEV;
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;
}
-
*/
+
/*******************************************************************************
* 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
@@ -531,12 +545,14 @@ static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value)
static int __init init_ops (void)
{
struct slot *slot_cur;
+ struct list_head *tmp;
int retval;
- int j;
int rc;
+ int j;
for (j = 0; j < MAX_OPS; j++) {
ops[j] = (int *) kmalloc ((max_slots + 1) * sizeof (int), GFP_KERNEL);
+ memset (ops[j], 0, (max_slots + 1) * sizeof (int));
if (!ops[j]) {
err ("out of system memory \n");
return -ENOMEM;
@@ -547,12 +563,13 @@ static int __init init_ops (void)
ops[REMOVE][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);
-
if (slot_cur->ctrl->revision == 0xFF)
if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision))
return -1;
@@ -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 ("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 */
- ops[ADD][j] = 1;
+ ops[ADD][slot_cur->number] = 1;
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 */
- ops[REMOVE][j] = 1;
+ ops[REMOVE][slot_cur->number] = 1;
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");
rc = power_off (slot_cur);
if (rc)
@@ -624,7 +641,7 @@ static int validate (struct slot *slot_cur, int opn)
if (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)))
ops[ADD][number] = 1;
else
@@ -632,7 +649,7 @@ static int validate (struct slot *slot_cur, int opn)
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)))
ops[REMOVE][number] = 1;
else
@@ -678,7 +695,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur)
}
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->latch_status = SLOT_LATCH (slot_cur->status);
if (!SLOT_PRESENT (slot_cur->status)) {
@@ -688,8 +705,8 @@ int ibmphp_update_slot_info (struct slot *slot_cur)
info->adapter_status = 1;
// get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0);
}
-/*
- bus_speed = slot_cur->bus_on->current_speed;
+ /* !!!!!!!!!TO DO: THIS NEEDS TO CHANGE!!!!!!!!!!!!! */
+/* bus_speed = slot_cur->bus_on->current_speed;
bus_speed &= 0x0f;
if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
@@ -701,7 +718,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur)
info->cur_bus_speed_status = bus_speed;
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);
kfree (info);
@@ -752,18 +769,6 @@ static struct pci_bus *find_bus (u8 busno)
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
* the pointers to pci_func, bus, hotplug_slot, controller,
@@ -775,8 +780,10 @@ static void free_slots (void)
struct list_head * tmp;
struct list_head * next;
- list_for_each_safe (tmp, next, &ibmphp_slot_head) {
+ debug ("%s -- enter\n", __FUNCTION__);
+ list_for_each_safe (tmp, next, &ibmphp_slot_head) {
+
slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
pci_hp_deregister (slot_cur->hotplug_slot);
@@ -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 */
kfree (slot_cur);
+ slot_cur = NULL;
}
+ debug ("%s -- exit\n", __FUNCTION__);
}
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
if (temp_func)
temp_func->dev = NULL;
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;
}
@@ -954,8 +963,8 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct
}
if (temp_func->dev) {
- pci_proc_attach_device (temp_func->dev);
- pci_announce_device_to_drivers (temp_func->dev);
+// pci_proc_attach_device (temp_func->dev);
+// pci_announce_device_to_drivers (temp_func->dev);
}
return 0;
@@ -965,6 +974,51 @@ static struct pci_visit configure_functions = {
.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)
{
unsigned char bus;
@@ -972,6 +1026,7 @@ static int ibm_configure_device (struct pci_func *func)
struct pci_bus *child;
struct pci_dev *temp;
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_bus_wrapped wrapped_bus;
@@ -980,6 +1035,8 @@ static int ibm_configure_device (struct pci_func *func)
memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
memset (&dev0, 0, sizeof (struct pci_dev));
+ if (!(bus_structure_fixup (func->busno)))
+ flag = 1;
if (func->dev == NULL)
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)
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);
child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus);
pci_do_scan_bus (child);
@@ -1028,7 +1085,7 @@ static int is_bus_empty (struct slot * slot_cur)
rc = slot_update (&tmp_slot);
if (rc)
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;
i++;
}
@@ -1046,6 +1103,9 @@ static int set_bus (struct slot * slot_cur)
int rc;
u8 speed;
u8 cmd = 0x0;
+ const struct list_head *tmp;
+ struct pci_dev * dev;
+ int retval;
debug ("%s - entry slot # %d \n", __FUNCTION__, slot_cur->number);
if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) {
@@ -1091,6 +1151,14 @@ static int set_bus (struct slot * slot_cur)
cmd = HPC_BUS_100PCIXMODE;
break;
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;
break;
default:
@@ -1103,9 +1171,17 @@ static int set_bus (struct slot * slot_cur)
return -ENODEV;
}
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 */
long_delay (1 * HZ);
debug ("%s -Exit \n", __FUNCTION__);
@@ -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++) {
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++;
}
get_cur_bus_info (&slot_cur);
@@ -1384,11 +1460,15 @@ int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
debug ("DISABLING SLOT... \n");
- if (slot_cur == NULL)
+ if (slot_cur == NULL) {
+ ibmphp_unlock_operations ();
return -ENODEV;
+ }
- if (slot_cur->ctrl == NULL)
+ if (slot_cur->ctrl == NULL) {
+ ibmphp_unlock_operations ();
return -ENODEV;
+ }
flag = slot_cur->flag; /* to see if got here from polling */
@@ -1463,7 +1543,8 @@ int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
return -EFAULT;
}
- ibmphp_update_slot_info (slot_cur);
+ if (flag)
+ ibmphp_update_slot_info (slot_cur);
ibmphp_unlock_operations ();
return -EFAULT;
}
@@ -1503,10 +1584,10 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
.get_attention_status = get_attention_status,
.get_latch_status = get_latch_status,
.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_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)
static int __init ibmphp_init (void)
{
+ struct pci_bus *bus;
int i = 0;
int rc = 0;
@@ -1533,12 +1615,19 @@ static int __init ibmphp_init (void)
info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
- ibmphp_pci_root_ops = get_root_pci_ops ();
- if (ibmphp_pci_root_ops == NULL) {
- err ("cannot read bus operations... will not be able to read the cards. Please check your system\n");
- return -ENODEV;
+ ibmphp_pci_bus = kmalloc (sizeof (*ibmphp_pci_bus), GFP_KERNEL);
+ if (!ibmphp_pci_bus) {
+ 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;
+ }
+ memcpy (ibmphp_pci_bus, bus, sizeof (*ibmphp_pci_bus));
+
ibmphp_debug = debug;
ibmphp_hpc_initvars ();
@@ -1559,6 +1648,11 @@ static int __init ibmphp_init (void)
debug ("AFTER Resource & EBDA INITIALIZATIONS\n");
max_slots = get_max_slots ();
+
+ if ((rc = ibmphp_register_pci ())) {
+ ibmphp_unload ();
+ return rc;
+ }
if (init_ops ()) {
ibmphp_unload ();
@@ -1570,11 +1664,9 @@ static int __init ibmphp_init (void)
return -ENODEV;
}
- /* lock ourselves into memory with a module count of -1
- * so that no one can unload us. */
+ /* if no NVRAM module selected, lock ourselves into memory with a
+ * module count of -1 so that no one can unload us. */
MOD_DEC_USE_COUNT;
-
-
return 0;
}
diff --git a/drivers/hotplug/ibmphp_ebda.c b/drivers/hotplug/ibmphp_ebda.c
index de180f16e01a..86a88433da5f 100644
--- a/drivers/hotplug/ibmphp_ebda.c
+++ b/drivers/hotplug/ibmphp_ebda.c
@@ -56,11 +56,17 @@ LIST_HEAD (ibmphp_slot_head);
/* Local variables */
static struct ebda_hpc_list *hpc_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 (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;
+char *chassis_str, *rxe_str, *str;
+
/* Local functions */
static int ebda_rsrc_controller (void);
static int ebda_rsrc_rsrc (void);
@@ -125,6 +131,7 @@ static void free_ebda_hpc (struct controller *controller)
controller->slots = NULL;
kfree (controller->buses);
controller->buses = NULL;
+ controller->ctrl_dev = NULL;
kfree (controller);
}
@@ -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 list_head *ptr1;
list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
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);
}
}
+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)
{
struct controller *hpc_ptr;
@@ -221,6 +287,7 @@ static void __init print_ebda_hpc (void)
break;
case 2:
+ case 4:
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 - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
@@ -357,31 +424,382 @@ int __init ibmphp_access_ebda (void)
rio_complete = 1;
}
+ }
- if (hs_complete && rio_complete) {
- rc = ebda_rsrc_controller ();
- if (rc) {
- iounmap(io_mem);
- return rc;
- }
- rc = ebda_rsrc_rsrc ();
- if (rc) {
- iounmap(io_mem);
- return rc;
- }
+ if (!hs_complete && !rio_complete) {
+ 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) {
- iounmap(io_mem);
+ iounmap (io_mem);
return rc;
- }
- iounmap (io_mem);
- return 0;
+ }
}
}
+ rc = ebda_rsrc_controller ();
+ if (rc) {
+ iounmap (io_mem);
+ return rc;
+ }
+
+ rc = ebda_rsrc_rsrc ();
+ if (rc) {
+ iounmap (io_mem);
+ return rc;
+ }
+
iounmap (io_mem);
- return -ENODEV;
+ 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;
+ }
+ return NULL;
+}
+
+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
@@ -400,6 +818,9 @@ static int __init ebda_rsrc_controller (void)
struct ebda_hpc_slot *slot_ptr;
struct bus_info *bus_info_ptr1, *bus_info_ptr2;
int rc;
+ int retval;
+ struct slot *slot_cur;
+ struct list_head *list;
addr = hpc_list_ptr->phys_addr;
for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
@@ -510,23 +931,22 @@ static int __init ebda_rsrc_controller (void)
hpc_ptr->u.pci_ctlr.bus = readb (io_mem + addr);
hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);
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;
case 0:
hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr);
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);
addr += 5;
break;
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:
hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
@@ -537,12 +957,10 @@ static int __init ebda_rsrc_controller (void)
iounmap (io_mem);
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->options = 0xff;
hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num;
@@ -566,7 +984,7 @@ static int __init ebda_rsrc_controller (void)
}
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) {
iounmap (io_mem);
kfree (hp_slot_ptr->info);
@@ -583,9 +1001,7 @@ static int __init ebda_rsrc_controller (void)
return -ENOMEM;
}
-
((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;
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)
((struct slot *) hp_slot_ptr->private)->number = hpc_ptr->slots[index].slot_num;
((struct slot *) hp_slot_ptr->private)->hotplug_slot = hp_slot_ptr;
-
rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr);
if (rc) {
iounmap (io_mem);
@@ -631,8 +1046,6 @@ static int __init ebda_rsrc_controller (void)
}
hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;
- pci_hp_register (hp_slot_ptr);
-
// end of registering ibm slot with hotplug core
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)
list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head );
} /* 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_ibm_slot ();
return 0;
}
@@ -682,7 +1108,7 @@ static int __init ebda_rsrc_rsrc (void)
addr += 6;
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);
list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
@@ -703,7 +1129,7 @@ static int __init ebda_rsrc_rsrc (void)
addr += 10;
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);
list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
@@ -715,56 +1141,6 @@ static int __init ebda_rsrc_rsrc (void)
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)
{
return hpc_list_ptr->num_ctlrs;
@@ -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)
{
- struct controller *controller;
+ struct controller *controller = NULL;
struct list_head *list;
struct list_head *next;
+ int pci_flag = 0;
list_for_each_safe (list, next, &ebda_hpc_head) {
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);
}
}
@@ -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;
+}
+
diff --git a/drivers/hotplug/ibmphp_hpc.c b/drivers/hotplug/ibmphp_hpc.c
index bf2e067aaad0..ae959809e8a8 100644
--- a/drivers/hotplug/ibmphp_hpc.c
+++ b/drivers/hotplug/ibmphp_hpc.c
@@ -107,8 +107,8 @@ static struct semaphore sem_exit; // make sure polling thread goes away
//----------------------------------------------------------------------------
// local function prototypes
//----------------------------------------------------------------------------
-static u8 ctrl_read (struct controller *, void *, u8);
-static u8 ctrl_write (struct controller *, void *, u8, u8);
+static u8 i2c_ctrl_read (struct controller *, void *, u8);
+static u8 i2c_ctrl_write (struct controller *, void *, u8, u8);
static u8 hpc_writecmdtoindex (u8, u8);
static u8 hpc_readcmdtoindex (u8, u8);
static void get_hpc_access (void);
@@ -142,12 +142,12 @@ void __init ibmphp_hpc_initvars (void)
}
/*----------------------------------------------------------------------
-* Name: ctrl_read
+* Name: i2c_ctrl_read
*
* 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;
int i;
@@ -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
*
* 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;
void *wpg_addr; // base addr + offset
@@ -351,6 +351,93 @@ static u8 ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 c
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()
*
@@ -449,7 +536,7 @@ static u8 hpc_readcmdtoindex (u8 cmd, u8 index)
*---------------------------------------------------------------------*/
int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
{
- void *wpg_bbar;
+ void *wpg_bbar = NULL;
struct controller *ctlr_ptr;
struct list_head *pslotlist;
u8 index, status;
@@ -491,7 +578,8 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
//--------------------------------------------------------------------
// map physical address to logical address
//--------------------------------------------------------------------
- wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
+ if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
+ wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
//--------------------------------------------------------------------
// check controller status before reading
@@ -569,7 +657,11 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
//--------------------------------------------------------------------
// 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 ();
debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
@@ -583,7 +675,7 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
*---------------------------------------------------------------------*/
int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
{
- void *wpg_bbar;
+ void *wpg_bbar = NULL;
struct controller *ctlr_ptr;
u8 index, status;
int busindex;
@@ -626,12 +718,13 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
//--------------------------------------------------------------------
// map physical address to logical address
//--------------------------------------------------------------------
- wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
+ if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
+ 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->u.wpeg_ctlr.i2c_addr);
-
+ }
//--------------------------------------------------------------------
// check controller status before writing
//--------------------------------------------------------------------
@@ -668,7 +761,10 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
ctlr_ptr->status = status;
}
// 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 ();
debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
@@ -701,6 +797,7 @@ void free_hpc_access (void)
void ibmphp_lock_operations (void)
{
down (&semOperations);
+ to_debug = TRUE;
}
/*----------------------------------------------------------------------
@@ -710,6 +807,7 @@ void ibmphp_unlock_operations (void)
{
debug ("%s - Entry\n", __FUNCTION__);
up (&semOperations);
+ to_debug = FALSE;
debug ("%s - Exit\n", __FUNCTION__);
}
@@ -734,82 +832,86 @@ static void poll_hpc (void)
debug ("%s - Entry\n", __FUNCTION__);
while (!ibmphp_shutdown) {
+ if (ibmphp_shutdown)
+ break;
+
/* try to get the lock to do some kind of harware access */
down (&semOperations);
switch (poll_state) {
- case POLL_LATCH_REGISTER:
- oldlatchlow = curlatchlow;
- ctrl_count = 0x00;
- list_for_each (pslotlist, &ibmphp_slot_head) {
- if (ctrl_count >= ibmphp_get_total_controllers())
- break;
- pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
- if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
- ctrl_count++;
- if (READ_SLOT_LATCH (pslot->ctrl)) {
- rc = ibmphp_hpc_readslot (pslot,
- READ_SLOTLATCHLOWREG,
- &curlatchlow);
- if (oldlatchlow != curlatchlow)
- process_changeinlatch (oldlatchlow,
- curlatchlow,
- pslot->ctrl);
- }
+ case POLL_LATCH_REGISTER:
+ oldlatchlow = curlatchlow;
+ ctrl_count = 0x00;
+ list_for_each (pslotlist, &ibmphp_slot_head) {
+ if (ctrl_count >= ibmphp_get_total_controllers())
+ break;
+ pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+ if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
+ ctrl_count++;
+ if (READ_SLOT_LATCH (pslot->ctrl)) {
+ rc = ibmphp_hpc_readslot (pslot,
+ READ_SLOTLATCHLOWREG,
+ &curlatchlow);
+ if (oldlatchlow != curlatchlow)
+ process_changeinlatch (oldlatchlow,
+ curlatchlow,
+ pslot->ctrl);
}
}
- poll_state = POLL_SLOTS;
- break;
-
- case POLL_SLOTS:
- list_for_each (pslotlist, &ibmphp_slot_head) {
- pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
- // make a copy of the old status
- memcpy ((void *) &myslot, (void *) pslot,
- sizeof (struct slot));
- rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
- if ((myslot.status != pslot->status)
- || (myslot.ext_status != pslot->ext_status))
- process_changeinstatus (pslot, &myslot);
+ }
+ ++poll_count;
+ poll_state = POLL_SLEEP;
+ break;
+ case POLL_SLOTS:
+ list_for_each (pslotlist, &ibmphp_slot_head) {
+ pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+ // make a copy of the old status
+ memcpy ((void *) &myslot, (void *) pslot,
+ sizeof (struct slot));
+ rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
+ if ((myslot.status != pslot->status)
+ || (myslot.ext_status != pslot->ext_status))
+ process_changeinstatus (pslot, &myslot);
+ }
+ ctrl_count = 0x00;
+ list_for_each (pslotlist, &ibmphp_slot_head) {
+ if (ctrl_count >= ibmphp_get_total_controllers())
+ break;
+ pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+ if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
+ ctrl_count++;
+ if (READ_SLOT_LATCH (pslot->ctrl))
+ rc = ibmphp_hpc_readslot (pslot,
+ READ_SLOTLATCHLOWREG,
+ &curlatchlow);
}
+ }
+ ++poll_count;
+ poll_state = POLL_SLEEP;
+ break;
+ case POLL_SLEEP:
+ /* don't sleep with a lock on the hardware */
+ up (&semOperations);
+ long_delay (POLL_INTERVAL_SEC * HZ);
- ctrl_count = 0x00;
- list_for_each (pslotlist, &ibmphp_slot_head) {
- if (ctrl_count >= ibmphp_get_total_controllers())
- break;
- pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
- if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
- ctrl_count++;
- if (READ_SLOT_LATCH (pslot->ctrl))
- rc = ibmphp_hpc_readslot (pslot,
- READ_SLOTLATCHLOWREG,
- &curlatchlow);
- }
- }
- ++poll_count;
- if (poll_count >= POLL_LATCH_CNT) {
- poll_count = 0;
- poll_state = POLL_SLEEP;
- }
+ if (ibmphp_shutdown)
break;
-
- case POLL_SLEEP:
- /* don't sleep with a lock on the hardware */
- up (&semOperations);
- long_delay (POLL_INTERVAL_SEC * HZ);
- down (&semOperations);
+
+ down (&semOperations);
+
+ if (poll_count >= POLL_LATCH_CNT) {
+ poll_count = 0;
+ poll_state = POLL_SLOTS;
+ } else
poll_state = POLL_LATCH_REGISTER;
- break;
- }
-
+ break;
+ }
/* give up the harware semaphore */
up (&semOperations);
-
/* sleep for a short time just for good measure */
set_current_state (TASK_INTERRUPTIBLE);
schedule_timeout (HZ/10);
}
-
up (&sem_exit);
debug ("%s - Exit\n", __FUNCTION__);
}
@@ -1070,15 +1172,23 @@ void __exit ibmphp_hpc_stop_poll_thread (void)
debug ("%s - Entry\n", __FUNCTION__);
ibmphp_shutdown = TRUE;
+ debug ("before locking operations \n");
ibmphp_lock_operations ();
-
+ debug ("after locking operations \n");
+
// wait for poll thread to exit
+ debug ("before sem_exit down \n");
down (&sem_exit);
+ debug ("after sem_exit down \n");
// cleanup
+ debug ("before free_hpc_access \n");
free_hpc_access ();
+ debug ("after free_hpc_access \n");
ibmphp_unlock_operations ();
+ debug ("after unlock operations \n");
up (&sem_exit);
+ debug ("after sem exit up\n");
debug ("%s - Exit\n", __FUNCTION__);
}
diff --git a/drivers/hotplug/ibmphp_pci.c b/drivers/hotplug/ibmphp_pci.c
index 6273c448880f..cfc9ecffd650 100644
--- a/drivers/hotplug/ibmphp_pci.c
+++ b/drivers/hotplug/ibmphp_pci.c
@@ -104,11 +104,15 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
/* For every function on the card */
for (function = 0x00; function < 0x08; function++) {
+ unsigned int devfn = PCI_DEVFN(device, function);
+ ibmphp_pci_bus->number = cur_func->busno;
+
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);
if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
@@ -122,8 +126,8 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
* |_=> 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_read_config_dword_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_CLASS_REVISION, &class);
+ pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+ pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
class_code = class >> 24;
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)
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;
for (i = 0; i < 32; i++) {
if (func->devices[i]) {
@@ -267,8 +271,9 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
cleanup_count = 2;
goto error;
}
- debug ("cur_func->busno = %x, device = %x, function = %x\n", cur_func->busno, device, function);
- pci_read_config_byte_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_SECONDARY_BUS, &sec_number);
+ debug ("cur_func->busno = %x, device = %x, function = %x\n",
+ 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);
flag = FALSE;
for (i = 0; i < 32; i++) {
@@ -361,13 +366,12 @@ static int configure_device (struct pci_func *func)
struct resource_node *mem[6];
struct resource_node *mem_tmp;
struct resource_node *pfmem[6];
- u8 device;
- u8 function;
+ unsigned int devfn;
debug ("%s - inside\n", __FUNCTION__);
- device = func->device;
- function = func->function;
+ devfn = PCI_DEVFN(func->device, func->function);
+ ibmphp_pci_bus->number = func->busno;
for (count = 0; address[count]; count++) { /* for 6 BARs */
@@ -384,8 +388,8 @@ static int configure_device (struct pci_func *func)
pcibios_write_config_dword(cur_func->busno, cur_func->device,
PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF);
*/
- pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0xFFFFFFFF);
- pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]);
+ pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+ pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
if (!bar[count]) /* This BAR is not implemented */
continue;
@@ -421,11 +425,11 @@ static int configure_device (struct pci_func *func)
kfree (io[count]);
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_____________________ */
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]);
/* _________________________________________________________________________*/
@@ -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);
- 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]);
/*_________________________________________________________________________________*/
@@ -496,7 +500,7 @@ static int configure_device (struct pci_func *func)
debug ("inside the mem 64 case, count %d\n", count);
count += 1;
/* 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 {
/* regular memory */
@@ -526,10 +530,10 @@ static int configure_device (struct pci_func *func)
kfree (mem[count]);
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 _______________________*/
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]);
/* __________________________________________________________________________________*/
@@ -538,22 +542,22 @@ static int configure_device (struct pci_func *func)
debug ("inside mem 64 case, reg. mem, count %d\n", count);
count += 1;
/* 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 for */
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))
- 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_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_CACHE_LINE_SIZE, CACHE);
+ 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_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_ROM_ADDRESS, 0x00L);
+ pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
return 0;
}
@@ -593,24 +597,23 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
0
};
struct pci_func *func = *func_passed;
- u8 function;
- u8 device;
+ unsigned int devfn;
u8 irq;
int retval;
debug ("%s - enter\n", __FUNCTION__);
- function = func->function;
- device = func->device;
+ devfn = PCI_DEVFN(func->function, func->device);
+ ibmphp_pci_bus->number = func->busno;
/* Configuring necessary info for the bridge so that we could see the devices
* 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 __________________________
- 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);
___________________________________________________________________________*/
@@ -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, 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 __________________________________
- 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);
________________________________________________________________________________*/
- 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 ____________________________________
- 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);
__________________________________________________________________________________*/
- pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_CACHE_LINE_SIZE, CACHE);
- pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, 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_CACHE_LINE_SIZE, CACHE);
+ pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_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 ("sec_number after writing is %x\n", sec_number);
@@ -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 */
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_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]);
+ pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+ pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
if (!bar[count]) {
/* This BAR is not implemented */
@@ -694,7 +697,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
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 {
/* This is Memory */
@@ -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) {
/* takes up another dword */
count += 1;
/* 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 {
@@ -784,13 +787,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
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) {
/* takes up another dword */
count += 1;
/* 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)
if (amount_needed == NULL)
return -ENOMEM;
+ ibmphp_pci_bus->number = func->busno;
debug ("after coming back from scan_behind_bridge\n");
debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct);
debug ("amount_needed->io = %x\n", amount_needed->io);
@@ -920,16 +924,30 @@ 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);
if (flag_io && flag_mem && flag_pfmem) {
- bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+ /* 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) {
- err ("out of system memory \n");
- retval = -ENOMEM;
+ bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+ if (!bus) {
+ err ("out of system memory \n");
+ retval = -ENOMEM;
+ goto error;
+ }
+ memset (bus, 0, sizeof (struct bus_node));
+ bus->busno = sec_number;
+ debug ("b4 adding new bus\n");
+ 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;
}
- memset (bus, 0, sizeof (struct bus_node));
- bus->busno = sec_number;
- debug ("b4 adding new bus\n");
- rc = add_new_bus (bus, io, mem, pfmem, func->busno);
if (rc) {
if (rc == -ENOMEM) {
ibmphp_remove_bus (bus, func->busno);
@@ -938,8 +956,8 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
retval = rc;
goto error;
}
- pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, 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_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &io_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) {
debug ("io 32\n");
@@ -951,73 +969,73 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
}
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_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_BASE, 0x00 | bus->rangeIO->start >> 8);
+ pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);
/* _______________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);
- 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);
________________________________________________________________________*/
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_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_BASE_UPPER16, 0x0000);
+ pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, 0x0000);
}
} else {
- pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, 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_BASE, 0x00);
+ pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00);
}
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_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_BASE, 0x0000 | bus->rangeMem->start >> 16);
+ pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16);
/* ____________________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);
- 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);
__________________________________________________________________________________*/
} else {
- pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, 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_BASE, 0xffff);
+ pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000);
}
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_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_BASE, 0x0000 | bus->rangePFMem->start >> 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 _______________________
- 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);
- 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);
______________________________________________________________________________________*/
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_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_BASE_UPPER32, 0x00000000);
+ pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, 0x00000000);
}
} else {
- pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, 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_BASE, 0xffff);
+ pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000);
}
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))
- 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_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, 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, ctrl);
+ pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);
+ 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_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_COMMAND, DEVICEENABLE);
+ pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, 0x07);
for (i = 0; i < 32; i++) {
if (amount_needed->devices[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)
u16 vendor_id;
u8 hdr_type;
u8 device, function;
+ unsigned int devfn;
int howmany = 0; /*this is to see if there are any devices behind the bridge */
u32 bar[6], class;
@@ -1092,20 +1111,23 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
return NULL;
memset (amount, 0, sizeof (struct res_needed));
+ ibmphp_pci_bus->number = busno;
+
debug ("the bus_no behind the bridge is %x\n", busno);
debug ("scanning devices behind the bridge...\n");
for (device = 0; device < 32; device++) {
amount->devices[device] = 0;
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) {
/* found correct device!!! */
howmany++;
- pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, 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_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+ pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
debug ("hdr_type behind the bridge is %x\n", hdr_type);
if (hdr_type & PCI_HEADER_TYPE_BRIDGE) {
@@ -1132,14 +1154,14 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
for (count = 0; address[count]; count++) {
/* 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
- 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
- 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_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &bar[count]);
+ pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+ 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);
@@ -1223,6 +1245,7 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
u32 temp_end;
u32 size;
u32 tmp_address;
+ unsigned int devfn;
debug ("%s - enter\n", __FUNCTION__);
@@ -1232,14 +1255,16 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
return -EINVAL;
}
+ devfn = PCI_DEVFN(device, function);
+ ibmphp_pci_bus->number = busno;
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 */
- pci_write_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFF);
- pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, 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], 0xFFFFFFFF);
+ pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &size);
+ pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], start_address);
debug ("start_address is %x\n", start_address);
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)
PCI_BASE_ADDRESS_1,
0
};
+ unsigned int devfn;
+ devfn = PCI_DEVFN(device, function);
+ ibmphp_pci_bus->number = busno;
bus_no = (int) 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);
- 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);
sec_no = (int) sec_number;
pri_no = (int) pri_number;
@@ -1351,10 +1379,10 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
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;
- 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;
debug ("sub_no is %d, sec_no is %d\n", sub_no, sec_no);
if (sec_no != sub_number) {
@@ -1374,7 +1402,7 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
for (count = 0; address[count]; count++) {
/* 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) {
/* This BAR is not implemented */
@@ -1447,6 +1475,7 @@ static int unconfigure_boot_card (struct slot *slot_cur)
u8 busno;
u8 function;
int rc;
+ unsigned int devfn;
u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */
debug ("%s - enter\n", __FUNCTION__);
@@ -1457,8 +1486,10 @@ static int unconfigure_boot_card (struct slot *slot_cur)
debug ("b4 for loop, device is %x\n", device);
/* For every function on the card */
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) {
/* found correct device!!! */
@@ -1471,8 +1502,8 @@ static int unconfigure_boot_card (struct slot *slot_cur)
* |_=> 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_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_CLASS_REVISION, &class);
+ pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+ pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
debug ("hdr_type %x, class %x\n", hdr_type, class);
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)
}
if (sl->func) {
- debug ("do we come in here? \n");
cur_func = sl->func;
while (cur_func) {
/* 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)
sl->func = NULL;
*slot_cur = sl;
+ debug ("%s - exit\n", __FUNCTION__);
return 0;
}
@@ -1638,14 +1669,15 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
struct bus_node *cur_bus = NULL;
/* Trying to find the parent bus number */
- cur_bus = ibmphp_find_res_bus (parent_busno);
- if (!cur_bus) {
- err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
- return -ENODEV;
+ if (parent_busno != 0xFF) {
+ cur_bus = ibmphp_find_res_bus (parent_busno);
+ if (!cur_bus) {
+ err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
+ return -ENODEV;
+ }
+
+ list_add (&bus->bus_list, &cur_bus->bus_list);
}
-
- list_add (&bus->bus_list, &cur_bus->bus_list);
-
if (io) {
io_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
if (!io_range) {
@@ -1698,6 +1730,7 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno)
int min, max;
u8 busno;
struct bus_info *bus;
+ struct bus_node *bus_cur;
bus = ibmphp_find_same_bus_num (primary_busno);
if (!bus) {
@@ -1712,7 +1745,12 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno)
}
busno = (u8) (slotno - (u8) min);
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 0xff;
}
diff --git a/drivers/hotplug/ibmphp_res.c b/drivers/hotplug/ibmphp_res.c
index 0cf06e48e078..762ad60c71a7 100644
--- a/drivers/hotplug/ibmphp_res.c
+++ b/drivers/hotplug/ibmphp_res.c
@@ -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 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;
+ if (!(curr) && !(flag)) {
+ err ("NULL pointer passed \n");
+ return NULL;
+ }
+
newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
if (!newbus) {
err ("out of system memory \n");
@@ -57,14 +63,24 @@ static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr)
}
memset (newbus, 0, sizeof (struct bus_node));
- newbus->busno = curr->bus_num;
+ if (flag)
+ newbus->busno = busno;
+ else
+ newbus->busno = curr->bus_num;
list_add_tail (&newbus->bus_list, &gbuses);
return newbus;
}
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) {
err ("out of system memory \n");
return NULL;
@@ -299,7 +315,7 @@ int __init ibmphp_rsrc_init (void)
* actually appears...
*/
if (ibmphp_add_resource (new_mem) < 0) {
- newbus = alloc_error_bus (curr);
+ newbus = alloc_error_bus (curr, 0, 0);
if (!newbus)
return -ENOMEM;
newbus->firstMem = new_mem;
@@ -316,7 +332,7 @@ int __init ibmphp_rsrc_init (void)
new_pfmem->type = PFMEM;
new_pfmem->fromMem = FALSE;
if (ibmphp_add_resource (new_pfmem) < 0) {
- newbus = alloc_error_bus (curr);
+ newbus = alloc_error_bus (curr, 0, 0);
if (!newbus)
return -ENOMEM;
newbus->firstPFMem = new_pfmem;
@@ -340,7 +356,7 @@ int __init ibmphp_rsrc_init (void)
* range actually appears...
*/
if (ibmphp_add_resource (new_io) < 0) {
- newbus = alloc_error_bus (curr);
+ newbus = alloc_error_bus (curr, 0, 0);
if (!newbus)
return -ENOMEM;
newbus->firstIO = new_io;
@@ -352,8 +368,6 @@ int __init ibmphp_rsrc_init (void)
}
}
- debug ("after the while loop in rsrc_init \n");
-
list_for_each (tmp, &gbuses) {
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 */
@@ -361,11 +375,9 @@ int __init ibmphp_rsrc_init (void)
if (rc)
return rc;
}
- debug ("b4 once_over in rsrc_init \n");
rc = once_over (); /* This is to align ranges (so no -1) */
if (rc)
return rc;
- debug ("after once_over in rsrc_init \n");
return 0;
}
@@ -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
* 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)
* 0 or -1
*******************************************************************************/
@@ -593,12 +605,17 @@ int ibmphp_add_resource (struct resource_node *res)
struct resource_node *res_start = NULL;
debug ("%s - enter\n", __FUNCTION__);
+
+ if (!res) {
+ err ("NULL passed to add \n");
+ return -ENODEV;
+ }
bus_cur = find_bus_wprev (res->busno, NULL, 0);
if (!bus_cur) {
/* 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;
}
@@ -769,6 +786,11 @@ int ibmphp_remove_resource (struct resource_node *res)
struct resource_node *mem_cur;
char * type = "";
+ if (!res) {
+ err ("resource to remove is NULL \n");
+ return -ENODEV;
+ }
+
bus_cur = find_bus_wprev (res->busno, NULL, 0);
if (!bus_cur) {
@@ -797,7 +819,6 @@ int ibmphp_remove_resource (struct resource_node *res)
res_prev = NULL;
while (res_cur) {
- /* ???????????DO WE _NEED_ TO BE CHECKING FOR END AS WELL?????????? */
if ((res_cur->start == res->start) && (res_cur->end == res->end))
break;
res_prev = res_cur;
@@ -981,7 +1002,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
if (!bus_cur) {
/* 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;
}
@@ -1340,7 +1361,7 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
prev_bus = find_bus_wprev (parent_busno, NULL, 0);
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;
}
@@ -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
- * 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)
{
struct resource_node *res_cur = NULL;
char * type = "";
+ if (!bus) {
+ err ("The bus passed in NULL to find resource \n");
+ return -ENODEV;
+ }
+
switch (flag) {
case IO:
res_cur = bus->firstIO;
@@ -1514,11 +1540,11 @@ int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resour
res_cur = res_cur->next;
}
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;
}
} 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;
}
}
@@ -1756,6 +1782,8 @@ void ibmphp_print_test (void)
struct range_node *range;
struct resource_node *res;
struct list_head *tmp;
+
+ debug_pci ("*****************START**********************\n");
if ((!list_empty(&gbuses)) && flags) {
err ("The GBUSES is not NULL?!?!?!?!?\n");
@@ -1764,50 +1792,50 @@ void ibmphp_print_test (void)
list_for_each (tmp, &gbuses) {
bus_cur = list_entry (tmp, struct bus_node, bus_list);
- debug ("This is bus # %d. There are \n", bus_cur->busno);
- debug ("IORanges = %d\t", bus_cur->noIORanges);
- debug ("MemRanges = %d\t", bus_cur->noMemRanges);
- debug ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
- debug ("The IO Ranges are as follows:\n");
+ debug_pci ("This is bus # %d. There are \n", bus_cur->busno);
+ debug_pci ("IORanges = %d\t", bus_cur->noIORanges);
+ debug_pci ("MemRanges = %d\t", bus_cur->noMemRanges);
+ debug_pci ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
+ debug_pci ("The IO Ranges are as follows:\n");
if (bus_cur->rangeIO) {
range = bus_cur->rangeIO;
for (i = 0; i < bus_cur->noIORanges; i++) {
- debug ("rangeno is %d\n", range->rangeno);
- debug ("[%x - %x]\n", range->start, range->end);
+ debug_pci ("rangeno is %d\n", range->rangeno);
+ debug_pci ("[%x - %x]\n", range->start, range->end);
range = range->next;
}
}
- debug ("The Mem Ranges are as follows:\n");
+ debug_pci ("The Mem Ranges are as follows:\n");
if (bus_cur->rangeMem) {
range = bus_cur->rangeMem;
for (i = 0; i < bus_cur->noMemRanges; i++) {
- debug ("rangeno is %d\n", range->rangeno);
- debug ("[%x - %x]\n", range->start, range->end);
+ debug_pci ("rangeno is %d\n", range->rangeno);
+ debug_pci ("[%x - %x]\n", range->start, range->end);
range = range->next;
}
}
- debug ("The PFMem Ranges are as follows:\n");
+ debug_pci ("The PFMem Ranges are as follows:\n");
if (bus_cur->rangePFMem) {
range = bus_cur->rangePFMem;
for (i = 0; i < bus_cur->noPFMemRanges; i++) {
- debug ("rangeno is %d\n", range->rangeno);
- debug ("[%x - %x]\n", range->start, range->end);
+ debug_pci ("rangeno is %d\n", range->rangeno);
+ debug_pci ("[%x - %x]\n", range->start, range->end);
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) {
res = bus_cur->firstIO;
while (res) {
- debug ("The range # is %d\n", res->rangeno);
- debug ("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 ("The range # is %d\n", res->rangeno);
+ debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+ debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
if (res->next)
res = res->next;
else if (res->nextRange)
@@ -1816,13 +1844,13 @@ void ibmphp_print_test (void)
break;
}
}
- debug ("Mem...\n");
+ debug_pci ("Mem...\n");
if (bus_cur->firstMem) {
res = bus_cur->firstMem;
while (res) {
- debug ("The range # is %d\n", res->rangeno);
- debug ("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 ("The range # is %d\n", res->rangeno);
+ debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+ debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
if (res->next)
res = res->next;
else if (res->nextRange)
@@ -1831,13 +1859,13 @@ void ibmphp_print_test (void)
break;
}
}
- debug ("PFMem...\n");
+ debug_pci ("PFMem...\n");
if (bus_cur->firstPFMem) {
res = bus_cur->firstPFMem;
while (res) {
- debug ("The range # is %d\n", res->rangeno);
- debug ("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 ("The range # is %d\n", res->rangeno);
+ debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+ debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
if (res->next)
res = res->next;
else if (res->nextRange)
@@ -1847,23 +1875,53 @@ void ibmphp_print_test (void)
}
}
- debug ("PFMemFromMem...\n");
+ debug_pci ("PFMemFromMem...\n");
if (bus_cur->firstPFMemFromMem) {
res = bus_cur->firstPFMemFromMem;
while (res) {
- debug ("The range # is %d\n", res->rangeno);
- debug ("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 ("The range # is %d\n", res->rangeno);
+ debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+ debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
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
* 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
- * 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
* Returns: none
* Note: this function doesn't take into account IO restrictions etc,
@@ -1874,7 +1932,7 @@ void ibmphp_print_test (void)
*/
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;
u32 start_address, end_address, upper_start, upper_end;
struct bus_node *bus_sec;
@@ -1883,19 +1941,24 @@ static int __init update_bridge_ranges (struct bus_node **bus)
struct resource_node *mem;
struct resource_node *pfmem;
struct range_node *range;
+ unsigned int devfn;
+
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 ("bus_cur->busno = %x\n", bus_cur->busno);
for (device = 0; device < 32; device++) {
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) {
/* 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) {
case PCI_HEADER_TYPE_NORMAL:
@@ -1914,21 +1977,25 @@ static int __init update_bridge_ranges (struct bus_node **bus)
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);
- pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_BASE, &start_io_address);
- pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_LIMIT, &end_io_address);
- pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_BASE_UPPER16, &upper_io_start);
- pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_LIMIT_UPPER16, &upper_io_end);
+ /* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */
+ if (!bus_sec) {
+ bus_sec = alloc_error_bus (NULL, sec_busno, 1);
+ /* 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 |= (upper_io_start << 16);
end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8;
end_address |= (upper_io_end << 16);
if ((start_address) && (start_address <= end_address)) {
-
range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
-
if (!range) {
err ("out of system memory \n");
return -ENOMEM;
@@ -1937,36 +2004,42 @@ static int __init update_bridge_ranges (struct bus_node **bus)
range->start = start_address;
range->end = end_address + 0xfff;
- if (bus_sec->noIORanges > 0)
- add_range (IO, range, bus_sec);
- else {
+ if (bus_sec->noIORanges > 0) {
+ if (!range_exists_already (range, bus_sec, IO)) {
+ add_range (IO, range, bus_sec);
+ ++bus_sec->noIORanges;
+ } else {
+ kfree (range);
+ range = NULL;
+ }
+ } else {
/* 1st IO Range on the bus */
range->rangeno = 1;
bus_sec->rangeIO = range;
+ ++bus_sec->noIORanges;
}
-
- ++bus_sec->noIORanges;
fix_resources (bus_sec);
-
- io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
- if (!io) {
- kfree (range);
- err ("out of system memory \n");
- return -ENOMEM;
+
+ if (ibmphp_find_resource (bus_cur, start_address, &io, IO)) {
+ io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+ if (!io) {
+ kfree (range);
+ err ("out of system memory \n");
+ return -ENOMEM;
+ }
+ memset (io, 0, sizeof (struct resource_node));
+ io->type = IO;
+ io->busno = bus_cur->busno;
+ io->devfunc = ((device << 3) | (function & 0x7));
+ io->start = start_address;
+ io->end = end_address + 0xfff;
+ io->len = io->end - io->start + 1;
+ ibmphp_add_resource (io);
}
- memset (io, 0, sizeof (struct resource_node));
- io->type = IO;
- io->busno = bus_cur->busno;
- io->devfunc = ((device << 3) | (function & 0x7));
- io->start = start_address;
- io->end = end_address + 0xfff;
- io->len = io->end - io->start + 1;
-
- ibmphp_add_resource (io);
- }
+ }
- pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, 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_BASE, &start_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;
end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
@@ -1982,36 +2055,44 @@ static int __init update_bridge_ranges (struct bus_node **bus)
range->start = start_address;
range->end = end_address + 0xfffff;
- if (bus_sec->noMemRanges > 0)
- add_range (MEM, range, bus_sec);
- else {
+ if (bus_sec->noMemRanges > 0) {
+ if (!range_exists_already (range, bus_sec, MEM)) {
+ add_range (MEM, range, bus_sec);
+ ++bus_sec->noMemRanges;
+ } else {
+ kfree (range);
+ range = NULL;
+ }
+ } else {
/* 1st Mem Range on the bus */
range->rangeno = 1;
bus_sec->rangeMem = range;
+ ++bus_sec->noMemRanges;
}
- ++bus_sec->noMemRanges;
fix_resources (bus_sec);
- mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
- if (!mem) {
- kfree (range);
- err ("out of system memory \n");
- return -ENOMEM;
+ if (ibmphp_find_resource (bus_cur, start_address, &mem, MEM)) {
+ mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+ if (!mem) {
+ kfree (range);
+ err ("out of system memory \n");
+ return -ENOMEM;
+ }
+ memset (mem, 0, sizeof (struct resource_node));
+ mem->type = MEM;
+ mem->busno = bus_cur->busno;
+ mem->devfunc = ((device << 3) | (function & 0x7));
+ mem->start = start_address;
+ mem->end = end_address + 0xfffff;
+ mem->len = mem->end - mem->start + 1;
+ ibmphp_add_resource (mem);
}
- memset (mem, 0, sizeof (struct resource_node));
- mem->type = MEM;
- mem->busno = bus_cur->busno;
- mem->devfunc = ((device << 3) | (function & 0x7));
- mem->start = start_address;
- mem->end = end_address + 0xfffff;
- mem->len = mem->end - mem->start + 1;
- 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_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_BASE_UPPER32, &upper_start);
- pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_LIMIT_UPPER32, &upper_end);
+ pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &start_mem_address);
+ pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &end_mem_address);
+ 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;
end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
#if BITS_PER_LONG == 64
@@ -2030,32 +2111,40 @@ static int __init update_bridge_ranges (struct bus_node **bus)
range->start = start_address;
range->end = end_address + 0xfffff;
- if (bus_sec->noPFMemRanges > 0)
- add_range (PFMEM, range, bus_sec);
- else {
+ if (bus_sec->noPFMemRanges > 0) {
+ if (!range_exists_already (range, bus_sec, PFMEM)) {
+ add_range (PFMEM, range, bus_sec);
+ ++bus_sec->noPFMemRanges;
+ } else {
+ kfree (range);
+ range = NULL;
+ }
+ } else {
/* 1st PFMem Range on the bus */
range->rangeno = 1;
bus_sec->rangePFMem = range;
+ ++bus_sec->noPFMemRanges;
}
- ++bus_sec->noPFMemRanges;
fix_resources (bus_sec);
-
- pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
- if (!pfmem) {
- kfree (range);
- err ("out of system memory \n");
- return -ENOMEM;
+ if (ibmphp_find_resource (bus_cur, start_address, &pfmem, PFMEM)) {
+ pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+ if (!pfmem) {
+ kfree (range);
+ err ("out of system memory \n");
+ return -ENOMEM;
+ }
+ memset (pfmem, 0, sizeof (struct resource_node));
+ pfmem->type = PFMEM;
+ pfmem->busno = bus_cur->busno;
+ pfmem->devfunc = ((device << 3) | (function & 0x7));
+ pfmem->start = start_address;
+ pfmem->end = end_address + 0xfffff;
+ pfmem->len = pfmem->end - pfmem->start + 1;
+ pfmem->fromMem = FALSE;
+
+ ibmphp_add_resource (pfmem);
}
- memset (pfmem, 0, sizeof (struct resource_node));
- pfmem->type = PFMEM;
- pfmem->busno = bus_cur->busno;
- pfmem->devfunc = ((device << 3) | (function & 0x7));
- pfmem->start = start_address;
- pfmem->end = end_address + 0xfffff;
- pfmem->len = pfmem->end - pfmem->start + 1;
- pfmem->fromMem = FALSE;
- ibmphp_add_resource (pfmem);
}
break;
} /* end of switch */
diff --git a/drivers/hotplug/pci_hotplug.h b/drivers/hotplug/pci_hotplug.h
index 4ca357f6590a..ae13d0c7ee5b 100644
--- a/drivers/hotplug/pci_hotplug.h
+++ b/drivers/hotplug/pci_hotplug.h
@@ -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
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 579edc49e82a..14b5dcb183bf 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -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
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
index 63dc49410dbc..c493d2f0216f 100644
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -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
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6460e5f08eda..dcb4afa71840 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -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
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 67c7e1feb732..582fac9f16f7 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -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);
}
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 5537baa9739d..7145e151e1f8 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -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);
}
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 6e8be7d8f115..a25f9865d6a7 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -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)
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 3cfed588b719..32d40841f232 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -57,7 +57,7 @@ static void dbg_hcs_params (struct ehci_hcd *ehci, char *label)
strcat(buf, tmp);
}
dbg ("%s: %s portroute %s",
- ehci->hcd.self.bus_name, label,
+ hcd_to_bus (&ehci->hcd)->bus_name, label,
buf);
}
}
@@ -122,7 +122,8 @@ dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
}
}
-static int dbg_status_buf (char *buf, unsigned len, char *label, u32 status)
+static int __attribute__((__unused__))
+dbg_status_buf (char *buf, unsigned len, char *label, u32 status)
{
return snprintf (buf, len,
"%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
@@ -140,7 +141,8 @@ static int dbg_status_buf (char *buf, unsigned len, char *label, u32 status)
);
}
-static int dbg_intr_buf (char *buf, unsigned len, char *label, u32 enable)
+static int __attribute__((__unused__))
+dbg_intr_buf (char *buf, unsigned len, char *label, u32 enable)
{
return snprintf (buf, len,
"%s%sintrenable %02x%s%s%s%s%s%s",
@@ -213,19 +215,19 @@ dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
static inline int __attribute__((__unused__))
dbg_status_buf (char *buf, unsigned len, char *label, u32 status)
-{}
+{ return 0; }
static inline int __attribute__((__unused__))
dbg_command_buf (char *buf, unsigned len, char *label, u32 command)
-{}
+{ return 0; }
static inline int __attribute__((__unused__))
dbg_intr_buf (char *buf, unsigned len, char *label, u32 enable)
-{}
+{ return 0; }
static inline int __attribute__((__unused__))
dbg_port_buf (char *buf, unsigned len, char *label, int port, u32 status)
-{}
+{ return 0; }
#endif /* DEBUG */
@@ -248,7 +250,16 @@ dbg_port_buf (char *buf, unsigned len, char *label, int port, u32 status)
dbg ("%s", _buf); \
}
-#ifdef DEBUG
+/*-------------------------------------------------------------------------*/
+
+#ifdef STUB_DEBUG_FILES
+
+static inline void create_debug_files (struct ehci_hcd *bus) { }
+static inline void remove_debug_files (struct ehci_hcd *bus) { }
+
+#else
+
+/* troubleshooting help: expose state in driverfs */
#define speed_char(info1) ({ char tmp; \
switch (info1 & (3 << 12)) { \
@@ -258,6 +269,49 @@ dbg_port_buf (char *buf, unsigned len, char *label, int port, u32 status)
default: tmp = '?'; break; \
}; tmp; })
+static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep)
+{
+ u32 scratch;
+ struct list_head *entry;
+ struct ehci_qtd *td;
+ unsigned temp;
+ unsigned size = *sizep;
+ char *next = *nextp;
+
+ scratch = cpu_to_le32p (&qh->hw_info1);
+ temp = snprintf (next, size, "qh/%p dev%d %cs ep%d %08x %08x",
+ qh, scratch & 0x007f,
+ speed_char (scratch),
+ (scratch >> 8) & 0x000f,
+ scratch, cpu_to_le32p (&qh->hw_info2));
+ size -= temp;
+ next += temp;
+
+ list_for_each (entry, &qh->qtd_list) {
+ td = list_entry (entry, struct ehci_qtd,
+ qtd_list);
+ scratch = cpu_to_le32p (&td->hw_token);
+ temp = snprintf (next, size,
+ "\n\ttd/%p %s len=%d %08x urb %p",
+ td, ({ char *tmp;
+ switch ((scratch>>8)&0x03) {
+ case 0: tmp = "out"; break;
+ case 1: tmp = "in"; break;
+ case 2: tmp = "setup"; break;
+ default: tmp = "?"; break;
+ } tmp;}),
+ (scratch >> 16) & 0x7fff,
+ scratch,
+ td->urb);
+ size -= temp;
+ next += temp;
+ }
+
+ temp = snprintf (next, size, "\n");
+ *sizep = size - temp;
+ *nextp = next + temp;
+}
+
static ssize_t
show_async (struct device *dev, char *buf, size_t count, loff_t off)
{
@@ -284,49 +338,21 @@ show_async (struct device *dev, char *buf, size_t count, loff_t off)
if (ehci->async) {
qh = ehci->async;
do {
- u32 scratch;
- struct list_head *entry;
- struct ehci_qtd *td;
-
- scratch = cpu_to_le32p (&qh->hw_info1);
- temp = snprintf (next, size, "qh %p dev%d %cs ep%d",
- qh, scratch & 0x007f,
- speed_char (scratch),
- (scratch >> 8) & 0x000f);
- size -= temp;
- next += temp;
-
- list_for_each (entry, &qh->qtd_list) {
- td = list_entry (entry, struct ehci_qtd,
- qtd_list);
- scratch = cpu_to_le32p (&td->hw_token);
- temp = snprintf (next, size,
- ", td %p len=%d tok %04x %s",
- td, scratch >> 16,
- scratch & 0xffff,
- ({ char *tmp;
- switch ((scratch>>8)&0x03) {
- case 0: tmp = "out"; break;
- case 1: tmp = "in"; break;
- case 2: tmp = "setup"; break;
- default: tmp = "?"; break;
- } tmp;})
- );
- size -= temp;
- next += temp;
- }
-
- temp = snprintf (next, size, "\n");
- size -= temp;
- next += temp;
-
+ qh_lines (qh, &next, &size);
} while ((qh = qh->qh_next.qh) != ehci->async);
}
+ if (ehci->reclaim) {
+ temp = snprintf (next, size, "\nreclaim =\n");
+ size -= temp;
+ next += temp;
+
+ qh_lines (ehci->reclaim, &next, &size);
+ }
spin_unlock_irqrestore (&ehci->lock, flags);
return count - size;
}
-static DEVICE_ATTR (async, S_IRUSR, show_async, NULL);
+static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
#define DBG_SCHED_LIMIT 64
@@ -373,7 +399,7 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
do {
switch (tag) {
case Q_TYPE_QH:
- temp = snprintf (next, size, " intr-%d %p",
+ temp = snprintf (next, size, " qh%d/%p",
p.qh->period, p.qh);
size -= temp;
next += temp;
@@ -387,12 +413,14 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
&p.qh->hw_info1);
temp = snprintf (next, size,
- " (%cs dev%d ep%d)",
+ " (%cs dev%d ep%d [%d/%d] %d)",
speed_char (scratch),
scratch & 0x007f,
- (scratch >> 8) & 0x000f);
+ (scratch >> 8) & 0x000f,
+ p.qh->usecs, p.qh->c_usecs,
+ scratch >> 16);
- /* FIXME TDs too */
+ /* FIXME TD info too */
if (seen_count < DBG_SCHED_LIMIT)
seen [seen_count++].qh = p.qh;
@@ -434,7 +462,7 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
return count - size;
}
-static DEVICE_ATTR (periodic, S_IRUSR, show_periodic, NULL);
+static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL);
#undef DBG_SCHED_LIMIT
@@ -522,7 +550,7 @@ show_registers (struct device *dev, char *buf, size_t count, loff_t off)
return count - size;
}
-static DEVICE_ATTR (registers, S_IRUSR, show_registers, NULL);
+static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
static inline void create_debug_files (struct ehci_hcd *bus)
{
@@ -538,14 +566,5 @@ static inline void remove_debug_files (struct ehci_hcd *bus)
device_remove_file (&bus->hcd.pdev->dev, &dev_attr_registers);
}
-#else /* DEBUG */
-
-static inline void create_debug_files (struct ehci_hcd *bus)
-{
-}
-
-static inline void remove_debug_files (struct ehci_hcd *bus)
-{
-}
+#endif /* STUB_DEBUG_FILES */
-#endif /* DEBUG */
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 6aaf8a72f382..833de904194c 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -38,7 +38,12 @@
#endif
#include <linux/usb.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
+#include "../hcd.h"
+#else
#include "../core/hcd.h"
+#endif
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -87,7 +92,7 @@
* 2001-June Works with usb-storage and NEC EHCI on 2.4
*/
-#define DRIVER_VERSION "2002-Aug-06"
+#define DRIVER_VERSION "2002-Aug-28"
#define DRIVER_AUTHOR "David Brownell"
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
@@ -104,6 +109,8 @@
#define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */
#define EHCI_TUNE_MULT_TT 1
+#define EHCI_WATCHDOG_JIFFIES (HZ/100) /* arbitrary; ~10 msec */
+
/* Initial IRQ latency: lower than default */
static int log2_irq_thresh = 0; // 0 to 6
MODULE_PARM (log2_irq_thresh, "i");
@@ -232,6 +239,19 @@ static void ehci_ready (struct ehci_hcd *ehci)
static void ehci_tasklet (unsigned long param);
+static void ehci_irq (struct usb_hcd *hcd);
+
+static void ehci_watchdog (unsigned long param)
+{
+ struct ehci_hcd *ehci = (struct ehci_hcd *) param;
+ unsigned long flags;
+
+ /* guard against lost IAA, which wedges everything */
+ spin_lock_irqsave (&ehci->lock, flags);
+ ehci_irq (&ehci->hcd);
+ spin_unlock_irqrestore (&ehci->lock, flags);
+}
+
/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/...
* off the controller (maybe it can boot from highspeed USB disks).
*/
@@ -267,6 +287,7 @@ static int ehci_start (struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
u32 temp;
struct usb_device *udev;
+ struct usb_bus *bus;
int retval;
u32 hcc_params;
u8 tempbyte;
@@ -372,16 +393,19 @@ static int ehci_start (struct usb_hcd *hcd)
ehci->tasklet.func = ehci_tasklet;
ehci->tasklet.data = (unsigned long) ehci;
+ init_timer (&ehci->watchdog);
+ ehci->watchdog.function = ehci_watchdog;
+ ehci->watchdog.data = (unsigned long) ehci;
+
/* wire up the root hub */
- hcd->self.root_hub = udev = usb_alloc_dev (NULL, &hcd->self);
+ bus = hcd_to_bus (hcd);
+ bus->root_hub = udev = usb_alloc_dev (NULL, bus);
if (!udev) {
done2:
ehci_mem_cleanup (ehci);
return -ENOMEM;
}
- create_debug_files (ehci);
-
/*
* Start, enabling full USB 2.0 functionality ... usb 1.1 devices
* are explicitly handed to companion controller(s), so no TT is
@@ -394,7 +418,7 @@ done2:
/* PCI Serial Bus Release Number is at 0x60 offset */
pci_read_config_byte (hcd->pdev, 0x60, &tempbyte);
temp = readw (&ehci->caps->hci_version);
- info ("USB %x.%x support enabled, EHCI rev %x.%2x",
+ info ("USB %x.%x support enabled, EHCI rev %x.%02x",
((tempbyte & 0xf0)>>4),
(tempbyte & 0x0f),
temp >> 8,
@@ -409,16 +433,22 @@ done2:
*/
usb_connect (udev);
udev->speed = USB_SPEED_HIGH;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
+ if (usb_new_device (udev) != 0) {
+#else
if (usb_register_root_hub (udev, &ehci->hcd.pdev->dev) != 0) {
+#endif
if (hcd->state == USB_STATE_RUNNING)
ehci_ready (ehci);
ehci_reset (ehci);
- hcd->self.root_hub = 0;
+ bus->root_hub = 0;
usb_free_dev (udev);
retval = -ENODEV;
goto done2;
}
+ create_debug_files (ehci);
+
return 0;
}
@@ -428,13 +458,20 @@ static void ehci_stop (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
- dbg ("%s: stop", hcd->self.bus_name);
+ dbg ("%s: stop", hcd_to_bus (hcd)->bus_name);
/* no more interrupts ... */
if (hcd->state == USB_STATE_RUNNING)
ehci_ready (ehci);
+ if (in_interrupt ()) /* should not happen!! */
+ err ("stopped %s!", RUN_CONTEXT);
+ else
+ del_timer_sync (&ehci->watchdog);
ehci_reset (ehci);
+ /* let companion controllers work when we aren't */
+ writel (0, &ehci->regs->configured_flag);
+
remove_debug_files (ehci);
/* root hub is shut down separately (first, when possible) */
@@ -463,7 +500,7 @@ static int ehci_suspend (struct usb_hcd *hcd, u32 state)
int ports;
int i;
- dbg ("%s: suspend to %d", hcd->self.bus_name, state);
+ dbg ("%s: suspend to %d", hcd_to_bus (hcd)->bus_name, state);
ports = HCS_N_PORTS (ehci->hcs_params);
@@ -480,7 +517,7 @@ static int ehci_suspend (struct usb_hcd *hcd, u32 state)
if ((temp & PORT_PE) == 0
|| (temp & PORT_OWNER) != 0)
continue;
-dbg ("%s: suspend port %d", hcd->self.bus_name, i);
+dbg ("%s: suspend port %d", hcd_to_bus (hcd)->bus_name, i);
temp |= PORT_SUSPEND;
writel (temp, &ehci->regs->port_status [i]);
}
@@ -502,7 +539,7 @@ static int ehci_resume (struct usb_hcd *hcd)
int ports;
int i;
- dbg ("%s: resume", hcd->self.bus_name);
+ dbg ("%s: resume", hcd_to_bus (hcd)->bus_name);
ports = HCS_N_PORTS (ehci->hcs_params);
@@ -522,7 +559,7 @@ static int ehci_resume (struct usb_hcd *hcd)
if ((temp & PORT_PE) == 0
|| (temp & PORT_SUSPEND) != 0)
continue;
-dbg ("%s: resume port %d", hcd->self.bus_name, i);
+dbg ("%s: resume port %d", hcd_to_bus (hcd)->bus_name, i);
temp |= PORT_RESUME;
writel (temp, &ehci->regs->port_status [i]);
readl (&ehci->regs->command); /* unblock posted writes */
@@ -546,12 +583,17 @@ dbg ("%s: resume port %d", hcd->self.bus_name, i);
static void ehci_tasklet (unsigned long param)
{
struct ehci_hcd *ehci = (struct ehci_hcd *) param;
+ unsigned long flags;
+
+ spin_lock_irqsave (&ehci->lock, flags);
if (ehci->reclaim_ready)
- end_unlink_async (ehci);
- scan_async (ehci);
+ flags = end_unlink_async (ehci, flags);
+ flags = scan_async (ehci, flags);
if (ehci->next_uframe != -1)
- scan_periodic (ehci);
+ flags = scan_periodic (ehci, flags);
+
+ spin_unlock_irqrestore (&ehci->lock, flags);
}
/*-------------------------------------------------------------------------*/
@@ -564,7 +606,7 @@ static void ehci_irq (struct usb_hcd *hcd)
/* e.g. cardbus physical eject */
if (status == ~(u32) 0) {
- dbg ("%s: device removed!", hcd->self.bus_name);
+ dbg ("%s: device removed!", hcd_to_bus (hcd)->bus_name);
goto dead;
}
@@ -597,7 +639,7 @@ static void ehci_irq (struct usb_hcd *hcd)
/* PCI errors [4.15.2.4] */
if (unlikely ((status & STS_FATAL) != 0)) {
err ("%s: fatal error, state %x",
- hcd->self.bus_name, hcd->state);
+ hcd_to_bus (hcd)->bus_name, hcd->state);
dead:
ehci_reset (ehci);
/* generic layer kills/unlinks all urbs, then
@@ -673,7 +715,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
unsigned long flags;
dbg ("%s urb_dequeue %p qh %p state %d",
- hcd->self.bus_name, urb, qh, qh->qh_state);
+ hcd_to_bus (hcd)->bus_name, urb, qh, qh->qh_state);
switch (usb_pipetype (urb->pipe)) {
// case PIPE_CONTROL:
@@ -681,7 +723,13 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
default:
spin_lock_irqsave (&ehci->lock, flags);
if (ehci->reclaim) {
- dbg ("dq: reclaim busy, %s", RUN_CONTEXT);
+ dbg ("dq %p: reclaim = %p, %s",
+ qh, ehci->reclaim, RUN_CONTEXT);
+ if (qh == ehci->reclaim) {
+ /* unlinking qh for another queued urb? */
+ spin_unlock_irqrestore (&ehci->lock, flags);
+ return 0;
+ }
if (in_interrupt ()) {
spin_unlock_irqrestore (&ehci->lock, flags);
return -EAGAIN;
@@ -702,19 +750,19 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
break;
case PIPE_INTERRUPT:
+ spin_lock_irqsave (&ehci->lock, flags);
if (qh->qh_state == QH_STATE_LINKED) {
/* messy, can spin or block a microframe ... */
- intr_deschedule (ehci, qh, 1);
+ flags = intr_deschedule (ehci, qh, 1, flags);
/* qh_state == IDLE */
}
- qh_completions (ehci, qh);
+ flags = qh_completions (ehci, qh, flags);
/* reschedule QH iff another request is queued */
if (!list_empty (&qh->qtd_list)
&& HCD_IS_RUNNING (ehci->hcd.state)) {
int status;
- spin_lock_irqsave (&ehci->lock, flags);
status = qh_schedule (ehci, qh);
spin_unlock_irqrestore (&ehci->lock, flags);
@@ -726,7 +774,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
}
return status;
}
-
+ spin_unlock_irqrestore (&ehci->lock, flags);
break;
case PIPE_ISOCHRONOUS:
@@ -754,7 +802,8 @@ static void ehci_free_config (struct usb_hcd *hcd, struct usb_device *udev)
/* ASSERT: no requests/urbs are still linked (so no TDs) */
/* ASSERT: nobody can be submitting urbs for this any more */
- dbg ("%s: free_config devnum %d", hcd->self.bus_name, udev->devnum);
+ dbg ("%s: free_config devnum %d",
+ hcd_to_bus (hcd)->bus_name, udev->devnum);
spin_lock_irqsave (&ehci->lock, flags);
for (i = 0; i < 32; i++) {
@@ -775,7 +824,8 @@ static void ehci_free_config (struct usb_hcd *hcd, struct usb_device *udev)
why = 0;
if (why) {
err ("dev %s-%s ep %d-%s error: %s",
- hcd->self.bus_name, udev->devpath,
+ hcd_to_bus (hcd)->bus_name,
+ udev->devpath,
i & 0xf, (i & 0x10) ? "IN" : "OUT",
why);
BUG ();
@@ -805,8 +855,7 @@ static void ehci_free_config (struct usb_hcd *hcd, struct usb_device *udev)
start_unlink_async (ehci, qh);
while (qh->qh_state != QH_STATE_IDLE
&& ehci->hcd.state != USB_STATE_HALT) {
- spin_unlock_irqrestore (&ehci->lock,
- flags);
+ spin_unlock_irqrestore (&ehci->lock, flags);
wait_ms (1);
spin_lock_irqsave (&ehci->lock, flags);
}
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 22d4919cbf97..a0cc9d50b2ff 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -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;
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 7c401d7d2c60..157e2306e793 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -161,9 +161,10 @@ static inline void qtd_copy_status (struct urb *urb, size_t length, u32 token)
/* urb->lock ignored from here on (hcd is done with urb) */
-static void ehci_urb_done (
+static unsigned long ehci_urb_done (
struct ehci_hcd *ehci,
- struct urb *urb
+ struct urb *urb,
+ unsigned long flags
) {
#ifdef INTR_AUTOMAGIC
struct urb *resubmit = 0;
@@ -177,7 +178,7 @@ static void ehci_urb_done (
if ((qh->hw_info2 & cpu_to_le32 (0x00ff)) != 0) {
/* ... update hc-wide periodic stats (for usbfs) */
- ehci->hcd.self.bandwidth_int_reqs--;
+ hcd_to_bus (&ehci->hcd)->bandwidth_int_reqs--;
#ifdef INTR_AUTOMAGIC
if (!((urb->status == -ENOENT)
@@ -199,6 +200,8 @@ static void ehci_urb_done (
urb->status = 0;
}
+ /* complete() can reenter this HCD */
+ spin_unlock_irqrestore (&ehci->lock, flags);
usb_hcd_giveback_urb (&ehci->hcd, urb);
#ifdef INTR_AUTOMAGIC
@@ -212,34 +215,32 @@ static void ehci_urb_done (
int status;
resubmit->dev = dev;
- status = usb_submit_urb (resubmit, SLAB_KERNEL);
+ status = SUBMIT_URB (resubmit, SLAB_KERNEL);
if (status != 0)
err ("can't resubmit interrupt urb %p: status %d",
resubmit, status);
usb_put_urb (resubmit);
}
#endif
+
+ spin_lock_irqsave (&ehci->lock, flags);
+ return flags;
}
/*
- * Process completed qtds for a qh, issuing completions if needed.
- * Frees qtds, unmaps buf, returns URB to driver.
- * Races up to qh->hw_current; returns number of urb completions.
+ * Process and free completed qtds for a qh, returning URBs to drivers.
+ * Chases up to qh->hw_current, returns irqsave flags (maybe modified).
*/
-static void
-qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
+static unsigned long
+qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, unsigned long flags)
{
struct ehci_qtd *qtd, *last;
struct list_head *next, *qtd_list = &qh->qtd_list;
int unlink = 0, halted = 0;
- unsigned long flags;
- spin_lock_irqsave (&ehci->lock, flags);
- if (unlikely (list_empty (qtd_list))) {
- spin_unlock_irqrestore (&ehci->lock, flags);
- return;
- }
+ if (unlikely (list_empty (qtd_list)))
+ return flags;
/* scan QTDs till end of list, or we reach an active one */
for (qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list),
@@ -252,12 +253,8 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
/* clean up any state from previous QTD ...*/
if (last) {
- if (likely (last->urb != urb)) {
- /* complete() can reenter this HCD */
- spin_unlock_irqrestore (&ehci->lock, flags);
- ehci_urb_done (ehci, last->urb);
- spin_lock_irqsave (&ehci->lock, flags);
- }
+ if (likely (last->urb != urb))
+ flags = ehci_urb_done (ehci, last->urb, flags);
/* qh overlays can have HC's old cached copies of
* next qtd ptrs, if an URB was queued afterwards.
@@ -283,6 +280,9 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
|| (ehci->hcd.state == USB_STATE_HALT)
|| (qh->qh_state == QH_STATE_IDLE);
+ // FIXME Remove the automagic unlink mode.
+ // Drivers can now clean up safely; its' their job.
+
/* fault: unlink the rest, since this qtd saw an error? */
if (unlikely ((token & QTD_STS_HALT) != 0)) {
unlink = 1;
@@ -341,18 +341,19 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
#endif
}
- /* patch up list head? */
+ /* last urb's completion might still need calling */
+ if (likely (last != 0)) {
+ flags = ehci_urb_done (ehci, last->urb, flags);
+ ehci_qtd_free (ehci, last);
+ }
+
+ /* reactivate queue after error and driver's cleanup */
if (unlikely (halted && !list_empty (qtd_list))) {
qh_update (qh, list_entry (qtd_list->next,
struct ehci_qtd, qtd_list));
}
- spin_unlock_irqrestore (&ehci->lock, flags);
- /* last urb's completion might still need calling */
- if (likely (last != 0)) {
- ehci_urb_done (ehci, last->urb);
- ehci_qtd_free (ehci, last);
- }
+ return flags;
}
/*-------------------------------------------------------------------------*/
@@ -367,31 +368,12 @@ static void qtd_list_free (
struct list_head *qtd_list
) {
struct list_head *entry, *temp;
- int unmapped = 0;
list_for_each_safe (entry, temp, qtd_list) {
struct ehci_qtd *qtd;
qtd = list_entry (entry, struct ehci_qtd, qtd_list);
list_del (&qtd->qtd_list);
- if (unmapped != 2) {
- int direction;
- size_t size;
-
- /* for ctrl unmap twice: SETUP and DATA;
- * else (bulk, intr) just once: DATA
- */
- if (!unmapped++ && usb_pipecontrol (urb->pipe)) {
- direction = PCI_DMA_TODEVICE;
- size = sizeof (struct usb_ctrlrequest);
- } else {
- direction = usb_pipein (urb->pipe)
- ? PCI_DMA_FROMDEVICE
- : PCI_DMA_TODEVICE;
- size = qtd->urb->transfer_buffer_length;
- unmapped++;
- }
- }
ehci_qtd_free (ehci, qtd);
}
}
@@ -670,8 +652,8 @@ ehci_qh_make (
info2 |= hb_mult (maxp) << 30;
}
break;
-#ifdef DEBUG
default:
+#ifdef DEBUG
BUG ();
#endif
}
@@ -859,7 +841,8 @@ submit_async (
epnum |= 0x10;
vdbg ("%s: submit_async urb %p len %d ep %d-%s qtd %p [qh %p]",
- ehci->hcd.self.bus_name, urb, urb->transfer_buffer_length,
+ hcd_to_bus (&ehci->hcd)->bus_name,
+ urb, urb->transfer_buffer_length,
epnum & 0x0f, (epnum & 0x10) ? "in" : "out",
qtd, dev ? dev->ep [epnum] : (void *)~0);
@@ -886,25 +869,28 @@ submit_async (
/* the async qh for the qtds being reclaimed are now unlinked from the HC */
/* caller must not own ehci->lock */
-static void end_unlink_async (struct ehci_hcd *ehci)
+static unsigned long
+end_unlink_async (struct ehci_hcd *ehci, unsigned long flags)
{
struct ehci_qh *qh = ehci->reclaim;
+ del_timer (&ehci->watchdog);
+
qh->qh_state = QH_STATE_IDLE;
qh->qh_next.qh = 0;
qh_put (ehci, qh); // refcount from reclaim
ehci->reclaim = 0;
ehci->reclaim_ready = 0;
- qh_completions (ehci, qh);
+ flags = qh_completions (ehci, qh, flags);
- // unlink any urb should now unlink all following urbs, so that
- // relinking only happens for urbs before the unlinked ones.
if (!list_empty (&qh->qtd_list)
&& HCD_IS_RUNNING (ehci->hcd.state))
qh_link_async (ehci, qh);
else
qh_put (ehci, qh); // refcount from async list
+
+ return flags;
}
@@ -975,16 +961,17 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
cmd |= CMD_IAAD;
writel (cmd, &ehci->regs->command);
/* posted write need not be known to HC yet ... */
+
+ mod_timer (&ehci->watchdog, jiffies + EHCI_WATCHDOG_JIFFIES);
}
/*-------------------------------------------------------------------------*/
-static void scan_async (struct ehci_hcd *ehci)
+static unsigned long
+scan_async (struct ehci_hcd *ehci, unsigned long flags)
{
struct ehci_qh *qh;
- unsigned long flags;
- spin_lock_irqsave (&ehci->lock, flags);
rescan:
qh = ehci->async;
if (likely (qh != 0)) {
@@ -993,12 +980,9 @@ rescan:
if (!list_empty (&qh->qtd_list)) {
// dbg_qh ("scan_async", ehci, qh);
qh = qh_get (qh);
- spin_unlock_irqrestore (&ehci->lock, flags);
/* concurrent unlink could happen here */
- qh_completions (ehci, qh);
-
- spin_lock_irqsave (&ehci->lock, flags);
+ flags = qh_completions (ehci, qh, flags);
qh_put (ehci, qh);
}
@@ -1020,6 +1004,5 @@ rescan:
goto rescan;
} while (qh != ehci->async);
}
-
- spin_unlock_irqrestore (&ehci->lock, flags);
+ return flags;
}
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index e11edf8307fc..2802fa125663 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -222,17 +222,15 @@ static int disable_periodic (struct ehci_hcd *ehci)
// FIXME microframe periods not yet handled
-static void intr_deschedule (
+static unsigned long intr_deschedule (
struct ehci_hcd *ehci,
struct ehci_qh *qh,
- int wait
+ int wait,
+ unsigned long flags
) {
- unsigned long flags;
int status;
unsigned frame = qh->start;
- spin_lock_irqsave (&ehci->lock, flags);
-
do {
periodic_unlink (ehci, frame, qh);
qh_put (ehci, qh);
@@ -251,8 +249,6 @@ static void intr_deschedule (
vdbg ("periodic schedule still enabled");
}
- spin_unlock_irqrestore (&ehci->lock, flags);
-
/*
* If the hc may be looking at this qh, then delay a uframe
* (yeech!) to be sure it's done.
@@ -260,8 +256,10 @@ static void intr_deschedule (
*/
if (((ehci_get_frame (&ehci->hcd) - frame) % qh->period) == 0) {
if (wait) {
+ spin_unlock_irqrestore (&ehci->lock, flags);
udelay (125);
qh->hw_next = EHCI_LIST_END;
+ spin_lock_irqsave (&ehci->lock, flags);
} else {
/* we may not be IDLE yet, but if the qh is empty
* the race is very short. then if qh also isn't
@@ -275,12 +273,13 @@ static void intr_deschedule (
qh->qh_state = QH_STATE_IDLE;
/* update per-qh bandwidth utilization (for usbfs) */
- ehci->hcd.self.bandwidth_allocated -=
+ hcd_to_bus (&ehci->hcd)->bandwidth_allocated -=
(qh->usecs + qh->c_usecs) / qh->period;
vdbg ("descheduled qh %p, per = %d frame = %d count = %d, urbs = %d",
qh, qh->period, frame,
atomic_read (&qh->refcount), ehci->periodic_sched);
+ return flags;
}
static int check_period (
@@ -436,7 +435,7 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
} while (frame < ehci->periodic_size);
/* update per-qh bandwidth for usbfs */
- ehci->hcd.self.bandwidth_allocated +=
+ hcd_to_bus (&ehci->hcd)->bandwidth_allocated +=
(qh->usecs + qh->c_usecs) / qh->period;
/* maybe enable periodic schedule processing */
@@ -486,7 +485,7 @@ static int intr_submit (
BUG_ON (qh == 0);
/* ... update usbfs periodic stats */
- ehci->hcd.self.bandwidth_int_reqs++;
+ hcd_to_bus (&ehci->hcd)->bandwidth_int_reqs++;
done:
spin_unlock_irqrestore (&ehci->lock, flags);
@@ -513,12 +512,10 @@ intr_complete (
}
/* handle any completions */
- spin_unlock_irqrestore (&ehci->lock, flags);
- qh_completions (ehci, qh);
- spin_lock_irqsave (&ehci->lock, flags);
+ flags = qh_completions (ehci, qh, flags);
if (unlikely (list_empty (&qh->qtd_list)))
- intr_deschedule (ehci, qh, 0);
+ flags = intr_deschedule (ehci, qh, 0, flags);
return flags;
}
@@ -1091,13 +1088,12 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags)
/*-------------------------------------------------------------------------*/
-static void scan_periodic (struct ehci_hcd *ehci)
+static unsigned long
+scan_periodic (struct ehci_hcd *ehci, unsigned long flags)
{
unsigned frame, clock, now_uframe, mod;
- unsigned long flags;
mod = ehci->periodic_size << 3;
- spin_lock_irqsave (&ehci->lock, flags);
/*
* When running, scan from last scan point up to "now"
@@ -1237,5 +1233,5 @@ restart:
} else
frame = (frame + 1) % ehci->periodic_size;
}
- spin_unlock_irqrestore (&ehci->lock, flags);
+ return flags;
}
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 45af6f3c7726..76cddfd04f27 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -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 */
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index 4545a999df90..b338d3a6328a 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -72,37 +72,6 @@ static void urb_print (struct urb * urb, char * str, int small)
#endif
}
-static inline struct ed *
-dma_to_ed (struct ohci_hcd *hc, dma_addr_t ed_dma);
-
-/* print non-empty branches of the periodic ed tree */
-static void __attribute__ ((unused))
-ohci_dump_periodic (struct ohci_hcd *ohci, char *label)
-{
- int i, j;
- u32 *ed_p;
- int printed = 0;
-
- for (i= 0; i < 32; i++) {
- j = 5;
- ed_p = &(ohci->hcca->int_table [i]);
- if (*ed_p == 0)
- continue;
- printed = 1;
- printk (KERN_DEBUG "%s, ohci %s frame %2d:",
- label, ohci->hcd.self.bus_name, i);
- while (*ed_p != 0 && j--) {
- struct ed *ed = dma_to_ed (ohci, le32_to_cpup(ed_p));
- printk (" %p/%08x;", ed, ed->hwINFO);
- ed_p = &ed->hwNextED;
- }
- printk ("\n");
- }
- if (!printed)
- printk (KERN_DEBUG "%s, ohci %s, empty periodic schedule\n",
- label, ohci->hcd.self.bus_name);
-}
-
static void ohci_dump_intr_mask (char *label, __u32 mask)
{
dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s",
@@ -239,7 +208,8 @@ static void ohci_dump (struct ohci_hcd *controller, int verbose)
if (verbose)
ohci_dump_periodic (controller, "hcca");
#endif
- dbg ("hcca frame #%04x", controller->hcca->frame_no);
+ if (controller->hcca)
+ dbg ("hcca frame #%04x", controller->hcca->frame_no);
ohci_dump_roothub (controller, 1);
}
@@ -316,8 +286,9 @@ ohci_dump_ed (struct ohci_hcd *ohci, char *label, struct ed *ed, int verbose)
case ED_IN: type = "-IN"; break;
/* else from TDs ... control */
}
- dbg (" info %08x MAX=%d%s%s%s EP=%d%s DEV=%d", le32_to_cpu (tmp),
- 0x0fff & (le32_to_cpu (tmp) >> 16),
+ dbg (" info %08x MAX=%d%s%s%s%s EP=%d%s DEV=%d", le32_to_cpu (tmp),
+ 0x03ff & (le32_to_cpu (tmp) >> 16),
+ (tmp & ED_DEQUEUE) ? " DQ" : "",
(tmp & ED_ISO) ? " ISO" : "",
(tmp & ED_SKIP) ? " SKIP" : "",
(tmp & ED_LOWSPEED) ? " LOW" : "",
@@ -344,5 +315,222 @@ ohci_dump_ed (struct ohci_hcd *ohci, char *label, struct ed *ed, int verbose)
}
}
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,32)
+# define DRIVERFS_DEBUG_FILES
#endif
+#endif /* DEBUG */
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DRIVERFS_DEBUG_FILES
+
+static ssize_t
+show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed)
+{
+ unsigned temp, size = count;
+
+ if (!ed)
+ return 0;
+
+ /* print first --> last */
+ while (ed->ed_prev)
+ ed = ed->ed_prev;
+
+ /* dump a snapshot of the bulk or control schedule */
+ while (ed) {
+ u32 info = ed->hwINFO;
+ u32 scratch = cpu_to_le32p (&ed->hwINFO);
+ struct list_head *entry;
+ struct td *td;
+
+ temp = snprintf (buf, size,
+ "ed/%p %cs dev%d ep%d-%s max %d %08x%s%s %s",
+ ed,
+ (info & ED_LOWSPEED) ? 'l' : 'f',
+ scratch & 0x7f,
+ (scratch >> 7) & 0xf,
+ (info & ED_IN) ? "in" : "out",
+ 0x03ff & (scratch >> 16),
+ scratch,
+ (info & ED_SKIP) ? " s" : "",
+ (ed->hwHeadP & ED_H) ? " H" : "",
+ (ed->hwHeadP & ED_C) ? data1 : data0);
+ size -= temp;
+ buf += temp;
+
+ list_for_each (entry, &ed->td_list) {
+ u32 cbp, be;
+
+ td = list_entry (entry, struct td, td_list);
+ scratch = cpu_to_le32p (&td->hwINFO);
+ cbp = le32_to_cpup (&td->hwCBP);
+ be = le32_to_cpup (&td->hwBE);
+ temp = snprintf (buf, size,
+ "\n\ttd %p %s %d cc=%x urb %p (%08x)",
+ td,
+ ({ char *pid;
+ switch (scratch & TD_DP) {
+ case TD_DP_SETUP: pid = "setup"; break;
+ case TD_DP_IN: pid = "in"; break;
+ case TD_DP_OUT: pid = "out"; break;
+ default: pid = "(?)"; break;
+ } pid;}),
+ cbp ? (be + 1 - cbp) : 0,
+ TD_CC_GET (scratch), td->urb, scratch);
+ size -= temp;
+ buf += temp;
+ }
+
+ temp = snprintf (buf, size, "\n");
+ size -= temp;
+ buf += temp;
+
+ ed = ed->ed_next;
+ }
+ return count - size;
+}
+
+static ssize_t
+show_async (struct device *dev, char *buf, size_t count, loff_t off)
+{
+ struct pci_dev *pdev;
+ struct ohci_hcd *ohci;
+ size_t temp;
+ unsigned long flags;
+
+ if (off != 0)
+ return 0;
+ pdev = container_of (dev, struct pci_dev, dev);
+ ohci = container_of (pci_get_drvdata (pdev), struct ohci_hcd, hcd);
+
+ /* display control and bulk lists together, for simplicity */
+ spin_lock_irqsave (&ohci->lock, flags);
+ temp = show_list (ohci, buf, count, ohci->ed_controltail);
+ count = show_list (ohci, buf + temp, count - temp, ohci->ed_bulktail);
+ spin_unlock_irqrestore (&ohci->lock, flags);
+
+ return temp + count;
+}
+static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
+
+
+#define DBG_SCHED_LIMIT 64
+
+static ssize_t
+show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
+{
+ struct pci_dev *pdev;
+ struct ohci_hcd *ohci;
+ struct ed **seen, *ed;
+ unsigned long flags;
+ unsigned temp, size, seen_count;
+ char *next;
+ unsigned i;
+
+ if (off != 0)
+ return 0;
+ if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC)))
+ return 0;
+ seen_count = 0;
+
+ pdev = container_of (dev, struct pci_dev, dev);
+ ohci = container_of (pci_get_drvdata (pdev), struct ohci_hcd, hcd);
+ next = buf;
+ size = count;
+
+ temp = snprintf (next, size, "size = %d\n", NUM_INTS);
+ size -= temp;
+ next += temp;
+
+ /* dump a snapshot of the periodic schedule (and load) */
+ spin_lock_irqsave (&ohci->lock, flags);
+ for (i = 0; i < NUM_INTS; i++) {
+ if (!(ed = ohci->periodic [i]))
+ continue;
+
+ temp = snprintf (next, size, "%2d [%3d]:", i, ohci->load [i]);
+ size -= temp;
+ next += temp;
+
+ do {
+ temp = snprintf (next, size, " ed%d/%p",
+ ed->interval, ed);
+ size -= temp;
+ next += temp;
+ for (temp = 0; temp < seen_count; temp++) {
+ if (seen [temp] == ed)
+ break;
+ }
+
+ /* show more info the first time around */
+ if (temp == seen_count) {
+ u32 info = ed->hwINFO;
+ u32 scratch = cpu_to_le32p (&ed->hwINFO);
+
+ temp = snprintf (next, size,
+ " (%cs dev%d%s ep%d-%s"
+ " max %d %08x%s%s)",
+ (info & ED_LOWSPEED) ? 'l' : 'f',
+ scratch & 0x7f,
+ (info & ED_ISO) ? " iso" : "",
+ (scratch >> 7) & 0xf,
+ (info & ED_IN) ? "in" : "out",
+ 0x03ff & (scratch >> 16),
+ scratch,
+ (info & ED_SKIP) ? " s" : "",
+ (ed->hwHeadP & ED_H) ? " H" : "");
+ size -= temp;
+ next += temp;
+
+ // FIXME some TD info too
+
+ if (seen_count < DBG_SCHED_LIMIT)
+ seen [seen_count++] = ed;
+
+ ed = ed->ed_next;
+
+ } else {
+ /* we've seen it and what's after */
+ temp = 0;
+ ed = 0;
+ }
+
+ } while (ed);
+
+ temp = snprintf (next, size, "\n");
+ size -= temp;
+ next += temp;
+ }
+ spin_unlock_irqrestore (&ohci->lock, flags);
+ kfree (seen);
+
+ return count - size;
+}
+static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL);
+
+#undef DBG_SCHED_LIMIT
+
+static inline void create_debug_files (struct ohci_hcd *bus)
+{
+ device_create_file (&bus->hcd.pdev->dev, &dev_attr_async);
+ device_create_file (&bus->hcd.pdev->dev, &dev_attr_periodic);
+ // registers
+ dbg ("%s: created debug files", bus->hcd.self.bus_name);
+}
+
+static inline void remove_debug_files (struct ohci_hcd *bus)
+{
+ device_remove_file (&bus->hcd.pdev->dev, &dev_attr_async);
+ device_remove_file (&bus->hcd.pdev->dev, &dev_attr_periodic);
+}
+
+#else /* empty stubs for creating those files */
+
+static inline void create_debug_files (struct ohci_hcd *bus) { }
+static inline void remove_debug_files (struct ohci_hcd *bus) { }
+
+#endif /* DRIVERFS_DEBUG_FILES */
+
+/*-------------------------------------------------------------------------*/
+
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index d7cc8c544068..f8f5d5757987 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -17,6 +17,8 @@
*
* History:
*
+ * 2002/09/03 get rid of ed hashtables, rework periodic scheduling and
+ * bandwidth accounting; if debugging, show schedules in driverfs
* 2002/07/19 fixes to management of ED and schedule state.
* 2002/06/09 SA-1111 support (Christopher Hoover)
* 2002/06/01 remember frame when HC won't see EDs any more; use that info
@@ -66,7 +68,6 @@
* v1.0 1999/04/27 initial release
*
* This file is licenced under the GPL.
- * $Id: ohci-hcd.c,v 1.9 2002/03/27 20:41:57 dbrownell Exp $
*/
#include <linux/config.h>
@@ -107,8 +108,8 @@
* - lots more testing!!
*/
-#define DRIVER_VERSION "2002-Jul-19"
-#define DRIVER_AUTHOR "Roman Weissgaerber <weissg@vienna.at>, David Brownell"
+#define DRIVER_VERSION "2002-Sep-03"
+#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
/*-------------------------------------------------------------------------*/
@@ -152,7 +153,6 @@ static int ohci_urb_enqueue (
unsigned int pipe = urb->pipe;
int i, size = 0;
unsigned long flags;
- int bustime = 0;
int retval = 0;
#ifdef OHCI_VERBOSE_DEBUG
@@ -230,43 +230,32 @@ static int ohci_urb_enqueue (
}
}
-// FIXME: much of this switch should be generic, move to hcd code ...
-// ... and what's not generic can't really be handled this way.
-// need to consider periodicity for both types!
-
- /* allocate and claim bandwidth if needed; ISO
- * needs start frame index if it was't provided.
- */
- switch (usb_pipetype (pipe)) {
- case PIPE_ISOCHRONOUS:
- if (urb->transfer_flags & USB_ISO_ASAP) {
- urb->start_frame = ((ed->state != ED_IDLE)
- ? (ed->intriso.last_iso + 1)
- : (le16_to_cpu (ohci->hcca->frame_no)
- + 10)) & 0xffff;
- }
- /* FALLTHROUGH */
- case PIPE_INTERRUPT:
- if (urb->bandwidth == 0) {
- bustime = usb_check_bandwidth (urb->dev, urb);
- }
- if (bustime < 0) {
- retval = bustime;
- goto fail;
- }
- usb_claim_bandwidth (urb->dev, urb,
- bustime, usb_pipeisoc (urb->pipe));
- }
+ /* schedule the ed if needed */
+ if (ed->state == ED_IDLE) {
+ retval = ed_schedule (ohci, ed);
+ if (retval < 0)
+ goto fail;
+ if (ed->type == PIPE_ISOCHRONOUS) {
+ u16 frame = le16_to_cpu (ohci->hcca->frame_no);
- urb->hcpriv = urb_priv;
+ /* delay a few frames before the first TD */
+ frame += max_t (u16, 8, ed->interval);
+ frame &= ~(ed->interval - 1);
+ frame |= ed->branch;
+ urb->start_frame = frame;
- /* schedule the ed if needed */
- if (ed->state == ED_IDLE)
- ed_schedule (ohci, ed);
+ /* yes, only USB_ISO_ASAP is supported, and
+ * urb->start_frame is never used as input.
+ */
+ }
+ } else if (ed->type == PIPE_ISOCHRONOUS)
+ urb->start_frame = ed->last_iso + ed->interval;
/* fill the TDs and link them to the ed; and
* enable that part of the schedule, if needed
+ * and update count of queued periodic urbs
*/
+ urb->hcpriv = urb_priv;
td_submit_urb (ohci, urb);
fail:
@@ -530,13 +519,15 @@ static int hc_start (struct ohci_hcd *ohci)
usb_connect (udev);
udev->speed = USB_SPEED_FULL;
if (usb_register_root_hub (udev, ohci->parent_dev) != 0) {
- usb_free_dev (udev);
+ usb_free_dev (udev);
+ ohci->hcd.self.root_hub = NULL;
disable (ohci);
ohci->hc_control &= ~OHCI_CTRL_HCFS;
writel (ohci->hc_control, &ohci->regs->control);
return -ENODEV;
}
+ create_debug_files (ohci);
return 0;
}
@@ -571,7 +562,8 @@ static void ohci_irq (struct usb_hcd *hcd)
if (ints & OHCI_INTR_UE) {
disable (ohci);
- err ("OHCI Unrecoverable Error, %s disabled", hcd->self.bus_name);
+ err ("OHCI Unrecoverable Error, %s disabled",
+ hcd->self.bus_name);
// e.g. due to PCI Master/Target Abort
#ifdef DEBUG
@@ -620,10 +612,14 @@ static void ohci_stop (struct usb_hcd *hcd)
if (!ohci->disabled)
hc_reset (ohci);
+ remove_debug_files (ohci);
ohci_mem_cleanup (ohci);
-
- pci_free_consistent (ohci->hcd.pdev, sizeof *ohci->hcca,
- ohci->hcca, ohci->hcca_dma);
+ if (ohci->hcca) {
+ pci_free_consistent (ohci->hcd.pdev, sizeof *ohci->hcca,
+ ohci->hcca, ohci->hcca_dma);
+ ohci->hcca = NULL;
+ ohci->hcca_dma = 0;
+ }
}
/*-------------------------------------------------------------------------*/
@@ -646,14 +642,13 @@ static int hc_restart (struct ohci_hcd *ohci)
usb_disconnect (&ohci->hcd.self.root_hub);
/* empty the interrupt branches */
- for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load [i] = 0;
+ for (i = 0; i < NUM_INTS; i++) ohci->load [i] = 0;
for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table [i] = 0;
/* no EDs to remove */
ohci->ed_rm_list = NULL;
/* empty control and bulk lists */
- ohci->ed_isotail = NULL;
ohci->ed_controltail = NULL;
ohci->ed_bulktail = NULL;
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
index c2b0b2ac8be9..51322551606b 100644
--- a/drivers/usb/host/ohci-mem.c
+++ b/drivers/usb/host/ohci-mem.c
@@ -5,7 +5,6 @@
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under the GPL.
- * $Id: ohci-mem.c,v 1.3 2002/03/22 16:04:54 dbrownell Exp $
*/
/*-------------------------------------------------------------------------*/
@@ -52,13 +51,6 @@ dma_to_ed_td (struct hash_list_t * entry, dma_addr_t dma)
return scan->virt;
}
-static struct ed *
-dma_to_ed (struct ohci_hcd *hc, dma_addr_t ed_dma)
-{
- return (struct ed *) dma_to_ed_td(&(hc->ed_hash [ED_HASH_FUNC(ed_dma)]),
- ed_dma);
-}
-
static struct td *
dma_to_td (struct ohci_hcd *hc, dma_addr_t td_dma)
{
@@ -98,13 +90,6 @@ hash_add_ed_td (
}
static inline int
-hash_add_ed (struct ohci_hcd *hc, struct ed *ed, int mem_flags)
-{
- return hash_add_ed_td (&(hc->ed_hash [ED_HASH_FUNC (ed->dma)]),
- ed, ed->dma, mem_flags);
-}
-
-static inline int
hash_add_td (struct ohci_hcd *hc, struct td *td, int mem_flags)
{
return hash_add_ed_td (&(hc->td_hash [TD_HASH_FUNC (td->td_dma)]),
@@ -139,12 +124,6 @@ hash_free_ed_td (struct hash_list_t *entry, void *virt)
}
static inline void
-hash_free_ed (struct ohci_hcd *hc, struct ed * ed)
-{
- hash_free_ed_td (&(hc->ed_hash[ED_HASH_FUNC(ed->dma)]), ed);
-}
-
-static inline void
hash_free_td (struct ohci_hcd *hc, struct td * td)
{
hash_free_ed_td (&(hc->td_hash[TD_HASH_FUNC(td->td_dma)]), td);
@@ -223,11 +202,6 @@ ed_alloc (struct ohci_hcd *hc, int mem_flags)
memset (ed, 0, sizeof (*ed));
INIT_LIST_HEAD (&ed->td_list);
ed->dma = dma;
- /* hash it for later reverse mapping */
- if (!hash_add_ed (hc, ed, mem_flags)) {
- pci_pool_free (hc->ed_cache, ed, dma);
- return NULL;
- }
}
return ed;
}
@@ -235,7 +209,6 @@ ed_alloc (struct ohci_hcd *hc, int mem_flags)
static void
ed_free (struct ohci_hcd *hc, struct ed *ed)
{
- hash_free_ed (hc, ed);
pci_pool_free (hc->ed_cache, ed, ed->dma);
}
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index fd3c2680f9eb..f4ab56e84030 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -5,7 +5,6 @@
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under the GPL.
- * $Id: ohci-q.c,v 1.8 2002/03/27 20:57:01 dbrownell Exp $
*/
static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv)
@@ -52,6 +51,15 @@ static void finish_urb (struct ohci_hcd *ohci, struct urb *urb)
urb->status = 0;
spin_unlock_irqrestore (&urb->lock, flags);
+ switch (usb_pipetype (urb->pipe)) {
+ case PIPE_ISOCHRONOUS:
+ ohci->hcd.self.bandwidth_isoc_reqs--;
+ break;
+ case PIPE_INTERRUPT:
+ ohci->hcd.self.bandwidth_int_reqs--;
+ break;
+ }
+
#ifdef OHCI_VERBOSE_DEBUG
urb_print (urb, "RET", usb_pipeout (urb->pipe));
#endif
@@ -111,67 +119,111 @@ static inline void intr_resub (struct ohci_hcd *hc, struct urb *urb)
* ED handling functions
*-------------------------------------------------------------------------*/
-/* search for the right branch to insert an interrupt ed into the int tree
- * do some load balancing;
- * returns the branch
- * FIXME allow for failure, when there's no bandwidth left;
- * and consider iso loads too
+/* search for the right schedule branch to use for a periodic ed.
+ * does some load balancing; returns the branch, or negative errno.
*/
-static int ep_int_balance (struct ohci_hcd *ohci, int interval, int load)
+static int balance (struct ohci_hcd *ohci, int interval, int load)
{
- int i, branch = 0;
-
- /* search for the least loaded interrupt endpoint branch */
- for (i = 0; i < NUM_INTS ; i++)
- if (ohci->ohci_int_load [branch] > ohci->ohci_int_load [i])
- branch = i;
+ int i, branch = -ENOSPC;
- branch = branch % interval;
- for (i = branch; i < NUM_INTS; i += interval)
- ohci->ohci_int_load [i] += load;
+ /* iso periods can be huge; iso tds specify frame numbers */
+ if (interval > NUM_INTS)
+ interval = NUM_INTS;
+ /* search for the least loaded schedule branch of that period
+ * that has enough bandwidth left unreserved.
+ */
+ for (i = 0; i < interval ; i++) {
+ if (branch < 0 || ohci->load [branch] > ohci->load [i]) {
+#ifdef CONFIG_USB_BANDWIDTH
+ int j;
+
+ /* usb 1.1 says 90% of one frame */
+ for (j = i; j < NUM_INTS; j += interval) {
+ if ((ohci->load [j] + load) > 900)
+ break;
+ }
+ if (j < NUM_INTS)
+ continue;
+#endif
+ branch = i;
+ }
+ }
return branch;
}
/*-------------------------------------------------------------------------*/
-/* the int tree is a binary tree
- * in order to process it sequentially the indexes of the branches have
- * to be mapped the mapping reverses the bits of a word of num_bits length
+/* both iso and interrupt requests have periods; this routine puts them
+ * into the schedule tree in the apppropriate place. most iso devices use
+ * 1msec periods, but that's not required.
*/
-static int ep_rev (int num_bits, int word)
+static void periodic_link (struct ohci_hcd *ohci, struct ed *ed)
{
- int i, wout = 0;
+ unsigned i;
- for (i = 0; i < num_bits; i++)
- wout |= (( (word >> i) & 1) << (num_bits - i - 1));
- return wout;
-}
+ dbg ("%s: link %sed %p branch %d [%dus.], interval %d",
+ ohci->hcd.self.bus_name,
+ (ed->hwINFO & ED_ISO) ? "iso " : "",
+ ed, ed->branch, ed->load, ed->interval);
-/*-------------------------------------------------------------------------*/
+ for (i = ed->branch; i < NUM_INTS; i += ed->interval) {
+ struct ed **prev = &ohci->periodic [i];
+ u32 *prev_p = &ohci->hcca->int_table [i];
+ struct ed *here = *prev;
+
+ /* sorting each branch by period (slow before fast)
+ * lets us share the faster parts of the tree.
+ * (plus maybe: put interrupt eds before iso)
+ */
+ while (here && ed != here) {
+ if (ed->interval > here->interval)
+ break;
+ prev = &here->ed_next;
+ prev_p = &here->hwNextED;
+ here = *prev;
+ }
+ if (ed != here) {
+ ed->ed_next = here;
+ if (here)
+ ed->hwNextED = *prev_p;
+ wmb ();
+ *prev = ed;
+ *prev_p = cpu_to_le32p (&ed->dma);
+ }
+ ohci->load [i] += ed->load;
+ }
+ ohci->hcd.self.bandwidth_allocated += ed->load / ed->interval;
+}
/* link an ed into one of the HC chains */
-static void ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
+static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
{
- int int_branch, i;
- int inter, interval, load;
- __u32 *ed_p;
+ int branch;
ed->state = ED_OPER;
+ ed->ed_prev = 0;
+ ed->ed_next = 0;
ed->hwNextED = 0;
wmb ();
/* we care about rm_list when setting CLE/BLE in case the HC was at
* work on some TD when CLE/BLE was turned off, and isn't quiesced
* yet. finish_unlinks() restarts as needed, some upcoming INTR_SF.
+ *
+ * control and bulk EDs are doubly linked (ed_next, ed_prev), but
+ * periodic ones are singly linked (ed_next). that's because the
+ * periodic schedule encodes a tree like figure 3-5 in the ohci
+ * spec: each qh can have several "previous" nodes, and the tree
+ * doesn't have unused/idle descriptors.
*/
-
switch (ed->type) {
case PIPE_CONTROL:
if (ohci->ed_controltail == NULL) {
writel (ed->dma, &ohci->regs->ed_controlhead);
} else {
+ ohci->ed_controltail->ed_next = ed;
ohci->ed_controltail->hwNextED = cpu_to_le32 (ed->dma);
}
ed->ed_prev = ohci->ed_controltail;
@@ -187,6 +239,7 @@ static void ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
if (ohci->ed_bulktail == NULL) {
writel (ed->dma, &ohci->regs->ed_bulkhead);
} else {
+ ohci->ed_bulktail->ed_next = ed;
ohci->ed_bulktail->hwNextED = cpu_to_le32 (ed->dma);
}
ed->ed_prev = ohci->ed_bulktail;
@@ -198,74 +251,55 @@ static void ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
ohci->ed_bulktail = ed;
break;
- case PIPE_INTERRUPT:
- load = ed->intriso.intr_info.int_load;
- interval = ed->interval;
- int_branch = ep_int_balance (ohci, interval, load);
- ed->intriso.intr_info.int_branch = int_branch;
-
- for (i = 0; i < ep_rev (6, interval); i += inter) {
- inter = 1;
- for (ed_p = & (ohci->hcca->int_table [ep_rev (5, i) + int_branch]);
- (*ed_p != 0) && ((dma_to_ed (ohci, le32_to_cpup (ed_p)))->interval >= interval);
- ed_p = & ((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED))
- inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->interval);
- ed->hwNextED = *ed_p;
- *ed_p = cpu_to_le32 (ed->dma);
+ // case PIPE_INTERRUPT:
+ // case PIPE_ISOCHRONOUS:
+ default:
+ branch = balance (ohci, ed->interval, ed->load);
+ if (branch < 0) {
+ dbg ("%s: ERR %d, interval %d msecs, load %d",
+ ohci->hcd.self.bus_name,
+ branch, ed->interval, ed->load);
+ // FIXME if there are TDs queued, fail them!
+ return branch;
}
- wmb ();
-#ifdef OHCI_VERBOSE_DEBUG
- ohci_dump_periodic (ohci, "LINK_INT");
-#endif
- break;
-
- case PIPE_ISOCHRONOUS:
- ed->ed_prev = ohci->ed_isotail;
- if (ohci->ed_isotail != NULL) {
- ohci->ed_isotail->hwNextED = cpu_to_le32 (ed->dma);
- } else {
- for ( i = 0; i < NUM_INTS; i += inter) {
- inter = 1;
- for (ed_p = & (ohci->hcca->int_table [ep_rev (5, i)]);
- *ed_p != 0;
- ed_p = & ((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED))
- inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->interval);
- *ed_p = cpu_to_le32 (ed->dma);
- }
- }
- wmb ();
- ohci->ed_isotail = ed;
-#ifdef OHCI_VERBOSE_DEBUG
- ohci_dump_periodic (ohci, "LINK_ISO");
-#endif
- break;
+ ed->branch = branch;
+ periodic_link (ohci, ed);
}
/* the HC may not see the schedule updates yet, but if it does
* then they'll be properly ordered.
*/
+ return 0;
}
/*-------------------------------------------------------------------------*/
/* scan the periodic table to find and unlink this ED */
-static void periodic_unlink (
- struct ohci_hcd *ohci,
- struct ed *ed,
- unsigned index,
- unsigned period
-) {
- for (; index < NUM_INTS; index += period) {
- __u32 *ed_p = &ohci->hcca->int_table [index];
+static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed)
+{
+ int i;
- while (*ed_p != 0) {
- if ((dma_to_ed (ohci, le32_to_cpup (ed_p))) == ed) {
- *ed_p = ed->hwNextED;
- break;
- }
- ed_p = & ((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED);
+ for (i = ed->branch; i < NUM_INTS; i += ed->interval) {
+ struct ed *temp;
+ struct ed **prev = &ohci->periodic [i];
+ u32 *prev_p = &ohci->hcca->int_table [i];
+
+ while (*prev && (temp = *prev) != ed) {
+ prev_p = &temp->hwNextED;
+ prev = &temp->ed_next;
+ }
+ if (*prev) {
+ *prev_p = ed->hwNextED;
+ *prev = ed->ed_next;
}
+ ohci->load [i] -= ed->load;
}
+ ohci->hcd.self.bandwidth_allocated -= ed->load / ed->interval;
+
+ dbg ("%s: unlink %sed %p branch %d [%dus.], interval %d",
+ ohci->hcd.self.bus_name,
+ (ed->hwINFO & ED_ISO) ? "iso " : "",
+ ed, ed->branch, ed->load, ed->interval);
}
/* unlink an ed from one of the HC chains.
@@ -275,8 +309,6 @@ static void periodic_unlink (
*/
static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
{
- int i;
-
ed->hwINFO |= ED_SKIP;
switch (ed->type) {
@@ -289,13 +321,15 @@ static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
writel (le32_to_cpup (&ed->hwNextED),
&ohci->regs->ed_controlhead);
} else {
+ ed->ed_prev->ed_next = ed->ed_next;
ed->ed_prev->hwNextED = ed->hwNextED;
}
if (ohci->ed_controltail == ed) {
ohci->ed_controltail = ed->ed_prev;
+ if (ohci->ed_controltail)
+ ohci->ed_controltail->ed_next = 0;
} else {
- (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))
- ->ed_prev = ed->ed_prev;
+ ed->ed_next->ed_prev = ed->ed_prev;
}
break;
@@ -308,50 +342,33 @@ static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
writel (le32_to_cpup (&ed->hwNextED),
&ohci->regs->ed_bulkhead);
} else {
+ ed->ed_prev->ed_next = ed->ed_next;
ed->ed_prev->hwNextED = ed->hwNextED;
}
if (ohci->ed_bulktail == ed) {
ohci->ed_bulktail = ed->ed_prev;
+ if (ohci->ed_bulktail)
+ ohci->ed_bulktail->ed_next = 0;
} else {
- (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))
- ->ed_prev = ed->ed_prev;
+ ed->ed_next->ed_prev = ed->ed_prev;
}
break;
- case PIPE_INTERRUPT:
- periodic_unlink (ohci, ed, ed->intriso.intr_info.int_branch, ed->interval);
- for (i = ed->intriso.intr_info.int_branch; i < NUM_INTS; i += ed->interval)
- ohci->ohci_int_load [i] -= ed->intriso.intr_info.int_load;
-#ifdef OHCI_VERBOSE_DEBUG
- ohci_dump_periodic (ohci, "UNLINK_INT");
-#endif
- break;
-
- case PIPE_ISOCHRONOUS:
- if (ohci->ed_isotail == ed)
- ohci->ed_isotail = ed->ed_prev;
- if (ed->hwNextED != 0)
- (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))
- ->ed_prev = ed->ed_prev;
-
- if (ed->ed_prev != NULL)
- ed->ed_prev->hwNextED = ed->hwNextED;
- else
- periodic_unlink (ohci, ed, 0, 1);
-#ifdef OHCI_VERBOSE_DEBUG
- ohci_dump_periodic (ohci, "UNLINK_ISO");
-#endif
+ // case PIPE_INTERRUPT:
+ // case PIPE_ISOCHRONOUS:
+ default:
+ periodic_unlink (ohci, ed);
break;
}
- /* FIXME Except for a couple of exceptionally clean unlink cases
+ /* NOTE: Except for a couple of exceptionally clean unlink cases
* (like unlinking the only c/b ED, with no TDs) HCs may still be
- * caching this (till SOF).
- *
- * To avoid racing with the hardware, this needs to use ED_UNLINK
- * and delay til next INTR_SF. Merge with start_urb_unlink().
+ * caching this operational ED (or its address). Safe unlinking
+ * involves not marking it ED_IDLE till INTR_SF; we always do that
+ * if td_list isn't empty. Otherwise the race is small; but ...
*/
- ed->state = ED_IDLE;
+ if (ed->state == ED_OPER)
+ ed->state = ED_IDLE;
}
@@ -369,7 +386,6 @@ static struct ed *ed_get (
) {
int is_out = !usb_pipein (pipe);
int type = usb_pipetype (pipe);
- int bus_msecs = 0;
struct hcd_dev *dev = (struct hcd_dev *) udev->hcpriv;
struct ed *ed;
unsigned ep;
@@ -378,9 +394,6 @@ static struct ed *ed_get (
ep = usb_pipeendpoint (pipe) << 1;
if (type != PIPE_CONTROL && is_out)
ep |= 1;
- if (type == PIPE_INTERRUPT)
- bus_msecs = usb_calc_bus_time (udev->speed, !is_out, 0,
- usb_maxpacket (udev, pipe, is_out)) / 1000;
spin_lock_irqsave (&ohci->lock, flags);
@@ -422,23 +435,25 @@ static struct ed *ed_get (
info = cpu_to_le32 (info);
if (udev->speed == USB_SPEED_LOW)
info |= ED_LOWSPEED;
- /* control transfers store pids in tds */
+ /* only control transfers store pids in tds */
if (type != PIPE_CONTROL) {
info |= is_out ? ED_OUT : ED_IN;
- if (type == PIPE_ISOCHRONOUS)
- info |= ED_ISO;
- if (type == PIPE_INTERRUPT) {
- ed->intriso.intr_info.int_load = bus_msecs;
- if (interval > 32)
+ if (type != PIPE_BULK) {
+ /* periodic transfers... */
+ if (type == PIPE_ISOCHRONOUS)
+ info |= ED_ISO;
+ else if (interval > 32) /* iso can be bigger */
interval = 32;
+ ed->interval = interval;
+ ed->load = usb_calc_bus_time (
+ udev->speed, !is_out,
+ type == PIPE_ISOCHRONOUS,
+ usb_maxpacket (udev, pipe, is_out))
+ / 1000;
}
}
ed->hwINFO = info;
- /* value ignored except on periodic EDs, where
- * we know it's already a power of 2
- */
- ed->interval = interval;
#ifdef DEBUG
/*
* There are two other cases we ought to change hwINFO, both during
@@ -473,8 +488,9 @@ done:
*/
static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed)
{
- ed_deschedule (ohci, ed);
+ ed->hwINFO |= ED_DEQUEUE;
ed->state = ED_UNLINK;
+ ed_deschedule (ohci, ed);
/* SF interrupt might get delayed; record the frame counter value that
* indicates when the HC isn't looking at it, so concurrent unlinks
@@ -483,7 +499,9 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed)
*/
ed->tick = le16_to_cpu (ohci->hcca->frame_no) + 1;
+ /* rm_list is just singly linked, for simplicity */
ed->ed_next = ohci->ed_rm_list;
+ ed->ed_prev = 0;
ohci->ed_rm_list = ed;
/* enable SOF interrupt */
@@ -529,7 +547,6 @@ td_fill (unsigned int info,
/* use this td as the next dummy */
td_pt = urb_priv->td [index];
- td_pt->hwNextTD = 0;
/* fill the old dummy TD */
td = urb_priv->td [index] = urb_priv->ed->dummy;
@@ -547,7 +564,7 @@ td_fill (unsigned int info,
if (is_iso) {
td->hwCBP = cpu_to_le32 (data & 0xFFFFF000);
td->hwPSW [0] = cpu_to_le16 ((data & 0x0FFF) | 0xE000);
- td->ed->intriso.last_iso = info & 0xffff;
+ td->ed->last_iso = info & 0xffff;
} else {
td->hwCBP = cpu_to_le32 (data);
}
@@ -608,9 +625,11 @@ static void td_submit_urb (
/* Bulk and interrupt are identical except for where in the schedule
* their EDs live.
*/
- // case PIPE_BULK:
- // case PIPE_INTERRUPT:
- default:
+ case PIPE_INTERRUPT:
+ /* ... and periodic urbs have extra accounting */
+ ohci->hcd.self.bandwidth_int_reqs++;
+ /* FALLTHROUGH */
+ case PIPE_BULK:
info = is_out
? TD_T_TOGGLE | TD_CC | TD_DP_OUT
: TD_T_TOGGLE | TD_CC | TD_DP_IN;
@@ -676,6 +695,7 @@ static void td_submit_urb (
data + urb->iso_frame_desc [cnt].offset,
urb->iso_frame_desc [cnt].length, urb, cnt);
}
+ ohci->hcd.self.bandwidth_isoc_reqs++;
break;
}
if (urb_priv->length != cnt)
@@ -707,8 +727,12 @@ static void td_done (struct urb *urb, struct td *td)
if (usb_pipeout (urb->pipe))
dlen = urb->iso_frame_desc [td->index].length;
- else
+ else {
+ /* short reads are always OK for ISO */
+ if (cc == TD_DATAUNDERRUN)
+ cc = TD_CC_NOERROR;
dlen = tdPSW & 0x3ff;
+ }
urb->actual_length += dlen;
urb->iso_frame_desc [td->index].actual_length = dlen;
urb->iso_frame_desc [td->index].status = cc_to_error [cc];
@@ -802,6 +826,7 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci)
if (td_list->ed->hwHeadP & ED_H) {
if (urb_priv && ((td_list->index + 1)
< urb_priv->length)) {
+#ifdef DEBUG
struct urb *urb = td_list->urb;
/* help for troubleshooting: */
@@ -817,6 +842,7 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci)
1 + td_list->index,
urb_priv->length,
cc, cc_to_error [cc]);
+#endif
td_list->ed->hwHeadP =
(urb_priv->td [urb_priv->length - 1]->hwNextTD
& __constant_cpu_to_le32 (TD_MASK))
@@ -872,8 +898,7 @@ rescan_all:
* we call a completion since it might have unlinked
* another (earlier) urb
*
- * FIXME use td_list to scan, not ed hashtables.
- * completely abolish ed hashtables!
+ * FIXME use td_list to scan, not td hashtables.
*/
rescan_this:
completed = 0;
@@ -894,8 +919,7 @@ rescan_this:
td_done (urb, td);
urb_priv->td_cnt++;
- *td_p = td->hwNextTD | (*td_p
- & __constant_cpu_to_le32 (0x3));
+ *td_p = td->hwNextTD | (*td_p & ~TD_MASK);
/* URB is done; clean up */
if (urb_priv->td_cnt == urb_priv->length) {
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 4af5cdf0aa34..d2cfdc659e24 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -5,7 +5,6 @@
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under the GPL.
- * $Id: ohci.h,v 1.6 2002/03/22 16:04:54 dbrownell Exp $
*/
/*
@@ -18,13 +17,16 @@
struct ed {
/* first fields are hardware-specified, le32 */
__u32 hwINFO; /* endpoint config bitmap */
+ /* info bits defined by hcd */
+#define ED_DEQUEUE __constant_cpu_to_le32(1 << 27)
+ /* info bits defined by the hardware */
#define ED_ISO __constant_cpu_to_le32(1 << 15)
#define ED_SKIP __constant_cpu_to_le32(1 << 14)
#define ED_LOWSPEED __constant_cpu_to_le32(1 << 13)
#define ED_OUT __constant_cpu_to_le32(0x01 << 11)
#define ED_IN __constant_cpu_to_le32(0x02 << 11)
__u32 hwTailP; /* tail of TD list */
- __u32 hwHeadP; /* head of TD list */
+ __u32 hwHeadP; /* head of TD list (hc r/w) */
#define ED_C __constant_cpu_to_le32(0x02) /* toggle carry */
#define ED_H __constant_cpu_to_le32(0x01) /* halted */
__u32 hwNextED; /* next ED in list */
@@ -48,14 +50,12 @@ struct ed {
#define ED_OPER 0x02 /* IS linked to hc */
u8 type; /* PIPE_{BULK,...} */
- u16 interval; /* interrupt, isochronous */
- union {
- struct intr_info { /* interrupt */
- u8 int_branch;
- u8 int_load;
- } intr_info;
- u16 last_iso; /* isochronous */
- } intriso;
+
+ /* periodic scheduling params (for intr and iso) */
+ u8 branch;
+ u16 interval;
+ u16 load;
+ u16 last_iso; /* iso only */
/* HC may see EDs on rm_list until next frame (frame_no == tick) */
u16 tick;
@@ -335,10 +335,8 @@ struct hash_list_t {
};
#define TD_HASH_SIZE 64 /* power'o'two */
-#define ED_HASH_SIZE 64 /* power'o'two */
#define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 5)) % TD_HASH_SIZE)
-#define ED_HASH_FUNC(ed_dma) ((ed_dma ^ (ed_dma >> 5)) % ED_HASH_SIZE)
/*
@@ -373,7 +371,7 @@ struct ohci_hcd {
struct ed *ed_bulktail; /* last in bulk list */
struct ed *ed_controltail; /* last in ctrl list */
- struct ed *ed_isotail; /* last in iso list */
+ struct ed *periodic [NUM_INTS]; /* shadow int_table */
/*
* memory management for queue data structures
@@ -381,14 +379,13 @@ struct ohci_hcd {
struct pci_pool *td_cache;
struct pci_pool *ed_cache;
struct hash_list_t td_hash [TD_HASH_SIZE];
- struct hash_list_t ed_hash [ED_HASH_SIZE];
/*
* driver state
*/
int disabled; /* e.g. got a UE, we're hung */
int sleeping;
- int ohci_int_load [NUM_INTS];
+ int load [NUM_INTS];
u32 hc_control; /* copy of hc control reg */
unsigned long flags; /* for HC bugs */
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 150ae60fe1e6..161420c58fb9 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -105,12 +105,10 @@ static void wakeup_hc(struct uhci_hcd *uhci);
/* to make sure it doesn't hog all of the bandwidth */
#define DEPTH_INTERVAL 5
-#define MAX_URB_LOOP 2048 /* Maximum number of linked URB's */
-
/*
* Technically, updating td->status here is a race, but it's not really a
* problem. The worst that can happen is that we set the IOC bit again
- * generating a spurios interrupt. We could fix this by creating another
+ * generating a spurious interrupt. We could fix this by creating another
* QH and leaving the IOC bit always set, but then we would have to play
* games with the FSBR code to make sure we get the correct order in all
* the cases. I don't think it's worth the effort
@@ -148,7 +146,7 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci, struct usb_device *d
dma_addr_t dma_handle;
struct uhci_td *td;
- td = pci_pool_alloc(uhci->td_pool, GFP_DMA | GFP_ATOMIC, &dma_handle);
+ td = pci_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle);
if (!td)
return NULL;
@@ -273,7 +271,7 @@ out:
/*
* Inserts a td into qh list at the top.
*/
-static void uhci_insert_tds_in_qh(struct uhci_qh *qh, struct urb *urb, int breadth)
+static void uhci_insert_tds_in_qh(struct uhci_qh *qh, struct urb *urb, u32 breadth)
{
struct list_head *tmp, *head;
struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
@@ -290,7 +288,7 @@ static void uhci_insert_tds_in_qh(struct uhci_qh *qh, struct urb *urb, int bread
td = list_entry(tmp, struct uhci_td, list);
/* Add the first TD to the QH element pointer */
- qh->element = cpu_to_le32(td->dma_handle) | (breadth ? 0 : UHCI_PTR_DEPTH);
+ qh->element = cpu_to_le32(td->dma_handle) | breadth;
ptd = td;
@@ -301,7 +299,7 @@ static void uhci_insert_tds_in_qh(struct uhci_qh *qh, struct urb *urb, int bread
tmp = tmp->next;
- ptd->link = cpu_to_le32(td->dma_handle) | (breadth ? 0 : UHCI_PTR_DEPTH);
+ ptd->link = cpu_to_le32(td->dma_handle) | breadth;
ptd = td;
}
@@ -311,10 +309,6 @@ static void uhci_insert_tds_in_qh(struct uhci_qh *qh, struct urb *urb, int bread
static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
{
-/*
- if (!list_empty(&td->list) || !list_empty(&td->fl_list))
- dbg("td %p is still in URB list!", td);
-*/
if (!list_empty(&td->list))
dbg("td %p is still in list!", td);
if (!list_empty(&td->fl_list))
@@ -331,7 +325,7 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, struct usb_device *d
dma_addr_t dma_handle;
struct uhci_qh *qh;
- qh = pci_pool_alloc(uhci->qh_pool, GFP_DMA | GFP_ATOMIC, &dma_handle);
+ qh = pci_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle);
if (!qh)
return NULL;
@@ -365,43 +359,57 @@ static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
}
/*
+ * Append this urb's qh after the last qh in skelqh->list
* MUST be called with uhci->frame_list_lock acquired
+ *
+ * Note that urb_priv.queue_list doesn't have a separate queue head;
+ * it's a ring with every element "live".
*/
static void _uhci_insert_qh(struct uhci_hcd *uhci, struct uhci_qh *skelqh, struct urb *urb)
{
struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
- struct list_head *head, *tmp;
+ struct list_head *tmp;
struct uhci_qh *lqh;
/* Grab the last QH */
lqh = list_entry(skelqh->list.prev, struct uhci_qh, list);
+ /* Patch this endpoint's URBs' QHs to point to the next skelQH:
+ * SkelQH --> ... lqh --> NewQH --> NextSkelQH
+ * Do this first, so the HC always sees the right QH after this one.
+ */
+ list_for_each (tmp, &urbp->queue_list) {
+ struct urb_priv *turbp =
+ list_entry(tmp, struct urb_priv, queue_list);
+
+ turbp->qh->link = lqh->link;
+ }
+ urbp->qh->link = lqh->link;
+ wmb(); /* Ordering is important */
+
+ /* Patch QHs for previous endpoint's queued URBs? HC goes
+ * here next, not to the NextSkelQH it now points to.
+ *
+ * lqh --> td ... --> qh ... --> td --> qh ... --> td
+ * | | |
+ * v v v
+ * +<----------------+-----------------+
+ * v
+ * NewQH --> td ... --> td
+ * |
+ * v
+ * ...
+ *
+ * The HC could see (and use!) any of these as we write them.
+ */
if (lqh->urbp) {
- head = &lqh->urbp->queue_list;
- tmp = head->next;
- while (head != tmp) {
+ list_for_each (tmp, &lqh->urbp->queue_list) {
struct urb_priv *turbp =
list_entry(tmp, struct urb_priv, queue_list);
- tmp = tmp->next;
-
turbp->qh->link = cpu_to_le32(urbp->qh->dma_handle) | UHCI_PTR_QH;
}
}
-
- head = &urbp->queue_list;
- tmp = head->next;
- while (head != tmp) {
- struct urb_priv *turbp =
- list_entry(tmp, struct urb_priv, queue_list);
-
- tmp = tmp->next;
-
- turbp->qh->link = lqh->link;
- }
-
- urbp->qh->link = lqh->link;
- mb(); /* Ordering is important */
lqh->link = cpu_to_le32(urbp->qh->dma_handle) | UHCI_PTR_QH;
list_add_tail(&urbp->qh->list, &skelqh->list);
@@ -416,6 +424,9 @@ static void uhci_insert_qh(struct uhci_hcd *uhci, struct uhci_qh *skelqh, struct
spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
}
+/* start removal of qh from schedule; it finishes next frame.
+ * TDs should be unlinked before this is called.
+ */
static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
{
unsigned long flags;
@@ -869,12 +880,12 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb)
urbp->qh = qh;
qh->urbp = urbp;
- /* Low speed or small transfers gets a different queue and treatment */
+ /* Low speed transfers get a different queue, and won't hog the bus */
if (urb->dev->speed == USB_SPEED_LOW) {
- uhci_insert_tds_in_qh(qh, urb, 0);
+ uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_DEPTH);
uhci_insert_qh(uhci, uhci->skel_ls_control_qh, urb);
} else {
- uhci_insert_tds_in_qh(qh, urb, 1);
+ uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_BREADTH);
uhci_insert_qh(uhci, uhci->skel_hs_control_qh, urb);
uhci_inc_fsbr(uhci, urb);
}
@@ -914,9 +925,9 @@ static int usb_control_retrigger_status(struct uhci_hcd *uhci, struct urb *urb)
urbp->qh->urbp = urbp;
/* One TD, who cares about Breadth first? */
- uhci_insert_tds_in_qh(urbp->qh, urb, 0);
+ uhci_insert_tds_in_qh(urbp->qh, urb, UHCI_PTR_DEPTH);
- /* Low speed or small transfers gets a different queue and treatment */
+ /* Low speed transfers get a different queue */
if (urb->dev->speed == USB_SPEED_LOW)
uhci_insert_qh(uhci, uhci->skel_ls_control_qh, urb);
else
@@ -1242,8 +1253,8 @@ static int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, struct urb *
urbp->qh = qh;
qh->urbp = urbp;
- /* Always assume breadth first */
- uhci_insert_tds_in_qh(qh, urb, 1);
+ /* Always breadth first */
+ uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_BREADTH);
if (eurb)
uhci_append_queued_urb(uhci, eurb, urb);
@@ -1487,6 +1498,10 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, int mem_flags)
spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+ if (ret != -EINPROGRESS) {
+ uhci_destroy_urb_priv (uhci, urb);
+ return ret;
+ }
return 0;
}
@@ -1795,8 +1810,7 @@ static void uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb)
spin_lock_irqsave(&urb->lock, flags);
- killed = (urb->status == -ENOENT || urb->status == -ECONNABORTED ||
- urb->status == -ECONNRESET);
+ killed = (urb->status == -ENOENT || urb->status == -ECONNRESET);
resubmit_interrupt = (usb_pipetype(urb->pipe) == PIPE_INTERRUPT &&
urb->interval);
@@ -1817,9 +1831,7 @@ static void uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb)
if (resubmit_interrupt)
/* Recheck the status. The completion handler may have */
/* unlinked the resubmitting interrupt URB */
- killed = (urb->status == -ENOENT ||
- urb->status == -ECONNABORTED ||
- urb->status == -ECONNRESET);
+ killed = (urb->status == -ENOENT || urb->status == -ECONNRESET);
if (resubmit_interrupt && !killed) {
urb->dev = dev;
@@ -2016,19 +2028,12 @@ static void start_hc(struct uhci_hcd *uhci)
uhci->hcd.state = USB_STATE_READY;
}
-#ifdef CONFIG_PROC_FS
-static int uhci_num = 0;
-#endif
-
/*
* De-allocate all resources..
*/
static void release_uhci(struct uhci_hcd *uhci)
{
int i;
-#ifdef CONFIG_PROC_FS
- char buf[8];
-#endif
for (i = 0; i < UHCI_NUM_SKELQH; i++)
if (uhci->skelqh[i]) {
@@ -2053,15 +2058,13 @@ static void release_uhci(struct uhci_hcd *uhci)
}
if (uhci->fl) {
- pci_free_consistent(uhci->dev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle);
+ pci_free_consistent(uhci->hcd.pdev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle);
uhci->fl = NULL;
}
#ifdef CONFIG_PROC_FS
if (uhci->proc_entry) {
- sprintf(buf, "hc%d", uhci->num);
-
- remove_proc_entry(buf, uhci_proc_root);
+ remove_proc_entry(uhci->hcd.self.bus_name, uhci_proc_root);
uhci->proc_entry = NULL;
}
#endif
@@ -2086,33 +2089,20 @@ static void release_uhci(struct uhci_hcd *uhci)
static int __devinit uhci_start(struct usb_hcd *hcd)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
- struct pci_dev *dev = hcd->pdev;
int retval = -EBUSY;
int i, port;
+ unsigned io_size;
dma_addr_t dma_handle;
+ struct usb_device *udev;
#ifdef CONFIG_PROC_FS
- char buf[8];
struct proc_dir_entry *ent;
#endif
- uhci->dev = dev;
-
- /* Should probably move to core/hcd.c */
- if (pci_set_dma_mask(dev, 0xFFFFFFFF)) {
- err("couldn't set PCI dma mask");
- retval = -ENODEV;
- goto err_pci_set_dma_mask;
- }
-
- uhci->io_addr = pci_resource_start(dev, hcd->region);
- uhci->io_size = pci_resource_len(dev, hcd->region);
+ uhci->io_addr = (unsigned) hcd->regs;
+ io_size = pci_resource_len(hcd->pdev, hcd->region);
#ifdef CONFIG_PROC_FS
- uhci->num = uhci_num++;
-
- sprintf(buf, "hc%d", uhci->num);
-
- ent = create_proc_entry(buf, S_IFREG|S_IRUGO|S_IWUSR, uhci_proc_root);
+ ent = create_proc_entry(hcd->self.bus_name, S_IFREG|S_IRUGO|S_IWUSR, uhci_proc_root);
if (!ent) {
err("couldn't create uhci proc entry");
retval = -ENOMEM;
@@ -2148,7 +2138,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
spin_lock_init(&uhci->frame_list_lock);
- uhci->fl = pci_alloc_consistent(dev, sizeof(*uhci->fl), &dma_handle);
+ uhci->fl = pci_alloc_consistent(hcd->pdev, sizeof(*uhci->fl), &dma_handle);
if (!uhci->fl) {
err("unable to allocate consistent memory for frame list");
goto err_alloc_fl;
@@ -2158,15 +2148,15 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
uhci->fl->dma_handle = dma_handle;
- uhci->td_pool = pci_pool_create("uhci_td", dev,
- sizeof(struct uhci_td), 16, 0, GFP_DMA | GFP_ATOMIC);
+ uhci->td_pool = pci_pool_create("uhci_td", hcd->pdev,
+ sizeof(struct uhci_td), 16, 0, GFP_ATOMIC);
if (!uhci->td_pool) {
err("unable to create td pci_pool");
goto err_create_td_pool;
}
- uhci->qh_pool = pci_pool_create("uhci_qh", dev,
- sizeof(struct uhci_qh), 16, 0, GFP_DMA | GFP_ATOMIC);
+ uhci->qh_pool = pci_pool_create("uhci_qh", hcd->pdev,
+ sizeof(struct uhci_qh), 16, 0, GFP_ATOMIC);
if (!uhci->qh_pool) {
err("unable to create qh pci_pool");
goto err_create_qh_pool;
@@ -2178,7 +2168,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
/* they may have more but give no way to determine how many they */
/* have. However, according to the UHCI spec, Bit 7 is always set */
/* to 1. So we try to use this to our advantage */
- for (port = 0; port < (uhci->io_size - 0x10) / 2; port++) {
+ for (port = 0; port < (io_size - 0x10) / 2; port++) {
unsigned int portstatus;
portstatus = inw(uhci->io_addr + 0x10 + (port * 2));
@@ -2197,13 +2187,13 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
uhci->rh_numports = port;
- hcd->self.root_hub = uhci->rh_dev = usb_alloc_dev(NULL, &hcd->self);
- if (!uhci->rh_dev) {
+ hcd->self.root_hub = udev = usb_alloc_dev(NULL, &hcd->self);
+ if (!udev) {
err("unable to allocate root hub");
goto err_alloc_root_hub;
}
- uhci->skeltd[0] = uhci_alloc_td(uhci, uhci->rh_dev);
+ uhci->skeltd[0] = uhci_alloc_td(uhci, udev);
if (!uhci->skeltd[0]) {
err("unable to allocate TD 0");
goto err_alloc_skeltd;
@@ -2216,7 +2206,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
for (i = 1; i < 9; i++) {
struct uhci_td *td;
- td = uhci->skeltd[i] = uhci_alloc_td(uhci, uhci->rh_dev);
+ td = uhci->skeltd[i] = uhci_alloc_td(uhci, udev);
if (!td) {
err("unable to allocate TD %d", i);
goto err_alloc_skeltd;
@@ -2227,14 +2217,14 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
td->link = cpu_to_le32(uhci->skeltd[i - 1]->dma_handle);
}
- uhci->skel_term_td = uhci_alloc_td(uhci, uhci->rh_dev);
+ uhci->skel_term_td = uhci_alloc_td(uhci, udev);
if (!uhci->skel_term_td) {
err("unable to allocate skel TD term");
goto err_alloc_skeltd;
}
for (i = 0; i < UHCI_NUM_SKELQH; i++) {
- uhci->skelqh[i] = uhci_alloc_qh(uhci, uhci->rh_dev);
+ uhci->skelqh[i] = uhci_alloc_qh(uhci, udev);
if (!uhci->skelqh[i]) {
err("unable to allocate QH %d", i);
goto err_alloc_skelqh;
@@ -2303,12 +2293,12 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
init_stall_timer(hcd);
/* disable legacy emulation */
- pci_write_config_word(dev, USBLEGSUP, USBLEGSUP_DEFAULT);
+ pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
- usb_connect(uhci->rh_dev);
- uhci->rh_dev->speed = USB_SPEED_FULL;
+ usb_connect(udev);
+ udev->speed = USB_SPEED_FULL;
- if (usb_register_root_hub(uhci->rh_dev, &dev->dev) != 0) {
+ if (usb_register_root_hub(udev, &hcd->pdev->dev) != 0) {
err("unable to start root hub");
retval = -ENOMEM;
goto err_start_root_hub;
@@ -2322,7 +2312,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
err_start_root_hub:
reset_hc(uhci);
- del_timer(&uhci->stall_timer);
+ del_timer_sync(&uhci->stall_timer);
for (i = 0; i < UHCI_NUM_SKELQH; i++)
if (uhci->skelqh[i]) {
@@ -2338,8 +2328,8 @@ err_alloc_skelqh:
}
err_alloc_skeltd:
- usb_free_dev(uhci->rh_dev);
- uhci->rh_dev = NULL;
+ usb_free_dev(udev);
+ hcd->self.root_hub = NULL;
err_alloc_root_hub:
pci_pool_destroy(uhci->qh_pool);
@@ -2350,19 +2340,17 @@ err_create_qh_pool:
uhci->td_pool = NULL;
err_create_td_pool:
- pci_free_consistent(dev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle);
+ pci_free_consistent(hcd->pdev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle);
uhci->fl = NULL;
err_alloc_fl:
#ifdef CONFIG_PROC_FS
- remove_proc_entry(buf, uhci_proc_root);
+ remove_proc_entry(hcd->self.bus_name, uhci_proc_root);
uhci->proc_entry = NULL;
err_create_proc_entry:
#endif
-err_pci_set_dma_mask:
-
return retval;
}
@@ -2370,10 +2358,7 @@ static void uhci_stop(struct usb_hcd *hcd)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
- if (uhci->rh_dev)
- usb_disconnect(&uhci->rh_dev);
-
- del_timer(&uhci->stall_timer);
+ del_timer_sync(&uhci->stall_timer);
/*
* At this point, we're guaranteed that no new connects can be made
@@ -2402,7 +2387,7 @@ static int uhci_resume(struct usb_hcd *hcd)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
- pci_set_master(uhci->dev);
+ pci_set_master(uhci->hcd.pdev);
reset_hc(uhci);
start_hc(uhci);
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index 2de75a2b577f..809434e6e78b 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -65,6 +65,7 @@
#define UHCI_PTR_TERM cpu_to_le32(0x0001)
#define UHCI_PTR_QH cpu_to_le32(0x0002)
#define UHCI_PTR_DEPTH cpu_to_le32(0x0004)
+#define UHCI_PTR_BREADTH cpu_to_le32(0x0000)
#define UHCI_NUMFRAMES 1024 /* in the frame list [array] */
#define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */
@@ -80,6 +81,19 @@ struct uhci_frame_list {
struct urb_priv;
+/* One role of a QH is to hold a queue of TDs for some endpoint. Each QH is
+ * used with one URB, and qh->element (updated by the HC) is either:
+ * - the next unprocessed TD for the URB, or
+ * - UHCI_PTR_TERM (when there's no more traffic for this endpoint), or
+ * - the QH for the next URB queued to the same endpoint.
+ *
+ * The other role of a QH is to serve as a "skeleton" framelist entry, so we
+ * can easily splice a QH for some endpoint into the schedule at the right
+ * place. Then qh->element is UHCI_PTR_TERM.
+ *
+ * In the frame list, qh->link maintains a list of QHs seen by the HC:
+ * skel1 --> ep1-qh --> ep2-qh --> ... --> skel2 --> ...
+ */
struct uhci_qh {
/* Hardware fields */
__u32 link; /* Next queue */
@@ -156,6 +170,9 @@ struct uhci_qh {
*
* Alas, not anymore, we have more than 4 words for software, woops.
* Everything still works tho, surprise! -jerdfelt
+ *
+ * td->link points to either another TD (not necessarily for the same urb or
+ * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs)
*/
struct uhci_td {
/* Hardware fields */
@@ -172,7 +189,7 @@ struct uhci_td {
struct list_head list; /* P: urb->lock */
- int frame;
+ int frame; /* for iso: what frame? */
struct list_head fl_list; /* P: uhci->frame_list_lock */
} __attribute__((aligned(16)));
@@ -217,6 +234,22 @@ struct uhci_td {
*
* To keep with Linus' nomenclature, this is called the QH skeleton. These
* labels (below) are only signficant to the root hub's QH's
+ *
+ *
+ * NOTE: That ASCII art doesn't match the current (August 2002) code, in
+ * more ways than just not using QHs for ISO.
+ *
+ * NOTE: Another way to look at the UHCI schedules is to compare them to what
+ * other host controller interfaces use. EHCI, OHCI, and UHCI all have tables
+ * of transfers that the controller scans, frame by frame, and which hold the
+ * scheduled periodic transfers. The key differences are that UHCI
+ *
+ * (a) puts control and bulk transfers into that same table; the others
+ * have separate data structures for non-periodic transfers.
+ * (b) lets QHs be linked from TDs, not just other QHs, since they don't
+ * hold endpoint data. this driver chooses to use one QH per URB.
+ * (c) needs more TDs, since it uses one per packet. the data toggle
+ * is stored in those TDs, along with all other endpoint state.
*/
#define UHCI_NUM_SKELTD 10
@@ -275,7 +308,7 @@ static inline int __interval_to_skel(int interval)
return 7; /* int128 for 128-255 ms (Max.) */
}
-#define hcd_to_uhci(hcd_ptr) list_entry(hcd_ptr, struct uhci_hcd, hcd)
+#define hcd_to_uhci(hcd_ptr) container_of(hcd_ptr, struct uhci_hcd, hcd)
/*
* This describes the full uhci information.
@@ -286,18 +319,13 @@ static inline int __interval_to_skel(int interval)
struct uhci_hcd {
struct usb_hcd hcd;
- struct pci_dev *dev;
-
#ifdef CONFIG_PROC_FS
/* procfs */
- int num;
struct proc_dir_entry *proc_entry;
#endif
/* Grabbed from PCI */
- int irq;
unsigned int io_addr;
- unsigned int io_size;
struct pci_pool *qh_pool;
struct pci_pool *td_pool;
@@ -329,7 +357,6 @@ struct uhci_hcd {
spinlock_t complete_list_lock;
struct list_head complete_list; /* P: uhci->complete_list_lock */
- struct usb_device *rh_dev; /* Root hub */
int rh_numports;
struct timer_list stall_timer;
diff --git a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c
index 9c9550e5cce7..f1248f7a3f07 100644
--- a/drivers/usb/image/scanner.c
+++ b/drivers/usb/image/scanner.c
@@ -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) {
diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
index 0df4777f0bd4..7fb881cbadc3 100644
--- a/drivers/usb/media/se401.c
+++ b/drivers/usb/media/se401.c
@@ -25,7 +25,7 @@
* - Jeroen Vreeken
*/
-static const char version[] = "0.23";
+static const char version[] = "0.24";
#include <linux/config.h>
#include <linux/module.h>
@@ -980,6 +980,34 @@ static int se401_newframe(struct usb_se401 *se401, int framenr)
return 0;
}
+static void usb_se401_remove_disconnected (struct usb_se401 *se401)
+{
+ int i;
+
+ se401->dev = NULL;
+
+ for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
+ usb_unlink_urb(se401->urb[i]);
+ usb_free_urb(se401->urb[i]);
+ se401->urb[i] = NULL;
+ kfree(se401->sbuf[i].data);
+ }
+ for (i=0; i<SE401_NUMSCRATCH; i++) if (se401->scratch[i].data) {
+ kfree(se401->scratch[i].data);
+ }
+ if (se401->inturb) {
+ usb_unlink_urb(se401->inturb);
+ usb_free_urb(se401->inturb);
+ }
+ info("%s disconnected", se401->camera_name);
+
+ /* Free the memory */
+ kfree(se401->width);
+ kfree(se401->height);
+ kfree(se401);
+}
+
+
/****************************************************************************
*
@@ -1015,20 +1043,16 @@ static int se401_close(struct inode *inode, struct file *file)
struct usb_se401 *se401 = (struct usb_se401 *)dev;
int i;
- for (i=0; i<SE401_NUMFRAMES; i++)
- se401->frame[i].grabstate=FRAME_UNUSED;
- if (se401->streaming)
- se401_stop_stream(se401);
-
rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
- se401->user=0;
-
if (se401->removed) {
- kfree(se401->width);
- kfree(se401->height);
- kfree(se401);
- se401 = NULL;
+ usb_se401_remove_disconnected(se401);
info("device unregistered");
+ } else {
+ for (i=0; i<SE401_NUMFRAMES; i++)
+ se401->frame[i].grabstate=FRAME_UNUSED;
+ if (se401->streaming)
+ se401_stop_stream(se401);
+ se401->user=0;
}
file->private_data = NULL;
return 0;
@@ -1302,7 +1326,7 @@ static struct video_device se401_template = {
/***************************/
-static int se401_init(struct usb_se401 *se401)
+static int se401_init(struct usb_se401 *se401, int button)
{
int i=0, rc;
unsigned char cp[0x40];
@@ -1367,22 +1391,25 @@ static int se401_init(struct usb_se401 *se401)
se401->readcount=0;
/* Start interrupt transfers for snapshot button */
- se401->inturb=usb_alloc_urb(0, GFP_KERNEL);
- if (!se401->inturb) {
- info("Allocation of inturb failed");
- return 1;
- }
- FILL_INT_URB(se401->inturb, se401->dev,
- usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
- &se401->button, sizeof(se401->button),
- se401_button_irq,
- se401,
- HZ/10
- );
- if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
- info("int urb burned down");
- return 1;
- }
+ if (button) {
+ se401->inturb=usb_alloc_urb(0, GFP_KERNEL);
+ if (!se401->inturb) {
+ info("Allocation of inturb failed");
+ return 1;
+ }
+ FILL_INT_URB(se401->inturb, se401->dev,
+ usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
+ &se401->button, sizeof(se401->button),
+ se401_button_irq,
+ se401,
+ HZ/10
+ );
+ if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
+ info("int urb burned down");
+ return 1;
+ }
+ } else
+ se401->inturb=NULL;
/* Flash the led */
se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
@@ -1399,6 +1426,7 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum,
struct usb_interface_descriptor *interface;
struct usb_se401 *se401;
char *camera_name=NULL;
+ int button=1;
/* We don't handle multi-config cameras */
if (dev->descriptor.bNumConfigurations != 1)
@@ -1422,6 +1450,7 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum,
} else if (dev->descriptor.idVendor == 0x047d &&
dev->descriptor.idProduct == 0x5003) {
camera_name="Kensington VideoCAM 67016";
+ button=0;
} else
return NULL;
@@ -1447,7 +1476,7 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum,
info("firmware version: %02x", dev->descriptor.bcdDevice & 255);
- if (se401_init(se401)) {
+ if (se401_init(se401, button)) {
kfree(se401);
return NULL;
}
@@ -1479,45 +1508,18 @@ static void se401_disconnect(struct usb_device *dev, void *ptr)
if (!se401->user){
usb_se401_remove_disconnected(se401);
} else {
- se401->removed = 1;
- }
-}
+ se401->frame[0].grabstate = FRAME_ERROR;
+ se401->frame[0].grabstate = FRAME_ERROR;
-static inline void usb_se401_remove_disconnected (struct usb_se401 *se401)
-{
- int i;
-
- se401->dev = NULL;
- se401->frame[0].grabstate = FRAME_ERROR;
- se401->frame[1].grabstate = FRAME_ERROR;
-
- se401->streaming = 0;
-
- wake_up_interruptible(&se401->wq);
-
- for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
- usb_unlink_urb(se401->urb[i]);
- usb_free_urb(se401->urb[i]);
- se401->urb[i] = NULL;
- kfree(se401->sbuf[i].data);
- }
- for (i=0; i<SE401_NUMSCRATCH; i++) if (se401->scratch[i].data) {
- kfree(se401->scratch[i].data);
- }
- if (se401->inturb) {
- usb_unlink_urb(se401->inturb);
- usb_free_urb(se401->inturb);
+ se401->streaming = 0;
+
+ wake_up_interruptible(&se401->wq);
+ se401->removed = 1;
}
- info("%s disconnected", se401->camera_name);
-
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
destroy_proc_se401_cam(se401);
#endif
- /* Free the memory */
- kfree(se401->width);
- kfree(se401->height);
- kfree(se401);
}
static struct usb_driver se401_driver = {
diff --git a/drivers/usb/media/se401.h b/drivers/usb/media/se401.h
index 861210147ca9..c8f97d089216 100644
--- a/drivers/usb/media/se401.h
+++ b/drivers/usb/media/se401.h
@@ -230,7 +230,6 @@ struct usb_se401 {
int nullpackets;
};
-static inline void usb_se401_remove_disconnected (struct usb_se401 *se401);
#endif
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
index 799c5df48f53..2562a704a438 100644
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -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);
diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h
index d231998a4698..b01f5cef133b 100644
--- a/drivers/usb/net/pegasus.h
+++ b/drivers/usb/net/pegasus.h
@@ -191,6 +191,8 @@ PEGASUS_DEV( "Billionton USBE-100", VENDOR_BILLIONTON, 0x8511,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Corega FEter USB-TX", VENDOR_COREGA, 0x0004,
DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "Corega FEter", VENDOR_COREGA, 0x0004,
+ DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001,
LINKSYS_GPIO_RESET )
PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4002,
@@ -205,7 +207,7 @@ PEGASUS_DEV( "D-Link DSB-650TX(PNA)", VENDOR_DLINK, 0x4003,
DEFAULT_GPIO_RESET | HAS_HOME_PNA )
PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1,
DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "ELCON EPLC10Mi USB to Powerline Adapter", VENDOR_ELCON, 0x0002,
+PEGASUS_DEV( "GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002,
DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
DEFAULT_GPIO_RESET )
@@ -254,7 +256,7 @@ PEGASUS_DEV( "SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100,
PEGASUS_DEV( "SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001,
- DEFAULT_GPIO_RESET )
+ DEFAULT_GPIO_RESET | PEGASUS_II )
#endif /* PEGASUS_DEV */
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index c5bc8e92c8cf..4904c614f40d 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -2086,7 +2086,12 @@ static const struct usb_device_id products [] = {
// 1183 = 0x049F, both used as hex values?
USB_DEVICE (0x049F, 0x505A), // Compaq "Itsy"
.driver_info = (unsigned long) &linuxdev_info,
+}, {
+ USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy"
+ .driver_info = (unsigned long) &linuxdev_info,
},
+ // NOTE: the Sharp Zaurus uses a modified version of
+ // this driver, which is not interoperable with this.
#endif
#ifdef CONFIG_USB_NET1080
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index d879f82a5029..d80cb3377839 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -54,10 +54,27 @@
* Helper routines
***********************************************************************/
-/* Fix-up the return data from an INQUIRY command to show
+static void *
+find_data_location(Scsi_Cmnd *srb) {
+ if (srb->use_sg) {
+ /*
+ * This piece of code only works if the first page is
+ * big enough to hold more than 3 bytes -- which is
+ * _very_ likely.
+ */
+ struct scatterlist *sg;
+
+ sg = (struct scatterlist *) srb->request_buffer;
+ return (void *) page_address(sg[0].page) + sg[0].offset;
+ } else
+ return (void *) srb->request_buffer;
+}
+
+/*
+ * Fix-up the return data from an INQUIRY command to show
* ANSI SCSI rev 2 so we don't confuse the SCSI layers above us
*/
-void fix_inquiry_data(Scsi_Cmnd *srb)
+static void fix_inquiry_data(Scsi_Cmnd *srb)
{
unsigned char *data_ptr;
@@ -65,24 +82,43 @@ void fix_inquiry_data(Scsi_Cmnd *srb)
if (srb->cmnd[0] != INQUIRY)
return;
- US_DEBUGP("Fixing INQUIRY data to show SCSI rev 2\n");
+ data_ptr = find_data_location(srb);
- /* find the location of the data */
- if (srb->use_sg) {
- /* this piece of code only works if the first page is big enough to
- * hold more than 3 bytes -- which is _very_ likely
- */
- struct scatterlist *sg;
+ if ((data_ptr[2] & 7) == 2)
+ return;
- sg = (struct scatterlist *) srb->request_buffer;
- data_ptr = (unsigned char *) page_address(sg[0].page) + sg[0].offset;
- } else
- data_ptr = (unsigned char *)srb->request_buffer;
+ US_DEBUGP("Fixing INQUIRY data to show SCSI rev 2 - was %d\n",
+ data_ptr[2] & 7);
/* Change the SCSI revision number */
data_ptr[2] = (data_ptr[2] & ~7) | 2;
}
+/*
+ * Fix-up the return data from a READ CAPACITY command. My Feiya reader
+ * returns a value that is 1 too large.
+ */
+static void fix_read_capacity(Scsi_Cmnd *srb)
+{
+ unsigned char *dp;
+ unsigned long capacity;
+
+ /* verify that it's a READ CAPACITY command */
+ if (srb->cmnd[0] != READ_CAPACITY)
+ return;
+
+ dp = find_data_location(srb);
+
+ capacity = (dp[0]<<24) + (dp[1]<<16) + (dp[2]<<8) + (dp[3]);
+ US_DEBUGP("US: Fixing capacity: from %ld to %ld\n",
+ capacity+1, capacity);
+ capacity--;
+ dp[0] = (capacity >> 24);
+ dp[1] = (capacity >> 16);
+ dp[2] = (capacity >> 8);
+ dp[3] = (capacity);
+}
+
/***********************************************************************
* Protocol routines
***********************************************************************/
@@ -346,8 +382,11 @@ void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us)
if ((us->flags & US_FL_MODE_XLATE) && (old_cmnd == MODE_SENSE))
usb_stor_scsiSense10to6(srb);
- /* fix the INQUIRY data if necessary */
+ /* Fix the INQUIRY data if necessary */
fix_inquiry_data(srb);
+
+ /* Fix the READ CAPACITY result if necessary */
+ if (us->flags & US_FL_FIX_CAPACITY)
+ fix_read_capacity(srb);
}
}
-
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 872d8773c5ac..70cac2634164 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -883,6 +883,9 @@ void usb_stor_abort_transport(struct us_data *us)
usb_stor_CBI_irq(us->irq_urb);
}
+ /* Wait for the aborted command to finish */
+ wait_for_completion(&us->notify);
+
/* Reacquire the lock */
scsi_lock(us->srb->host);
}
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index f1e2eb3071f3..abb117bfe6e4 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -310,6 +310,13 @@ UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001,
US_FL_MODE_XLATE ),
#endif
+/* Reported by Blake Matheny <bmatheny@purdue.edu> */
+UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113,
+ "Lexar",
+ "USB CF Reader",
+ US_SC_SCSI, US_PR_BULK, NULL,
+ US_FL_FIX_INQUIRY ),
+
/* Reported by Carlos Villegas <cav@uniscope.co.jp>
* This device needs an INQUIRY of exactly 36-bytes to function.
* That is the only reason this entry is needed.
@@ -507,6 +514,13 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009,
US_SC_8070, US_PR_CB, NULL,
US_FL_FIX_INQUIRY ),
+/* aeb */
+UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
+ "Feiya",
+ "5-in-1 Card Reader",
+ US_SC_SCSI, US_PR_BULK, NULL,
+ US_FL_FIX_CAPACITY ),
+
UNUSUAL_DEV( 0x097a, 0x0001, 0x0000, 0x0001,
"Minds@Work",
"Digital Wallet",
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 84a72fde8a75..67d969a7fa99 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -440,8 +440,14 @@ static int usb_stor_control_thread(void * __us)
/* Most USB devices can't handle START_STOP. But we
* need something for media-change, so we'll use TUR
* instead.
+ *
+ * We specifically allow this command through if either:
+ * (a) it's a load/eject command (cmnd[4] & 2)
+ * (b) it's a multi-target unit (i.e. legacy SCSI adaptor)
*/
- else if (us->srb->cmnd[0] == START_STOP) {
+ else if (us->srb->cmnd[0] == START_STOP &&
+ !(us->srb->cmnd[4] & 2) &&
+ !(us->flags & US_FL_SCM_MULT_TARG)) {
unsigned char saved_cdb[16]; /* largest SCSI-III cmd */
__u8 old_cmd_len;
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 0418d92651aa..19ecbe4b898e 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -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? */
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 4ee650d38e7c..c23edd0315b8 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -32,7 +32,7 @@
#define UDF_NAME_LEN 255
#define UDF_PATH_LEN 1023
-#define CURRENT_UTIME (xtime.tv_usec)
+#define CURRENT_UTIME (xtime.tv_nsec / 1000)
#define udf_file_entry_alloc_offset(inode)\
((UDF_I_EXTENDED_FE(inode) ?\
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index eda1ea41f86a..10f706b7f02d 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -605,7 +605,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
}
again:
- if (sb_set_blocksize(sb, block_size)) {
+ if (!sb_set_blocksize(sb, block_size)) {
printk(KERN_ERR "UFS: failed to set blocksize\n");
goto failed;
}
diff --git a/include/asm-i386/mtrr.h b/include/asm-i386/mtrr.h
index ff3ea870d0d6..f2727e61fe63 100644
--- a/include/asm-i386/mtrr.h
+++ b/include/asm-i386/mtrr.h
@@ -115,13 +115,6 @@ static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {;}
# 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 /* _LINUX_MTRR_H */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 9c619036dfb6..1bdcda4d36c8 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -354,11 +354,11 @@ void acpi_numa_arch_fixup(void);
extern int acpi_mp_config;
-#else /*!CONFIG_ACPI_BOOT*/
+#else
#define acpi_mp_config 0
-#endif /*CONFIG_ACPI_BOOT*/
+#endif
#ifdef CONFIG_ACPI_PCI
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b82ec8e41174..79d909a8643a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -634,7 +634,6 @@ void pci_insert_device(struct pci_dev *, struct pci_bus *);
void pci_remove_device(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);
-void pci_announce_device_to_drivers(struct pci_dev *);
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);
diff --git a/include/linux/time.h b/include/linux/time.h
index d9f9c6a340d8..088c52d09449 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -113,7 +113,7 @@ mktime (unsigned int year, unsigned int mon,
)*60 + sec; /* finally seconds */
}
-extern struct timeval xtime;
+extern struct timespec xtime;
#define CURRENT_TIME (xtime.tv_sec)
diff --git a/include/linux/timex.h b/include/linux/timex.h
index b82cbdc776f7..5b2b0ac18ae7 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -155,6 +155,28 @@
/* LATCH is used in the interval timer and ftape setup. */
#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
+/* Suppose we want to devide two numbers NOM and DEN: NOM/DEN, the we can
+ * improve accuracy by shifting LSH bits, hence calculating:
+ * (NOM << LSH) / DEN
+ * This however means trouble for large NOM, because (NOM << LSH) may no
+ * longer fit in 32 bits. The following way of calculating this gives us
+ * some slack, under the following onditions:
+ * - (NOM / DEN) fits in (32 - LSH) bits.
+ * - (NOM % DEN) fits in (32 - LSH) bits.
+ */
+#define SH_DIV(NOM,DEN,LSH) ( ((NOM / DEN) << LSH) \
+ + (((NOM % DEN) << LSH) + DEN / 2) / DEN)
+
+/* HZ is the requested value. ACTHZ is actual HZ ("<< 8" is for accuracy) */
+#define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8))
+
+/* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */
+#define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ)
+
+/* TICK_NSEC is the time between ticks in nsec assuming real ACTHZ and */
+/* a value TUSEC for TICK_USEC (can be set bij adjtimex) */
+#define TICK_NSEC(TUSEC) (SH_DIV (TUSEC * USER_HZ * 1000, ACTHZ, 8))
+
/*
* syscall interface - used (mainly by NTP daemon)
* to discipline kernel clock oscillator
@@ -251,7 +273,8 @@ struct timex {
* Note: maximum error = NTP synch distance = dispersion + delay / 2;
* estimated error = NTP dispersion.
*/
-extern long tick; /* timer interrupt period */
+extern unsigned long tick_usec; /* USER_HZ period (usec) */
+extern unsigned long tick_nsec; /* ACTHZ period (nsec) */
extern int tickadj; /* amount of adjustment per tick */
/*
diff --git a/init/main.c b/init/main.c
index 9aa3a0600960..b484d14df3a2 100644
--- a/init/main.c
+++ b/init/main.c
@@ -38,10 +38,6 @@
#include <asm/s390mach.h>
#endif
-#ifdef CONFIG_MTRR
-# include <asm/mtrr.h>
-#endif
-
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/smp.h>
#endif
@@ -536,15 +532,6 @@ static int init(void * unused)
*/
child_reaper = current;
-#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
-
/* Sets up cpus_possible() */
smp_prepare_cpus(max_cpus);
diff --git a/kernel/time.c b/kernel/time.c
index edb7eb7b8b73..716e0bbe071a 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -82,7 +82,7 @@ asmlinkage long sys_stime(int * tptr)
return -EFAULT;
write_lock_irq(&xtime_lock);
xtime.tv_sec = value;
- xtime.tv_usec = 0;
+ xtime.tv_nsec = 0;
last_time_offset = 0;
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
@@ -231,7 +231,8 @@ int do_adjtimex(struct timex *txc)
/* if the quartz is off by more than 10% something is VERY wrong ! */
if (txc->modes & ADJ_TICK)
- if (txc->tick < 900000/HZ || txc->tick > 1100000/HZ)
+ if (txc->tick < 900000/USER_HZ ||
+ txc->tick > 1100000/USER_HZ)
return -EINVAL;
write_lock_irq(&xtime_lock);
@@ -344,13 +345,8 @@ int do_adjtimex(struct timex *txc)
} /* STA_PLL || STA_PPSTIME */
} /* txc->modes & ADJ_OFFSET */
if (txc->modes & ADJ_TICK) {
- /* if the quartz is off by more than 10% something is
- VERY wrong ! */
- if (txc->tick < 900000/HZ || txc->tick > 1100000/HZ) {
- result = -EINVAL;
- goto leave;
- }
- tick = txc->tick;
+ tick_usec = txc->tick;
+ tick_nsec = TICK_NSEC(tick_usec);
}
} /* txc->modes */
leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
@@ -380,7 +376,7 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
txc->constant = time_constant;
txc->precision = time_precision;
txc->tolerance = time_tolerance;
- txc->tick = tick;
+ txc->tick = tick_usec;
txc->ppsfreq = pps_freq;
txc->jitter = pps_jitter >> PPS_AVG;
txc->shift = pps_shift;
diff --git a/kernel/timer.c b/kernel/timer.c
index d4efe5823e94..3b4be840f931 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -33,10 +33,11 @@ struct kernel_stat kstat;
* Timekeeping variables
*/
-long tick = (1000000 + HZ/2) / HZ; /* timer interrupt period */
+unsigned long tick_usec = TICK_USEC; /* ACTHZ period (usec) */
+unsigned long tick_nsec = TICK_NSEC(TICK_USEC); /* USER_HZ period (nsec) */
/* The current time */
-struct timeval xtime __attribute__ ((aligned (16)));
+struct timespec xtime __attribute__ ((aligned (16)));
/* Don't completely fail for HZ > 500. */
int tickadj = 500/HZ ? : 1; /* microsecs */
@@ -63,7 +64,6 @@ long time_adj; /* tick adjust (scaled 1 / HZ) */
long time_reftime; /* time at last adjustment (s) */
long time_adjust;
-long time_adjust_step;
unsigned long event;
@@ -465,6 +465,8 @@ static void second_overflow(void)
/* in the NTP reference this is called "hardclock()" */
static void update_wall_time_one_tick(void)
{
+ long time_adjust_step;
+
if ( (time_adjust_step = time_adjust) != 0 ) {
/* We are doing an adjtime thing.
*
@@ -483,21 +485,21 @@ static void update_wall_time_one_tick(void)
/* Reduce by this step the amount of time left */
time_adjust -= time_adjust_step;
}
- xtime.tv_usec += tick + time_adjust_step;
+ xtime.tv_nsec += tick_nsec + time_adjust_step * 1000;
/*
* Advance the phase, once it gets to one microsecond, then
* advance the tick more.
*/
time_phase += time_adj;
if (time_phase <= -FINEUSEC) {
- long ltemp = -time_phase >> SHIFT_SCALE;
- time_phase += ltemp << SHIFT_SCALE;
- xtime.tv_usec -= ltemp;
+ long ltemp = -time_phase >> (SHIFT_SCALE - 10);
+ time_phase += ltemp << (SHIFT_SCALE - 10);
+ xtime.tv_nsec -= ltemp;
}
else if (time_phase >= FINEUSEC) {
- long ltemp = time_phase >> SHIFT_SCALE;
- time_phase -= ltemp << SHIFT_SCALE;
- xtime.tv_usec += ltemp;
+ long ltemp = time_phase >> (SHIFT_SCALE - 10);
+ time_phase -= ltemp << (SHIFT_SCALE - 10);
+ xtime.tv_nsec += ltemp;
}
}
@@ -515,8 +517,8 @@ static void update_wall_time(unsigned long ticks)
update_wall_time_one_tick();
} while (ticks);
- if (xtime.tv_usec >= 1000000) {
- xtime.tv_usec -= 1000000;
+ if (xtime.tv_nsec >= 1000000000) {
+ xtime.tv_nsec -= 1000000000;
xtime.tv_sec++;
second_overflow();
}