提交 84cdda8a 编写于 作者: S Steve French

Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git

...@@ -433,9 +433,8 @@ static void __devinit pci_post_fixup_toshiba_ohci1394(struct pci_dev *dev) ...@@ -433,9 +433,8 @@ static void __devinit pci_post_fixup_toshiba_ohci1394(struct pci_dev *dev)
return; /* only applies to certain Toshibas (so far) */ return; /* only applies to certain Toshibas (so far) */
/* Restore config space on Toshiba laptops */ /* Restore config space on Toshiba laptops */
mdelay(10);
pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size); pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size);
pci_write_config_word(dev, PCI_INTERRUPT_LINE, dev->irq); pci_read_config_byte(dev, PCI_INTERRUPT_LINE, (u8 *)&dev->irq);
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
pci_resource_start(dev, 0)); pci_resource_start(dev, 0));
pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,
......
...@@ -987,7 +987,7 @@ efi_initialize_iomem_resources(struct resource *code_resource, ...@@ -987,7 +987,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
break; break;
} }
if ((res = kcalloc(1, sizeof(struct resource), GFP_KERNEL)) == NULL) { if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) {
printk(KERN_ERR "failed to alocate resource for iomem\n"); printk(KERN_ERR "failed to alocate resource for iomem\n");
return; return;
} }
......
...@@ -347,7 +347,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -347,7 +347,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
((struct fnptr *)kretprobe_trampoline)->ip; ((struct fnptr *)kretprobe_trampoline)->ip;
spin_lock_irqsave(&kretprobe_lock, flags); spin_lock_irqsave(&kretprobe_lock, flags);
head = kretprobe_inst_table_head(current); head = kretprobe_inst_table_head(current);
/* /*
* It is possible to have multiple instances associated with a given * It is possible to have multiple instances associated with a given
...@@ -363,9 +363,9 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -363,9 +363,9 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
* kretprobe_trampoline * kretprobe_trampoline
*/ */
hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
if (ri->task != current) if (ri->task != current)
/* another task is sharing our hash bucket */ /* another task is sharing our hash bucket */
continue; continue;
if (ri->rp && ri->rp->handler) if (ri->rp && ri->rp->handler)
ri->rp->handler(ri, regs); ri->rp->handler(ri, regs);
...@@ -394,7 +394,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -394,7 +394,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
* kprobe_handler() that we don't want the post_handler * kprobe_handler() that we don't want the post_handler
* to run (and have re-enabled preemption) * to run (and have re-enabled preemption)
*/ */
return 1; return 1;
} }
/* Called with kretprobe_lock held */ /* Called with kretprobe_lock held */
...@@ -739,12 +739,16 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, ...@@ -739,12 +739,16 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
switch(val) { switch(val) {
case DIE_BREAK: case DIE_BREAK:
if (pre_kprobes_handler(args)) /* err is break number from ia64_bad_break() */
ret = NOTIFY_STOP; if (args->err == 0x80200 || args->err == 0x80300)
if (pre_kprobes_handler(args))
ret = NOTIFY_STOP;
break; break;
case DIE_SS: case DIE_FAULT:
if (post_kprobes_handler(args->regs)) /* err is vector number from ia64_fault() */
ret = NOTIFY_STOP; if (args->err == 36)
if (post_kprobes_handler(args->regs))
ret = NOTIFY_STOP;
break; break;
case DIE_PAGE_FAULT: case DIE_PAGE_FAULT:
/* kprobe_running() needs smp_processor_id() */ /* kprobe_running() needs smp_processor_id() */
......
...@@ -51,6 +51,9 @@ ...@@ -51,6 +51,9 @@
* *
* 2005-08-12 Keith Owens <kaos@sgi.com> * 2005-08-12 Keith Owens <kaos@sgi.com>
* Convert MCA/INIT handlers to use per event stacks and SAL/OS state. * Convert MCA/INIT handlers to use per event stacks and SAL/OS state.
*
* 2005-10-07 Keith Owens <kaos@sgi.com>
* Add notify_die() hooks.
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -58,7 +61,6 @@ ...@@ -58,7 +61,6 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/kallsyms.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/acpi.h> #include <linux/acpi.h>
...@@ -69,6 +71,7 @@ ...@@ -69,6 +71,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/kdebug.h>
#include <asm/machvec.h> #include <asm/machvec.h>
#include <asm/meminit.h> #include <asm/meminit.h>
#include <asm/page.h> #include <asm/page.h>
...@@ -132,6 +135,14 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe); ...@@ -132,6 +135,14 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
static int mca_init; static int mca_init;
static void inline
ia64_mca_spin(const char *func)
{
printk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func);
while (1)
cpu_relax();
}
/* /*
* IA64_MCA log support * IA64_MCA log support
*/ */
...@@ -526,13 +537,16 @@ ia64_mca_wakeup_all(void) ...@@ -526,13 +537,16 @@ ia64_mca_wakeup_all(void)
* Outputs : None * Outputs : None
*/ */
static irqreturn_t static irqreturn_t
ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
{ {
unsigned long flags; unsigned long flags;
int cpu = smp_processor_id(); int cpu = smp_processor_id();
/* Mask all interrupts */ /* Mask all interrupts */
local_irq_save(flags); local_irq_save(flags);
if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, 0, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE; ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
/* Register with the SAL monarch that the slave has /* Register with the SAL monarch that the slave has
...@@ -540,10 +554,18 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) ...@@ -540,10 +554,18 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
*/ */
ia64_sal_mc_rendez(); ia64_sal_mc_rendez();
if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, 0, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
/* Wait for the monarch cpu to exit. */ /* Wait for the monarch cpu to exit. */
while (monarch_cpu != -1) while (monarch_cpu != -1)
cpu_relax(); /* spin until monarch leaves */ cpu_relax(); /* spin until monarch leaves */
if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, 0, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
/* Enable all interrupts */ /* Enable all interrupts */
local_irq_restore(flags); local_irq_restore(flags);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -933,6 +955,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, ...@@ -933,6 +955,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
monarch_cpu = cpu; monarch_cpu = cpu;
if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
ia64_wait_for_slaves(cpu); ia64_wait_for_slaves(cpu);
/* Wakeup all the processors which are spinning in the rendezvous loop. /* Wakeup all the processors which are spinning in the rendezvous loop.
...@@ -942,6 +967,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, ...@@ -942,6 +967,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
* spinning in SAL does not work. * spinning in SAL does not work.
*/ */
ia64_mca_wakeup_all(); ia64_mca_wakeup_all();
if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, 0, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
/* Get the MCA error record and log it */ /* Get the MCA error record and log it */
ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA); ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
...@@ -960,6 +988,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, ...@@ -960,6 +988,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
sos->os_status = IA64_MCA_CORRECTED; sos->os_status = IA64_MCA_CORRECTED;
} }
if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, 0, 0, recover)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
set_curr_task(cpu, previous_current); set_curr_task(cpu, previous_current);
monarch_cpu = -1; monarch_cpu = -1;
...@@ -1188,6 +1219,37 @@ ia64_mca_cpe_poll (unsigned long dummy) ...@@ -1188,6 +1219,37 @@ ia64_mca_cpe_poll (unsigned long dummy)
#endif /* CONFIG_ACPI */ #endif /* CONFIG_ACPI */
static int
default_monarch_init_process(struct notifier_block *self, unsigned long val, void *data)
{
int c;
struct task_struct *g, *t;
if (val != DIE_INIT_MONARCH_PROCESS)
return NOTIFY_DONE;
printk(KERN_ERR "Processes interrupted by INIT -");
for_each_online_cpu(c) {
struct ia64_sal_os_state *s;
t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET);
s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET);
g = s->prev_task;
if (g) {
if (g->pid)
printk(" %d", g->pid);
else
printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
}
}
printk("\n\n");
if (read_trylock(&tasklist_lock)) {
do_each_thread (g, t) {
printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
show_stack(t, NULL);
} while_each_thread (g, t);
read_unlock(&tasklist_lock);
}
return NOTIFY_DONE;
}
/* /*
* C portion of the OS INIT handler * C portion of the OS INIT handler
* *
...@@ -1212,8 +1274,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, ...@@ -1212,8 +1274,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
static atomic_t slaves; static atomic_t slaves;
static atomic_t monarchs; static atomic_t monarchs;
task_t *previous_current; task_t *previous_current;
int cpu = smp_processor_id(), c; int cpu = smp_processor_id();
struct task_struct *g, *t;
oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
console_loglevel = 15; /* make sure printks make it to console */ console_loglevel = 15; /* make sure printks make it to console */
...@@ -1253,8 +1314,17 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, ...@@ -1253,8 +1314,17 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
while (monarch_cpu == -1) while (monarch_cpu == -1)
cpu_relax(); /* spin until monarch enters */ cpu_relax(); /* spin until monarch enters */
if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, 0, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, 0, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
while (monarch_cpu != -1) while (monarch_cpu != -1)
cpu_relax(); /* spin until monarch leaves */ cpu_relax(); /* spin until monarch leaves */
if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, 0, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
printk("Slave on cpu %d returning to normal service.\n", cpu); printk("Slave on cpu %d returning to normal service.\n", cpu);
set_curr_task(cpu, previous_current); set_curr_task(cpu, previous_current);
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
...@@ -1263,6 +1333,9 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, ...@@ -1263,6 +1333,9 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
} }
monarch_cpu = cpu; monarch_cpu = cpu;
if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, 0, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
/* /*
* Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be
...@@ -1273,27 +1346,16 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, ...@@ -1273,27 +1346,16 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
printk("Delaying for 5 seconds...\n"); printk("Delaying for 5 seconds...\n");
udelay(5*1000000); udelay(5*1000000);
ia64_wait_for_slaves(cpu); ia64_wait_for_slaves(cpu);
printk(KERN_ERR "Processes interrupted by INIT -"); /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through
for_each_online_cpu(c) { * to default_monarch_init_process() above and just print all the
struct ia64_sal_os_state *s; * tasks.
t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET); */
s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET); if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0)
g = s->prev_task; == NOTIFY_STOP)
if (g) { ia64_mca_spin(__FUNCTION__);
if (g->pid) if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0)
printk(" %d", g->pid); == NOTIFY_STOP)
else ia64_mca_spin(__FUNCTION__);
printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
}
}
printk("\n\n");
if (read_trylock(&tasklist_lock)) {
do_each_thread (g, t) {
printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
show_stack(t, NULL);
} while_each_thread (g, t);
read_unlock(&tasklist_lock);
}
printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu);
atomic_dec(&monarchs); atomic_dec(&monarchs);
set_curr_task(cpu, previous_current); set_curr_task(cpu, previous_current);
...@@ -1462,6 +1524,10 @@ ia64_mca_init(void) ...@@ -1462,6 +1524,10 @@ ia64_mca_init(void)
s64 rc; s64 rc;
struct ia64_sal_retval isrv; struct ia64_sal_retval isrv;
u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */ u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */
static struct notifier_block default_init_monarch_nb = {
.notifier_call = default_monarch_init_process,
.priority = 0/* we need to notified last */
};
IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__); IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
...@@ -1555,6 +1621,10 @@ ia64_mca_init(void) ...@@ -1555,6 +1621,10 @@ ia64_mca_init(void)
"(status %ld)\n", rc); "(status %ld)\n", rc);
return; return;
} }
if (register_die_notifier(&default_init_monarch_nb)) {
printk(KERN_ERR "Failed to register default monarch INIT process\n");
return;
}
IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__); IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__);
......
...@@ -547,9 +547,20 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, ...@@ -547,9 +547,20 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
(pal_processor_state_info_t*)peidx_psp(peidx); (pal_processor_state_info_t*)peidx_psp(peidx);
/* /*
* We cannot recover errors with other than bus_check. * Processor recovery status must key off of the PAL recovery
* status in the Processor State Parameter.
*/ */
if (psp->cc || psp->rc || psp->uc)
/*
* The machine check is corrected.
*/
if (psp->cm == 1)
return 1;
/*
* The error was not contained. Software must be reset.
*/
if (psp->us || psp->ci == 0)
return 0; return 0;
/* /*
...@@ -570,8 +581,6 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, ...@@ -570,8 +581,6 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
return 0; return 0;
if (pbci->eb && pbci->bsi > 0) if (pbci->eb && pbci->bsi > 0)
return 0; return 0;
if (psp->ci == 0)
return 0;
/* /*
* This is a local MCA and estimated as recoverble external bus error. * This is a local MCA and estimated as recoverble external bus error.
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
* Copyright (C) 1998-2003 Hewlett-Packard Co * Copyright (C) 1998-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
* 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support * 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support
*
* 2005-10-07 Keith Owens <kaos@sgi.com>
* Add notify_die() hooks.
*/ */
#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */ #define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */
#include <linux/config.h> #include <linux/config.h>
...@@ -34,6 +37,7 @@ ...@@ -34,6 +37,7 @@
#include <asm/elf.h> #include <asm/elf.h>
#include <asm/ia32.h> #include <asm/ia32.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/kdebug.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/sal.h> #include <asm/sal.h>
...@@ -808,12 +812,14 @@ cpu_halt (void) ...@@ -808,12 +812,14 @@ cpu_halt (void)
void void
machine_restart (char *restart_cmd) machine_restart (char *restart_cmd)
{ {
(void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0);
(*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL); (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
} }
void void
machine_halt (void) machine_halt (void)
{ {
(void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0);
cpu_halt(); cpu_halt();
} }
......
...@@ -461,6 +461,7 @@ setup_arch (char **cmdline_p) ...@@ -461,6 +461,7 @@ setup_arch (char **cmdline_p)
#endif #endif
cpu_init(); /* initialize the bootstrap CPU */ cpu_init(); /* initialize the bootstrap CPU */
mmu_context_init(); /* initialize context_id bitmap */
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
acpi_boot_init(); acpi_boot_init();
......
...@@ -387,15 +387,14 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, ...@@ -387,15 +387,14 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
struct sigscratch *scr) struct sigscratch *scr)
{ {
extern char __kernel_sigtramp[]; extern char __kernel_sigtramp[];
unsigned long tramp_addr, new_rbs = 0; unsigned long tramp_addr, new_rbs = 0, new_sp;
struct sigframe __user *frame; struct sigframe __user *frame;
long err; long err;
frame = (void __user *) scr->pt.r12; new_sp = scr->pt.r12;
tramp_addr = (unsigned long) __kernel_sigtramp; tramp_addr = (unsigned long) __kernel_sigtramp;
if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags((unsigned long) frame) == 0) { if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(new_sp) == 0) {
frame = (void __user *) ((current->sas_ss_sp + current->sas_ss_size) new_sp = current->sas_ss_sp + current->sas_ss_size;
& ~(STACK_ALIGN - 1));
/* /*
* We need to check for the register stack being on the signal stack * We need to check for the register stack being on the signal stack
* separately, because it's switched separately (memory stack is switched * separately, because it's switched separately (memory stack is switched
...@@ -404,7 +403,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, ...@@ -404,7 +403,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
if (!rbs_on_sig_stack(scr->pt.ar_bspstore)) if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1); new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
} }
frame = (void __user *) frame - ((sizeof(*frame) + STACK_ALIGN - 1) & ~(STACK_ALIGN - 1)); frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
return force_sigsegv_info(sig, frame); return force_sigsegv_info(sig, frame);
......
...@@ -30,17 +30,20 @@ fpswa_interface_t *fpswa_interface; ...@@ -30,17 +30,20 @@ fpswa_interface_t *fpswa_interface;
EXPORT_SYMBOL(fpswa_interface); EXPORT_SYMBOL(fpswa_interface);
struct notifier_block *ia64die_chain; struct notifier_block *ia64die_chain;
static DEFINE_SPINLOCK(die_notifier_lock);
int register_die_notifier(struct notifier_block *nb) int
register_die_notifier(struct notifier_block *nb)
{ {
int err = 0; return notifier_chain_register(&ia64die_chain, nb);
unsigned long flags;
spin_lock_irqsave(&die_notifier_lock, flags);
err = notifier_chain_register(&ia64die_chain, nb);
spin_unlock_irqrestore(&die_notifier_lock, flags);
return err;
} }
EXPORT_SYMBOL_GPL(register_die_notifier);
int
unregister_die_notifier(struct notifier_block *nb)
{
return notifier_chain_unregister(&ia64die_chain, nb);
}
EXPORT_SYMBOL_GPL(unregister_die_notifier);
void __init void __init
trap_init (void) trap_init (void)
...@@ -105,6 +108,7 @@ die (const char *str, struct pt_regs *regs, long err) ...@@ -105,6 +108,7 @@ die (const char *str, struct pt_regs *regs, long err)
if (++die.lock_owner_depth < 3) { if (++die.lock_owner_depth < 3) {
printk("%s[%d]: %s %ld [%d]\n", printk("%s[%d]: %s %ld [%d]\n",
current->comm, current->pid, str, err, ++die_counter); current->comm, current->pid, str, err, ++die_counter);
(void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
show_regs(regs); show_regs(regs);
} else } else
printk(KERN_ERR "Recursive die() failure, output suppressed\n"); printk(KERN_ERR "Recursive die() failure, output suppressed\n");
...@@ -155,9 +159,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) ...@@ -155,9 +159,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
switch (break_num) { switch (break_num) {
case 0: /* unknown error (used by GCC for __builtin_abort()) */ case 0: /* unknown error (used by GCC for __builtin_abort()) */
if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
== NOTIFY_STOP) { == NOTIFY_STOP)
return; return;
}
die_if_kernel("bugcheck!", regs, break_num); die_if_kernel("bugcheck!", regs, break_num);
sig = SIGILL; code = ILL_ILLOPC; sig = SIGILL; code = ILL_ILLOPC;
break; break;
...@@ -210,15 +213,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) ...@@ -210,15 +213,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
sig = SIGILL; code = __ILL_BNDMOD; sig = SIGILL; code = __ILL_BNDMOD;
break; break;
case 0x80200:
case 0x80300:
if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
== NOTIFY_STOP) {
return;
}
sig = SIGTRAP; code = TRAP_BRKPT;
break;
default: default:
if (break_num < 0x40000 || break_num > 0x100000) if (break_num < 0x40000 || break_num > 0x100000)
die_if_kernel("Bad break", regs, break_num); die_if_kernel("Bad break", regs, break_num);
...@@ -226,6 +220,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) ...@@ -226,6 +220,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
if (break_num < 0x80000) { if (break_num < 0x80000) {
sig = SIGILL; code = __ILL_BREAK; sig = SIGILL; code = __ILL_BREAK;
} else { } else {
if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP)
== NOTIFY_STOP)
return;
sig = SIGTRAP; code = TRAP_BRKPT; sig = SIGTRAP; code = TRAP_BRKPT;
} }
} }
...@@ -578,12 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, ...@@ -578,12 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
#endif #endif
break; break;
case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
case 36: case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
if (notify_die(DIE_SS, "ss", &regs, vector,
vector, SIGTRAP) == NOTIFY_STOP)
return;
siginfo.si_code = TRAP_TRACE; ifa = 0; break;
} }
if (notify_die(DIE_FAULT, "ia64_fault", &regs, vector, siginfo.si_code, SIGTRAP)
== NOTIFY_STOP)
return;
siginfo.si_signo = SIGTRAP; siginfo.si_signo = SIGTRAP;
siginfo.si_errno = 0; siginfo.si_errno = 0;
siginfo.si_addr = (void __user *) ifa; siginfo.si_addr = (void __user *) ifa;
......
...@@ -350,14 +350,12 @@ static void __init initialize_pernode_data(void) ...@@ -350,14 +350,12 @@ static void __init initialize_pernode_data(void)
* for best. * for best.
* @nid: node id * @nid: node id
* @pernodesize: size of this node's pernode data * @pernodesize: size of this node's pernode data
* @align: alignment to use for this node's pernode data
*/ */
static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize, static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize)
unsigned long align)
{ {
void *ptr = NULL; void *ptr = NULL;
u8 best = 0xff; u8 best = 0xff;
int bestnode = -1, node; int bestnode = -1, node, anynode = 0;
for_each_online_node(node) { for_each_online_node(node) {
if (node_isset(node, memory_less_mask)) if (node_isset(node, memory_less_mask))
...@@ -366,13 +364,15 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize, ...@@ -366,13 +364,15 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize,
best = node_distance(nid, node); best = node_distance(nid, node);
bestnode = node; bestnode = node;
} }
anynode = node;
} }
ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, if (bestnode == -1)
pernodesize, align, __pa(MAX_DMA_ADDRESS)); bestnode = anynode;
ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, pernodesize,
PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
if (!ptr)
panic("NO memory for memory less node\n");
return ptr; return ptr;
} }
...@@ -413,8 +413,7 @@ static void __init memory_less_nodes(void) ...@@ -413,8 +413,7 @@ static void __init memory_less_nodes(void)
for_each_node_mask(node, memory_less_mask) { for_each_node_mask(node, memory_less_mask) {
pernodesize = compute_pernodesize(node); pernodesize = compute_pernodesize(node);
pernode = memory_less_node_alloc(node, pernodesize, pernode = memory_less_node_alloc(node, pernodesize);
(node) ? (node * PERCPU_PAGE_SIZE) : (1024*1024));
fill_pernode(node, __pa(pernode), pernodesize); fill_pernode(node, __pa(pernode), pernodesize);
} }
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
* Modified RID allocation for SMP * Modified RID allocation for SMP
* Goutham Rao <goutham.rao@intel.com> * Goutham Rao <goutham.rao@intel.com>
* IPI based ptc implementation and A-step IPI implementation. * IPI based ptc implementation and A-step IPI implementation.
* Rohit Seth <rohit.seth@intel.com>
* Ken Chen <kenneth.w.chen@intel.com>
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -16,78 +18,75 @@ ...@@ -16,78 +18,75 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/bootmem.h>
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/pal.h> #include <asm/pal.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/dma.h>
static struct { static struct {
unsigned long mask; /* mask of supported purge page-sizes */ unsigned long mask; /* mask of supported purge page-sizes */
unsigned long max_bits; /* log2() of largest supported purge page-size */ unsigned long max_bits; /* log2 of largest supported purge page-size */
} purge; } purge;
struct ia64_ctx ia64_ctx = { struct ia64_ctx ia64_ctx = {
.lock = SPIN_LOCK_UNLOCKED, .lock = SPIN_LOCK_UNLOCKED,
.next = 1, .next = 1,
.limit = (1 << 15) - 1, /* start out with the safe (architected) limit */
.max_ctx = ~0U .max_ctx = ~0U
}; };
DEFINE_PER_CPU(u8, ia64_need_tlb_flush); DEFINE_PER_CPU(u8, ia64_need_tlb_flush);
/*
* Initializes the ia64_ctx.bitmap array based on max_ctx+1.
* Called after cpu_init() has setup ia64_ctx.max_ctx based on
* maximum RID that is supported by boot CPU.
*/
void __init
mmu_context_init (void)
{
ia64_ctx.bitmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
ia64_ctx.flushmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
}
/* /*
* Acquire the ia64_ctx.lock before calling this function! * Acquire the ia64_ctx.lock before calling this function!
*/ */
void void
wrap_mmu_context (struct mm_struct *mm) wrap_mmu_context (struct mm_struct *mm)
{ {
unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx; int i, cpu;
struct task_struct *tsk; unsigned long flush_bit;
int i;
if (ia64_ctx.next > max_ctx) for (i=0; i <= ia64_ctx.max_ctx / BITS_PER_LONG; i++) {
ia64_ctx.next = 300; /* skip daemons */ flush_bit = xchg(&ia64_ctx.flushmap[i], 0);
ia64_ctx.limit = max_ctx + 1; ia64_ctx.bitmap[i] ^= flush_bit;
}
/* use offset at 300 to skip daemons */
ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
ia64_ctx.max_ctx, 300);
ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap,
ia64_ctx.max_ctx, ia64_ctx.next);
/* /*
* Scan all the task's mm->context and set proper safe range * can't call flush_tlb_all() here because of race condition
* with O(1) scheduler [EF]
*/ */
cpu = get_cpu(); /* prevent preemption/migration */
read_lock(&tasklist_lock); for_each_online_cpu(i)
repeat: if (i != cpu)
for_each_process(tsk) { per_cpu(ia64_need_tlb_flush, i) = 1;
if (!tsk->mm) put_cpu();
continue;
tsk_context = tsk->mm->context;
if (tsk_context == ia64_ctx.next) {
if (++ia64_ctx.next >= ia64_ctx.limit) {
/* empty range: reset the range limit and start over */
if (ia64_ctx.next > max_ctx)
ia64_ctx.next = 300;
ia64_ctx.limit = max_ctx + 1;
goto repeat;
}
}
if ((tsk_context > ia64_ctx.next) && (tsk_context < ia64_ctx.limit))
ia64_ctx.limit = tsk_context;
}
read_unlock(&tasklist_lock);
/* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */
{
int cpu = get_cpu(); /* prevent preemption/migration */
for_each_online_cpu(i) {
if (i != cpu)
per_cpu(ia64_need_tlb_flush, i) = 1;
}
put_cpu();
}
local_flush_tlb_all(); local_flush_tlb_all();
} }
void void
ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long nbits) ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
unsigned long end, unsigned long nbits)
{ {
static DEFINE_SPINLOCK(ptcg_lock); static DEFINE_SPINLOCK(ptcg_lock);
...@@ -135,7 +134,8 @@ local_flush_tlb_all (void) ...@@ -135,7 +134,8 @@ local_flush_tlb_all (void)
} }
void void
flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end) flush_tlb_range (struct vm_area_struct *vma, unsigned long start,
unsigned long end)
{ {
struct mm_struct *mm = vma->vm_mm; struct mm_struct *mm = vma->vm_mm;
unsigned long size = end - start; unsigned long size = end - start;
...@@ -149,7 +149,8 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long ...@@ -149,7 +149,8 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
#endif #endif
nbits = ia64_fls(size + 0xfff); nbits = ia64_fls(size + 0xfff);
while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits)) while (unlikely (((1UL << nbits) & purge.mask) == 0) &&
(nbits < purge.max_bits))
++nbits; ++nbits;
if (nbits > purge.max_bits) if (nbits > purge.max_bits)
nbits = purge.max_bits; nbits = purge.max_bits;
...@@ -191,5 +192,5 @@ ia64_tlb_init (void) ...@@ -191,5 +192,5 @@ ia64_tlb_init (void)
local_cpu_data->ptce_stride[0] = ptce_info.stride[0]; local_cpu_data->ptce_stride[0] = ptce_info.stride[0];
local_cpu_data->ptce_stride[1] = ptce_info.stride[1]; local_cpu_data->ptce_stride[1] = ptce_info.stride[1];
local_flush_tlb_all(); /* nuke left overs from bootstrapping... */ local_flush_tlb_all(); /* nuke left overs from bootstrapping... */
} }
...@@ -95,7 +95,7 @@ pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn, ...@@ -95,7 +95,7 @@ pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn,
} }
static struct pci_raw_ops pci_sal_ops = { static struct pci_raw_ops pci_sal_ops = {
.read = pci_sal_read, .read = pci_sal_read,
.write = pci_sal_write .write = pci_sal_write
}; };
...@@ -137,35 +137,98 @@ alloc_pci_controller (int seg) ...@@ -137,35 +137,98 @@ alloc_pci_controller (int seg)
return controller; return controller;
} }
static u64 __devinit struct pci_root_info {
add_io_space (struct acpi_resource_address64 *addr) struct pci_controller *controller;
char *name;
};
static unsigned int
new_space (u64 phys_base, int sparse)
{ {
u64 offset; u64 mmio_base;
int sparse = 0;
int i; int i;
if (addr->address_translation_offset == 0) if (phys_base == 0)
return IO_SPACE_BASE(0); /* part of legacy IO space */ return 0; /* legacy I/O port space */
if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
sparse = 1;
offset = (u64) ioremap(addr->address_translation_offset, 0); mmio_base = (u64) ioremap(phys_base, 0);
for (i = 0; i < num_io_spaces; i++) for (i = 0; i < num_io_spaces; i++)
if (io_space[i].mmio_base == offset && if (io_space[i].mmio_base == mmio_base &&
io_space[i].sparse == sparse) io_space[i].sparse == sparse)
return IO_SPACE_BASE(i); return i;
if (num_io_spaces == MAX_IO_SPACES) { if (num_io_spaces == MAX_IO_SPACES) {
printk("Too many IO port spaces\n"); printk(KERN_ERR "PCI: Too many IO port spaces "
"(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES);
return ~0; return ~0;
} }
i = num_io_spaces++; i = num_io_spaces++;
io_space[i].mmio_base = offset; io_space[i].mmio_base = mmio_base;
io_space[i].sparse = sparse; io_space[i].sparse = sparse;
return IO_SPACE_BASE(i); return i;
}
static u64 __devinit
add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr)
{
struct resource *resource;
char *name;
u64 base, min, max, base_port;
unsigned int sparse = 0, space_nr, len;
resource = kzalloc(sizeof(*resource), GFP_KERNEL);
if (!resource) {
printk(KERN_ERR "PCI: No memory for %s I/O port space\n",
info->name);
goto out;
}
len = strlen(info->name) + 32;
name = kzalloc(len, GFP_KERNEL);
if (!name) {
printk(KERN_ERR "PCI: No memory for %s I/O port space name\n",
info->name);
goto free_resource;
}
min = addr->min_address_range;
max = min + addr->address_length - 1;
if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
sparse = 1;
space_nr = new_space(addr->address_translation_offset, sparse);
if (space_nr == ~0)
goto free_name;
base = __pa(io_space[space_nr].mmio_base);
base_port = IO_SPACE_BASE(space_nr);
snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name,
base_port + min, base_port + max);
/*
* The SDM guarantees the legacy 0-64K space is sparse, but if the
* mapping is done by the processor (not the bridge), ACPI may not
* mark it as sparse.
*/
if (space_nr == 0)
sparse = 1;
resource->name = name;
resource->flags = IORESOURCE_MEM;
resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
insert_resource(&iomem_resource, resource);
return base_port;
free_name:
kfree(name);
free_resource:
kfree(resource);
out:
return ~0;
} }
static acpi_status __devinit resource_to_window(struct acpi_resource *resource, static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
...@@ -205,11 +268,6 @@ count_window (struct acpi_resource *resource, void *data) ...@@ -205,11 +268,6 @@ count_window (struct acpi_resource *resource, void *data)
return AE_OK; return AE_OK;
} }
struct pci_root_info {
struct pci_controller *controller;
char *name;
};
static __devinit acpi_status add_window(struct acpi_resource *res, void *data) static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
{ {
struct pci_root_info *info = data; struct pci_root_info *info = data;
...@@ -231,7 +289,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) ...@@ -231,7 +289,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
} else if (addr.resource_type == ACPI_IO_RANGE) { } else if (addr.resource_type == ACPI_IO_RANGE) {
flags = IORESOURCE_IO; flags = IORESOURCE_IO;
root = &ioport_resource; root = &ioport_resource;
offset = add_io_space(&addr); offset = add_io_space(info, &addr);
if (offset == ~0) if (offset == ~0)
return AE_OK; return AE_OK;
} else } else
...@@ -241,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) ...@@ -241,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
window->resource.name = info->name; window->resource.name = info->name;
window->resource.flags = flags; window->resource.flags = flags;
window->resource.start = addr.min_address_range + offset; window->resource.start = addr.min_address_range + offset;
window->resource.end = addr.max_address_range + offset; window->resource.end = window->resource.start + addr.address_length - 1;
window->resource.child = NULL; window->resource.child = NULL;
window->offset = offset; window->offset = offset;
...@@ -739,7 +797,7 @@ int pci_vector_resources(int last, int nr_released) ...@@ -739,7 +797,7 @@ int pci_vector_resources(int last, int nr_released)
{ {
int count = nr_released; int count = nr_released;
count += (IA64_LAST_DEVICE_VECTOR - last); count += (IA64_LAST_DEVICE_VECTOR - last);
return count; return count;
} }
...@@ -349,7 +349,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) ...@@ -349,7 +349,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
return; /*bus # does not exist */ return; /*bus # does not exist */
prom_bussoft_ptr = __va(prom_bussoft_ptr); prom_bussoft_ptr = __va(prom_bussoft_ptr);
controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL); controller = kzalloc(sizeof(struct pci_controller), GFP_KERNEL);
controller->segment = segment; controller->segment = segment;
if (!controller) if (!controller)
BUG(); BUG();
......
...@@ -163,7 +163,7 @@ struct xpc_vars { ...@@ -163,7 +163,7 @@ struct xpc_vars {
u8 version; u8 version;
u64 heartbeat; u64 heartbeat;
u64 heartbeating_to_mask; u64 heartbeating_to_mask;
u64 kdb_status; /* 0 = machine running */ u64 heartbeat_offline; /* if 0, heartbeat should be changing */
int act_nasid; int act_nasid;
int act_phys_cpuid; int act_phys_cpuid;
u64 vars_part_pa; u64 vars_part_pa;
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#include <linux/reboot.h> #include <linux/reboot.h>
#include <asm/sn/intr.h> #include <asm/sn/intr.h>
#include <asm/sn/sn_sal.h> #include <asm/sn/sn_sal.h>
#include <asm/kdebug.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "xpc.h" #include "xpc.h"
...@@ -188,6 +189,11 @@ static struct notifier_block xpc_reboot_notifier = { ...@@ -188,6 +189,11 @@ static struct notifier_block xpc_reboot_notifier = {
.notifier_call = xpc_system_reboot, .notifier_call = xpc_system_reboot,
}; };
static int xpc_system_die(struct notifier_block *, unsigned long, void *);
static struct notifier_block xpc_die_notifier = {
.notifier_call = xpc_system_die,
};
/* /*
* Timer function to enforce the timelimit on the partition disengage request. * Timer function to enforce the timelimit on the partition disengage request.
...@@ -997,6 +1003,9 @@ xpc_do_exit(enum xpc_retval reason) ...@@ -997,6 +1003,9 @@ xpc_do_exit(enum xpc_retval reason)
/* take ourselves off of the reboot_notifier_list */ /* take ourselves off of the reboot_notifier_list */
(void) unregister_reboot_notifier(&xpc_reboot_notifier); (void) unregister_reboot_notifier(&xpc_reboot_notifier);
/* take ourselves off of the die_notifier list */
(void) unregister_die_notifier(&xpc_die_notifier);
/* close down protections for IPI operations */ /* close down protections for IPI operations */
xpc_restrict_IPI_ops(); xpc_restrict_IPI_ops();
...@@ -1010,6 +1019,63 @@ xpc_do_exit(enum xpc_retval reason) ...@@ -1010,6 +1019,63 @@ xpc_do_exit(enum xpc_retval reason)
} }
/*
* Called when the system is about to be either restarted or halted.
*/
static void
xpc_die_disengage(void)
{
struct xpc_partition *part;
partid_t partid;
unsigned long engaged;
long time, print_time, disengage_request_timeout;
/* keep xpc_hb_checker thread from doing anything (just in case) */
xpc_exiting = 1;
xpc_vars->heartbeating_to_mask = 0; /* indicate we're deactivated */
for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
part = &xpc_partitions[partid];
if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part->
remote_vars_version)) {
/* just in case it was left set by an earlier XPC */
xpc_clear_partition_engaged(1UL << partid);
continue;
}
if (xpc_partition_engaged(1UL << partid) ||
part->act_state != XPC_P_INACTIVE) {
xpc_request_partition_disengage(part);
xpc_mark_partition_disengaged(part);
xpc_IPI_send_disengage(part);
}
}
print_time = rtc_time();
disengage_request_timeout = print_time +
(xpc_disengage_request_timelimit * sn_rtc_cycles_per_second);
/* wait for all other partitions to disengage from us */
while ((engaged = xpc_partition_engaged(-1UL)) &&
(time = rtc_time()) < disengage_request_timeout) {
if (time >= print_time) {
dev_info(xpc_part, "waiting for remote partitions to "
"disengage, engaged=0x%lx\n", engaged);
print_time = time + (XPC_DISENGAGE_PRINTMSG_INTERVAL *
sn_rtc_cycles_per_second);
}
}
dev_info(xpc_part, "finished waiting for remote partitions to "
"disengage, engaged=0x%lx\n", engaged);
}
/* /*
* This function is called when the system is being rebooted. * This function is called when the system is being rebooted.
*/ */
...@@ -1038,6 +1104,33 @@ xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused) ...@@ -1038,6 +1104,33 @@ xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
} }
/*
* This function is called when the system is being rebooted.
*/
static int
xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
{
switch (event) {
case DIE_MACHINE_RESTART:
case DIE_MACHINE_HALT:
xpc_die_disengage();
break;
case DIE_MCA_MONARCH_ENTER:
case DIE_INIT_MONARCH_ENTER:
xpc_vars->heartbeat++;
xpc_vars->heartbeat_offline = 1;
break;
case DIE_MCA_MONARCH_LEAVE:
case DIE_INIT_MONARCH_LEAVE:
xpc_vars->heartbeat++;
xpc_vars->heartbeat_offline = 0;
break;
}
return NOTIFY_DONE;
}
int __init int __init
xpc_init(void) xpc_init(void)
{ {
...@@ -1154,6 +1247,12 @@ xpc_init(void) ...@@ -1154,6 +1247,12 @@ xpc_init(void)
dev_warn(xpc_part, "can't register reboot notifier\n"); dev_warn(xpc_part, "can't register reboot notifier\n");
} }
/* add ourselves to the die_notifier list (i.e., ia64die_chain) */
ret = register_die_notifier(&xpc_die_notifier);
if (ret != 0) {
dev_warn(xpc_part, "can't register die notifier\n");
}
/* /*
* Set the beating to other partitions into motion. This is * Set the beating to other partitions into motion. This is
...@@ -1179,6 +1278,9 @@ xpc_init(void) ...@@ -1179,6 +1278,9 @@ xpc_init(void)
/* take ourselves off of the reboot_notifier_list */ /* take ourselves off of the reboot_notifier_list */
(void) unregister_reboot_notifier(&xpc_reboot_notifier); (void) unregister_reboot_notifier(&xpc_reboot_notifier);
/* take ourselves off of the die_notifier list */
(void) unregister_die_notifier(&xpc_die_notifier);
del_timer_sync(&xpc_hb_timer); del_timer_sync(&xpc_hb_timer);
free_irq(SGI_XPC_ACTIVATE, NULL); free_irq(SGI_XPC_ACTIVATE, NULL);
xpc_restrict_IPI_ops(); xpc_restrict_IPI_ops();
......
...@@ -436,13 +436,13 @@ xpc_check_remote_hb(void) ...@@ -436,13 +436,13 @@ xpc_check_remote_hb(void)
} }
dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat" dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat"
" = %ld, kdb_status = %ld, HB_mask = 0x%lx\n", partid, " = %ld, heartbeat_offline = %ld, HB_mask = 0x%lx\n",
remote_vars->heartbeat, part->last_heartbeat, partid, remote_vars->heartbeat, part->last_heartbeat,
remote_vars->kdb_status, remote_vars->heartbeat_offline,
remote_vars->heartbeating_to_mask); remote_vars->heartbeating_to_mask);
if (((remote_vars->heartbeat == part->last_heartbeat) && if (((remote_vars->heartbeat == part->last_heartbeat) &&
(remote_vars->kdb_status == 0)) || (remote_vars->heartbeat_offline == 0)) ||
!xpc_hb_allowed(sn_partition_id, remote_vars)) { !xpc_hb_allowed(sn_partition_id, remote_vars)) {
XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat); XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
......
...@@ -218,7 +218,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, ...@@ -218,7 +218,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
if (i > last) if (i > last)
return 0; return 0;
map = kcalloc(1, sizeof(struct tioce_dmamap), GFP_ATOMIC); map = kzalloc(sizeof(struct tioce_dmamap), GFP_ATOMIC);
if (!map) if (!map)
return 0; return 0;
...@@ -555,7 +555,7 @@ tioce_kern_init(struct tioce_common *tioce_common) ...@@ -555,7 +555,7 @@ tioce_kern_init(struct tioce_common *tioce_common)
struct tioce *tioce_mmr; struct tioce *tioce_mmr;
struct tioce_kernel *tioce_kern; struct tioce_kernel *tioce_kern;
tioce_kern = kcalloc(1, sizeof(struct tioce_kernel), GFP_KERNEL); tioce_kern = kzalloc(sizeof(struct tioce_kernel), GFP_KERNEL);
if (!tioce_kern) { if (!tioce_kern) {
return NULL; return NULL;
} }
...@@ -727,7 +727,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont ...@@ -727,7 +727,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
* Allocate kernel bus soft and copy from prom. * Allocate kernel bus soft and copy from prom.
*/ */
tioce_common = kcalloc(1, sizeof(struct tioce_common), GFP_KERNEL); tioce_common = kzalloc(sizeof(struct tioce_common), GFP_KERNEL);
if (!tioce_common) if (!tioce_common)
return NULL; return NULL;
......
...@@ -61,20 +61,6 @@ struct pci_controller** hose_tail = &hose_head; ...@@ -61,20 +61,6 @@ struct pci_controller** hose_tail = &hose_head;
static int pci_bus_count; static int pci_bus_count;
static void
fixup_rev1_53c810(struct pci_dev* dev)
{
/* rev 1 ncr53c810 chips don't set the class at all which means
* they don't get their resources remapped. Fix that here.
*/
if ((dev->class == PCI_CLASS_NOT_DEFINED)) {
printk("NCR 53c810 rev 1 detected, setting PCI class.\n");
dev->class = PCI_CLASS_STORAGE_SCSI;
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
static void static void
fixup_broken_pcnet32(struct pci_dev* dev) fixup_broken_pcnet32(struct pci_dev* dev)
{ {
......
...@@ -203,6 +203,7 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) ...@@ -203,6 +203,7 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL); acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL);
return find.handle; return find.handle;
} }
EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
/* Get device's handler per its address under its parent */ /* Get device's handler per its address under its parent */
struct acpi_find_child { struct acpi_find_child {
......
...@@ -389,7 +389,6 @@ static struct pci_device_id agp_ali_pci_table[] = { ...@@ -389,7 +389,6 @@ static struct pci_device_id agp_ali_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_ali_pci_table); MODULE_DEVICE_TABLE(pci, agp_ali_pci_table);
static struct pci_driver agp_ali_pci_driver = { static struct pci_driver agp_ali_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-ali", .name = "agpgart-ali",
.id_table = agp_ali_pci_table, .id_table = agp_ali_pci_table,
.probe = agp_ali_probe, .probe = agp_ali_probe,
......
...@@ -515,7 +515,6 @@ static struct pci_device_id agp_amdk7_pci_table[] = { ...@@ -515,7 +515,6 @@ static struct pci_device_id agp_amdk7_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table); MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table);
static struct pci_driver agp_amdk7_pci_driver = { static struct pci_driver agp_amdk7_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-amdk7", .name = "agpgart-amdk7",
.id_table = agp_amdk7_pci_table, .id_table = agp_amdk7_pci_table,
.probe = agp_amdk7_probe, .probe = agp_amdk7_probe,
......
...@@ -703,7 +703,6 @@ static struct pci_device_id agp_amd64_pci_table[] = { ...@@ -703,7 +703,6 @@ static struct pci_device_id agp_amd64_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table); MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);
static struct pci_driver agp_amd64_pci_driver = { static struct pci_driver agp_amd64_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-amd64", .name = "agpgart-amd64",
.id_table = agp_amd64_pci_table, .id_table = agp_amd64_pci_table,
.probe = agp_amd64_probe, .probe = agp_amd64_probe,
......
...@@ -521,7 +521,6 @@ static struct pci_device_id agp_ati_pci_table[] = { ...@@ -521,7 +521,6 @@ static struct pci_device_id agp_ati_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_ati_pci_table); MODULE_DEVICE_TABLE(pci, agp_ati_pci_table);
static struct pci_driver agp_ati_pci_driver = { static struct pci_driver agp_ati_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-ati", .name = "agpgart-ati",
.id_table = agp_ati_pci_table, .id_table = agp_ati_pci_table,
.probe = agp_ati_probe, .probe = agp_ati_probe,
......
...@@ -429,7 +429,6 @@ static struct pci_device_id agp_efficeon_pci_table[] = { ...@@ -429,7 +429,6 @@ static struct pci_device_id agp_efficeon_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_efficeon_pci_table); MODULE_DEVICE_TABLE(pci, agp_efficeon_pci_table);
static struct pci_driver agp_efficeon_pci_driver = { static struct pci_driver agp_efficeon_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-efficeon", .name = "agpgart-efficeon",
.id_table = agp_efficeon_pci_table, .id_table = agp_efficeon_pci_table,
.probe = agp_efficeon_probe, .probe = agp_efficeon_probe,
......
...@@ -622,7 +622,6 @@ static struct pci_device_id agp_intel_i460_pci_table[] = { ...@@ -622,7 +622,6 @@ static struct pci_device_id agp_intel_i460_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_intel_i460_pci_table); MODULE_DEVICE_TABLE(pci, agp_intel_i460_pci_table);
static struct pci_driver agp_intel_i460_pci_driver = { static struct pci_driver agp_intel_i460_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-intel-i460", .name = "agpgart-intel-i460",
.id_table = agp_intel_i460_pci_table, .id_table = agp_intel_i460_pci_table,
.probe = agp_intel_i460_probe, .probe = agp_intel_i460_probe,
......
...@@ -1827,7 +1827,6 @@ static struct pci_device_id agp_intel_pci_table[] = { ...@@ -1827,7 +1827,6 @@ static struct pci_device_id agp_intel_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_intel_pci_table); MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
static struct pci_driver agp_intel_pci_driver = { static struct pci_driver agp_intel_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-intel", .name = "agpgart-intel",
.id_table = agp_intel_pci_table, .id_table = agp_intel_pci_table,
.probe = agp_intel_probe, .probe = agp_intel_probe,
......
...@@ -398,7 +398,6 @@ static struct pci_device_id agp_nvidia_pci_table[] = { ...@@ -398,7 +398,6 @@ static struct pci_device_id agp_nvidia_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_nvidia_pci_table); MODULE_DEVICE_TABLE(pci, agp_nvidia_pci_table);
static struct pci_driver agp_nvidia_pci_driver = { static struct pci_driver agp_nvidia_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-nvidia", .name = "agpgart-nvidia",
.id_table = agp_nvidia_pci_table, .id_table = agp_nvidia_pci_table,
.probe = agp_nvidia_probe, .probe = agp_nvidia_probe,
......
...@@ -332,7 +332,6 @@ static struct pci_device_id agp_sis_pci_table[] = { ...@@ -332,7 +332,6 @@ static struct pci_device_id agp_sis_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_sis_pci_table); MODULE_DEVICE_TABLE(pci, agp_sis_pci_table);
static struct pci_driver agp_sis_pci_driver = { static struct pci_driver agp_sis_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-sis", .name = "agpgart-sis",
.id_table = agp_sis_pci_table, .id_table = agp_sis_pci_table,
.probe = agp_sis_probe, .probe = agp_sis_probe,
......
...@@ -545,7 +545,6 @@ static struct pci_device_id agp_serverworks_pci_table[] = { ...@@ -545,7 +545,6 @@ static struct pci_device_id agp_serverworks_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_serverworks_pci_table); MODULE_DEVICE_TABLE(pci, agp_serverworks_pci_table);
static struct pci_driver agp_serverworks_pci_driver = { static struct pci_driver agp_serverworks_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-serverworks", .name = "agpgart-serverworks",
.id_table = agp_serverworks_pci_table, .id_table = agp_serverworks_pci_table,
.probe = agp_serverworks_probe, .probe = agp_serverworks_probe,
......
...@@ -658,7 +658,6 @@ static struct pci_device_id agp_uninorth_pci_table[] = { ...@@ -658,7 +658,6 @@ static struct pci_device_id agp_uninorth_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agp_uninorth_pci_table); MODULE_DEVICE_TABLE(pci, agp_uninorth_pci_table);
static struct pci_driver agp_uninorth_pci_driver = { static struct pci_driver agp_uninorth_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-uninorth", .name = "agpgart-uninorth",
.id_table = agp_uninorth_pci_table, .id_table = agp_uninorth_pci_table,
.probe = agp_uninorth_probe, .probe = agp_uninorth_probe,
......
...@@ -518,7 +518,6 @@ MODULE_DEVICE_TABLE(pci, agp_via_pci_table); ...@@ -518,7 +518,6 @@ MODULE_DEVICE_TABLE(pci, agp_via_pci_table);
static struct pci_driver agp_via_pci_driver = { static struct pci_driver agp_via_pci_driver = {
.owner = THIS_MODULE,
.name = "agpgart-via", .name = "agpgart-via",
.id_table = agp_via_pci_table, .id_table = agp_via_pci_table,
.probe = agp_via_probe, .probe = agp_via_probe,
......
...@@ -3113,7 +3113,6 @@ MODULE_DEVICE_TABLE(pci, epca_pci_tbl); ...@@ -3113,7 +3113,6 @@ MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
int __init init_PCI (void) int __init init_PCI (void)
{ /* Begin init_PCI */ { /* Begin init_PCI */
memset (&epca_driver, 0, sizeof (epca_driver)); memset (&epca_driver, 0, sizeof (epca_driver));
epca_driver.owner = THIS_MODULE;
epca_driver.name = "epca"; epca_driver.name = "epca";
epca_driver.id_table = epca_pci_tbl; epca_driver.id_table = epca_pci_tbl;
epca_driver.probe = epca_init_one; epca_driver.probe = epca_init_one;
......
...@@ -912,7 +912,6 @@ MODULE_DEVICE_TABLE(pci, synclink_pci_tbl); ...@@ -912,7 +912,6 @@ MODULE_DEVICE_TABLE(pci, synclink_pci_tbl);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static struct pci_driver synclink_pci_driver = { static struct pci_driver synclink_pci_driver = {
.owner = THIS_MODULE,
.name = "synclink", .name = "synclink",
.id_table = synclink_pci_tbl, .id_table = synclink_pci_tbl,
.probe = synclink_init_one, .probe = synclink_init_one,
......
...@@ -500,7 +500,6 @@ MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl); ...@@ -500,7 +500,6 @@ MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static struct pci_driver synclinkmp_pci_driver = { static struct pci_driver synclinkmp_pci_driver = {
.owner = THIS_MODULE,
.name = "synclinkmp", .name = "synclinkmp",
.id_table = synclinkmp_pci_tbl, .id_table = synclinkmp_pci_tbl,
.probe = synclinkmp_init_one, .probe = synclinkmp_init_one,
......
...@@ -755,7 +755,6 @@ static struct pci_device_id pcipcwd_pci_tbl[] = { ...@@ -755,7 +755,6 @@ static struct pci_device_id pcipcwd_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl); MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl);
static struct pci_driver pcipcwd_driver = { static struct pci_driver pcipcwd_driver = {
.owner = THIS_MODULE,
.name = WATCHDOG_NAME, .name = WATCHDOG_NAME,
.id_table = pcipcwd_pci_tbl, .id_table = pcipcwd_pci_tbl,
.probe = pcipcwd_card_init, .probe = pcipcwd_card_init,
......
...@@ -711,7 +711,6 @@ MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl); ...@@ -711,7 +711,6 @@ MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl);
static struct pci_driver wdtpci_driver = { static struct pci_driver wdtpci_driver = {
.owner = THIS_MODULE,
.name = "wdt_pci", .name = "wdt_pci",
.id_table = wdtpci_pci_tbl, .id_table = wdtpci_pci_tbl,
.probe = wdtpci_init_one, .probe = wdtpci_init_one,
......
...@@ -513,7 +513,6 @@ static void __devexit ali1535_remove(struct pci_dev *dev) ...@@ -513,7 +513,6 @@ static void __devexit ali1535_remove(struct pci_dev *dev)
} }
static struct pci_driver ali1535_driver = { static struct pci_driver ali1535_driver = {
.owner = THIS_MODULE,
.name = "ali1535_smbus", .name = "ali1535_smbus",
.id_table = ali1535_ids, .id_table = ali1535_ids,
.probe = ali1535_probe, .probe = ali1535_probe,
......
...@@ -408,7 +408,6 @@ static struct pci_device_id __devinitdata ali1563_id_table[] = { ...@@ -408,7 +408,6 @@ static struct pci_device_id __devinitdata ali1563_id_table[] = {
MODULE_DEVICE_TABLE (pci, ali1563_id_table); MODULE_DEVICE_TABLE (pci, ali1563_id_table);
static struct pci_driver ali1563_pci_driver = { static struct pci_driver ali1563_pci_driver = {
.owner = THIS_MODULE,
.name = "ali1563_smbus", .name = "ali1563_smbus",
.id_table = ali1563_id_table, .id_table = ali1563_id_table,
.probe = ali1563_probe, .probe = ali1563_probe,
......
...@@ -504,7 +504,6 @@ static void __devexit ali15x3_remove(struct pci_dev *dev) ...@@ -504,7 +504,6 @@ static void __devexit ali15x3_remove(struct pci_dev *dev)
} }
static struct pci_driver ali15x3_driver = { static struct pci_driver ali15x3_driver = {
.owner = THIS_MODULE,
.name = "ali15x3_smbus", .name = "ali15x3_smbus",
.id_table = ali15x3_ids, .id_table = ali15x3_ids,
.probe = ali15x3_probe, .probe = ali15x3_probe,
......
...@@ -401,7 +401,6 @@ static void __devexit amd756_remove(struct pci_dev *dev) ...@@ -401,7 +401,6 @@ static void __devexit amd756_remove(struct pci_dev *dev)
} }
static struct pci_driver amd756_driver = { static struct pci_driver amd756_driver = {
.owner = THIS_MODULE,
.name = "amd756_smbus", .name = "amd756_smbus",
.id_table = amd756_ids, .id_table = amd756_ids,
.probe = amd756_probe, .probe = amd756_probe,
......
...@@ -384,7 +384,6 @@ static void __devexit amd8111_remove(struct pci_dev *dev) ...@@ -384,7 +384,6 @@ static void __devexit amd8111_remove(struct pci_dev *dev)
} }
static struct pci_driver amd8111_driver = { static struct pci_driver amd8111_driver = {
.owner = THIS_MODULE,
.name = "amd8111_smbus2", .name = "amd8111_smbus2",
.id_table = amd8111_ids, .id_table = amd8111_ids,
.probe = amd8111_probe, .probe = amd8111_probe,
......
...@@ -155,7 +155,6 @@ static void __devexit hydra_remove(struct pci_dev *dev) ...@@ -155,7 +155,6 @@ static void __devexit hydra_remove(struct pci_dev *dev)
static struct pci_driver hydra_driver = { static struct pci_driver hydra_driver = {
.owner = THIS_MODULE,
.name = "hydra_smbus", .name = "hydra_smbus",
.id_table = hydra_ids, .id_table = hydra_ids,
.probe = hydra_probe, .probe = hydra_probe,
......
...@@ -560,7 +560,6 @@ static void __devexit i801_remove(struct pci_dev *dev) ...@@ -560,7 +560,6 @@ static void __devexit i801_remove(struct pci_dev *dev)
} }
static struct pci_driver i801_driver = { static struct pci_driver i801_driver = {
.owner = THIS_MODULE,
.name = "i801_smbus", .name = "i801_smbus",
.id_table = i801_ids, .id_table = i801_ids,
.probe = i801_probe, .probe = i801_probe,
......
...@@ -233,7 +233,6 @@ static void __devexit i810_remove(struct pci_dev *dev) ...@@ -233,7 +233,6 @@ static void __devexit i810_remove(struct pci_dev *dev)
} }
static struct pci_driver i810_driver = { static struct pci_driver i810_driver = {
.owner = THIS_MODULE,
.name = "i810_smbus", .name = "i810_smbus",
.id_table = i810_ids, .id_table = i810_ids,
.probe = i810_probe, .probe = i810_probe,
......
...@@ -347,7 +347,6 @@ static void __devexit nforce2_remove(struct pci_dev *dev) ...@@ -347,7 +347,6 @@ static void __devexit nforce2_remove(struct pci_dev *dev)
} }
static struct pci_driver nforce2_driver = { static struct pci_driver nforce2_driver = {
.owner = THIS_MODULE,
.name = "nForce2_smbus", .name = "nForce2_smbus",
.id_table = nforce2_ids, .id_table = nforce2_ids,
.probe = nforce2_probe, .probe = nforce2_probe,
......
...@@ -462,7 +462,6 @@ static void __devexit piix4_remove(struct pci_dev *dev) ...@@ -462,7 +462,6 @@ static void __devexit piix4_remove(struct pci_dev *dev)
} }
static struct pci_driver piix4_driver = { static struct pci_driver piix4_driver = {
.owner = THIS_MODULE,
.name = "piix4_smbus", .name = "piix4_smbus",
.id_table = piix4_ids, .id_table = piix4_ids,
.probe = piix4_probe, .probe = piix4_probe,
......
...@@ -301,7 +301,6 @@ static struct pci_device_id prosavage_pci_tbl[] = { ...@@ -301,7 +301,6 @@ static struct pci_device_id prosavage_pci_tbl[] = {
MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl); MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl);
static struct pci_driver prosavage_driver = { static struct pci_driver prosavage_driver = {
.owner = THIS_MODULE,
.name = "prosavage_smbus", .name = "prosavage_smbus",
.id_table = prosavage_pci_tbl, .id_table = prosavage_pci_tbl,
.probe = prosavage_probe, .probe = prosavage_probe,
......
...@@ -179,7 +179,6 @@ static void __devexit savage4_remove(struct pci_dev *dev) ...@@ -179,7 +179,6 @@ static void __devexit savage4_remove(struct pci_dev *dev)
} }
static struct pci_driver savage4_driver = { static struct pci_driver savage4_driver = {
.owner = THIS_MODULE,
.name = "savage4_smbus", .name = "savage4_smbus",
.id_table = savage4_ids, .id_table = savage4_ids,
.probe = savage4_probe, .probe = savage4_probe,
......
...@@ -398,7 +398,6 @@ static void __devexit sis5595_remove(struct pci_dev *dev) ...@@ -398,7 +398,6 @@ static void __devexit sis5595_remove(struct pci_dev *dev)
} }
static struct pci_driver sis5595_driver = { static struct pci_driver sis5595_driver = {
.owner = THIS_MODULE,
.name = "sis5595_smbus", .name = "sis5595_smbus",
.id_table = sis5595_ids, .id_table = sis5595_ids,
.probe = sis5595_probe, .probe = sis5595_probe,
......
...@@ -496,7 +496,6 @@ static void __devexit sis630_remove(struct pci_dev *dev) ...@@ -496,7 +496,6 @@ static void __devexit sis630_remove(struct pci_dev *dev)
static struct pci_driver sis630_driver = { static struct pci_driver sis630_driver = {
.owner = THIS_MODULE,
.name = "sis630_smbus", .name = "sis630_smbus",
.id_table = sis630_ids, .id_table = sis630_ids,
.probe = sis630_probe, .probe = sis630_probe,
......
...@@ -329,7 +329,6 @@ static void __devexit sis96x_remove(struct pci_dev *dev) ...@@ -329,7 +329,6 @@ static void __devexit sis96x_remove(struct pci_dev *dev)
} }
static struct pci_driver sis96x_driver = { static struct pci_driver sis96x_driver = {
.owner = THIS_MODULE,
.name = "sis96x_smbus", .name = "sis96x_smbus",
.id_table = sis96x_ids, .id_table = sis96x_ids,
.probe = sis96x_probe, .probe = sis96x_probe,
......
...@@ -159,7 +159,6 @@ static void __devexit vt586b_remove(struct pci_dev *dev) ...@@ -159,7 +159,6 @@ static void __devexit vt586b_remove(struct pci_dev *dev)
static struct pci_driver vt586b_driver = { static struct pci_driver vt586b_driver = {
.owner = THIS_MODULE,
.name = "vt586b_smbus", .name = "vt586b_smbus",
.id_table = vt586b_ids, .id_table = vt586b_ids,
.probe = vt586b_probe, .probe = vt586b_probe,
......
...@@ -440,7 +440,6 @@ static struct pci_device_id vt596_ids[] = { ...@@ -440,7 +440,6 @@ static struct pci_device_id vt596_ids[] = {
MODULE_DEVICE_TABLE(pci, vt596_ids); MODULE_DEVICE_TABLE(pci, vt596_ids);
static struct pci_driver vt596_driver = { static struct pci_driver vt596_driver = {
.owner = THIS_MODULE,
.name = "vt596_smbus", .name = "vt596_smbus",
.id_table = vt596_ids, .id_table = vt596_ids,
.probe = vt596_probe, .probe = vt596_probe,
......
...@@ -225,7 +225,6 @@ static void __devexit voodoo3_remove(struct pci_dev *dev) ...@@ -225,7 +225,6 @@ static void __devexit voodoo3_remove(struct pci_dev *dev)
} }
static struct pci_driver voodoo3_driver = { static struct pci_driver voodoo3_driver = {
.owner = THIS_MODULE,
.name = "voodoo3_smbus", .name = "voodoo3_smbus",
.id_table = voodoo3_ids, .id_table = voodoo3_ids,
.probe = voodoo3_probe, .probe = voodoo3_probe,
......
...@@ -787,8 +787,9 @@ static int pre_init = 1; /* Before first ordered IDE scan */ ...@@ -787,8 +787,9 @@ static int pre_init = 1; /* Before first ordered IDE scan */
static LIST_HEAD(ide_pci_drivers); static LIST_HEAD(ide_pci_drivers);
/* /*
* ide_register_pci_driver - attach IDE driver * __ide_register_pci_driver - attach IDE driver
* @driver: pci driver * @driver: pci driver
* @module: owner module of the driver
* *
* Registers a driver with the IDE layer. The IDE layer arranges that * Registers a driver with the IDE layer. The IDE layer arranges that
* boot time setup is done in the expected device order and then * boot time setup is done in the expected device order and then
...@@ -801,15 +802,16 @@ static LIST_HEAD(ide_pci_drivers); ...@@ -801,15 +802,16 @@ static LIST_HEAD(ide_pci_drivers);
* Returns are the same as for pci_register_driver * Returns are the same as for pci_register_driver
*/ */
int ide_pci_register_driver(struct pci_driver *driver) int __ide_pci_register_driver(struct pci_driver *driver, struct module *module)
{ {
if(!pre_init) if(!pre_init)
return pci_module_init(driver); return __pci_register_driver(driver, module);
driver->driver.owner = module;
list_add_tail(&driver->node, &ide_pci_drivers); list_add_tail(&driver->node, &ide_pci_drivers);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ide_pci_register_driver); EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
/** /**
* ide_unregister_pci_driver - unregister an IDE driver * ide_unregister_pci_driver - unregister an IDE driver
...@@ -897,6 +899,6 @@ void __init ide_scan_pcibus (int scan_direction) ...@@ -897,6 +899,6 @@ void __init ide_scan_pcibus (int scan_direction)
{ {
list_del(l); list_del(l);
d = list_entry(l, struct pci_driver, node); d = list_entry(l, struct pci_driver, node);
pci_register_driver(d); __pci_register_driver(d, d->driver.owner);
} }
} }
...@@ -1198,7 +1198,6 @@ MODULE_DEVICE_TABLE(pci, mthca_pci_table); ...@@ -1198,7 +1198,6 @@ MODULE_DEVICE_TABLE(pci, mthca_pci_table);
static struct pci_driver mthca_driver = { static struct pci_driver mthca_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.owner = THIS_MODULE,
.id_table = mthca_pci_table, .id_table = mthca_pci_table,
.probe = mthca_init_one, .probe = mthca_init_one,
.remove = __devexit_p(mthca_remove_one) .remove = __devexit_p(mthca_remove_one)
......
...@@ -2290,7 +2290,6 @@ spider_net_remove(struct pci_dev *pdev) ...@@ -2290,7 +2290,6 @@ spider_net_remove(struct pci_dev *pdev)
} }
static struct pci_driver spider_net_driver = { static struct pci_driver spider_net_driver = {
.owner = THIS_MODULE,
.name = spider_net_driver_name, .name = spider_net_driver_name,
.id_table = spider_net_pci_tbl, .id_table = spider_net_pci_tbl,
.probe = spider_net_probe, .probe = spider_net_probe,
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include "pci.h"
/* /*
* This interrupt-safe spinlock protects all accesses to PCI * This interrupt-safe spinlock protects all accesses to PCI
* configuration space. * configuration space.
......
...@@ -32,8 +32,6 @@ ...@@ -32,8 +32,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <asm/semaphore.h>
#include <asm/io.h>
#include <linux/pcieport_if.h> #include <linux/pcieport_if.h>
#include "pci_hotplug.h" #include "pci_hotplug.h"
...@@ -42,6 +40,7 @@ ...@@ -42,6 +40,7 @@
extern int pciehp_poll_mode; extern int pciehp_poll_mode;
extern int pciehp_poll_time; extern int pciehp_poll_time;
extern int pciehp_debug; extern int pciehp_debug;
extern int pciehp_force;
/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ /*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) #define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
...@@ -49,39 +48,20 @@ extern int pciehp_debug; ...@@ -49,39 +48,20 @@ extern int pciehp_debug;
#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
struct pci_func { struct hotplug_params {
struct pci_func *next; u8 cache_line_size;
u8 bus; u8 latency_timer;
u8 device; u8 enable_serr;
u8 function; u8 enable_perr;
u8 is_a_board;
u16 status;
u8 configured;
u8 switch_save;
u8 presence_save;
u32 base_length[0x06];
u8 base_type[0x06];
u16 reserved2;
u32 config_space[0x20];
struct pci_resource *mem_head;
struct pci_resource *p_mem_head;
struct pci_resource *io_head;
struct pci_resource *bus_head;
struct pci_dev* pci_dev;
}; };
struct slot { struct slot {
struct slot *next; struct slot *next;
u8 bus; u8 bus;
u8 device; u8 device;
u16 status;
u32 number; u32 number;
u8 is_a_board;
u8 configured;
u8 state; u8 state;
u8 switch_save;
u8 presence_save;
u32 capabilities;
u16 reserved2;
struct timer_list task_event; struct timer_list task_event;
u8 hp_slot; u8 hp_slot;
struct controller *ctrl; struct controller *ctrl;
...@@ -90,42 +70,47 @@ struct slot { ...@@ -90,42 +70,47 @@ struct slot {
struct list_head slot_list; struct list_head slot_list;
}; };
struct pci_resource {
struct pci_resource * next;
u32 base;
u32 length;
};
struct event_info { struct event_info {
u32 event_type; u32 event_type;
u8 hp_slot; u8 hp_slot;
}; };
typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
struct php_ctlr_state_s {
struct php_ctlr_state_s *pnext;
struct pci_dev *pci_dev;
unsigned int irq;
unsigned long flags; /* spinlock's */
u32 slot_device_offset;
u32 num_slots;
struct timer_list int_poll_timer; /* Added for poll event */
php_intr_callback_t attention_button_callback;
php_intr_callback_t switch_change_callback;
php_intr_callback_t presence_change_callback;
php_intr_callback_t power_fault_callback;
void *callback_instance_id;
struct ctrl_reg *creg; /* Ptr to controller register space */
};
#define MAX_EVENTS 10
struct controller { struct controller {
struct controller *next; struct controller *next;
struct semaphore crit_sect; /* critical section semaphore */ struct semaphore crit_sect; /* critical section semaphore */
void *hpc_ctlr_handle; /* HPC controller handle */ struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
int num_slots; /* Number of slots on ctlr */ int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */ int slot_num_inc; /* 1 or -1 */
struct pci_resource *mem_head;
struct pci_resource *p_mem_head;
struct pci_resource *io_head;
struct pci_resource *bus_head;
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
struct pci_bus *pci_bus; struct pci_bus *pci_bus;
struct event_info event_queue[10]; struct event_info event_queue[MAX_EVENTS];
struct slot *slot; struct slot *slot;
struct hpc_ops *hpc_ops; struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */ wait_queue_head_t queue; /* sleep & wake process */
u8 next_event; u8 next_event;
u8 seg;
u8 bus; u8 bus;
u8 device; u8 device;
u8 function; u8 function;
u8 rev;
u8 slot_device_offset; u8 slot_device_offset;
u8 add_support;
enum pci_bus_speed speed;
u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */ u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */
u8 slot_bus; /* Bus where the slots handled by this controller sit */ u8 slot_bus; /* Bus where the slots handled by this controller sit */
u8 ctrlcap; u8 ctrlcap;
...@@ -133,20 +118,6 @@ struct controller { ...@@ -133,20 +118,6 @@ struct controller {
u8 cap_base; u8 cap_base;
}; };
struct irq_mapping {
u8 barber_pole;
u8 valid_INT;
u8 interrupt[4];
};
struct resource_lists {
struct pci_resource *mem_head;
struct pci_resource *p_mem_head;
struct pci_resource *io_head;
struct pci_resource *bus_head;
struct irq_mapping *irqs;
};
#define INT_BUTTON_IGNORE 0 #define INT_BUTTON_IGNORE 0
#define INT_PRESENCE_ON 1 #define INT_PRESENCE_ON 1
#define INT_PRESENCE_OFF 2 #define INT_PRESENCE_OFF 2
...@@ -200,21 +171,14 @@ struct resource_lists { ...@@ -200,21 +171,14 @@ struct resource_lists {
* error Messages * error Messages
*/ */
#define msg_initialization_err "Initialization failure, error=%d\n" #define msg_initialization_err "Initialization failure, error=%d\n"
#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
#define msg_HPC_non_pcie "The PCI hot plug controller is not supported by this driver.\n"
#define msg_HPC_not_supported "This system is not supported by this version of pciephd module. Upgrade to a newer version of pciehpd\n"
#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
#define msg_button_on "PCI slot #%d - powering on due to button press.\n" #define msg_button_on "PCI slot #%d - powering on due to button press.\n"
#define msg_button_off "PCI slot #%d - powering off due to button press.\n" #define msg_button_off "PCI slot #%d - powering off due to button press.\n"
#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" #define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n" #define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
/* controller functions */ /* controller functions */
extern int pciehprm_find_available_resources (struct controller *ctrl);
extern int pciehp_event_start_thread (void); extern int pciehp_event_start_thread (void);
extern void pciehp_event_stop_thread (void); extern void pciehp_event_stop_thread (void);
extern struct pci_func *pciehp_slot_create (unsigned char busnumber);
extern struct pci_func *pciehp_slot_find (unsigned char bus, unsigned char device, unsigned char index);
extern int pciehp_enable_slot (struct slot *slot); extern int pciehp_enable_slot (struct slot *slot);
extern int pciehp_disable_slot (struct slot *slot); extern int pciehp_disable_slot (struct slot *slot);
...@@ -224,25 +188,17 @@ extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id); ...@@ -224,25 +188,17 @@ extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id);
extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id); extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id);
/* extern void long_delay (int delay); */ /* extern void long_delay (int delay); */
/* resource functions */
extern int pciehp_resource_sort_and_combine (struct pci_resource **head);
/* pci functions */ /* pci functions */
extern int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); extern int pciehp_configure_device (struct slot *p_slot);
/*extern int pciehp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/ extern int pciehp_unconfigure_device (struct slot *p_slot);
extern int pciehp_save_config (struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num); extern int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev);
extern int pciehp_save_used_resources (struct controller *ctrl, struct pci_func * func, int flag); extern void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
extern int pciehp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot); struct hotplug_params *hpp);
extern void pciehp_destroy_board_resources (struct pci_func * func);
extern int pciehp_return_board_resources (struct pci_func * func, struct resource_lists * resources);
extern void pciehp_destroy_resource_list (struct resource_lists * resources);
extern int pciehp_configure_device (struct controller* ctrl, struct pci_func* func);
extern int pciehp_unconfigure_device (struct pci_func* func);
/* Global variables */ /* Global variables */
extern struct controller *pciehp_ctrl_list; extern struct controller *pciehp_ctrl_list;
extern struct pci_func *pciehp_slot_list[256];
/* Inline functions */ /* Inline functions */
...@@ -252,12 +208,9 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) ...@@ -252,12 +208,9 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
p_slot = ctrl->slot; p_slot = ctrl->slot;
dbg("p_slot = %p\n", p_slot);
while (p_slot && (p_slot->device != device)) { while (p_slot && (p_slot->device != device)) {
tmp_slot = p_slot; tmp_slot = p_slot;
p_slot = p_slot->next; p_slot = p_slot->next;
dbg("In while loop, p_slot = %p\n", p_slot);
} }
if (p_slot == NULL) { if (p_slot == NULL) {
err("ERROR: pciehp_find_slot device=0x%x\n", device); err("ERROR: pciehp_find_slot device=0x%x\n", device);
...@@ -273,7 +226,6 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl) ...@@ -273,7 +226,6 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
dbg("%s : start\n", __FUNCTION__);
add_wait_queue(&ctrl->queue, &wait); add_wait_queue(&ctrl->queue, &wait);
if (!pciehp_poll_mode) if (!pciehp_poll_mode)
/* Sleep for up to 1 second */ /* Sleep for up to 1 second */
...@@ -285,19 +237,9 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl) ...@@ -285,19 +237,9 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
if (signal_pending(current)) if (signal_pending(current))
retval = -EINTR; retval = -EINTR;
dbg("%s : end\n", __FUNCTION__);
return retval; return retval;
} }
/* Puts node back in the resource list pointed to by head */
static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
{
if (!node || !head)
return;
node->next = *head;
*head = node;
}
#define SLOT_NAME_SIZE 10 #define SLOT_NAME_SIZE 10
static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
...@@ -311,14 +253,7 @@ enum php_ctlr_type { ...@@ -311,14 +253,7 @@ enum php_ctlr_type {
ACPI ACPI
}; };
typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id); int pcie_init(struct controller *ctrl, struct pcie_device *dev);
int pcie_init(struct controller *ctrl, struct pcie_device *dev,
php_intr_callback_t attention_button_callback,
php_intr_callback_t switch_change_callback,
php_intr_callback_t presence_change_callback,
php_intr_callback_t power_fault_callback);
/* This has no meaning for PCI Express, as there is only 1 slot per port */ /* This has no meaning for PCI Express, as there is only 1 slot per port */
int pcie_get_ctlr_slot_config(struct controller *ctrl, int pcie_get_ctlr_slot_config(struct controller *ctrl,
......
...@@ -27,27 +27,20 @@ ...@@ -27,27 +27,20 @@
* *
*/ */
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include "pciehp.h" #include "pciehp.h"
#include "pciehprm.h"
#include <linux/interrupt.h> #include <linux/interrupt.h>
/* Global variables */ /* Global variables */
int pciehp_debug; int pciehp_debug;
int pciehp_poll_mode; int pciehp_poll_mode;
int pciehp_poll_time; int pciehp_poll_time;
int pciehp_force;
struct controller *pciehp_ctrl_list; struct controller *pciehp_ctrl_list;
struct pci_func *pciehp_slot_list[256];
#define DRIVER_VERSION "0.4" #define DRIVER_VERSION "0.4"
#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
...@@ -60,9 +53,11 @@ MODULE_LICENSE("GPL"); ...@@ -60,9 +53,11 @@ MODULE_LICENSE("GPL");
module_param(pciehp_debug, bool, 0644); module_param(pciehp_debug, bool, 0644);
module_param(pciehp_poll_mode, bool, 0644); module_param(pciehp_poll_mode, bool, 0644);
module_param(pciehp_poll_time, int, 0644); module_param(pciehp_poll_time, int, 0644);
module_param(pciehp_force, bool, 0644);
MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing");
#define PCIE_MODULE_NAME "pciehp" #define PCIE_MODULE_NAME "pciehp"
...@@ -114,8 +109,6 @@ static int init_slots(struct controller *ctrl) ...@@ -114,8 +109,6 @@ static int init_slots(struct controller *ctrl)
u32 slot_number; u32 slot_number;
int result = -ENOMEM; int result = -ENOMEM;
dbg("%s\n",__FUNCTION__);
number_of_slots = ctrl->num_slots; number_of_slots = ctrl->num_slots;
slot_device = ctrl->slot_device_offset; slot_device = ctrl->slot_device_offset;
slot_number = ctrl->first_slot; slot_number = ctrl->first_slot;
...@@ -370,7 +363,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ ...@@ -370,7 +363,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
u8 value; u8 value;
struct pci_dev *pdev; struct pci_dev *pdev;
dbg("%s: Called by hp_drv\n", __FUNCTION__);
ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL); ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl) { if (!ctrl) {
err("%s : out of memory\n", __FUNCTION__); err("%s : out of memory\n", __FUNCTION__);
...@@ -378,22 +370,15 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ ...@@ -378,22 +370,15 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
} }
memset(ctrl, 0, sizeof(struct controller)); memset(ctrl, 0, sizeof(struct controller));
dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid);
pdev = dev->port; pdev = dev->port;
ctrl->pci_dev = pdev;
rc = pcie_init(ctrl, dev, rc = pcie_init(ctrl, dev);
(php_intr_callback_t) pciehp_handle_attention_button,
(php_intr_callback_t) pciehp_handle_switch_change,
(php_intr_callback_t) pciehp_handle_presence_change,
(php_intr_callback_t) pciehp_handle_power_fault);
if (rc) { if (rc) {
dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME); dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME);
goto err_out_free_ctrl; goto err_out_free_ctrl;
} }
ctrl->pci_dev = pdev;
pci_set_drvdata(pdev, ctrl); pci_set_drvdata(pdev, ctrl);
ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
...@@ -402,7 +387,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ ...@@ -402,7 +387,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
rc = -ENOMEM; rc = -ENOMEM;
goto err_out_unmap_mmio_region; goto err_out_unmap_mmio_region;
} }
dbg("%s: ctrl->pci_bus %p\n", __FUNCTION__, ctrl->pci_bus);
memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus)); memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
ctrl->bus = pdev->bus->number; /* ctrl bus */ ctrl->bus = pdev->bus->number; /* ctrl bus */
ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */ ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */
...@@ -424,25 +408,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ ...@@ -424,25 +408,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
first_device_num = ctrl->slot_device_offset; first_device_num = ctrl->slot_device_offset;
num_ctlr_slots = ctrl->num_slots; num_ctlr_slots = ctrl->num_slots;
/* Store PCI Config Space for all devices on this bus */
dbg("%s: Before calling pciehp_save_config, ctrl->bus %x,ctrl->slot_bus %x\n",
__FUNCTION__,ctrl->bus, ctrl->slot_bus);
rc = pciehp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num);
if (rc) {
err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
goto err_out_free_ctrl_bus;
}
/* Get IO, memory, and IRQ resources for new devices */
rc = pciehprm_find_available_resources(ctrl);
ctrl->add_support = !rc;
if (rc) {
dbg("pciehprm_find_available_resources = %#x\n", rc);
err("unable to locate PCI configuration resources for hot plug add.\n");
goto err_out_free_ctrl_bus;
}
/* Setup the slot information structures */ /* Setup the slot information structures */
rc = init_slots(ctrl); rc = init_slots(ctrl);
if (rc) { if (rc) {
...@@ -451,7 +416,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ ...@@ -451,7 +416,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
} }
t_slot = pciehp_find_slot(ctrl, first_device_num); t_slot = pciehp_find_slot(ctrl, first_device_num);
dbg("%s: t_slot %p\n", __FUNCTION__, t_slot);
/* Finish setting up the hot plug ctrl device */ /* Finish setting up the hot plug ctrl device */
ctrl->next_event = 0; ctrl->next_event = 0;
...@@ -468,7 +432,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ ...@@ -468,7 +432,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
down(&ctrl->crit_sect); down(&ctrl->crit_sect);
t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
dbg("%s: adpater value %x\n", __FUNCTION__, value);
if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
...@@ -501,7 +464,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ ...@@ -501,7 +464,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
static int pcie_start_thread(void) static int pcie_start_thread(void)
{ {
int loop;
int retval = 0; int retval = 0;
dbg("Initialize + Start the notification/polling mechanism \n"); dbg("Initialize + Start the notification/polling mechanism \n");
...@@ -512,32 +474,11 @@ static int pcie_start_thread(void) ...@@ -512,32 +474,11 @@ static int pcie_start_thread(void)
return retval; return retval;
} }
dbg("Initialize slot lists\n");
/* One slot list for each bus in the system */
for (loop = 0; loop < 256; loop++) {
pciehp_slot_list[loop] = NULL;
}
return retval; return retval;
} }
static inline void __exit
free_pciehp_res(struct pci_resource *res)
{
struct pci_resource *tres;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
}
static void __exit unload_pciehpd(void) static void __exit unload_pciehpd(void)
{ {
struct pci_func *next;
struct pci_func *TempSlot;
int loop;
struct controller *ctrl; struct controller *ctrl;
struct controller *tctrl; struct controller *tctrl;
...@@ -546,11 +487,6 @@ static void __exit unload_pciehpd(void) ...@@ -546,11 +487,6 @@ static void __exit unload_pciehpd(void)
while (ctrl) { while (ctrl) {
cleanup_slots(ctrl); cleanup_slots(ctrl);
free_pciehp_res(ctrl->io_head);
free_pciehp_res(ctrl->mem_head);
free_pciehp_res(ctrl->p_mem_head);
free_pciehp_res(ctrl->bus_head);
kfree (ctrl->pci_bus); kfree (ctrl->pci_bus);
ctrl->hpc_ops->release_ctlr(ctrl); ctrl->hpc_ops->release_ctlr(ctrl);
...@@ -561,20 +497,6 @@ static void __exit unload_pciehpd(void) ...@@ -561,20 +497,6 @@ static void __exit unload_pciehpd(void)
kfree(tctrl); kfree(tctrl);
} }
for (loop = 0; loop < 256; loop++) {
next = pciehp_slot_list[loop];
while (next != NULL) {
free_pciehp_res(next->io_head);
free_pciehp_res(next->mem_head);
free_pciehp_res(next->p_mem_head);
free_pciehp_res(next->bus_head);
TempSlot = next;
next = next->next;
kfree(TempSlot);
}
}
/* Stop the notification mechanism */ /* Stop the notification mechanism */
pciehp_event_stop_thread(); pciehp_event_stop_thread();
...@@ -639,21 +561,16 @@ static int __init pcied_init(void) ...@@ -639,21 +561,16 @@ static int __init pcied_init(void)
if (retval) if (retval)
goto error_hpc_init; goto error_hpc_init;
retval = pciehprm_init(PCI); retval = pcie_port_service_register(&hpdriver_portdrv);
if (!retval) { dbg("pcie_port_service_register = %d\n", retval);
retval = pcie_port_service_register(&hpdriver_portdrv); info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
dbg("pcie_port_service_register = %d\n", retval); if (retval)
info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); dbg("%s: Failure to register service\n", __FUNCTION__);
if (retval)
dbg("%s: Failure to register service\n", __FUNCTION__);
}
error_hpc_init: error_hpc_init:
if (retval) { if (retval) {
pciehprm_cleanup();
pciehp_event_stop_thread(); pciehp_event_stop_thread();
} else };
pciehprm_print_pirt();
return retval; return retval;
} }
...@@ -663,9 +580,6 @@ static void __exit pcied_cleanup(void) ...@@ -663,9 +580,6 @@ static void __exit pcied_cleanup(void)
dbg("unload_pciehpd()\n"); dbg("unload_pciehpd()\n");
unload_pciehpd(); unload_pciehpd();
pciehprm_cleanup();
dbg("pcie_port_service_unregister\n");
pcie_port_service_unregister(&hpdriver_portdrv); pcie_port_service_unregister(&hpdriver_portdrv);
info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
......
此差异已折叠。
...@@ -27,16 +27,10 @@ ...@@ -27,16 +27,10 @@
* *
*/ */
#include <linux/config.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/system.h>
#include "../pci.h" #include "../pci.h"
#include "pciehp.h" #include "pciehp.h"
...@@ -217,23 +211,6 @@ static int pcie_cap_base = 0; /* Base of the PCI Express capability item struct ...@@ -217,23 +211,6 @@ static int pcie_cap_base = 0; /* Base of the PCI Express capability item struct
#define MRL_STATE 0x0020 #define MRL_STATE 0x0020
#define PRSN_STATE 0x0040 #define PRSN_STATE 0x0040
struct php_ctlr_state_s {
struct php_ctlr_state_s *pnext;
struct pci_dev *pci_dev;
unsigned int irq;
unsigned long flags; /* spinlock's */
u32 slot_device_offset;
u32 num_slots;
struct timer_list int_poll_timer; /* Added for poll event */
php_intr_callback_t attention_button_callback;
php_intr_callback_t switch_change_callback;
php_intr_callback_t presence_change_callback;
php_intr_callback_t power_fault_callback;
void *callback_instance_id;
struct ctrl_reg *creg; /* Ptr to controller register space */
};
static spinlock_t hpc_event_lock; static spinlock_t hpc_event_lock;
DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
...@@ -297,7 +274,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) ...@@ -297,7 +274,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
DBG_ENTER_ROUTINE DBG_ENTER_ROUTINE
dbg("%s : Enter\n", __FUNCTION__);
if (!php_ctlr) { if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__); err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1; return -1;
...@@ -308,7 +284,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) ...@@ -308,7 +284,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return retval; return retval;
} }
dbg("%s : hp_register_read_word SLOT_STATUS %x\n", __FUNCTION__, slot_status);
if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) {
/* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue
...@@ -316,14 +291,11 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) ...@@ -316,14 +291,11 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__); dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
} }
dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE); retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE);
if (retval) { if (retval) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; return retval;
} }
dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd | CMD_CMPL_INTR_ENABLE);
dbg("%s : Exit\n", __FUNCTION__);
DBG_LEAVE_ROUTINE DBG_LEAVE_ROUTINE
return retval; return retval;
...@@ -509,7 +481,6 @@ static int hpc_query_power_fault(struct slot * slot) ...@@ -509,7 +481,6 @@ static int hpc_query_power_fault(struct slot * slot)
u16 slot_status; u16 slot_status;
u8 pwr_fault; u8 pwr_fault;
int retval = 0; int retval = 0;
u8 status;
DBG_ENTER_ROUTINE DBG_ENTER_ROUTINE
...@@ -521,15 +492,13 @@ static int hpc_query_power_fault(struct slot * slot) ...@@ -521,15 +492,13 @@ static int hpc_query_power_fault(struct slot * slot)
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
if (retval) { if (retval) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : Cannot check for power fault\n", __FUNCTION__);
return retval; return retval;
} }
pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
status = (pwr_fault != 1) ? 1 : 0;
DBG_LEAVE_ROUTINE DBG_LEAVE_ROUTINE
/* Note: Logic 0 => fault */ return pwr_fault;
return status;
} }
static int hpc_set_attention_status(struct slot *slot, u8 value) static int hpc_set_attention_status(struct slot *slot, u8 value)
...@@ -539,7 +508,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) ...@@ -539,7 +508,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
u16 slot_ctrl; u16 slot_ctrl;
int rc = 0; int rc = 0;
dbg("%s: \n", __FUNCTION__); DBG_ENTER_ROUTINE
if (!php_ctlr) { if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__); err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1; return -1;
...@@ -555,7 +525,6 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) ...@@ -555,7 +525,6 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return rc; return rc;
} }
dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
switch (value) { switch (value) {
case 0 : /* turn off */ case 0 : /* turn off */
...@@ -576,6 +545,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) ...@@ -576,6 +545,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
pcie_write_cmd(slot, slot_cmd); pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
DBG_LEAVE_ROUTINE
return rc; return rc;
} }
...@@ -587,7 +557,8 @@ static void hpc_set_green_led_on(struct slot *slot) ...@@ -587,7 +557,8 @@ static void hpc_set_green_led_on(struct slot *slot)
u16 slot_ctrl; u16 slot_ctrl;
int rc = 0; int rc = 0;
dbg("%s: \n", __FUNCTION__); DBG_ENTER_ROUTINE
if (!php_ctlr) { if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__); err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ; return ;
...@@ -604,7 +575,6 @@ static void hpc_set_green_led_on(struct slot *slot) ...@@ -604,7 +575,6 @@ static void hpc_set_green_led_on(struct slot *slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return; return;
} }
dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100; slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100;
if (!pciehp_poll_mode) if (!pciehp_poll_mode)
slot_cmd = slot_cmd | HP_INTR_ENABLE; slot_cmd = slot_cmd | HP_INTR_ENABLE;
...@@ -612,6 +582,7 @@ static void hpc_set_green_led_on(struct slot *slot) ...@@ -612,6 +582,7 @@ static void hpc_set_green_led_on(struct slot *slot)
pcie_write_cmd(slot, slot_cmd); pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
DBG_LEAVE_ROUTINE
return; return;
} }
...@@ -622,7 +593,8 @@ static void hpc_set_green_led_off(struct slot *slot) ...@@ -622,7 +593,8 @@ static void hpc_set_green_led_off(struct slot *slot)
u16 slot_ctrl; u16 slot_ctrl;
int rc = 0; int rc = 0;
dbg("%s: \n", __FUNCTION__); DBG_ENTER_ROUTINE
if (!php_ctlr) { if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__); err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ; return ;
...@@ -639,7 +611,6 @@ static void hpc_set_green_led_off(struct slot *slot) ...@@ -639,7 +611,6 @@ static void hpc_set_green_led_off(struct slot *slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return; return;
} }
dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300; slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300;
...@@ -648,6 +619,7 @@ static void hpc_set_green_led_off(struct slot *slot) ...@@ -648,6 +619,7 @@ static void hpc_set_green_led_off(struct slot *slot)
pcie_write_cmd(slot, slot_cmd); pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
DBG_LEAVE_ROUTINE
return; return;
} }
...@@ -658,7 +630,8 @@ static void hpc_set_green_led_blink(struct slot *slot) ...@@ -658,7 +630,8 @@ static void hpc_set_green_led_blink(struct slot *slot)
u16 slot_ctrl; u16 slot_ctrl;
int rc = 0; int rc = 0;
dbg("%s: \n", __FUNCTION__); DBG_ENTER_ROUTINE
if (!php_ctlr) { if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__); err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ; return ;
...@@ -675,7 +648,6 @@ static void hpc_set_green_led_blink(struct slot *slot) ...@@ -675,7 +648,6 @@ static void hpc_set_green_led_blink(struct slot *slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return; return;
} }
dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200; slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200;
...@@ -684,6 +656,7 @@ static void hpc_set_green_led_blink(struct slot *slot) ...@@ -684,6 +656,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
pcie_write_cmd(slot, slot_cmd); pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
DBG_LEAVE_ROUTINE
return; return;
} }
...@@ -780,7 +753,6 @@ static int hpc_power_on_slot(struct slot * slot) ...@@ -780,7 +753,6 @@ static int hpc_power_on_slot(struct slot * slot)
int retval = 0; int retval = 0;
DBG_ENTER_ROUTINE DBG_ENTER_ROUTINE
dbg("%s: \n", __FUNCTION__);
if (!php_ctlr) { if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__); err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
...@@ -799,8 +771,6 @@ static int hpc_power_on_slot(struct slot * slot) ...@@ -799,8 +771,6 @@ static int hpc_power_on_slot(struct slot * slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; return retval;
} }
dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
...@@ -829,7 +799,6 @@ static int hpc_power_off_slot(struct slot * slot) ...@@ -829,7 +799,6 @@ static int hpc_power_off_slot(struct slot * slot)
int retval = 0; int retval = 0;
DBG_ENTER_ROUTINE DBG_ENTER_ROUTINE
dbg("%s: \n", __FUNCTION__);
if (!php_ctlr) { if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__); err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
...@@ -848,8 +817,6 @@ static int hpc_power_off_slot(struct slot * slot) ...@@ -848,8 +817,6 @@ static int hpc_power_off_slot(struct slot * slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; return retval;
} }
dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
...@@ -924,7 +891,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -924,7 +891,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
return IRQ_NONE; return IRQ_NONE;
} }
dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__);
dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
...@@ -933,7 +899,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -933,7 +899,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
} }
dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) { if (rc) {
...@@ -949,14 +914,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -949,14 +914,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
} }
dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
} }
if (intr_loc & CMD_COMPLETED) { if (intr_loc & CMD_COMPLETED) {
/* /*
* Command Complete Interrupt Pending * Command Complete Interrupt Pending
*/ */
dbg("%s: In Command Complete Interrupt Pending\n", __FUNCTION__);
wake_up_interruptible(&ctrl->queue); wake_up_interruptible(&ctrl->queue);
} }
...@@ -989,7 +952,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -989,7 +952,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
} }
dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__); dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);
dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
...@@ -997,14 +959,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -997,14 +959,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
} }
dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
} }
dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
/* Clear command complete interrupt caused by this write */ /* Clear command complete interrupt caused by this write */
temp_word = 0x1F; temp_word = 0x1F;
...@@ -1248,12 +1208,7 @@ static struct hpc_ops pciehp_hpc_ops = { ...@@ -1248,12 +1208,7 @@ static struct hpc_ops pciehp_hpc_ops = {
.check_lnk_status = hpc_check_lnk_status, .check_lnk_status = hpc_check_lnk_status,
}; };
int pcie_init(struct controller * ctrl, int pcie_init(struct controller * ctrl, struct pcie_device *dev)
struct pcie_device *dev,
php_intr_callback_t attention_button_callback,
php_intr_callback_t switch_change_callback,
php_intr_callback_t presence_change_callback,
php_intr_callback_t power_fault_callback)
{ {
struct php_ctlr_state_s *php_ctlr, *p; struct php_ctlr_state_s *php_ctlr, *p;
void *instance_id = ctrl; void *instance_id = ctrl;
...@@ -1282,8 +1237,8 @@ int pcie_init(struct controller * ctrl, ...@@ -1282,8 +1237,8 @@ int pcie_init(struct controller * ctrl,
pdev = dev->port; pdev = dev->port;
php_ctlr->pci_dev = pdev; /* save pci_dev in context */ php_ctlr->pci_dev = pdev; /* save pci_dev in context */
dbg("%s: pdev->vendor %x pdev->device %x\n", __FUNCTION__, dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n",
pdev->vendor, pdev->device); __FUNCTION__, pdev->vendor, pdev->device);
saved_cap_base = pcie_cap_base; saved_cap_base = pcie_cap_base;
...@@ -1340,8 +1295,6 @@ int pcie_init(struct controller * ctrl, ...@@ -1340,8 +1295,6 @@ int pcie_init(struct controller * ctrl,
first = 0; first = 0;
} }
dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number,
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
if (pci_resource_len(pdev, rc) > 0) if (pci_resource_len(pdev, rc) > 0)
dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc, dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
...@@ -1359,13 +1312,12 @@ int pcie_init(struct controller * ctrl, ...@@ -1359,13 +1312,12 @@ int pcie_init(struct controller * ctrl,
/* find the IRQ */ /* find the IRQ */
php_ctlr->irq = dev->irq; php_ctlr->irq = dev->irq;
dbg("HPC interrupt = %d\n", php_ctlr->irq);
/* Save interrupt callback info */ /* Save interrupt callback info */
php_ctlr->attention_button_callback = attention_button_callback; php_ctlr->attention_button_callback = pciehp_handle_attention_button;
php_ctlr->switch_change_callback = switch_change_callback; php_ctlr->switch_change_callback = pciehp_handle_switch_change;
php_ctlr->presence_change_callback = presence_change_callback; php_ctlr->presence_change_callback = pciehp_handle_presence_change;
php_ctlr->power_fault_callback = power_fault_callback; php_ctlr->power_fault_callback = pciehp_handle_power_fault;
php_ctlr->callback_instance_id = instance_id; php_ctlr->callback_instance_id = instance_id;
/* return PCI Controller Info */ /* return PCI Controller Info */
...@@ -1387,15 +1339,12 @@ int pcie_init(struct controller * ctrl, ...@@ -1387,15 +1339,12 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base)
, slot_status);
temp_word = 0x1F; /* Clear all events */ temp_word = 0x1F; /* Clear all events */
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
...@@ -1403,7 +1352,6 @@ int pcie_init(struct controller * ctrl, ...@@ -1403,7 +1352,6 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
if (pciehp_poll_mode) {/* Install interrupt polling code */ if (pciehp_poll_mode) {/* Install interrupt polling code */
/* Install and start the interrupt polling timer */ /* Install and start the interrupt polling timer */
...@@ -1419,13 +1367,14 @@ int pcie_init(struct controller * ctrl, ...@@ -1419,13 +1367,14 @@ int pcie_init(struct controller * ctrl,
} }
} }
dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number,
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
intr_enable = intr_enable | PRSN_DETECT_ENABLE; intr_enable = intr_enable | PRSN_DETECT_ENABLE;
...@@ -1445,7 +1394,6 @@ int pcie_init(struct controller * ctrl, ...@@ -1445,7 +1394,6 @@ int pcie_init(struct controller * ctrl,
} else { } else {
temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
} }
dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
/* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
...@@ -1453,14 +1401,11 @@ int pcie_init(struct controller * ctrl, ...@@ -1453,14 +1401,11 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__,
SLOT_STATUS(ctrl->cap_base), slot_status);
temp_word = 0x1F; /* Clear all events */ temp_word = 0x1F; /* Clear all events */
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
...@@ -1468,8 +1413,16 @@ int pcie_init(struct controller * ctrl, ...@@ -1468,8 +1413,16 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
if (pciehp_force) {
dbg("Bypassing BIOS check for pciehp use on %s\n",
pci_name(ctrl->pci_dev));
} else {
rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
if (rc)
goto abort_free_ctlr;
}
/* Add this HPC instance into the HPC list */ /* Add this HPC instance into the HPC list */
spin_lock(&list_lock); spin_lock(&list_lock);
if (php_ctlr_list_head == 0) { if (php_ctlr_list_head == 0) {
......
此差异已折叠。
/*
* PCIEHPRM : PCIEHP Resource Manager for ACPI/non-ACPI platform
*
* Copyright (C) 1995,2001 Compaq Computer Corporation
* Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2001 IBM Corp.
* Copyright (C) 2003-2004 Intel Corporation
*
* All rights reserved.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
*/
#ifndef _PCIEHPRM_H_
#define _PCIEHPRM_H_
#ifdef CONFIG_HOTPLUG_PCI_PCIE_PHPRM_NONACPI
#include "pciehprm_nonacpi.h"
#endif
int pciehprm_init(enum php_ctlr_type ct);
void pciehprm_cleanup(void);
int pciehprm_print_pirt(void);
int pciehprm_find_available_resources(struct controller *ctrl);
int pciehprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
void pciehprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
#ifdef DEBUG
#define RES_CHECK(this, bits) \
{ if (((this) & (bits - 1))) \
printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
#else
#define RES_CHECK(this, bits)
#endif
#endif /* _PCIEHPRM_H_ */
此差异已折叠。
...@@ -27,479 +27,21 @@ ...@@ -27,479 +27,21 @@
* *
*/ */
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/uaccess.h>
#ifdef CONFIG_IA64
#include <asm/iosapic.h>
#endif
#include "pciehp.h" #include "pciehp.h"
#include "pciehprm.h"
#include "pciehprm_nonacpi.h"
void pciehprm_cleanup(void) void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp)
{ {
return; return;
} }
int pciehprm_print_pirt(void) int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
return 0;
}
int pciehprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
{
*sun = (u8) (ctrl->first_slot);
return 0;
}
static void print_pci_resource ( struct pci_resource *aprh)
{
struct pci_resource *res;
for (res = aprh; res; res = res->next)
dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
}
static void phprm_dump_func_res( struct pci_func *fun)
{
struct pci_func *func = fun;
if (func->bus_head) {
dbg(": BUS Resources:\n");
print_pci_resource (func->bus_head);
}
if (func->io_head) {
dbg(": IO Resources:\n");
print_pci_resource (func->io_head);
}
if (func->mem_head) {
dbg(": MEM Resources:\n");
print_pci_resource (func->mem_head);
}
if (func->p_mem_head) {
dbg(": PMEM Resources:\n");
print_pci_resource (func->p_mem_head);
}
}
static int phprm_get_used_resources (
struct controller *ctrl,
struct pci_func *func
)
{
return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
}
static int phprm_delete_resource(
struct pci_resource **aprh,
ulong base,
ulong size)
{
struct pci_resource *res;
struct pci_resource *prevnode;
struct pci_resource *split_node;
ulong tbase;
pciehp_resource_sort_and_combine(aprh);
for (res = *aprh; res; res = res->next) {
if (res->base > base)
continue;
if ((res->base + res->length) < (base + size))
continue;
if (res->base < base) {
tbase = base;
if ((res->length - (tbase - res->base)) < size)
continue;
split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
if (!split_node)
return -ENOMEM;
split_node->base = res->base;
split_node->length = tbase - res->base;
res->base = tbase;
res->length -= split_node->length;
split_node->next = res->next;
res->next = split_node;
}
if (res->length >= size) {
split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
if (!split_node)
return -ENOMEM;
split_node->base = res->base + size;
split_node->length = res->length - size;
res->length = size;
split_node->next = res->next;
res->next = split_node;
}
if (*aprh == res) {
*aprh = res->next;
} else {
prevnode = *aprh;
while (prevnode->next != res)
prevnode = prevnode->next;
prevnode->next = res->next;
}
res->next = NULL;
kfree(res);
break;
}
return 0;
}
static int phprm_delete_resources(
struct pci_resource **aprh,
struct pci_resource *this
)
{
struct pci_resource *res;
for (res = this; res; res = res->next)
phprm_delete_resource(aprh, res->base, res->length);
return 0;
}
static int configure_existing_function(
struct controller *ctrl,
struct pci_func *func
)
{
int rc;
/* see how much resources the func has used. */
rc = phprm_get_used_resources (ctrl, func);
if (!rc) {
/* subtract the resources used by the func from ctrl resources */
rc = phprm_delete_resources (&ctrl->bus_head, func->bus_head);
rc |= phprm_delete_resources (&ctrl->io_head, func->io_head);
rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head);
rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
if (rc)
warn("aCEF: cannot del used resources\n");
} else
err("aCEF: cannot get used resources\n");
return rc;
}
static int pciehprm_delete_resource(
struct pci_resource **aprh,
ulong base,
ulong size)
{
struct pci_resource *res;
struct pci_resource *prevnode;
struct pci_resource *split_node;
ulong tbase;
pciehp_resource_sort_and_combine(aprh);
for (res = *aprh; res; res = res->next) {
if (res->base > base)
continue;
if ((res->base + res->length) < (base + size))
continue;
if (res->base < base) {
tbase = base;
if ((res->length - (tbase - res->base)) < size)
continue;
split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
if (!split_node)
return -ENOMEM;
split_node->base = res->base;
split_node->length = tbase - res->base;
res->base = tbase;
res->length -= split_node->length;
split_node->next = res->next;
res->next = split_node;
}
if (res->length >= size) {
split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
if (!split_node)
return -ENOMEM;
split_node->base = res->base + size;
split_node->length = res->length - size;
res->length = size;
split_node->next = res->next;
res->next = split_node;
}
if (*aprh == res) {
*aprh = res->next;
} else {
prevnode = *aprh;
while (prevnode->next != res)
prevnode = prevnode->next;
prevnode->next = res->next;
}
res->next = NULL;
kfree(res);
break;
}
return 0;
}
static int bind_pci_resources_to_slots ( struct controller *ctrl)
{ {
struct pci_func *func, new_func;
int busn = ctrl->slot_bus;
int devn, funn;
u32 vid;
for (devn = 0; devn < 32; devn++) {
for (funn = 0; funn < 8; funn++) {
/*
if (devn == ctrl->device && funn == ctrl->function)
continue;
*/
/* find out if this entry is for an occupied slot */
vid = 0xFFFFFFFF;
pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
if (vid != 0xFFFFFFFF) {
dbg("%s: vid = %x bus %x dev %x fun %x\n", __FUNCTION__,
vid, busn, devn, funn);
func = pciehp_slot_find(busn, devn, funn);
dbg("%s: func = %p\n", __FUNCTION__,func);
if (!func) {
memset(&new_func, 0, sizeof(struct pci_func));
new_func.bus = busn;
new_func.device = devn;
new_func.function = funn;
new_func.is_a_board = 1;
configure_existing_function(ctrl, &new_func);
phprm_dump_func_res(&new_func);
} else {
configure_existing_function(ctrl, func);
phprm_dump_func_res(func);
}
dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
}
}
}
return 0; return 0;
} }
static void phprm_dump_ctrl_res( struct controller *ctlr)
{
struct controller *ctrl = ctlr;
if (ctrl->bus_head) {
dbg(": BUS Resources:\n");
print_pci_resource (ctrl->bus_head);
}
if (ctrl->io_head) {
dbg(": IO Resources:\n");
print_pci_resource (ctrl->io_head);
}
if (ctrl->mem_head) {
dbg(": MEM Resources:\n");
print_pci_resource (ctrl->mem_head);
}
if (ctrl->p_mem_head) {
dbg(": PMEM Resources:\n");
print_pci_resource (ctrl->p_mem_head);
}
}
/*
* phprm_find_available_resources
*
* Finds available memory, IO, and IRQ resources for programming
* devices which may be added to the system
* this function is for hot plug ADD!
*
* returns 0 if success
*/
int pciehprm_find_available_resources(struct controller *ctrl)
{
struct pci_func func;
u32 rc;
memset(&func, 0, sizeof(struct pci_func));
func.bus = ctrl->bus;
func.device = ctrl->device;
func.function = ctrl->function;
func.is_a_board = 1;
/* Get resources for this PCI bridge */
rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
dbg("%s: pciehp_save_used_resources rc = %d\n", __FUNCTION__, rc);
if (func.mem_head)
func.mem_head->next = ctrl->mem_head;
ctrl->mem_head = func.mem_head;
if (func.p_mem_head)
func.p_mem_head->next = ctrl->p_mem_head;
ctrl->p_mem_head = func.p_mem_head;
if (func.io_head)
func.io_head->next = ctrl->io_head;
ctrl->io_head = func.io_head;
if(func.bus_head)
func.bus_head->next = ctrl->bus_head;
ctrl->bus_head = func.bus_head;
if (ctrl->bus_head)
pciehprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1);
dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
phprm_dump_ctrl_res(ctrl);
dbg("%s: before bind_pci_resources_to slots\n", __FUNCTION__);
bind_pci_resources_to_slots (ctrl);
dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
phprm_dump_ctrl_res(ctrl);
return (rc);
}
int pciehprm_set_hpp(
struct controller *ctrl,
struct pci_func *func,
u8 card_type)
{
u32 rc;
u8 temp_byte;
struct pci_bus lpci_bus, *pci_bus;
unsigned int devfn;
memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
pci_bus = &lpci_bus;
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
temp_byte = 0x40; /* hard coded value for LT */
if (card_type == PCI_HEADER_TYPE_BRIDGE) {
/* set subordinate Latency Timer */
rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
if (rc) {
dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__,
func->bus, func->device, func->function);
return rc;
}
}
/* set base Latency Timer */
rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
if (rc) {
dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
return rc;
}
/* set Cache Line size */
temp_byte = 0x08; /* hard coded value for CLS */
rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
if (rc) {
dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
}
/* set enable_perr */
/* set enable_serr */
return rc;
}
void pciehprm_enable_card(
struct controller *ctrl,
struct pci_func *func,
u8 card_type)
{
u16 command, bcommand;
struct pci_bus lpci_bus, *pci_bus;
unsigned int devfn;
int rc;
memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
pci_bus = &lpci_bus;
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
| PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
| PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
if (card_type == PCI_HEADER_TYPE_BRIDGE) {
rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
| PCI_BRIDGE_CTL_NO_ISA;
rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
}
}
static int legacy_pciehprm_init_pci(void)
{
return 0;
}
int pciehprm_init(enum php_ctlr_type ctrl_type)
{
int retval;
switch (ctrl_type) {
case PCI:
retval = legacy_pciehprm_init_pci();
break;
default:
retval = -ENODEV;
break;
}
return retval;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -1970,7 +1970,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids); ...@@ -1970,7 +1970,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
static struct pci_driver goku_pci_driver = { static struct pci_driver goku_pci_driver = {
.name = (char *) driver_name, .name = (char *) driver_name,
.id_table = pci_ids, .id_table = pci_ids,
.owner = THIS_MODULE,
.probe = goku_probe, .probe = goku_probe,
.remove = goku_remove, .remove = goku_remove,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册