aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-01-14 12:55:28 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-14 12:55:28 -0500
commit59af70385fb125f819d953801b6c45629836e916 (patch)
tree6232fb052167c7cbd51851323088217617dbde42
parente7de369050534025b33aab1033358bf47a577e4d (diff)
parentd50f5c5ca0c3426669fbe11ad4d5708d333eb9fb (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
-rw-r--r--arch/ia64/hp/sim/simserial.c10
-rw-r--r--arch/ia64/kernel/fsys.S1
-rw-r--r--arch/ia64/kernel/jprobes.S27
-rw-r--r--arch/ia64/kernel/kprobes.c57
-rw-r--r--arch/ia64/kernel/mca_asm.S2
-rw-r--r--arch/ia64/kernel/salinfo.c170
-rw-r--r--arch/ia64/kernel/traps.c26
-rw-r--r--arch/ia64/mm/tlb.c2
-rw-r--r--arch/ia64/sn/include/xtalk/hubdev.h16
-rw-r--r--arch/ia64/sn/kernel/bte_error.c58
-rw-r--r--arch/ia64/sn/kernel/huberror.c9
-rw-r--r--arch/ia64/sn/kernel/io_init.c94
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c24
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c189
-rw-r--r--arch/ia64/sn/kernel/xpc_partition.c10
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_dma.c34
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c20
-rw-r--r--include/asm-ia64/kprobes.h6
-rw-r--r--include/asm-ia64/sn/sn_sal.h5
-rw-r--r--include/asm-ia64/sn/xp.h4
-rw-r--r--include/asm-ia64/sn/xpc.h (renamed from arch/ia64/sn/kernel/xpc.h)11
-rw-r--r--include/asm-ia64/thread_info.h4
22 files changed, 544 insertions, 235 deletions
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index a346e1833bf2..27f23fa5ca15 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -167,15 +167,9 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs)
167 } 167 }
168 } 168 }
169 seen_esc = 0; 169 seen_esc = 0;
170 if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
171 170
172 *tty->flip.char_buf_ptr = ch; 171 if (tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0)
173 172 break;
174 *tty->flip.flag_buf_ptr = 0;
175
176 tty->flip.flag_buf_ptr++;
177 tty->flip.char_buf_ptr++;
178 tty->flip.count++;
179 } 173 }
180 tty_flip_buffer_push(tty); 174 tty_flip_buffer_push(tty);
181} 175}
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index 2ddbac6f4999..ce423910ca97 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -903,5 +903,6 @@ fsyscall_table:
903 data8 0 903 data8 0
904 data8 0 904 data8 0
905 data8 0 905 data8 0
906 data8 0 // 1280
906 907
907 .org fsyscall_table + 8*NR_syscalls // guard against failures to increase NR_syscalls 908 .org fsyscall_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
diff --git a/arch/ia64/kernel/jprobes.S b/arch/ia64/kernel/jprobes.S
index 2323377e3695..5cd6226f44f2 100644
--- a/arch/ia64/kernel/jprobes.S
+++ b/arch/ia64/kernel/jprobes.S
@@ -60,3 +60,30 @@ END(jprobe_break)
60GLOBAL_ENTRY(jprobe_inst_return) 60GLOBAL_ENTRY(jprobe_inst_return)
61 br.call.sptk.many b0=jprobe_break 61 br.call.sptk.many b0=jprobe_break
62END(jprobe_inst_return) 62END(jprobe_inst_return)
63
64GLOBAL_ENTRY(invalidate_stacked_regs)
65 movl r16=invalidate_restore_cfm
66 ;;
67 mov b6=r16
68 ;;
69 br.ret.sptk.many b6
70 ;;
71invalidate_restore_cfm:
72 mov r16=ar.rsc
73 ;;
74 mov ar.rsc=r0
75 ;;
76 loadrs
77 ;;
78 mov ar.rsc=r16
79 ;;
80 br.cond.sptk.many rp
81END(invalidate_stacked_regs)
82
83GLOBAL_ENTRY(flush_register_stack)
84 // flush dirty regs to backing store (must be first in insn group)
85 flushrs
86 ;;
87 br.ret.sptk.many rp
88END(flush_register_stack)
89
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 346fedf9ea47..50ae8c7d453d 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -766,11 +766,56 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
766 return ret; 766 return ret;
767} 767}
768 768
769struct param_bsp_cfm {
770 unsigned long ip;
771 unsigned long *bsp;
772 unsigned long cfm;
773};
774
775static void ia64_get_bsp_cfm(struct unw_frame_info *info, void *arg)
776{
777 unsigned long ip;
778 struct param_bsp_cfm *lp = arg;
779
780 do {
781 unw_get_ip(info, &ip);
782 if (ip == 0)
783 break;
784 if (ip == lp->ip) {
785 unw_get_bsp(info, (unsigned long*)&lp->bsp);
786 unw_get_cfm(info, (unsigned long*)&lp->cfm);
787 return;
788 }
789 } while (unw_unwind(info) >= 0);
790 lp->bsp = 0;
791 lp->cfm = 0;
792 return;
793}
794
769int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) 795int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
770{ 796{
771 struct jprobe *jp = container_of(p, struct jprobe, kp); 797 struct jprobe *jp = container_of(p, struct jprobe, kp);
772 unsigned long addr = ((struct fnptr *)(jp->entry))->ip; 798 unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
773 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 799 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
800 struct param_bsp_cfm pa;
801 int bytes;
802
803 /*
804 * Callee owns the argument space and could overwrite it, eg
805 * tail call optimization. So to be absolutely safe
806 * we save the argument space before transfering the control
807 * to instrumented jprobe function which runs in
808 * the process context
809 */
810 pa.ip = regs->cr_iip;
811 unw_init_running(ia64_get_bsp_cfm, &pa);
812 bytes = (char *)ia64_rse_skip_regs(pa.bsp, pa.cfm & 0x3f)
813 - (char *)pa.bsp;
814 memcpy( kcb->jprobes_saved_stacked_regs,
815 pa.bsp,
816 bytes );
817 kcb->bsp = pa.bsp;
818 kcb->cfm = pa.cfm;
774 819
775 /* save architectural state */ 820 /* save architectural state */
776 kcb->jprobe_saved_regs = *regs; 821 kcb->jprobe_saved_regs = *regs;
@@ -792,8 +837,20 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
792int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 837int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
793{ 838{
794 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 839 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
840 int bytes;
795 841
842 /* restoring architectural state */
796 *regs = kcb->jprobe_saved_regs; 843 *regs = kcb->jprobe_saved_regs;
844
845 /* restoring the original argument space */
846 flush_register_stack();
847 bytes = (char *)ia64_rse_skip_regs(kcb->bsp, kcb->cfm & 0x3f)
848 - (char *)kcb->bsp;
849 memcpy( kcb->bsp,
850 kcb->jprobes_saved_stacked_regs,
851 bytes );
852 invalidate_stacked_regs();
853
797 preempt_enable_no_resched(); 854 preempt_enable_no_resched();
798 return 1; 855 return 1;
799} 856}
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
index db32fc1d3935..403a80a58c13 100644
--- a/arch/ia64/kernel/mca_asm.S
+++ b/arch/ia64/kernel/mca_asm.S
@@ -847,7 +847,7 @@ ia64_state_restore:
847 ;; 847 ;;
848 mov cr.iim=temp3 848 mov cr.iim=temp3
849 mov cr.iha=temp4 849 mov cr.iha=temp4
850 dep r22=0,r22,62,2 // pal_min_state, physical, uncached 850 dep r22=0,r22,62,1 // pal_min_state, physical, uncached
851 mov IA64_KR(CURRENT)=r21 851 mov IA64_KR(CURRENT)=r21
852 ld8 r8=[temp1] // os_status 852 ld8 r8=[temp1] // os_status
853 ld8 r10=[temp2] // context 853 ld8 r10=[temp2] // context
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
index a87a162a3086..9d5a823479a3 100644
--- a/arch/ia64/kernel/salinfo.c
+++ b/arch/ia64/kernel/salinfo.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Creates entries in /proc/sal for various system features. 4 * Creates entries in /proc/sal for various system features.
5 * 5 *
6 * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. 6 * Copyright (c) 2003, 2006 Silicon Graphics, Inc. All rights reserved.
7 * Copyright (c) 2003 Hewlett-Packard Co 7 * Copyright (c) 2003 Hewlett-Packard Co
8 * Bjorn Helgaas <bjorn.helgaas@hp.com> 8 * Bjorn Helgaas <bjorn.helgaas@hp.com>
9 * 9 *
@@ -27,9 +27,17 @@
27 * mca.c may not pass a buffer, a NULL buffer just indicates that a new 27 * mca.c may not pass a buffer, a NULL buffer just indicates that a new
28 * record is available in SAL. 28 * record is available in SAL.
29 * Replace some NR_CPUS by cpus_online, for hotplug cpu. 29 * Replace some NR_CPUS by cpus_online, for hotplug cpu.
30 *
31 * Jan 5 2006 kaos@sgi.com
32 * Handle hotplug cpus coming online.
33 * Handle hotplug cpus going offline while they still have outstanding records.
34 * Use the cpu_* macros consistently.
35 * Replace the counting semaphore with a mutex and a test if the cpumask is non-empty.
36 * Modify the locking to make the test for "work to do" an atomic operation.
30 */ 37 */
31 38
32#include <linux/capability.h> 39#include <linux/capability.h>
40#include <linux/cpu.h>
33#include <linux/types.h> 41#include <linux/types.h>
34#include <linux/proc_fs.h> 42#include <linux/proc_fs.h>
35#include <linux/module.h> 43#include <linux/module.h>
@@ -132,8 +140,8 @@ enum salinfo_state {
132}; 140};
133 141
134struct salinfo_data { 142struct salinfo_data {
135 volatile cpumask_t cpu_event; /* which cpus have outstanding events */ 143 cpumask_t cpu_event; /* which cpus have outstanding events */
136 struct semaphore sem; /* count of cpus with outstanding events (bits set in cpu_event) */ 144 struct semaphore mutex;
137 u8 *log_buffer; 145 u8 *log_buffer;
138 u64 log_size; 146 u64 log_size;
139 u8 *oemdata; /* decoded oem data */ 147 u8 *oemdata; /* decoded oem data */
@@ -174,6 +182,21 @@ struct salinfo_platform_oemdata_parms {
174 int ret; 182 int ret;
175}; 183};
176 184
185/* Kick the mutex that tells user space that there is work to do. Instead of
186 * trying to track the state of the mutex across multiple cpus, in user
187 * context, interrupt context, non-maskable interrupt context and hotplug cpu,
188 * it is far easier just to grab the mutex if it is free then release it.
189 *
190 * This routine must be called with data_saved_lock held, to make the down/up
191 * operation atomic.
192 */
193static void
194salinfo_work_to_do(struct salinfo_data *data)
195{
196 down_trylock(&data->mutex);
197 up(&data->mutex);
198}
199
177static void 200static void
178salinfo_platform_oemdata_cpu(void *context) 201salinfo_platform_oemdata_cpu(void *context)
179{ 202{
@@ -212,9 +235,9 @@ salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe)
212 235
213 BUG_ON(type >= ARRAY_SIZE(salinfo_log_name)); 236 BUG_ON(type >= ARRAY_SIZE(salinfo_log_name));
214 237
238 if (irqsafe)
239 spin_lock_irqsave(&data_saved_lock, flags);
215 if (buffer) { 240 if (buffer) {
216 if (irqsafe)
217 spin_lock_irqsave(&data_saved_lock, flags);
218 for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) { 241 for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) {
219 if (!data_saved->buffer) 242 if (!data_saved->buffer)
220 break; 243 break;
@@ -232,13 +255,11 @@ salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe)
232 data_saved->size = size; 255 data_saved->size = size;
233 data_saved->buffer = buffer; 256 data_saved->buffer = buffer;
234 } 257 }
235 if (irqsafe)
236 spin_unlock_irqrestore(&data_saved_lock, flags);
237 } 258 }
238 259 cpu_set(smp_processor_id(), data->cpu_event);
239 if (!test_and_set_bit(smp_processor_id(), &data->cpu_event)) { 260 if (irqsafe) {
240 if (irqsafe) 261 salinfo_work_to_do(data);
241 up(&data->sem); 262 spin_unlock_irqrestore(&data_saved_lock, flags);
242 } 263 }
243} 264}
244 265
@@ -249,20 +270,17 @@ static struct timer_list salinfo_timer;
249static void 270static void
250salinfo_timeout_check(struct salinfo_data *data) 271salinfo_timeout_check(struct salinfo_data *data)
251{ 272{
252 int i; 273 unsigned long flags;
253 if (!data->open) 274 if (!data->open)
254 return; 275 return;
255 for_each_online_cpu(i) { 276 if (!cpus_empty(data->cpu_event)) {
256 if (test_bit(i, &data->cpu_event)) { 277 spin_lock_irqsave(&data_saved_lock, flags);
257 /* double up() is not a problem, user space will see no 278 salinfo_work_to_do(data);
258 * records for the additional "events". 279 spin_unlock_irqrestore(&data_saved_lock, flags);
259 */
260 up(&data->sem);
261 }
262 } 280 }
263} 281}
264 282
265static void 283static void
266salinfo_timeout (unsigned long arg) 284salinfo_timeout (unsigned long arg)
267{ 285{
268 salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_MCA); 286 salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_MCA);
@@ -290,16 +308,20 @@ salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t
290 int i, n, cpu = -1; 308 int i, n, cpu = -1;
291 309
292retry: 310retry:
293 if (down_trylock(&data->sem)) { 311 if (cpus_empty(data->cpu_event) && down_trylock(&data->mutex)) {
294 if (file->f_flags & O_NONBLOCK) 312 if (file->f_flags & O_NONBLOCK)
295 return -EAGAIN; 313 return -EAGAIN;
296 if (down_interruptible(&data->sem)) 314 if (down_interruptible(&data->mutex))
297 return -EINTR; 315 return -EINTR;
298 } 316 }
299 317
300 n = data->cpu_check; 318 n = data->cpu_check;
301 for (i = 0; i < NR_CPUS; i++) { 319 for (i = 0; i < NR_CPUS; i++) {
302 if (test_bit(n, &data->cpu_event) && cpu_online(n)) { 320 if (cpu_isset(n, data->cpu_event)) {
321 if (!cpu_online(n)) {
322 cpu_clear(n, data->cpu_event);
323 continue;
324 }
303 cpu = n; 325 cpu = n;
304 break; 326 break;
305 } 327 }
@@ -310,9 +332,6 @@ retry:
310 if (cpu == -1) 332 if (cpu == -1)
311 goto retry; 333 goto retry;
312 334
313 /* events are sticky until the user says "clear" */
314 up(&data->sem);
315
316 /* for next read, start checking at next CPU */ 335 /* for next read, start checking at next CPU */
317 data->cpu_check = cpu; 336 data->cpu_check = cpu;
318 if (++data->cpu_check == NR_CPUS) 337 if (++data->cpu_check == NR_CPUS)
@@ -381,10 +400,8 @@ salinfo_log_release(struct inode *inode, struct file *file)
381static void 400static void
382call_on_cpu(int cpu, void (*fn)(void *), void *arg) 401call_on_cpu(int cpu, void (*fn)(void *), void *arg)
383{ 402{
384 cpumask_t save_cpus_allowed, new_cpus_allowed; 403 cpumask_t save_cpus_allowed = current->cpus_allowed;
385 memcpy(&save_cpus_allowed, &current->cpus_allowed, sizeof(save_cpus_allowed)); 404 cpumask_t new_cpus_allowed = cpumask_of_cpu(cpu);
386 memset(&new_cpus_allowed, 0, sizeof(new_cpus_allowed));
387 set_bit(cpu, &new_cpus_allowed);
388 set_cpus_allowed(current, new_cpus_allowed); 405 set_cpus_allowed(current, new_cpus_allowed);
389 (*fn)(arg); 406 (*fn)(arg);
390 set_cpus_allowed(current, save_cpus_allowed); 407 set_cpus_allowed(current, save_cpus_allowed);
@@ -433,10 +450,10 @@ retry:
433 if (!data->saved_num) 450 if (!data->saved_num)
434 call_on_cpu(cpu, salinfo_log_read_cpu, data); 451 call_on_cpu(cpu, salinfo_log_read_cpu, data);
435 if (!data->log_size) { 452 if (!data->log_size) {
436 data->state = STATE_NO_DATA; 453 data->state = STATE_NO_DATA;
437 clear_bit(cpu, &data->cpu_event); 454 cpu_clear(cpu, data->cpu_event);
438 } else { 455 } else {
439 data->state = STATE_LOG_RECORD; 456 data->state = STATE_LOG_RECORD;
440 } 457 }
441} 458}
442 459
@@ -473,27 +490,31 @@ static int
473salinfo_log_clear(struct salinfo_data *data, int cpu) 490salinfo_log_clear(struct salinfo_data *data, int cpu)
474{ 491{
475 sal_log_record_header_t *rh; 492 sal_log_record_header_t *rh;
493 unsigned long flags;
494 spin_lock_irqsave(&data_saved_lock, flags);
476 data->state = STATE_NO_DATA; 495 data->state = STATE_NO_DATA;
477 if (!test_bit(cpu, &data->cpu_event)) 496 if (!cpu_isset(cpu, data->cpu_event)) {
497 spin_unlock_irqrestore(&data_saved_lock, flags);
478 return 0; 498 return 0;
479 down(&data->sem); 499 }
480 clear_bit(cpu, &data->cpu_event); 500 cpu_clear(cpu, data->cpu_event);
481 if (data->saved_num) { 501 if (data->saved_num) {
482 unsigned long flags; 502 shift1_data_saved(data, data->saved_num - 1);
483 spin_lock_irqsave(&data_saved_lock, flags);
484 shift1_data_saved(data, data->saved_num - 1 );
485 data->saved_num = 0; 503 data->saved_num = 0;
486 spin_unlock_irqrestore(&data_saved_lock, flags);
487 } 504 }
505 spin_unlock_irqrestore(&data_saved_lock, flags);
488 rh = (sal_log_record_header_t *)(data->log_buffer); 506 rh = (sal_log_record_header_t *)(data->log_buffer);
489 /* Corrected errors have already been cleared from SAL */ 507 /* Corrected errors have already been cleared from SAL */
490 if (rh->severity != sal_log_severity_corrected) 508 if (rh->severity != sal_log_severity_corrected)
491 call_on_cpu(cpu, salinfo_log_clear_cpu, data); 509 call_on_cpu(cpu, salinfo_log_clear_cpu, data);
492 /* clearing a record may make a new record visible */ 510 /* clearing a record may make a new record visible */
493 salinfo_log_new_read(cpu, data); 511 salinfo_log_new_read(cpu, data);
494 if (data->state == STATE_LOG_RECORD && 512 if (data->state == STATE_LOG_RECORD) {
495 !test_and_set_bit(cpu, &data->cpu_event)) 513 spin_lock_irqsave(&data_saved_lock, flags);
496 up(&data->sem); 514 cpu_set(cpu, data->cpu_event);
515 salinfo_work_to_do(data);
516 spin_unlock_irqrestore(&data_saved_lock, flags);
517 }
497 return 0; 518 return 0;
498} 519}
499 520
@@ -550,6 +571,53 @@ static struct file_operations salinfo_data_fops = {
550 .write = salinfo_log_write, 571 .write = salinfo_log_write,
551}; 572};
552 573
574#ifdef CONFIG_HOTPLUG_CPU
575static int __devinit
576salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
577{
578 unsigned int i, cpu = (unsigned long)hcpu;
579 unsigned long flags;
580 struct salinfo_data *data;
581 switch (action) {
582 case CPU_ONLINE:
583 spin_lock_irqsave(&data_saved_lock, flags);
584 for (i = 0, data = salinfo_data;
585 i < ARRAY_SIZE(salinfo_data);
586 ++i, ++data) {
587 cpu_set(cpu, data->cpu_event);
588 salinfo_work_to_do(data);
589 }
590 spin_unlock_irqrestore(&data_saved_lock, flags);
591 break;
592 case CPU_DEAD:
593 spin_lock_irqsave(&data_saved_lock, flags);
594 for (i = 0, data = salinfo_data;
595 i < ARRAY_SIZE(salinfo_data);
596 ++i, ++data) {
597 struct salinfo_data_saved *data_saved;
598 int j;
599 for (j = ARRAY_SIZE(data->data_saved) - 1, data_saved = data->data_saved + j;
600 j >= 0;
601 --j, --data_saved) {
602 if (data_saved->buffer && data_saved->cpu == cpu) {
603 shift1_data_saved(data, j);
604 }
605 }
606 cpu_clear(cpu, data->cpu_event);
607 }
608 spin_unlock_irqrestore(&data_saved_lock, flags);
609 break;
610 }
611 return NOTIFY_OK;
612}
613
614static struct notifier_block salinfo_cpu_notifier =
615{
616 .notifier_call = salinfo_cpu_callback,
617 .priority = 0,
618};
619#endif /* CONFIG_HOTPLUG_CPU */
620
553static int __init 621static int __init
554salinfo_init(void) 622salinfo_init(void)
555{ 623{
@@ -557,7 +625,7 @@ salinfo_init(void)
557 struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */ 625 struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */
558 struct proc_dir_entry *dir, *entry; 626 struct proc_dir_entry *dir, *entry;
559 struct salinfo_data *data; 627 struct salinfo_data *data;
560 int i, j, online; 628 int i, j;
561 629
562 salinfo_dir = proc_mkdir("sal", NULL); 630 salinfo_dir = proc_mkdir("sal", NULL);
563 if (!salinfo_dir) 631 if (!salinfo_dir)
@@ -572,7 +640,7 @@ salinfo_init(void)
572 for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { 640 for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) {
573 data = salinfo_data + i; 641 data = salinfo_data + i;
574 data->type = i; 642 data->type = i;
575 sema_init(&data->sem, 0); 643 init_MUTEX(&data->mutex);
576 dir = proc_mkdir(salinfo_log_name[i], salinfo_dir); 644 dir = proc_mkdir(salinfo_log_name[i], salinfo_dir);
577 if (!dir) 645 if (!dir)
578 continue; 646 continue;
@@ -592,12 +660,8 @@ salinfo_init(void)
592 *sdir++ = entry; 660 *sdir++ = entry;
593 661
594 /* we missed any events before now */ 662 /* we missed any events before now */
595 online = 0; 663 for_each_online_cpu(j)
596 for_each_online_cpu(j) { 664 cpu_set(j, data->cpu_event);
597 set_bit(j, &data->cpu_event);
598 ++online;
599 }
600 sema_init(&data->sem, online);
601 665
602 *sdir++ = dir; 666 *sdir++ = dir;
603 } 667 }
@@ -609,6 +673,10 @@ salinfo_init(void)
609 salinfo_timer.function = &salinfo_timeout; 673 salinfo_timer.function = &salinfo_timeout;
610 add_timer(&salinfo_timer); 674 add_timer(&salinfo_timer);
611 675
676#ifdef CONFIG_HOTPLUG_CPU
677 register_cpu_notifier(&salinfo_cpu_notifier);
678#endif
679
612 return 0; 680 return 0;
613} 681}
614 682
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index d3e0ecb56d62..55391901b013 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -530,12 +530,15 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
530 if (fsys_mode(current, &regs)) { 530 if (fsys_mode(current, &regs)) {
531 extern char __kernel_syscall_via_break[]; 531 extern char __kernel_syscall_via_break[];
532 /* 532 /*
533 * Got a trap in fsys-mode: Taken Branch Trap and Single Step trap 533 * Got a trap in fsys-mode: Taken Branch Trap
534 * need special handling; Debug trap is not supposed to happen. 534 * and Single Step trap need special handling;
535 * Debug trap is ignored (we disable it here
536 * and re-enable it in the lower-privilege trap).
535 */ 537 */
536 if (unlikely(vector == 29)) { 538 if (unlikely(vector == 29)) {
537 die("Got debug trap in fsys-mode---not supposed to happen!", 539 set_thread_flag(TIF_DB_DISABLED);
538 &regs, 0); 540 ia64_psr(&regs)->db = 0;
541 ia64_psr(&regs)->lp = 1;
539 return; 542 return;
540 } 543 }
541 /* re-do the system call via break 0x100000: */ 544 /* re-do the system call via break 0x100000: */
@@ -589,10 +592,19 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
589 case 34: 592 case 34:
590 if (isr & 0x2) { 593 if (isr & 0x2) {
591 /* Lower-Privilege Transfer Trap */ 594 /* Lower-Privilege Transfer Trap */
595
596 /* If we disabled debug traps during an fsyscall,
597 * re-enable them here.
598 */
599 if (test_thread_flag(TIF_DB_DISABLED)) {
600 clear_thread_flag(TIF_DB_DISABLED);
601 ia64_psr(&regs)->db = 1;
602 }
603
592 /* 604 /*
593 * Just clear PSR.lp and then return immediately: all the 605 * Just clear PSR.lp and then return immediately:
594 * interesting work (e.g., signal delivery is done in the kernel 606 * all the interesting work (e.g., signal delivery)
595 * exit path). 607 * is done in the kernel exit path.
596 */ 608 */
597 ia64_psr(&regs)->lp = 0; 609 ia64_psr(&regs)->lp = 0;
598 return; 610 return;
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index 41105d454423..6a4eec9113e8 100644
--- a/arch/ia64/mm/tlb.c
+++ b/arch/ia64/mm/tlb.c
@@ -90,7 +90,7 @@ ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
90{ 90{
91 static DEFINE_SPINLOCK(ptcg_lock); 91 static DEFINE_SPINLOCK(ptcg_lock);
92 92
93 if (mm != current->active_mm) { 93 if (mm != current->active_mm || !current->mm) {
94 flush_tlb_all(); 94 flush_tlb_all();
95 return; 95 return;
96 } 96 }
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h
index 71c2b271b4c6..4d417c301201 100644
--- a/arch/ia64/sn/include/xtalk/hubdev.h
+++ b/arch/ia64/sn/include/xtalk/hubdev.h
@@ -26,11 +26,14 @@
26#define IIO_NUM_ITTES 7 26#define IIO_NUM_ITTES 7
27#define HUB_NUM_BIG_WINDOW (IIO_NUM_ITTES - 1) 27#define HUB_NUM_BIG_WINDOW (IIO_NUM_ITTES - 1)
28 28
29struct sn_flush_device_list { 29/* This struct is shared between the PROM and the kernel.
30 * Changes to this struct will require corresponding changes to the kernel.
31 */
32struct sn_flush_device_common {
30 int sfdl_bus; 33 int sfdl_bus;
31 int sfdl_slot; 34 int sfdl_slot;
32 int sfdl_pin; 35 int sfdl_pin;
33 struct bar_list { 36 struct common_bar_list {
34 unsigned long start; 37 unsigned long start;
35 unsigned long end; 38 unsigned long end;
36 } sfdl_bar_list[6]; 39 } sfdl_bar_list[6];
@@ -40,14 +43,19 @@ struct sn_flush_device_list {
40 uint32_t sfdl_persistent_busnum; 43 uint32_t sfdl_persistent_busnum;
41 uint32_t sfdl_persistent_segment; 44 uint32_t sfdl_persistent_segment;
42 struct pcibus_info *sfdl_pcibus_info; 45 struct pcibus_info *sfdl_pcibus_info;
46};
47
48/* This struct is kernel only and is not used by the PROM */
49struct sn_flush_device_kernel {
43 spinlock_t sfdl_flush_lock; 50 spinlock_t sfdl_flush_lock;
51 struct sn_flush_device_common *common;
44}; 52};
45 53
46/* 54/*
47 * **widget_p - Used as an array[wid_num][device] of sn_flush_device_list. 55 * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel.
48 */ 56 */
49struct sn_flush_nasid_entry { 57struct sn_flush_nasid_entry {
50 struct sn_flush_device_list **widget_p; /* Used as a array of wid_num */ 58 struct sn_flush_device_kernel **widget_p; // Used as an array of wid_num
51 uint64_t iio_itte[8]; 59 uint64_t iio_itte[8];
52}; 60};
53 61
diff --git a/arch/ia64/sn/kernel/bte_error.c b/arch/ia64/sn/kernel/bte_error.c
index fcbc748ae433..f1ec1370b3e3 100644
--- a/arch/ia64/sn/kernel/bte_error.c
+++ b/arch/ia64/sn/kernel/bte_error.c
@@ -33,7 +33,7 @@ void bte_error_handler(unsigned long);
33 * Wait until all BTE related CRBs are completed 33 * Wait until all BTE related CRBs are completed
34 * and then reset the interfaces. 34 * and then reset the interfaces.
35 */ 35 */
36void shub1_bte_error_handler(unsigned long _nodepda) 36int shub1_bte_error_handler(unsigned long _nodepda)
37{ 37{
38 struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda; 38 struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda;
39 struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer; 39 struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
@@ -53,7 +53,7 @@ void shub1_bte_error_handler(unsigned long _nodepda)
53 (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) { 53 (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) {
54 BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda, 54 BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda,
55 smp_processor_id())); 55 smp_processor_id()));
56 return; 56 return 1;
57 } 57 }
58 58
59 /* Determine information about our hub */ 59 /* Determine information about our hub */
@@ -81,7 +81,7 @@ void shub1_bte_error_handler(unsigned long _nodepda)
81 mod_timer(recovery_timer, HZ * 5); 81 mod_timer(recovery_timer, HZ * 5);
82 BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda, 82 BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
83 smp_processor_id())); 83 smp_processor_id()));
84 return; 84 return 1;
85 } 85 }
86 if (icmr.ii_icmr_fld_s.i_crb_vld != 0) { 86 if (icmr.ii_icmr_fld_s.i_crb_vld != 0) {
87 87
@@ -99,7 +99,7 @@ void shub1_bte_error_handler(unsigned long _nodepda)
99 BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n", 99 BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n",
100 err_nodepda, smp_processor_id(), 100 err_nodepda, smp_processor_id(),
101 i)); 101 i));
102 return; 102 return 1;
103 } 103 }
104 } 104 }
105 } 105 }
@@ -124,6 +124,42 @@ void shub1_bte_error_handler(unsigned long _nodepda)
124 REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval); 124 REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval);
125 125
126 del_timer(recovery_timer); 126 del_timer(recovery_timer);
127 return 0;
128}
129
130/*
131 * Wait until all BTE related CRBs are completed
132 * and then reset the interfaces.
133 */
134int shub2_bte_error_handler(unsigned long _nodepda)
135{
136 struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda;
137 struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
138 struct bteinfo_s *bte;
139 nasid_t nasid;
140 u64 status;
141 int i;
142
143 nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode);
144
145 /*
146 * Verify that all the BTEs are complete
147 */
148 for (i = 0; i < BTES_PER_NODE; i++) {
149 bte = &err_nodepda->bte_if[i];
150 status = BTE_LNSTAT_LOAD(bte);
151 if ((status & IBLS_ERROR) || !(status & IBLS_BUSY))
152 continue;
153 mod_timer(recovery_timer, HZ * 5);
154 BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
155 smp_processor_id()));
156 return 1;
157 }
158 if (ia64_sn_bte_recovery(nasid))
159 panic("bte_error_handler(): Fatal BTE Error");
160
161 del_timer(recovery_timer);
162 return 0;
127} 163}
128 164
129/* 165/*
@@ -135,7 +171,6 @@ void bte_error_handler(unsigned long _nodepda)
135 struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda; 171 struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda;
136 spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock; 172 spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock;
137 int i; 173 int i;
138 nasid_t nasid;
139 unsigned long irq_flags; 174 unsigned long irq_flags;
140 volatile u64 *notify; 175 volatile u64 *notify;
141 bte_result_t bh_error; 176 bte_result_t bh_error;
@@ -160,12 +195,15 @@ void bte_error_handler(unsigned long _nodepda)
160 } 195 }
161 196
162 if (is_shub1()) { 197 if (is_shub1()) {
163 shub1_bte_error_handler(_nodepda); 198 if (shub1_bte_error_handler(_nodepda)) {
199 spin_unlock_irqrestore(recovery_lock, irq_flags);
200 return;
201 }
164 } else { 202 } else {
165 nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode); 203 if (shub2_bte_error_handler(_nodepda)) {
166 204 spin_unlock_irqrestore(recovery_lock, irq_flags);
167 if (ia64_sn_bte_recovery(nasid)) 205 return;
168 panic("bte_error_handler(): Fatal BTE Error"); 206 }
169 } 207 }
170 208
171 for (i = 0; i < BTES_PER_NODE; i++) { 209 for (i = 0; i < BTES_PER_NODE; i++) {
diff --git a/arch/ia64/sn/kernel/huberror.c b/arch/ia64/sn/kernel/huberror.c
index 5c5eb01c50f0..56ab6bae00ee 100644
--- a/arch/ia64/sn/kernel/huberror.c
+++ b/arch/ia64/sn/kernel/huberror.c
@@ -32,13 +32,14 @@ static irqreturn_t hub_eint_handler(int irq, void *arg, struct pt_regs *ep)
32 ret_stuff.v0 = 0; 32 ret_stuff.v0 = 0;
33 hubdev_info = (struct hubdev_info *)arg; 33 hubdev_info = (struct hubdev_info *)arg;
34 nasid = hubdev_info->hdi_nasid; 34 nasid = hubdev_info->hdi_nasid;
35 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT, 35
36 if (is_shub1()) {
37 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT,
36 (u64) nasid, 0, 0, 0, 0, 0, 0); 38 (u64) nasid, 0, 0, 0, 0, 0, 0);
37 39
38 if ((int)ret_stuff.v0) 40 if ((int)ret_stuff.v0)
39 panic("hubii_eint_handler(): Fatal TIO Error"); 41 panic("hubii_eint_handler(): Fatal TIO Error");
40 42
41 if (is_shub1()) {
42 if (!(nasid & 1)) /* Not a TIO, handle CRB errors */ 43 if (!(nasid & 1)) /* Not a TIO, handle CRB errors */
43 (void)hubiio_crb_error_handler(hubdev_info); 44 (void)hubiio_crb_error_handler(hubdev_info);
44 } else 45 } else
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 318087e35b66..258d9d7aff98 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -76,11 +76,12 @@ static struct sn_pcibus_provider sn_pci_default_provider = {
76}; 76};
77 77
78/* 78/*
79 * Retrieve the DMA Flush List given nasid. This list is needed 79 * Retrieve the DMA Flush List given nasid, widget, and device.
80 * to implement the WAR - Flush DMA data on PIO Reads. 80 * This list is needed to implement the WAR - Flush DMA data on PIO Reads.
81 */ 81 */
82static inline uint64_t 82static inline u64
83sal_get_widget_dmaflush_list(u64 nasid, u64 widget_num, u64 address) 83sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num,
84 u64 address)
84{ 85{
85 86
86 struct ia64_sal_retval ret_stuff; 87 struct ia64_sal_retval ret_stuff;
@@ -88,17 +89,17 @@ sal_get_widget_dmaflush_list(u64 nasid, u64 widget_num, u64 address)
88 ret_stuff.v0 = 0; 89 ret_stuff.v0 = 0;
89 90
90 SAL_CALL_NOLOCK(ret_stuff, 91 SAL_CALL_NOLOCK(ret_stuff,
91 (u64) SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, 92 (u64) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST,
92 (u64) nasid, (u64) widget_num, (u64) address, 0, 0, 0, 93 (u64) nasid, (u64) widget_num,
93 0); 94 (u64) device_num, (u64) address, 0, 0, 0);
94 return ret_stuff.v0; 95 return ret_stuff.status;
95 96
96} 97}
97 98
98/* 99/*
99 * Retrieve the hub device info structure for the given nasid. 100 * Retrieve the hub device info structure for the given nasid.
100 */ 101 */
101static inline uint64_t sal_get_hubdev_info(u64 handle, u64 address) 102static inline u64 sal_get_hubdev_info(u64 handle, u64 address)
102{ 103{
103 104
104 struct ia64_sal_retval ret_stuff; 105 struct ia64_sal_retval ret_stuff;
@@ -114,7 +115,7 @@ static inline uint64_t sal_get_hubdev_info(u64 handle, u64 address)
114/* 115/*
115 * Retrieve the pci bus information given the bus number. 116 * Retrieve the pci bus information given the bus number.
116 */ 117 */
117static inline uint64_t sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) 118static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address)
118{ 119{
119 120
120 struct ia64_sal_retval ret_stuff; 121 struct ia64_sal_retval ret_stuff;
@@ -130,7 +131,7 @@ static inline uint64_t sal_get_pcibus_info(u64 segment, u64 busnum, u64 address)
130/* 131/*
131 * Retrieve the pci device information given the bus and device|function number. 132 * Retrieve the pci device information given the bus and device|function number.
132 */ 133 */
133static inline uint64_t 134static inline u64
134sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, 135sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev,
135 u64 sn_irq_info) 136 u64 sn_irq_info)
136{ 137{
@@ -170,12 +171,12 @@ sn_pcidev_info_get(struct pci_dev *dev)
170 */ 171 */
171static void sn_fixup_ionodes(void) 172static void sn_fixup_ionodes(void)
172{ 173{
173 174 struct sn_flush_device_kernel *sn_flush_device_kernel;
174 struct sn_flush_device_list *sn_flush_device_list; 175 struct sn_flush_device_kernel *dev_entry;
175 struct hubdev_info *hubdev; 176 struct hubdev_info *hubdev;
176 uint64_t status; 177 u64 status;
177 uint64_t nasid; 178 u64 nasid;
178 int i, widget; 179 int i, widget, device;
179 180
180 /* 181 /*
181 * Get SGI Specific HUB chipset information. 182 * Get SGI Specific HUB chipset information.
@@ -186,7 +187,7 @@ static void sn_fixup_ionodes(void)
186 nasid = cnodeid_to_nasid(i); 187 nasid = cnodeid_to_nasid(i);
187 hubdev->max_segment_number = 0xffffffff; 188 hubdev->max_segment_number = 0xffffffff;
188 hubdev->max_pcibus_number = 0xff; 189 hubdev->max_pcibus_number = 0xff;
189 status = sal_get_hubdev_info(nasid, (uint64_t) __pa(hubdev)); 190 status = sal_get_hubdev_info(nasid, (u64) __pa(hubdev));
190 if (status) 191 if (status)
191 continue; 192 continue;
192 193
@@ -213,38 +214,49 @@ static void sn_fixup_ionodes(void)
213 214
214 hubdev->hdi_flush_nasid_list.widget_p = 215 hubdev->hdi_flush_nasid_list.widget_p =
215 kmalloc((HUB_WIDGET_ID_MAX + 1) * 216 kmalloc((HUB_WIDGET_ID_MAX + 1) *
216 sizeof(struct sn_flush_device_list *), GFP_KERNEL); 217 sizeof(struct sn_flush_device_kernel *),
217 218 GFP_KERNEL);
218 memset(hubdev->hdi_flush_nasid_list.widget_p, 0x0, 219 memset(hubdev->hdi_flush_nasid_list.widget_p, 0x0,
219 (HUB_WIDGET_ID_MAX + 1) * 220 (HUB_WIDGET_ID_MAX + 1) *
220 sizeof(struct sn_flush_device_list *)); 221 sizeof(struct sn_flush_device_kernel *));
221 222
222 for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { 223 for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) {
223 sn_flush_device_list = kmalloc(DEV_PER_WIDGET * 224 sn_flush_device_kernel = kmalloc(DEV_PER_WIDGET *
224 sizeof(struct 225 sizeof(struct
225 sn_flush_device_list), 226 sn_flush_device_kernel),
226 GFP_KERNEL); 227 GFP_KERNEL);
227 memset(sn_flush_device_list, 0x0, 228 if (!sn_flush_device_kernel)
229 BUG();
230 memset(sn_flush_device_kernel, 0x0,
228 DEV_PER_WIDGET * 231 DEV_PER_WIDGET *
229 sizeof(struct sn_flush_device_list)); 232 sizeof(struct sn_flush_device_kernel));
230 233
231 status = 234 dev_entry = sn_flush_device_kernel;
232 sal_get_widget_dmaflush_list(nasid, widget, 235 for (device = 0; device < DEV_PER_WIDGET;
233 (uint64_t) 236 device++,dev_entry++) {
234 __pa 237 dev_entry->common = kmalloc(sizeof(struct
235 (sn_flush_device_list)); 238 sn_flush_device_common),
236 if (status) { 239 GFP_KERNEL);
237 kfree(sn_flush_device_list); 240 if (!dev_entry->common)
238 continue; 241 BUG();
242 memset(dev_entry->common, 0x0, sizeof(struct
243 sn_flush_device_common));
244
245 status = sal_get_device_dmaflush_list(nasid,
246 widget,
247 device,
248 (u64)(dev_entry->common));
249 if (status)
250 BUG();
251
252 spin_lock_init(&dev_entry->sfdl_flush_lock);
239 } 253 }
240 254
241 spin_lock_init(&sn_flush_device_list->sfdl_flush_lock); 255 if (sn_flush_device_kernel)
242 hubdev->hdi_flush_nasid_list.widget_p[widget] = 256 hubdev->hdi_flush_nasid_list.widget_p[widget] =
243 sn_flush_device_list; 257 sn_flush_device_kernel;
244 } 258 }
245
246 } 259 }
247
248} 260}
249 261
250/* 262/*
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index abf4fc2a87bb..0c0a68902409 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9 9
@@ -24,7 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <asm/sn/bte.h> 25#include <asm/sn/bte.h>
26#include <asm/sn/sn_sal.h> 26#include <asm/sn/sn_sal.h>
27#include "xpc.h" 27#include <asm/sn/xpc.h>
28 28
29 29
30/* 30/*
@@ -779,6 +779,12 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
779 779
780 /* both sides are disconnected now */ 780 /* both sides are disconnected now */
781 781
782 if (ch->flags & XPC_C_CONNECTCALLOUT) {
783 spin_unlock_irqrestore(&ch->lock, *irq_flags);
784 xpc_disconnect_callout(ch, xpcDisconnected);
785 spin_lock_irqsave(&ch->lock, *irq_flags);
786 }
787
782 /* it's now safe to free the channel's message queues */ 788 /* it's now safe to free the channel's message queues */
783 xpc_free_msgqueues(ch); 789 xpc_free_msgqueues(ch);
784 790
@@ -1645,7 +1651,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
1645 1651
1646 1652
1647void 1653void
1648xpc_disconnecting_callout(struct xpc_channel *ch) 1654xpc_disconnect_callout(struct xpc_channel *ch, enum xpc_retval reason)
1649{ 1655{
1650 /* 1656 /*
1651 * Let the channel's registerer know that the channel is being 1657 * Let the channel's registerer know that the channel is being
@@ -1654,15 +1660,13 @@ xpc_disconnecting_callout(struct xpc_channel *ch)
1654 */ 1660 */
1655 1661
1656 if (ch->func != NULL) { 1662 if (ch->func != NULL) {
1657 dev_dbg(xpc_chan, "ch->func() called, reason=xpcDisconnecting," 1663 dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, "
1658 " partid=%d, channel=%d\n", ch->partid, ch->number); 1664 "channel=%d\n", reason, ch->partid, ch->number);
1659 1665
1660 ch->func(xpcDisconnecting, ch->partid, ch->number, NULL, 1666 ch->func(reason, ch->partid, ch->number, NULL, ch->key);
1661 ch->key);
1662 1667
1663 dev_dbg(xpc_chan, "ch->func() returned, reason=" 1668 dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, "
1664 "xpcDisconnecting, partid=%d, channel=%d\n", 1669 "channel=%d\n", reason, ch->partid, ch->number);
1665 ch->partid, ch->number);
1666 } 1670 }
1667} 1671}
1668 1672
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index b617236524c6..8930586e0eb4 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9 9
@@ -59,7 +59,7 @@
59#include <asm/sn/sn_sal.h> 59#include <asm/sn/sn_sal.h>
60#include <asm/kdebug.h> 60#include <asm/kdebug.h>
61#include <asm/uaccess.h> 61#include <asm/uaccess.h>
62#include "xpc.h" 62#include <asm/sn/xpc.h>
63 63
64 64
65/* define two XPC debug device structures to be used with dev_dbg() et al */ 65/* define two XPC debug device structures to be used with dev_dbg() et al */
@@ -82,6 +82,9 @@ struct device *xpc_part = &xpc_part_dbg_subname;
82struct device *xpc_chan = &xpc_chan_dbg_subname; 82struct device *xpc_chan = &xpc_chan_dbg_subname;
83 83
84 84
85static int xpc_kdebug_ignore;
86
87
85/* systune related variables for /proc/sys directories */ 88/* systune related variables for /proc/sys directories */
86 89
87static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; 90static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL;
@@ -162,6 +165,8 @@ static ctl_table xpc_sys_dir[] = {
162}; 165};
163static struct ctl_table_header *xpc_sysctl; 166static struct ctl_table_header *xpc_sysctl;
164 167
168/* non-zero if any remote partition disengage request was timed out */
169int xpc_disengage_request_timedout;
165 170
166/* #of IRQs received */ 171/* #of IRQs received */
167static atomic_t xpc_act_IRQ_rcvd; 172static atomic_t xpc_act_IRQ_rcvd;
@@ -773,7 +778,7 @@ xpc_daemonize_kthread(void *args)
773 ch->flags |= XPC_C_DISCONNECTCALLOUT; 778 ch->flags |= XPC_C_DISCONNECTCALLOUT;
774 spin_unlock_irqrestore(&ch->lock, irq_flags); 779 spin_unlock_irqrestore(&ch->lock, irq_flags);
775 780
776 xpc_disconnecting_callout(ch); 781 xpc_disconnect_callout(ch, xpcDisconnecting);
777 } else { 782 } else {
778 spin_unlock_irqrestore(&ch->lock, irq_flags); 783 spin_unlock_irqrestore(&ch->lock, irq_flags);
779 } 784 }
@@ -921,9 +926,9 @@ static void
921xpc_do_exit(enum xpc_retval reason) 926xpc_do_exit(enum xpc_retval reason)
922{ 927{
923 partid_t partid; 928 partid_t partid;
924 int active_part_count; 929 int active_part_count, printed_waiting_msg = 0;
925 struct xpc_partition *part; 930 struct xpc_partition *part;
926 unsigned long printmsg_time; 931 unsigned long printmsg_time, disengage_request_timeout = 0;
927 932
928 933
929 /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */ 934 /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */
@@ -953,7 +958,8 @@ xpc_do_exit(enum xpc_retval reason)
953 958
954 /* wait for all partitions to become inactive */ 959 /* wait for all partitions to become inactive */
955 960
956 printmsg_time = jiffies; 961 printmsg_time = jiffies + (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ);
962 xpc_disengage_request_timedout = 0;
957 963
958 do { 964 do {
959 active_part_count = 0; 965 active_part_count = 0;
@@ -969,20 +975,39 @@ xpc_do_exit(enum xpc_retval reason)
969 active_part_count++; 975 active_part_count++;
970 976
971 XPC_DEACTIVATE_PARTITION(part, reason); 977 XPC_DEACTIVATE_PARTITION(part, reason);
972 }
973 978
974 if (active_part_count == 0) { 979 if (part->disengage_request_timeout >
975 break; 980 disengage_request_timeout) {
981 disengage_request_timeout =
982 part->disengage_request_timeout;
983 }
976 } 984 }
977 985
978 if (jiffies >= printmsg_time) { 986 if (xpc_partition_engaged(-1UL)) {
979 dev_info(xpc_part, "waiting for partitions to " 987 if (time_after(jiffies, printmsg_time)) {
980 "deactivate/disengage, active count=%d, remote " 988 dev_info(xpc_part, "waiting for remote "
981 "engaged=0x%lx\n", active_part_count, 989 "partitions to disengage, timeout in "
982 xpc_partition_engaged(1UL << partid)); 990 "%ld seconds\n",
983 991 (disengage_request_timeout - jiffies)
984 printmsg_time = jiffies + 992 / HZ);
993 printmsg_time = jiffies +
985 (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); 994 (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ);
995 printed_waiting_msg = 1;
996 }
997
998 } else if (active_part_count > 0) {
999 if (printed_waiting_msg) {
1000 dev_info(xpc_part, "waiting for local partition"
1001 " to disengage\n");
1002 printed_waiting_msg = 0;
1003 }
1004
1005 } else {
1006 if (!xpc_disengage_request_timedout) {
1007 dev_info(xpc_part, "all partitions have "
1008 "disengaged\n");
1009 }
1010 break;
986 } 1011 }
987 1012
988 /* sleep for a 1/3 of a second or so */ 1013 /* sleep for a 1/3 of a second or so */
@@ -1000,11 +1025,13 @@ xpc_do_exit(enum xpc_retval reason)
1000 del_timer_sync(&xpc_hb_timer); 1025 del_timer_sync(&xpc_hb_timer);
1001 DBUG_ON(xpc_vars->heartbeating_to_mask != 0); 1026 DBUG_ON(xpc_vars->heartbeating_to_mask != 0);
1002 1027
1003 /* take ourselves off of the reboot_notifier_list */ 1028 if (reason == xpcUnloading) {
1004 (void) unregister_reboot_notifier(&xpc_reboot_notifier); 1029 /* take ourselves off of the reboot_notifier_list */
1030 (void) unregister_reboot_notifier(&xpc_reboot_notifier);
1005 1031
1006 /* take ourselves off of the die_notifier list */ 1032 /* take ourselves off of the die_notifier list */
1007 (void) unregister_die_notifier(&xpc_die_notifier); 1033 (void) unregister_die_notifier(&xpc_die_notifier);
1034 }
1008 1035
1009 /* close down protections for IPI operations */ 1036 /* close down protections for IPI operations */
1010 xpc_restrict_IPI_ops(); 1037 xpc_restrict_IPI_ops();
@@ -1020,7 +1047,35 @@ xpc_do_exit(enum xpc_retval reason)
1020 1047
1021 1048
1022/* 1049/*
1023 * Called when the system is about to be either restarted or halted. 1050 * This function is called when the system is being rebooted.
1051 */
1052static int
1053xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
1054{
1055 enum xpc_retval reason;
1056
1057
1058 switch (event) {
1059 case SYS_RESTART:
1060 reason = xpcSystemReboot;
1061 break;
1062 case SYS_HALT:
1063 reason = xpcSystemHalt;
1064 break;
1065 case SYS_POWER_OFF:
1066 reason = xpcSystemPoweroff;
1067 break;
1068 default:
1069 reason = xpcSystemGoingDown;
1070 }
1071
1072 xpc_do_exit(reason);
1073 return NOTIFY_DONE;
1074}
1075
1076
1077/*
1078 * Notify other partitions to disengage from all references to our memory.
1024 */ 1079 */
1025static void 1080static void
1026xpc_die_disengage(void) 1081xpc_die_disengage(void)
@@ -1028,7 +1083,7 @@ xpc_die_disengage(void)
1028 struct xpc_partition *part; 1083 struct xpc_partition *part;
1029 partid_t partid; 1084 partid_t partid;
1030 unsigned long engaged; 1085 unsigned long engaged;
1031 long time, print_time, disengage_request_timeout; 1086 long time, printmsg_time, disengage_request_timeout;
1032 1087
1033 1088
1034 /* keep xpc_hb_checker thread from doing anything (just in case) */ 1089 /* keep xpc_hb_checker thread from doing anything (just in case) */
@@ -1055,57 +1110,53 @@ xpc_die_disengage(void)
1055 } 1110 }
1056 } 1111 }
1057 1112
1058 print_time = rtc_time(); 1113 time = rtc_time();
1059 disengage_request_timeout = print_time + 1114 printmsg_time = time +
1115 (XPC_DISENGAGE_PRINTMSG_INTERVAL * sn_rtc_cycles_per_second);
1116 disengage_request_timeout = time +
1060 (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second); 1117 (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second);
1061 1118
1062 /* wait for all other partitions to disengage from us */ 1119 /* wait for all other partitions to disengage from us */
1063 1120
1064 while ((engaged = xpc_partition_engaged(-1UL)) && 1121 while (1) {
1065 (time = rtc_time()) < disengage_request_timeout) { 1122 engaged = xpc_partition_engaged(-1UL);
1123 if (!engaged) {
1124 dev_info(xpc_part, "all partitions have disengaged\n");
1125 break;
1126 }
1066 1127
1067 if (time >= print_time) { 1128 time = rtc_time();
1129 if (time >= disengage_request_timeout) {
1130 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
1131 if (engaged & (1UL << partid)) {
1132 dev_info(xpc_part, "disengage from "
1133 "remote partition %d timed "
1134 "out\n", partid);
1135 }
1136 }
1137 break;
1138 }
1139
1140 if (time >= printmsg_time) {
1068 dev_info(xpc_part, "waiting for remote partitions to " 1141 dev_info(xpc_part, "waiting for remote partitions to "
1069 "disengage, engaged=0x%lx\n", engaged); 1142 "disengage, timeout in %ld seconds\n",
1070 print_time = time + (XPC_DISENGAGE_PRINTMSG_INTERVAL * 1143 (disengage_request_timeout - time) /
1144 sn_rtc_cycles_per_second);
1145 printmsg_time = time +
1146 (XPC_DISENGAGE_PRINTMSG_INTERVAL *
1071 sn_rtc_cycles_per_second); 1147 sn_rtc_cycles_per_second);
1072 } 1148 }
1073 } 1149 }
1074 dev_info(xpc_part, "finished waiting for remote partitions to "
1075 "disengage, engaged=0x%lx\n", engaged);
1076}
1077
1078
1079/*
1080 * This function is called when the system is being rebooted.
1081 */
1082static int
1083xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
1084{
1085 enum xpc_retval reason;
1086
1087
1088 switch (event) {
1089 case SYS_RESTART:
1090 reason = xpcSystemReboot;
1091 break;
1092 case SYS_HALT:
1093 reason = xpcSystemHalt;
1094 break;
1095 case SYS_POWER_OFF:
1096 reason = xpcSystemPoweroff;
1097 break;
1098 default:
1099 reason = xpcSystemGoingDown;
1100 }
1101
1102 xpc_do_exit(reason);
1103 return NOTIFY_DONE;
1104} 1150}
1105 1151
1106 1152
1107/* 1153/*
1108 * This function is called when the system is being rebooted. 1154 * This function is called when the system is being restarted or halted due
1155 * to some sort of system failure. If this is the case we need to notify the
1156 * other partitions to disengage from all references to our memory.
1157 * This function can also be called when our heartbeater could be offlined
1158 * for a time. In this case we need to notify other partitions to not worry
1159 * about the lack of a heartbeat.
1109 */ 1160 */
1110static int 1161static int
1111xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) 1162xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
@@ -1115,11 +1166,25 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
1115 case DIE_MACHINE_HALT: 1166 case DIE_MACHINE_HALT:
1116 xpc_die_disengage(); 1167 xpc_die_disengage();
1117 break; 1168 break;
1169
1170 case DIE_KDEBUG_ENTER:
1171 /* Should lack of heartbeat be ignored by other partitions? */
1172 if (!xpc_kdebug_ignore) {
1173 break;
1174 }
1175 /* fall through */
1118 case DIE_MCA_MONARCH_ENTER: 1176 case DIE_MCA_MONARCH_ENTER:
1119 case DIE_INIT_MONARCH_ENTER: 1177 case DIE_INIT_MONARCH_ENTER:
1120 xpc_vars->heartbeat++; 1178 xpc_vars->heartbeat++;
1121 xpc_vars->heartbeat_offline = 1; 1179 xpc_vars->heartbeat_offline = 1;
1122 break; 1180 break;
1181
1182 case DIE_KDEBUG_LEAVE:
1183 /* Is lack of heartbeat being ignored by other partitions? */
1184 if (!xpc_kdebug_ignore) {
1185 break;
1186 }
1187 /* fall through */
1123 case DIE_MCA_MONARCH_LEAVE: 1188 case DIE_MCA_MONARCH_LEAVE:
1124 case DIE_INIT_MONARCH_LEAVE: 1189 case DIE_INIT_MONARCH_LEAVE:
1125 xpc_vars->heartbeat++; 1190 xpc_vars->heartbeat++;
@@ -1344,3 +1409,7 @@ module_param(xpc_disengage_request_timelimit, int, 0);
1344MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait " 1409MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait "
1345 "for disengage request to complete."); 1410 "for disengage request to complete.");
1346 1411
1412module_param(xpc_kdebug_ignore, int, 0);
1413MODULE_PARM_DESC(xpc_kdebug_ignore, "Should lack of heartbeat be ignored by "
1414 "other partitions when dropping into kdebug.");
1415
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
index cdd6431853a1..88a730e6cfdb 100644
--- a/arch/ia64/sn/kernel/xpc_partition.c
+++ b/arch/ia64/sn/kernel/xpc_partition.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9 9
@@ -28,7 +28,7 @@
28#include <asm/sn/sn_sal.h> 28#include <asm/sn/sn_sal.h>
29#include <asm/sn/nodepda.h> 29#include <asm/sn/nodepda.h>
30#include <asm/sn/addrs.h> 30#include <asm/sn/addrs.h>
31#include "xpc.h" 31#include <asm/sn/xpc.h>
32 32
33 33
34/* XPC is exiting flag */ 34/* XPC is exiting flag */
@@ -771,7 +771,8 @@ xpc_identify_act_IRQ_req(int nasid)
771 } 771 }
772 } 772 }
773 773
774 if (!xpc_partition_disengaged(part)) { 774 if (part->disengage_request_timeout > 0 &&
775 !xpc_partition_disengaged(part)) {
775 /* still waiting on other side to disengage from us */ 776 /* still waiting on other side to disengage from us */
776 return; 777 return;
777 } 778 }
@@ -873,6 +874,9 @@ xpc_partition_disengaged(struct xpc_partition *part)
873 * request in a timely fashion, so assume it's dead. 874 * request in a timely fashion, so assume it's dead.
874 */ 875 */
875 876
877 dev_info(xpc_part, "disengage from remote partition %d "
878 "timed out\n", partid);
879 xpc_disengage_request_timedout = 1;
876 xpc_clear_partition_engaged(1UL << partid); 880 xpc_clear_partition_engaged(1UL << partid);
877 disengaged = 1; 881 disengaged = 1;
878 } 882 }
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
index 34093476e965..e68332d93171 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -218,7 +218,9 @@ void sn_dma_flush(uint64_t addr)
218 uint64_t flags; 218 uint64_t flags;
219 uint64_t itte; 219 uint64_t itte;
220 struct hubdev_info *hubinfo; 220 struct hubdev_info *hubinfo;
221 volatile struct sn_flush_device_list *p; 221 volatile struct sn_flush_device_kernel *p;
222 volatile struct sn_flush_device_common *common;
223
222 struct sn_flush_nasid_entry *flush_nasid_list; 224 struct sn_flush_nasid_entry *flush_nasid_list;
223 225
224 if (!sn_ioif_inited) 226 if (!sn_ioif_inited)
@@ -268,17 +270,17 @@ void sn_dma_flush(uint64_t addr)
268 p = &flush_nasid_list->widget_p[wid_num][0]; 270 p = &flush_nasid_list->widget_p[wid_num][0];
269 271
270 /* find a matching BAR */ 272 /* find a matching BAR */
271 for (i = 0; i < DEV_PER_WIDGET; i++) { 273 for (i = 0; i < DEV_PER_WIDGET; i++,p++) {
274 common = p->common;
272 for (j = 0; j < PCI_ROM_RESOURCE; j++) { 275 for (j = 0; j < PCI_ROM_RESOURCE; j++) {
273 if (p->sfdl_bar_list[j].start == 0) 276 if (common->sfdl_bar_list[j].start == 0)
274 break; 277 break;
275 if (addr >= p->sfdl_bar_list[j].start 278 if (addr >= common->sfdl_bar_list[j].start
276 && addr <= p->sfdl_bar_list[j].end) 279 && addr <= common->sfdl_bar_list[j].end)
277 break; 280 break;
278 } 281 }
279 if (j < PCI_ROM_RESOURCE && p->sfdl_bar_list[j].start != 0) 282 if (j < PCI_ROM_RESOURCE && common->sfdl_bar_list[j].start != 0)
280 break; 283 break;
281 p++;
282 } 284 }
283 285
284 /* if no matching BAR, return without doing anything. */ 286 /* if no matching BAR, return without doing anything. */
@@ -304,24 +306,24 @@ void sn_dma_flush(uint64_t addr)
304 if ((1 << XWIDGET_PART_REV_NUM_REV(revnum)) & PV907516) { 306 if ((1 << XWIDGET_PART_REV_NUM_REV(revnum)) & PV907516) {
305 return; 307 return;
306 } else { 308 } else {
307 pcireg_wrb_flush_get(p->sfdl_pcibus_info, 309 pcireg_wrb_flush_get(common->sfdl_pcibus_info,
308 (p->sfdl_slot - 1)); 310 (common->sfdl_slot - 1));
309 } 311 }
310 } else { 312 } else {
311 spin_lock_irqsave(&((struct sn_flush_device_list *)p)-> 313 spin_lock_irqsave((spinlock_t *)&p->sfdl_flush_lock,
312 sfdl_flush_lock, flags); 314 flags);
313 315 *common->sfdl_flush_addr = 0;
314 *p->sfdl_flush_addr = 0;
315 316
316 /* force an interrupt. */ 317 /* force an interrupt. */
317 *(volatile uint32_t *)(p->sfdl_force_int_addr) = 1; 318 *(volatile uint32_t *)(common->sfdl_force_int_addr) = 1;
318 319
319 /* wait for the interrupt to come back. */ 320 /* wait for the interrupt to come back. */
320 while (*(p->sfdl_flush_addr) != 0x10f) 321 while (*(common->sfdl_flush_addr) != 0x10f)
321 cpu_relax(); 322 cpu_relax();
322 323
323 /* okay, everything is synched up. */ 324 /* okay, everything is synched up. */
324 spin_unlock_irqrestore((spinlock_t *)&p->sfdl_flush_lock, flags); 325 spin_unlock_irqrestore((spinlock_t *)&p->sfdl_flush_lock,
326 flags);
325 } 327 }
326 return; 328 return;
327} 329}
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 1f500c81002c..e328e948175d 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -92,7 +92,8 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
92 cnodeid_t near_cnode; 92 cnodeid_t near_cnode;
93 struct hubdev_info *hubdev_info; 93 struct hubdev_info *hubdev_info;
94 struct pcibus_info *soft; 94 struct pcibus_info *soft;
95 struct sn_flush_device_list *sn_flush_device_list; 95 struct sn_flush_device_kernel *sn_flush_device_kernel;
96 struct sn_flush_device_common *common;
96 97
97 if (! IS_PCI_BRIDGE_ASIC(prom_bussoft->bs_asic_type)) { 98 if (! IS_PCI_BRIDGE_ASIC(prom_bussoft->bs_asic_type)) {
98 return NULL; 99 return NULL;
@@ -137,20 +138,19 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
137 hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); 138 hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
138 139
139 if (hubdev_info->hdi_flush_nasid_list.widget_p) { 140 if (hubdev_info->hdi_flush_nasid_list.widget_p) {
140 sn_flush_device_list = hubdev_info->hdi_flush_nasid_list. 141 sn_flush_device_kernel = hubdev_info->hdi_flush_nasid_list.
141 widget_p[(int)soft->pbi_buscommon.bs_xid]; 142 widget_p[(int)soft->pbi_buscommon.bs_xid];
142 if (sn_flush_device_list) { 143 if (sn_flush_device_kernel) {
143 for (j = 0; j < DEV_PER_WIDGET; 144 for (j = 0; j < DEV_PER_WIDGET;
144 j++, sn_flush_device_list++) { 145 j++, sn_flush_device_kernel++) {
145 if (sn_flush_device_list->sfdl_slot == -1) 146 common = sn_flush_device_kernel->common;
147 if (common->sfdl_slot == -1)
146 continue; 148 continue;
147 if ((sn_flush_device_list-> 149 if ((common->sfdl_persistent_segment ==
148 sfdl_persistent_segment ==
149 soft->pbi_buscommon.bs_persist_segment) && 150 soft->pbi_buscommon.bs_persist_segment) &&
150 (sn_flush_device_list-> 151 (common->sfdl_persistent_busnum ==
151 sfdl_persistent_busnum ==
152 soft->pbi_buscommon.bs_persist_busnum)) 152 soft->pbi_buscommon.bs_persist_busnum))
153 sn_flush_device_list->sfdl_pcibus_info = 153 common->sfdl_pcibus_info =
154 soft; 154 soft;
155 } 155 }
156 } 156 }
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h
index a74b68104559..8c0fc227f0fb 100644
--- a/include/asm-ia64/kprobes.h
+++ b/include/asm-ia64/kprobes.h
@@ -68,10 +68,14 @@ struct prev_kprobe {
68 unsigned long status; 68 unsigned long status;
69}; 69};
70 70
71#define MAX_PARAM_RSE_SIZE (0x60+0x60/0x3f)
71/* per-cpu kprobe control block */ 72/* per-cpu kprobe control block */
72struct kprobe_ctlblk { 73struct kprobe_ctlblk {
73 unsigned long kprobe_status; 74 unsigned long kprobe_status;
74 struct pt_regs jprobe_saved_regs; 75 struct pt_regs jprobe_saved_regs;
76 unsigned long jprobes_saved_stacked_regs[MAX_PARAM_RSE_SIZE];
77 unsigned long *bsp;
78 unsigned long cfm;
75 struct prev_kprobe prev_kprobe; 79 struct prev_kprobe prev_kprobe;
76}; 80};
77 81
@@ -118,5 +122,7 @@ extern int kprobe_exceptions_notify(struct notifier_block *self,
118static inline void jprobe_return(void) 122static inline void jprobe_return(void)
119{ 123{
120} 124}
125extern void invalidate_stacked_regs(void);
126extern void flush_register_stack(void);
121 127
122#endif /* _ASM_KPROBES_H */ 128#endif /* _ASM_KPROBES_H */
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
index 2a8b0d92a5d6..8b9e10e7cdba 100644
--- a/include/asm-ia64/sn/sn_sal.h
+++ b/include/asm-ia64/sn/sn_sal.h
@@ -75,7 +75,8 @@
75#define SN_SAL_IOIF_GET_HUBDEV_INFO 0x02000055 75#define SN_SAL_IOIF_GET_HUBDEV_INFO 0x02000055
76#define SN_SAL_IOIF_GET_PCIBUS_INFO 0x02000056 76#define SN_SAL_IOIF_GET_PCIBUS_INFO 0x02000056
77#define SN_SAL_IOIF_GET_PCIDEV_INFO 0x02000057 77#define SN_SAL_IOIF_GET_PCIDEV_INFO 0x02000057
78#define SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST 0x02000058 78#define SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST 0x02000058 // deprecated
79#define SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST 0x0200005a
79 80
80#define SN_SAL_HUB_ERROR_INTERRUPT 0x02000060 81#define SN_SAL_HUB_ERROR_INTERRUPT 0x02000060
81#define SN_SAL_BTE_RECOVER 0x02000061 82#define SN_SAL_BTE_RECOVER 0x02000061
@@ -1100,7 +1101,7 @@ ia64_sn_bte_recovery(nasid_t nasid)
1100 struct ia64_sal_retval rv; 1101 struct ia64_sal_retval rv;
1101 1102
1102 rv.status = 0; 1103 rv.status = 0;
1103 SAL_CALL_NOLOCK(rv, SN_SAL_BTE_RECOVER, 0, 0, 0, 0, 0, 0, 0); 1104 SAL_CALL_NOLOCK(rv, SN_SAL_BTE_RECOVER, (u64)nasid, 0, 0, 0, 0, 0, 0);
1104 if (rv.status == SALRET_NOT_IMPLEMENTED) 1105 if (rv.status == SALRET_NOT_IMPLEMENTED)
1105 return 0; 1106 return 0;
1106 return (int) rv.status; 1107 return (int) rv.status;
diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h
index 49faf8f26430..203945ae034e 100644
--- a/include/asm-ia64/sn/xp.h
+++ b/include/asm-ia64/sn/xp.h
@@ -227,7 +227,9 @@ enum xpc_retval {
227 227
228 xpcOpenCloseError, /* 50: channel open/close protocol error */ 228 xpcOpenCloseError, /* 50: channel open/close protocol error */
229 229
230 xpcUnknownReason /* 51: unknown reason -- must be last in list */ 230 xpcDisconnected, /* 51: channel disconnected (closed) */
231
232 xpcUnknownReason /* 52: unknown reason -- must be last in list */
231}; 233};
232 234
233 235
diff --git a/arch/ia64/sn/kernel/xpc.h b/include/asm-ia64/sn/xpc.h
index 5483a9f227d4..87e9cd588510 100644
--- a/arch/ia64/sn/kernel/xpc.h
+++ b/include/asm-ia64/sn/xpc.h
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9 9
@@ -11,8 +11,8 @@
11 * Cross Partition Communication (XPC) structures and macros. 11 * Cross Partition Communication (XPC) structures and macros.
12 */ 12 */
13 13
14#ifndef _IA64_SN_KERNEL_XPC_H 14#ifndef _ASM_IA64_SN_XPC_H
15#define _IA64_SN_KERNEL_XPC_H 15#define _ASM_IA64_SN_XPC_H
16 16
17 17
18#include <linux/config.h> 18#include <linux/config.h>
@@ -663,6 +663,7 @@ extern struct xpc_registration xpc_registrations[];
663extern struct device *xpc_part; 663extern struct device *xpc_part;
664extern struct device *xpc_chan; 664extern struct device *xpc_chan;
665extern int xpc_disengage_request_timelimit; 665extern int xpc_disengage_request_timelimit;
666extern int xpc_disengage_request_timedout;
666extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *); 667extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *);
667extern void xpc_dropped_IPI_check(struct xpc_partition *); 668extern void xpc_dropped_IPI_check(struct xpc_partition *);
668extern void xpc_activate_partition(struct xpc_partition *); 669extern void xpc_activate_partition(struct xpc_partition *);
@@ -707,7 +708,7 @@ extern void xpc_connected_callout(struct xpc_channel *);
707extern void xpc_deliver_msg(struct xpc_channel *); 708extern void xpc_deliver_msg(struct xpc_channel *);
708extern void xpc_disconnect_channel(const int, struct xpc_channel *, 709extern void xpc_disconnect_channel(const int, struct xpc_channel *,
709 enum xpc_retval, unsigned long *); 710 enum xpc_retval, unsigned long *);
710extern void xpc_disconnecting_callout(struct xpc_channel *); 711extern void xpc_disconnect_callout(struct xpc_channel *, enum xpc_retval);
711extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval); 712extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval);
712extern void xpc_teardown_infrastructure(struct xpc_partition *); 713extern void xpc_teardown_infrastructure(struct xpc_partition *);
713 714
@@ -1269,5 +1270,5 @@ xpc_check_for_channel_activity(struct xpc_partition *part)
1269} 1270}
1270 1271
1271 1272
1272#endif /* _IA64_SN_KERNEL_XPC_H */ 1273#endif /* _ASM_IA64_SN_XPC_H */
1273 1274
diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
index 653bb7f9a753..1d6518fe1f02 100644
--- a/include/asm-ia64/thread_info.h
+++ b/include/asm-ia64/thread_info.h
@@ -93,6 +93,7 @@ struct thread_info {
93#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ 93#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
94#define TIF_MEMDIE 17 94#define TIF_MEMDIE 17
95#define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */ 95#define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */
96#define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */
96 97
97#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 98#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
98#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) 99#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
@@ -100,9 +101,10 @@ struct thread_info {
100#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) 101#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
101#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 102#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
102#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 103#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
103#define _TIF_SIGDELAYED (1 << TIF_SIGDELAYED) 104#define _TIF_SIGDELAYED (1 << TIF_SIGDELAYED)
104#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) 105#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
105#define _TIF_MCA_INIT (1 << TIF_MCA_INIT) 106#define _TIF_MCA_INIT (1 << TIF_MCA_INIT)
107#define _TIF_DB_DISABLED (1 << TIF_DB_DISABLED)
106 108
107/* "work to do on user-return" bits */ 109/* "work to do on user-return" bits */
108#define TIF_ALLWORK_MASK (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SIGDELAYED) 110#define TIF_ALLWORK_MASK (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SIGDELAYED)