diff options
author | Steve French <sfrench@us.ibm.com> | 2006-01-17 22:49:59 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-01-17 22:49:59 -0500 |
commit | d65177c1ae7f085723154105c5dc8d9e16ae8265 (patch) | |
tree | 14408129d880d89cc5e937f2810f243ed1e6fcde /arch/ia64 | |
parent | d41f084a74de860fe879403fbbad13abdf7aea8e (diff) | |
parent | 15578eeb6cd4b74492f26e60624aa1a9a52ddd7b (diff) |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'arch/ia64')
32 files changed, 1112 insertions, 1759 deletions
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig index 80f8663bc6d9..1d07d8072ec2 100644 --- a/arch/ia64/configs/gensparse_defconfig +++ b/arch/ia64/configs/gensparse_defconfig | |||
@@ -701,6 +701,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y | |||
701 | CONFIG_SERIAL_SGI_L1_CONSOLE=y | 701 | CONFIG_SERIAL_SGI_L1_CONSOLE=y |
702 | # CONFIG_SERIAL_JSM is not set | 702 | # CONFIG_SERIAL_JSM is not set |
703 | CONFIG_SERIAL_SGI_IOC4=y | 703 | CONFIG_SERIAL_SGI_IOC4=y |
704 | CONFIG_SERIAL_SGI_IOC3=y | ||
704 | CONFIG_UNIX98_PTYS=y | 705 | CONFIG_UNIX98_PTYS=y |
705 | CONFIG_LEGACY_PTYS=y | 706 | CONFIG_LEGACY_PTYS=y |
706 | CONFIG_LEGACY_PTY_COUNT=256 | 707 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -1046,6 +1047,7 @@ CONFIG_INFINIBAND_IPOIB=m | |||
1046 | # SN Devices | 1047 | # SN Devices |
1047 | # | 1048 | # |
1048 | CONFIG_SGI_IOC4=y | 1049 | CONFIG_SGI_IOC4=y |
1050 | CONFIG_SGI_IOC3=y | ||
1049 | 1051 | ||
1050 | # | 1052 | # |
1051 | # File systems | 1053 | # File systems |
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index ff8bb3770c9d..3cb503b659e6 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig | |||
@@ -659,6 +659,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y | |||
659 | CONFIG_SERIAL_SGI_L1_CONSOLE=y | 659 | CONFIG_SERIAL_SGI_L1_CONSOLE=y |
660 | # CONFIG_SERIAL_JSM is not set | 660 | # CONFIG_SERIAL_JSM is not set |
661 | CONFIG_SERIAL_SGI_IOC4=y | 661 | CONFIG_SERIAL_SGI_IOC4=y |
662 | CONFIG_SERIAL_SGI_IOC3=y | ||
662 | CONFIG_UNIX98_PTYS=y | 663 | CONFIG_UNIX98_PTYS=y |
663 | CONFIG_LEGACY_PTYS=y | 664 | CONFIG_LEGACY_PTYS=y |
664 | CONFIG_LEGACY_PTY_COUNT=256 | 665 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -899,6 +900,7 @@ CONFIG_INFINIBAND_SRP=m | |||
899 | # SN Devices | 900 | # SN Devices |
900 | # | 901 | # |
901 | CONFIG_SGI_IOC4=y | 902 | CONFIG_SGI_IOC4=y |
903 | CONFIG_SGI_IOC3=y | ||
902 | 904 | ||
903 | # | 905 | # |
904 | # File systems | 906 | # File systems |
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index a346e1833bf2..626cdc83668b 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
@@ -108,7 +108,6 @@ static struct async_struct *IRQ_ports[NR_IRQS]; | |||
108 | static struct console *console; | 108 | static struct console *console; |
109 | 109 | ||
110 | static unsigned char *tmp_buf; | 110 | static unsigned char *tmp_buf; |
111 | static DECLARE_MUTEX(tmp_buf_sem); | ||
112 | 111 | ||
113 | extern struct console *console_drivers; /* from kernel/printk.c */ | 112 | extern struct console *console_drivers; /* from kernel/printk.c */ |
114 | 113 | ||
@@ -167,15 +166,9 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs) | |||
167 | } | 166 | } |
168 | } | 167 | } |
169 | seen_esc = 0; | 168 | seen_esc = 0; |
170 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) break; | ||
171 | 169 | ||
172 | *tty->flip.char_buf_ptr = ch; | 170 | if (tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) |
173 | 171 | 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 | } | 172 | } |
180 | tty_flip_buffer_push(tty); | 173 | tty_flip_buffer_push(tty); |
181 | } | 174 | } |
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) | |||
60 | GLOBAL_ENTRY(jprobe_inst_return) | 60 | GLOBAL_ENTRY(jprobe_inst_return) |
61 | br.call.sptk.many b0=jprobe_break | 61 | br.call.sptk.many b0=jprobe_break |
62 | END(jprobe_inst_return) | 62 | END(jprobe_inst_return) |
63 | |||
64 | GLOBAL_ENTRY(invalidate_stacked_regs) | ||
65 | movl r16=invalidate_restore_cfm | ||
66 | ;; | ||
67 | mov b6=r16 | ||
68 | ;; | ||
69 | br.ret.sptk.many b6 | ||
70 | ;; | ||
71 | invalidate_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 | ||
81 | END(invalidate_stacked_regs) | ||
82 | |||
83 | GLOBAL_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 | ||
88 | END(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 | ||
769 | struct param_bsp_cfm { | ||
770 | unsigned long ip; | ||
771 | unsigned long *bsp; | ||
772 | unsigned long cfm; | ||
773 | }; | ||
774 | |||
775 | static 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 | |||
769 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | 795 | int __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) | |||
792 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | 837 | int __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/perfmon.c b/arch/ia64/kernel/perfmon.c index bd87cb6b7a81..2ea4b39efffa 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -628,9 +628,11 @@ static int pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, | |||
628 | 628 | ||
629 | #include "perfmon_itanium.h" | 629 | #include "perfmon_itanium.h" |
630 | #include "perfmon_mckinley.h" | 630 | #include "perfmon_mckinley.h" |
631 | #include "perfmon_montecito.h" | ||
631 | #include "perfmon_generic.h" | 632 | #include "perfmon_generic.h" |
632 | 633 | ||
633 | static pmu_config_t *pmu_confs[]={ | 634 | static pmu_config_t *pmu_confs[]={ |
635 | &pmu_conf_mont, | ||
634 | &pmu_conf_mck, | 636 | &pmu_conf_mck, |
635 | &pmu_conf_ita, | 637 | &pmu_conf_ita, |
636 | &pmu_conf_gen, /* must be last */ | 638 | &pmu_conf_gen, /* must be last */ |
diff --git a/arch/ia64/kernel/perfmon_montecito.h b/arch/ia64/kernel/perfmon_montecito.h new file mode 100644 index 000000000000..cd06ac6a686c --- /dev/null +++ b/arch/ia64/kernel/perfmon_montecito.h | |||
@@ -0,0 +1,269 @@ | |||
1 | /* | ||
2 | * This file contains the Montecito PMU register description tables | ||
3 | * and pmc checker used by perfmon.c. | ||
4 | * | ||
5 | * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P. | ||
6 | * Contributed by Stephane Eranian <eranian@hpl.hp.com> | ||
7 | */ | ||
8 | static int pfm_mont_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs); | ||
9 | |||
10 | #define RDEP_MONT_ETB (RDEP(38)|RDEP(39)|RDEP(48)|RDEP(49)|RDEP(50)|RDEP(51)|RDEP(52)|RDEP(53)|RDEP(54)|\ | ||
11 | RDEP(55)|RDEP(56)|RDEP(57)|RDEP(58)|RDEP(59)|RDEP(60)|RDEP(61)|RDEP(62)|RDEP(63)) | ||
12 | #define RDEP_MONT_DEAR (RDEP(32)|RDEP(33)|RDEP(36)) | ||
13 | #define RDEP_MONT_IEAR (RDEP(34)|RDEP(35)) | ||
14 | |||
15 | static pfm_reg_desc_t pfm_mont_pmc_desc[PMU_MAX_PMCS]={ | ||
16 | /* pmc0 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
17 | /* pmc1 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
18 | /* pmc2 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
19 | /* pmc3 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
20 | /* pmc4 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(4),0, 0, 0}, {0,0, 0, 0}}, | ||
21 | /* pmc5 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(5),0, 0, 0}, {0,0, 0, 0}}, | ||
22 | /* pmc6 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(6),0, 0, 0}, {0,0, 0, 0}}, | ||
23 | /* pmc7 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(7),0, 0, 0}, {0,0, 0, 0}}, | ||
24 | /* pmc8 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(8),0, 0, 0}, {0,0, 0, 0}}, | ||
25 | /* pmc9 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(9),0, 0, 0}, {0,0, 0, 0}}, | ||
26 | /* pmc10 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(10),0, 0, 0}, {0,0, 0, 0}}, | ||
27 | /* pmc11 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(11),0, 0, 0}, {0,0, 0, 0}}, | ||
28 | /* pmc12 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(12),0, 0, 0}, {0,0, 0, 0}}, | ||
29 | /* pmc13 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(13),0, 0, 0}, {0,0, 0, 0}}, | ||
30 | /* pmc14 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(14),0, 0, 0}, {0,0, 0, 0}}, | ||
31 | /* pmc15 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(15),0, 0, 0}, {0,0, 0, 0}}, | ||
32 | /* pmc16 */ { PFM_REG_NOTIMPL, }, | ||
33 | /* pmc17 */ { PFM_REG_NOTIMPL, }, | ||
34 | /* pmc18 */ { PFM_REG_NOTIMPL, }, | ||
35 | /* pmc19 */ { PFM_REG_NOTIMPL, }, | ||
36 | /* pmc20 */ { PFM_REG_NOTIMPL, }, | ||
37 | /* pmc21 */ { PFM_REG_NOTIMPL, }, | ||
38 | /* pmc22 */ { PFM_REG_NOTIMPL, }, | ||
39 | /* pmc23 */ { PFM_REG_NOTIMPL, }, | ||
40 | /* pmc24 */ { PFM_REG_NOTIMPL, }, | ||
41 | /* pmc25 */ { PFM_REG_NOTIMPL, }, | ||
42 | /* pmc26 */ { PFM_REG_NOTIMPL, }, | ||
43 | /* pmc27 */ { PFM_REG_NOTIMPL, }, | ||
44 | /* pmc28 */ { PFM_REG_NOTIMPL, }, | ||
45 | /* pmc29 */ { PFM_REG_NOTIMPL, }, | ||
46 | /* pmc30 */ { PFM_REG_NOTIMPL, }, | ||
47 | /* pmc31 */ { PFM_REG_NOTIMPL, }, | ||
48 | /* pmc32 */ { PFM_REG_CONFIG, 0, 0x30f01ffffffffff, 0x30f01ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
49 | /* pmc33 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
50 | /* pmc34 */ { PFM_REG_CONFIG, 0, 0xf01ffffffffff, 0xf01ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
51 | /* pmc35 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
52 | /* pmc36 */ { PFM_REG_CONFIG, 0, 0xfffffff0, 0xf, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
53 | /* pmc37 */ { PFM_REG_MONITOR, 4, 0x0, 0x3fff, NULL, pfm_mont_pmc_check, {RDEP_MONT_IEAR, 0, 0, 0}, {0, 0, 0, 0}}, | ||
54 | /* pmc38 */ { PFM_REG_CONFIG, 0, 0xdb6, 0x2492, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
55 | /* pmc39 */ { PFM_REG_MONITOR, 6, 0x0, 0xffcf, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}}, | ||
56 | /* pmc40 */ { PFM_REG_MONITOR, 6, 0x2000000, 0xf01cf, NULL, pfm_mont_pmc_check, {RDEP_MONT_DEAR,0, 0, 0}, {0,0, 0, 0}}, | ||
57 | /* pmc41 */ { PFM_REG_CONFIG, 0, 0x00002078fefefefe, 0x1e00018181818, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
58 | /* pmc42 */ { PFM_REG_MONITOR, 6, 0x0, 0x7ff4f, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}}, | ||
59 | { PFM_REG_END , 0, 0x0, -1, NULL, NULL, {0,}, {0,}}, /* end marker */ | ||
60 | }; | ||
61 | |||
62 | static pfm_reg_desc_t pfm_mont_pmd_desc[PMU_MAX_PMDS]={ | ||
63 | /* pmd0 */ { PFM_REG_NOTIMPL, }, | ||
64 | /* pmd1 */ { PFM_REG_NOTIMPL, }, | ||
65 | /* pmd2 */ { PFM_REG_NOTIMPL, }, | ||
66 | /* pmd3 */ { PFM_REG_NOTIMPL, }, | ||
67 | /* pmd4 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(4),0, 0, 0}}, | ||
68 | /* pmd5 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(5),0, 0, 0}}, | ||
69 | /* pmd6 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(6),0, 0, 0}}, | ||
70 | /* pmd7 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(7),0, 0, 0}}, | ||
71 | /* pmd8 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(8),0, 0, 0}}, | ||
72 | /* pmd9 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(9),0, 0, 0}}, | ||
73 | /* pmd10 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(10),0, 0, 0}}, | ||
74 | /* pmd11 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(11),0, 0, 0}}, | ||
75 | /* pmd12 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(12),0, 0, 0}}, | ||
76 | /* pmd13 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(13),0, 0, 0}}, | ||
77 | /* pmd14 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(14),0, 0, 0}}, | ||
78 | /* pmd15 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(15),0, 0, 0}}, | ||
79 | /* pmd16 */ { PFM_REG_NOTIMPL, }, | ||
80 | /* pmd17 */ { PFM_REG_NOTIMPL, }, | ||
81 | /* pmd18 */ { PFM_REG_NOTIMPL, }, | ||
82 | /* pmd19 */ { PFM_REG_NOTIMPL, }, | ||
83 | /* pmd20 */ { PFM_REG_NOTIMPL, }, | ||
84 | /* pmd21 */ { PFM_REG_NOTIMPL, }, | ||
85 | /* pmd22 */ { PFM_REG_NOTIMPL, }, | ||
86 | /* pmd23 */ { PFM_REG_NOTIMPL, }, | ||
87 | /* pmd24 */ { PFM_REG_NOTIMPL, }, | ||
88 | /* pmd25 */ { PFM_REG_NOTIMPL, }, | ||
89 | /* pmd26 */ { PFM_REG_NOTIMPL, }, | ||
90 | /* pmd27 */ { PFM_REG_NOTIMPL, }, | ||
91 | /* pmd28 */ { PFM_REG_NOTIMPL, }, | ||
92 | /* pmd29 */ { PFM_REG_NOTIMPL, }, | ||
93 | /* pmd30 */ { PFM_REG_NOTIMPL, }, | ||
94 | /* pmd31 */ { PFM_REG_NOTIMPL, }, | ||
95 | /* pmd32 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(33)|RDEP(36),0, 0, 0}, {RDEP(40),0, 0, 0}}, | ||
96 | /* pmd33 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(32)|RDEP(36),0, 0, 0}, {RDEP(40),0, 0, 0}}, | ||
97 | /* pmd34 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(35),0, 0, 0}, {RDEP(37),0, 0, 0}}, | ||
98 | /* pmd35 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(34),0, 0, 0}, {RDEP(37),0, 0, 0}}, | ||
99 | /* pmd36 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(32)|RDEP(33),0, 0, 0}, {RDEP(40),0, 0, 0}}, | ||
100 | /* pmd37 */ { PFM_REG_NOTIMPL, }, | ||
101 | /* pmd38 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
102 | /* pmd39 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
103 | /* pmd40 */ { PFM_REG_NOTIMPL, }, | ||
104 | /* pmd41 */ { PFM_REG_NOTIMPL, }, | ||
105 | /* pmd42 */ { PFM_REG_NOTIMPL, }, | ||
106 | /* pmd43 */ { PFM_REG_NOTIMPL, }, | ||
107 | /* pmd44 */ { PFM_REG_NOTIMPL, }, | ||
108 | /* pmd45 */ { PFM_REG_NOTIMPL, }, | ||
109 | /* pmd46 */ { PFM_REG_NOTIMPL, }, | ||
110 | /* pmd47 */ { PFM_REG_NOTIMPL, }, | ||
111 | /* pmd48 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
112 | /* pmd49 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
113 | /* pmd50 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
114 | /* pmd51 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
115 | /* pmd52 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
116 | /* pmd53 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
117 | /* pmd54 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
118 | /* pmd55 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
119 | /* pmd56 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
120 | /* pmd57 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
121 | /* pmd58 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
122 | /* pmd59 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
123 | /* pmd60 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
124 | /* pmd61 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
125 | /* pmd62 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
126 | /* pmd63 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
127 | { PFM_REG_END , 0, 0x0, -1, NULL, NULL, {0,}, {0,}}, /* end marker */ | ||
128 | }; | ||
129 | |||
130 | /* | ||
131 | * PMC reserved fields must have their power-up values preserved | ||
132 | */ | ||
133 | static int | ||
134 | pfm_mont_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs) | ||
135 | { | ||
136 | unsigned long tmp1, tmp2, ival = *val; | ||
137 | |||
138 | /* remove reserved areas from user value */ | ||
139 | tmp1 = ival & PMC_RSVD_MASK(cnum); | ||
140 | |||
141 | /* get reserved fields values */ | ||
142 | tmp2 = PMC_DFL_VAL(cnum) & ~PMC_RSVD_MASK(cnum); | ||
143 | |||
144 | *val = tmp1 | tmp2; | ||
145 | |||
146 | DPRINT(("pmc[%d]=0x%lx, mask=0x%lx, reset=0x%lx, val=0x%lx\n", | ||
147 | cnum, ival, PMC_RSVD_MASK(cnum), PMC_DFL_VAL(cnum), *val)); | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | * task can be NULL if the context is unloaded | ||
153 | */ | ||
154 | static int | ||
155 | pfm_mont_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs) | ||
156 | { | ||
157 | int ret = 0; | ||
158 | unsigned long val32 = 0, val38 = 0, val41 = 0; | ||
159 | unsigned long tmpval; | ||
160 | int check_case1 = 0; | ||
161 | int is_loaded; | ||
162 | |||
163 | /* first preserve the reserved fields */ | ||
164 | pfm_mont_reserved(cnum, val, regs); | ||
165 | |||
166 | tmpval = *val; | ||
167 | |||
168 | /* sanity check */ | ||
169 | if (ctx == NULL) return -EINVAL; | ||
170 | |||
171 | is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED; | ||
172 | |||
173 | /* | ||
174 | * we must clear the debug registers if pmc41 has a value which enable | ||
175 | * memory pipeline event constraints. In this case we need to clear the | ||
176 | * the debug registers if they have not yet been accessed. This is required | ||
177 | * to avoid picking stale state. | ||
178 | * PMC41 is "active" if: | ||
179 | * one of the pmc41.cfg_dtagXX field is different from 0x3 | ||
180 | * AND | ||
181 | * at the corresponding pmc41.en_dbrpXX is set. | ||
182 | * AND | ||
183 | * ctx_fl_using_dbreg == 0 (i.e., dbr not yet used) | ||
184 | */ | ||
185 | DPRINT(("cnum=%u val=0x%lx, using_dbreg=%d loaded=%d\n", cnum, tmpval, ctx->ctx_fl_using_dbreg, is_loaded)); | ||
186 | |||
187 | if (cnum == 41 && is_loaded | ||
188 | && (tmpval & 0x1e00000000000) && (tmpval & 0x18181818UL) != 0x18181818UL && ctx->ctx_fl_using_dbreg == 0) { | ||
189 | |||
190 | DPRINT(("pmc[%d]=0x%lx has active pmc41 settings, clearing dbr\n", cnum, tmpval)); | ||
191 | |||
192 | /* don't mix debug with perfmon */ | ||
193 | if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; | ||
194 | |||
195 | /* | ||
196 | * a count of 0 will mark the debug registers if: | ||
197 | * AND | ||
198 | */ | ||
199 | ret = pfm_write_ibr_dbr(PFM_DATA_RR, ctx, NULL, 0, regs); | ||
200 | if (ret) return ret; | ||
201 | } | ||
202 | /* | ||
203 | * we must clear the (instruction) debug registers if: | ||
204 | * pmc38.ig_ibrpX is 0 (enabled) | ||
205 | * AND | ||
206 | * ctx_fl_using_dbreg == 0 (i.e., dbr not yet used) | ||
207 | */ | ||
208 | if (cnum == 38 && is_loaded && ((tmpval & 0x492UL) != 0x492UL) && ctx->ctx_fl_using_dbreg == 0) { | ||
209 | |||
210 | DPRINT(("pmc38=0x%lx has active pmc38 settings, clearing ibr\n", tmpval)); | ||
211 | |||
212 | /* don't mix debug with perfmon */ | ||
213 | if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; | ||
214 | |||
215 | /* | ||
216 | * a count of 0 will mark the debug registers as in use and also | ||
217 | * ensure that they are properly cleared. | ||
218 | */ | ||
219 | ret = pfm_write_ibr_dbr(PFM_CODE_RR, ctx, NULL, 0, regs); | ||
220 | if (ret) return ret; | ||
221 | |||
222 | } | ||
223 | switch(cnum) { | ||
224 | case 32: val32 = *val; | ||
225 | val38 = ctx->ctx_pmcs[38]; | ||
226 | val41 = ctx->ctx_pmcs[41]; | ||
227 | check_case1 = 1; | ||
228 | break; | ||
229 | case 38: val38 = *val; | ||
230 | val32 = ctx->ctx_pmcs[32]; | ||
231 | val41 = ctx->ctx_pmcs[41]; | ||
232 | check_case1 = 1; | ||
233 | break; | ||
234 | case 41: val41 = *val; | ||
235 | val32 = ctx->ctx_pmcs[32]; | ||
236 | val38 = ctx->ctx_pmcs[38]; | ||
237 | check_case1 = 1; | ||
238 | break; | ||
239 | } | ||
240 | /* check illegal configuration which can produce inconsistencies in tagging | ||
241 | * i-side events in L1D and L2 caches | ||
242 | */ | ||
243 | if (check_case1) { | ||
244 | ret = (((val41 >> 45) & 0xf) == 0 && ((val32>>57) & 0x1) == 0) | ||
245 | && ((((val38>>1) & 0x3) == 0x2 || ((val38>>1) & 0x3) == 0) | ||
246 | || (((val38>>4) & 0x3) == 0x2 || ((val38>>4) & 0x3) == 0)); | ||
247 | if (ret) { | ||
248 | DPRINT(("invalid config pmc38=0x%lx pmc41=0x%lx pmc32=0x%lx\n", val38, val41, val32)); | ||
249 | return -EINVAL; | ||
250 | } | ||
251 | } | ||
252 | *val = tmpval; | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | /* | ||
257 | * impl_pmcs, impl_pmds are computed at runtime to minimize errors! | ||
258 | */ | ||
259 | static pmu_config_t pmu_conf_mont={ | ||
260 | .pmu_name = "Montecito", | ||
261 | .pmu_family = 0x20, | ||
262 | .flags = PFM_PMU_IRQ_RESEND, | ||
263 | .ovfl_val = (1UL << 47) - 1, | ||
264 | .pmd_desc = pfm_mont_pmd_desc, | ||
265 | .pmc_desc = pfm_mont_pmc_desc, | ||
266 | .num_ibrs = 8, | ||
267 | .num_dbrs = 8, | ||
268 | .use_rr_dbregs = 1 /* debug register are use for range retrictions */ | ||
269 | }; | ||
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 | ||
134 | struct salinfo_data { | 142 | struct 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 | */ | ||
193 | static void | ||
194 | salinfo_work_to_do(struct salinfo_data *data) | ||
195 | { | ||
196 | down_trylock(&data->mutex); | ||
197 | up(&data->mutex); | ||
198 | } | ||
199 | |||
177 | static void | 200 | static void |
178 | salinfo_platform_oemdata_cpu(void *context) | 201 | salinfo_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; | |||
249 | static void | 270 | static void |
250 | salinfo_timeout_check(struct salinfo_data *data) | 271 | salinfo_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 | ||
265 | static void | 283 | static void |
266 | salinfo_timeout (unsigned long arg) | 284 | salinfo_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 | ||
292 | retry: | 310 | retry: |
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) | |||
381 | static void | 400 | static void |
382 | call_on_cpu(int cpu, void (*fn)(void *), void *arg) | 401 | call_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, ¤t->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 | |||
473 | salinfo_log_clear(struct salinfo_data *data, int cpu) | 490 | salinfo_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 | ||
575 | static int __devinit | ||
576 | salinfo_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 | |||
614 | static struct notifier_block salinfo_cpu_notifier = | ||
615 | { | ||
616 | .notifier_call = salinfo_cpu_callback, | ||
617 | .priority = 0, | ||
618 | }; | ||
619 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
620 | |||
553 | static int __init | 621 | static int __init |
554 | salinfo_init(void) | 622 | salinfo_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, ®s)) { | 530 | if (fsys_mode(current, ®s)) { |
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 | ®s, 0); | 540 | ia64_psr(®s)->db = 0; |
541 | ia64_psr(®s)->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(®s)->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(®s)->lp = 0; | 609 | ia64_psr(®s)->lp = 0; |
598 | return; | 610 | return; |
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index e3215ba64ffd..b38b6d213c15 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
@@ -635,3 +635,39 @@ mem_init (void) | |||
635 | ia32_mem_init(); | 635 | ia32_mem_init(); |
636 | #endif | 636 | #endif |
637 | } | 637 | } |
638 | |||
639 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
640 | void online_page(struct page *page) | ||
641 | { | ||
642 | ClearPageReserved(page); | ||
643 | set_page_count(page, 1); | ||
644 | __free_page(page); | ||
645 | totalram_pages++; | ||
646 | num_physpages++; | ||
647 | } | ||
648 | |||
649 | int add_memory(u64 start, u64 size) | ||
650 | { | ||
651 | pg_data_t *pgdat; | ||
652 | struct zone *zone; | ||
653 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
654 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
655 | int ret; | ||
656 | |||
657 | pgdat = NODE_DATA(0); | ||
658 | |||
659 | zone = pgdat->node_zones + ZONE_NORMAL; | ||
660 | ret = __add_pages(zone, start_pfn, nr_pages); | ||
661 | |||
662 | if (ret) | ||
663 | printk("%s: Problem encountered in __add_pages() as ret=%d\n", | ||
664 | __FUNCTION__, ret); | ||
665 | |||
666 | return ret; | ||
667 | } | ||
668 | |||
669 | int remove_memory(u64 start, u64 size) | ||
670 | { | ||
671 | return -EINVAL; | ||
672 | } | ||
673 | #endif | ||
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/pci/pci.c b/arch/ia64/pci/pci.c index 30dbc98bf0b3..d27ecdcb6fca 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -454,14 +454,13 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | |||
454 | return 0; | 454 | return 0; |
455 | } | 455 | } |
456 | 456 | ||
457 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | 457 | static void __devinit |
458 | pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) | ||
458 | { | 459 | { |
459 | struct pci_bus_region region; | 460 | struct pci_bus_region region; |
460 | int i; | 461 | int i; |
461 | int limit = (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) ? \ | ||
462 | PCI_BRIDGE_RESOURCES : PCI_NUM_RESOURCES; | ||
463 | 462 | ||
464 | for (i = 0; i < limit; i++) { | 463 | for (i = start; i < limit; i++) { |
465 | if (!dev->resource[i].flags) | 464 | if (!dev->resource[i].flags) |
466 | continue; | 465 | continue; |
467 | region.start = dev->resource[i].start; | 466 | region.start = dev->resource[i].start; |
@@ -472,6 +471,16 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | |||
472 | } | 471 | } |
473 | } | 472 | } |
474 | 473 | ||
474 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | ||
475 | { | ||
476 | pcibios_fixup_resources(dev, 0, PCI_BRIDGE_RESOURCES); | ||
477 | } | ||
478 | |||
479 | static void __devinit pcibios_fixup_bridge_resources(struct pci_dev *dev) | ||
480 | { | ||
481 | pcibios_fixup_resources(dev, PCI_BRIDGE_RESOURCES, PCI_NUM_RESOURCES); | ||
482 | } | ||
483 | |||
475 | /* | 484 | /* |
476 | * Called after each bus is probed, but before its children are examined. | 485 | * Called after each bus is probed, but before its children are examined. |
477 | */ | 486 | */ |
@@ -482,7 +491,7 @@ pcibios_fixup_bus (struct pci_bus *b) | |||
482 | 491 | ||
483 | if (b->self) { | 492 | if (b->self) { |
484 | pci_read_bridge_bases(b); | 493 | pci_read_bridge_bases(b); |
485 | pcibios_fixup_device_resources(b->self); | 494 | pcibios_fixup_bridge_resources(b->self); |
486 | } | 495 | } |
487 | list_for_each_entry(dev, &b->devices, bus_list) | 496 | list_for_each_entry(dev, &b->devices, bus_list) |
488 | pcibios_fixup_device_resources(dev); | 497 | pcibios_fixup_device_resources(dev); |
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h index 71c2b271b4c6..7c88e9a58516 100644 --- a/arch/ia64/sn/include/xtalk/hubdev.h +++ b/arch/ia64/sn/include/xtalk/hubdev.h | |||
@@ -26,29 +26,37 @@ | |||
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 | ||
29 | struct 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 | */ | ||
32 | struct 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]; |
37 | unsigned long sfdl_force_int_addr; | 40 | unsigned long sfdl_force_int_addr; |
38 | unsigned long sfdl_flush_value; | 41 | unsigned long sfdl_flush_value; |
39 | volatile unsigned long *sfdl_flush_addr; | 42 | volatile unsigned long *sfdl_flush_addr; |
40 | uint32_t sfdl_persistent_busnum; | 43 | u32 sfdl_persistent_busnum; |
41 | uint32_t sfdl_persistent_segment; | 44 | u32 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 */ | ||
49 | struct 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 | */ |
49 | struct sn_flush_nasid_entry { | 57 | struct 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 | u64 iio_itte[8]; |
52 | }; | 60 | }; |
53 | 61 | ||
54 | struct hubdev_info { | 62 | struct hubdev_info { |
@@ -62,8 +70,8 @@ struct hubdev_info { | |||
62 | 70 | ||
63 | void *hdi_nodepda; | 71 | void *hdi_nodepda; |
64 | void *hdi_node_vertex; | 72 | void *hdi_node_vertex; |
65 | uint32_t max_segment_number; | 73 | u32 max_segment_number; |
66 | uint32_t max_pcibus_number; | 74 | u32 max_pcibus_number; |
67 | }; | 75 | }; |
68 | 76 | ||
69 | extern void hubdev_init_node(nodepda_t *, cnodeid_t); | 77 | extern void hubdev_init_node(nodepda_t *, cnodeid_t); |
diff --git a/arch/ia64/sn/include/xtalk/xbow.h b/arch/ia64/sn/include/xtalk/xbow.h index ec56b3432f17..90f37a4133d0 100644 --- a/arch/ia64/sn/include/xtalk/xbow.h +++ b/arch/ia64/sn/include/xtalk/xbow.h | |||
@@ -3,7 +3,8 @@ | |||
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) 1992-1997,2000-2004 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (C) 1992-1997,2000-2006 Silicon Graphics, Inc. All Rights |
7 | * Reserved. | ||
7 | */ | 8 | */ |
8 | #ifndef _ASM_IA64_SN_XTALK_XBOW_H | 9 | #ifndef _ASM_IA64_SN_XTALK_XBOW_H |
9 | #define _ASM_IA64_SN_XTALK_XBOW_H | 10 | #define _ASM_IA64_SN_XTALK_XBOW_H |
@@ -21,94 +22,94 @@ | |||
21 | 22 | ||
22 | /* Register set for each xbow link */ | 23 | /* Register set for each xbow link */ |
23 | typedef volatile struct xb_linkregs_s { | 24 | typedef volatile struct xb_linkregs_s { |
24 | /* | 25 | /* |
25 | * we access these through synergy unswizzled space, so the address | 26 | * we access these through synergy unswizzled space, so the address |
26 | * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) | 27 | * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) |
27 | * That's why we put the register first and filler second. | 28 | * That's why we put the register first and filler second. |
28 | */ | 29 | */ |
29 | uint32_t link_ibf; | 30 | u32 link_ibf; |
30 | uint32_t filler0; /* filler for proper alignment */ | 31 | u32 filler0; /* filler for proper alignment */ |
31 | uint32_t link_control; | 32 | u32 link_control; |
32 | uint32_t filler1; | 33 | u32 filler1; |
33 | uint32_t link_status; | 34 | u32 link_status; |
34 | uint32_t filler2; | 35 | u32 filler2; |
35 | uint32_t link_arb_upper; | 36 | u32 link_arb_upper; |
36 | uint32_t filler3; | 37 | u32 filler3; |
37 | uint32_t link_arb_lower; | 38 | u32 link_arb_lower; |
38 | uint32_t filler4; | 39 | u32 filler4; |
39 | uint32_t link_status_clr; | 40 | u32 link_status_clr; |
40 | uint32_t filler5; | 41 | u32 filler5; |
41 | uint32_t link_reset; | 42 | u32 link_reset; |
42 | uint32_t filler6; | 43 | u32 filler6; |
43 | uint32_t link_aux_status; | 44 | u32 link_aux_status; |
44 | uint32_t filler7; | 45 | u32 filler7; |
45 | } xb_linkregs_t; | 46 | } xb_linkregs_t; |
46 | 47 | ||
47 | typedef volatile struct xbow_s { | 48 | typedef volatile struct xbow_s { |
48 | /* standard widget configuration 0x000000-0x000057 */ | 49 | /* standard widget configuration 0x000000-0x000057 */ |
49 | struct widget_cfg xb_widget; /* 0x000000 */ | 50 | struct widget_cfg xb_widget; /* 0x000000 */ |
50 | 51 | ||
51 | /* helper fieldnames for accessing bridge widget */ | 52 | /* helper fieldnames for accessing bridge widget */ |
52 | 53 | ||
53 | #define xb_wid_id xb_widget.w_id | 54 | #define xb_wid_id xb_widget.w_id |
54 | #define xb_wid_stat xb_widget.w_status | 55 | #define xb_wid_stat xb_widget.w_status |
55 | #define xb_wid_err_upper xb_widget.w_err_upper_addr | 56 | #define xb_wid_err_upper xb_widget.w_err_upper_addr |
56 | #define xb_wid_err_lower xb_widget.w_err_lower_addr | 57 | #define xb_wid_err_lower xb_widget.w_err_lower_addr |
57 | #define xb_wid_control xb_widget.w_control | 58 | #define xb_wid_control xb_widget.w_control |
58 | #define xb_wid_req_timeout xb_widget.w_req_timeout | 59 | #define xb_wid_req_timeout xb_widget.w_req_timeout |
59 | #define xb_wid_int_upper xb_widget.w_intdest_upper_addr | 60 | #define xb_wid_int_upper xb_widget.w_intdest_upper_addr |
60 | #define xb_wid_int_lower xb_widget.w_intdest_lower_addr | 61 | #define xb_wid_int_lower xb_widget.w_intdest_lower_addr |
61 | #define xb_wid_err_cmdword xb_widget.w_err_cmd_word | 62 | #define xb_wid_err_cmdword xb_widget.w_err_cmd_word |
62 | #define xb_wid_llp xb_widget.w_llp_cfg | 63 | #define xb_wid_llp xb_widget.w_llp_cfg |
63 | #define xb_wid_stat_clr xb_widget.w_tflush | 64 | #define xb_wid_stat_clr xb_widget.w_tflush |
64 | 65 | ||
65 | /* | 66 | /* |
66 | * we access these through synergy unswizzled space, so the address | 67 | * we access these through synergy unswizzled space, so the address |
67 | * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) | 68 | * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) |
68 | * That's why we put the register first and filler second. | 69 | * That's why we put the register first and filler second. |
69 | */ | 70 | */ |
70 | /* xbow-specific widget configuration 0x000058-0x0000FF */ | 71 | /* xbow-specific widget configuration 0x000058-0x0000FF */ |
71 | uint32_t xb_wid_arb_reload; /* 0x00005C */ | 72 | u32 xb_wid_arb_reload; /* 0x00005C */ |
72 | uint32_t _pad_000058; | 73 | u32 _pad_000058; |
73 | uint32_t xb_perf_ctr_a; /* 0x000064 */ | 74 | u32 xb_perf_ctr_a; /* 0x000064 */ |
74 | uint32_t _pad_000060; | 75 | u32 _pad_000060; |
75 | uint32_t xb_perf_ctr_b; /* 0x00006c */ | 76 | u32 xb_perf_ctr_b; /* 0x00006c */ |
76 | uint32_t _pad_000068; | 77 | u32 _pad_000068; |
77 | uint32_t xb_nic; /* 0x000074 */ | 78 | u32 xb_nic; /* 0x000074 */ |
78 | uint32_t _pad_000070; | 79 | u32 _pad_000070; |
79 | 80 | ||
80 | /* Xbridge only */ | 81 | /* Xbridge only */ |
81 | uint32_t xb_w0_rst_fnc; /* 0x00007C */ | 82 | u32 xb_w0_rst_fnc; /* 0x00007C */ |
82 | uint32_t _pad_000078; | 83 | u32 _pad_000078; |
83 | uint32_t xb_l8_rst_fnc; /* 0x000084 */ | 84 | u32 xb_l8_rst_fnc; /* 0x000084 */ |
84 | uint32_t _pad_000080; | 85 | u32 _pad_000080; |
85 | uint32_t xb_l9_rst_fnc; /* 0x00008c */ | 86 | u32 xb_l9_rst_fnc; /* 0x00008c */ |
86 | uint32_t _pad_000088; | 87 | u32 _pad_000088; |
87 | uint32_t xb_la_rst_fnc; /* 0x000094 */ | 88 | u32 xb_la_rst_fnc; /* 0x000094 */ |
88 | uint32_t _pad_000090; | 89 | u32 _pad_000090; |
89 | uint32_t xb_lb_rst_fnc; /* 0x00009c */ | 90 | u32 xb_lb_rst_fnc; /* 0x00009c */ |
90 | uint32_t _pad_000098; | 91 | u32 _pad_000098; |
91 | uint32_t xb_lc_rst_fnc; /* 0x0000a4 */ | 92 | u32 xb_lc_rst_fnc; /* 0x0000a4 */ |
92 | uint32_t _pad_0000a0; | 93 | u32 _pad_0000a0; |
93 | uint32_t xb_ld_rst_fnc; /* 0x0000ac */ | 94 | u32 xb_ld_rst_fnc; /* 0x0000ac */ |
94 | uint32_t _pad_0000a8; | 95 | u32 _pad_0000a8; |
95 | uint32_t xb_le_rst_fnc; /* 0x0000b4 */ | 96 | u32 xb_le_rst_fnc; /* 0x0000b4 */ |
96 | uint32_t _pad_0000b0; | 97 | u32 _pad_0000b0; |
97 | uint32_t xb_lf_rst_fnc; /* 0x0000bc */ | 98 | u32 xb_lf_rst_fnc; /* 0x0000bc */ |
98 | uint32_t _pad_0000b8; | 99 | u32 _pad_0000b8; |
99 | uint32_t xb_lock; /* 0x0000c4 */ | 100 | u32 xb_lock; /* 0x0000c4 */ |
100 | uint32_t _pad_0000c0; | 101 | u32 _pad_0000c0; |
101 | uint32_t xb_lock_clr; /* 0x0000cc */ | 102 | u32 xb_lock_clr; /* 0x0000cc */ |
102 | uint32_t _pad_0000c8; | 103 | u32 _pad_0000c8; |
103 | /* end of Xbridge only */ | 104 | /* end of Xbridge only */ |
104 | uint32_t _pad_0000d0[12]; | 105 | u32 _pad_0000d0[12]; |
105 | 106 | ||
106 | /* Link Specific Registers, port 8..15 0x000100-0x000300 */ | 107 | /* Link Specific Registers, port 8..15 0x000100-0x000300 */ |
107 | xb_linkregs_t xb_link_raw[MAX_XBOW_PORTS]; | 108 | xb_linkregs_t xb_link_raw[MAX_XBOW_PORTS]; |
108 | #define xb_link(p) xb_link_raw[(p) & (MAX_XBOW_PORTS - 1)] | ||
109 | |||
110 | } xbow_t; | 109 | } xbow_t; |
111 | 110 | ||
111 | #define xb_link(p) xb_link_raw[(p) & (MAX_XBOW_PORTS - 1)] | ||
112 | |||
112 | #define XB_FLAGS_EXISTS 0x1 /* device exists */ | 113 | #define XB_FLAGS_EXISTS 0x1 /* device exists */ |
113 | #define XB_FLAGS_MASTER 0x2 | 114 | #define XB_FLAGS_MASTER 0x2 |
114 | #define XB_FLAGS_SLAVE 0x0 | 115 | #define XB_FLAGS_SLAVE 0x0 |
@@ -160,7 +161,7 @@ typedef volatile struct xbow_s { | |||
160 | /* End of Xbridge only */ | 161 | /* End of Xbridge only */ |
161 | 162 | ||
162 | /* used only in ide, but defined here within the reserved portion */ | 163 | /* used only in ide, but defined here within the reserved portion */ |
163 | /* of the widget0 address space (before 0xf4) */ | 164 | /* of the widget0 address space (before 0xf4) */ |
164 | #define XBOW_WID_UNDEF 0xe4 | 165 | #define XBOW_WID_UNDEF 0xe4 |
165 | 166 | ||
166 | /* xbow link register set base, legal value for x is 0x8..0xf */ | 167 | /* xbow link register set base, legal value for x is 0x8..0xf */ |
@@ -179,29 +180,37 @@ typedef volatile struct xbow_s { | |||
179 | 180 | ||
180 | /* link_control(x) */ | 181 | /* link_control(x) */ |
181 | #define XB_CTRL_LINKALIVE_IE 0x80000000 /* link comes alive */ | 182 | #define XB_CTRL_LINKALIVE_IE 0x80000000 /* link comes alive */ |
182 | /* reserved: 0x40000000 */ | 183 | /* reserved: 0x40000000 */ |
183 | #define XB_CTRL_PERF_CTR_MODE_MSK 0x30000000 /* perf counter mode */ | 184 | #define XB_CTRL_PERF_CTR_MODE_MSK 0x30000000 /* perf counter mode */ |
184 | #define XB_CTRL_IBUF_LEVEL_MSK 0x0e000000 /* input packet buffer level */ | 185 | #define XB_CTRL_IBUF_LEVEL_MSK 0x0e000000 /* input packet buffer |
185 | #define XB_CTRL_8BIT_MODE 0x01000000 /* force link into 8 bit mode */ | 186 | level */ |
186 | #define XB_CTRL_BAD_LLP_PKT 0x00800000 /* force bad LLP packet */ | 187 | #define XB_CTRL_8BIT_MODE 0x01000000 /* force link into 8 |
187 | #define XB_CTRL_WIDGET_CR_MSK 0x007c0000 /* LLP widget credit mask */ | 188 | bit mode */ |
188 | #define XB_CTRL_WIDGET_CR_SHFT 18 /* LLP widget credit shift */ | 189 | #define XB_CTRL_BAD_LLP_PKT 0x00800000 /* force bad LLP |
189 | #define XB_CTRL_ILLEGAL_DST_IE 0x00020000 /* illegal destination */ | 190 | packet */ |
190 | #define XB_CTRL_OALLOC_IBUF_IE 0x00010000 /* overallocated input buffer */ | 191 | #define XB_CTRL_WIDGET_CR_MSK 0x007c0000 /* LLP widget credit |
191 | /* reserved: 0x0000fe00 */ | 192 | mask */ |
193 | #define XB_CTRL_WIDGET_CR_SHFT 18 /* LLP widget credit | ||
194 | shift */ | ||
195 | #define XB_CTRL_ILLEGAL_DST_IE 0x00020000 /* illegal destination | ||
196 | */ | ||
197 | #define XB_CTRL_OALLOC_IBUF_IE 0x00010000 /* overallocated input | ||
198 | buffer */ | ||
199 | /* reserved: 0x0000fe00 */ | ||
192 | #define XB_CTRL_BNDWDTH_ALLOC_IE 0x00000100 /* bandwidth alloc */ | 200 | #define XB_CTRL_BNDWDTH_ALLOC_IE 0x00000100 /* bandwidth alloc */ |
193 | #define XB_CTRL_RCV_CNT_OFLOW_IE 0x00000080 /* rcv retry overflow */ | 201 | #define XB_CTRL_RCV_CNT_OFLOW_IE 0x00000080 /* rcv retry overflow */ |
194 | #define XB_CTRL_XMT_CNT_OFLOW_IE 0x00000040 /* xmt retry overflow */ | 202 | #define XB_CTRL_XMT_CNT_OFLOW_IE 0x00000040 /* xmt retry overflow */ |
195 | #define XB_CTRL_XMT_MAX_RTRY_IE 0x00000020 /* max transmit retry */ | 203 | #define XB_CTRL_XMT_MAX_RTRY_IE 0x00000020 /* max transmit retry */ |
196 | #define XB_CTRL_RCV_IE 0x00000010 /* receive */ | 204 | #define XB_CTRL_RCV_IE 0x00000010 /* receive */ |
197 | #define XB_CTRL_XMT_RTRY_IE 0x00000008 /* transmit retry */ | 205 | #define XB_CTRL_XMT_RTRY_IE 0x00000008 /* transmit retry */ |
198 | /* reserved: 0x00000004 */ | 206 | /* reserved: 0x00000004 */ |
199 | #define XB_CTRL_MAXREQ_TOUT_IE 0x00000002 /* maximum request timeout */ | 207 | #define XB_CTRL_MAXREQ_TOUT_IE 0x00000002 /* maximum request |
208 | timeout */ | ||
200 | #define XB_CTRL_SRC_TOUT_IE 0x00000001 /* source timeout */ | 209 | #define XB_CTRL_SRC_TOUT_IE 0x00000001 /* source timeout */ |
201 | 210 | ||
202 | /* link_status(x) */ | 211 | /* link_status(x) */ |
203 | #define XB_STAT_LINKALIVE XB_CTRL_LINKALIVE_IE | 212 | #define XB_STAT_LINKALIVE XB_CTRL_LINKALIVE_IE |
204 | /* reserved: 0x7ff80000 */ | 213 | /* reserved: 0x7ff80000 */ |
205 | #define XB_STAT_MULTI_ERR 0x00040000 /* multi error */ | 214 | #define XB_STAT_MULTI_ERR 0x00040000 /* multi error */ |
206 | #define XB_STAT_ILLEGAL_DST_ERR XB_CTRL_ILLEGAL_DST_IE | 215 | #define XB_STAT_ILLEGAL_DST_ERR XB_CTRL_ILLEGAL_DST_IE |
207 | #define XB_STAT_OALLOC_IBUF_ERR XB_CTRL_OALLOC_IBUF_IE | 216 | #define XB_STAT_OALLOC_IBUF_ERR XB_CTRL_OALLOC_IBUF_IE |
@@ -211,7 +220,7 @@ typedef volatile struct xbow_s { | |||
211 | #define XB_STAT_XMT_MAX_RTRY_ERR XB_CTRL_XMT_MAX_RTRY_IE | 220 | #define XB_STAT_XMT_MAX_RTRY_ERR XB_CTRL_XMT_MAX_RTRY_IE |
212 | #define XB_STAT_RCV_ERR XB_CTRL_RCV_IE | 221 | #define XB_STAT_RCV_ERR XB_CTRL_RCV_IE |
213 | #define XB_STAT_XMT_RTRY_ERR XB_CTRL_XMT_RTRY_IE | 222 | #define XB_STAT_XMT_RTRY_ERR XB_CTRL_XMT_RTRY_IE |
214 | /* reserved: 0x00000004 */ | 223 | /* reserved: 0x00000004 */ |
215 | #define XB_STAT_MAXREQ_TOUT_ERR XB_CTRL_MAXREQ_TOUT_IE | 224 | #define XB_STAT_MAXREQ_TOUT_ERR XB_CTRL_MAXREQ_TOUT_IE |
216 | #define XB_STAT_SRC_TOUT_ERR XB_CTRL_SRC_TOUT_IE | 225 | #define XB_STAT_SRC_TOUT_ERR XB_CTRL_SRC_TOUT_IE |
217 | 226 | ||
@@ -222,7 +231,7 @@ typedef volatile struct xbow_s { | |||
222 | #define XB_AUX_LINKFAIL_RST_BAD 0x00000040 | 231 | #define XB_AUX_LINKFAIL_RST_BAD 0x00000040 |
223 | #define XB_AUX_STAT_PRESENT 0x00000020 | 232 | #define XB_AUX_STAT_PRESENT 0x00000020 |
224 | #define XB_AUX_STAT_PORT_WIDTH 0x00000010 | 233 | #define XB_AUX_STAT_PORT_WIDTH 0x00000010 |
225 | /* reserved: 0x0000000f */ | 234 | /* reserved: 0x0000000f */ |
226 | 235 | ||
227 | /* | 236 | /* |
228 | * link_arb_upper/link_arb_lower(x), (reg) should be the link_arb_upper | 237 | * link_arb_upper/link_arb_lower(x), (reg) should be the link_arb_upper |
@@ -238,7 +247,8 @@ typedef volatile struct xbow_s { | |||
238 | /* XBOW_WID_STAT */ | 247 | /* XBOW_WID_STAT */ |
239 | #define XB_WID_STAT_LINK_INTR_SHFT (24) | 248 | #define XB_WID_STAT_LINK_INTR_SHFT (24) |
240 | #define XB_WID_STAT_LINK_INTR_MASK (0xFF << XB_WID_STAT_LINK_INTR_SHFT) | 249 | #define XB_WID_STAT_LINK_INTR_MASK (0xFF << XB_WID_STAT_LINK_INTR_SHFT) |
241 | #define XB_WID_STAT_LINK_INTR(x) (0x1 << (((x)&7) + XB_WID_STAT_LINK_INTR_SHFT)) | 250 | #define XB_WID_STAT_LINK_INTR(x) \ |
251 | (0x1 << (((x)&7) + XB_WID_STAT_LINK_INTR_SHFT)) | ||
242 | #define XB_WID_STAT_WIDGET0_INTR 0x00800000 | 252 | #define XB_WID_STAT_WIDGET0_INTR 0x00800000 |
243 | #define XB_WID_STAT_SRCID_MASK 0x000003c0 /* Xbridge only */ | 253 | #define XB_WID_STAT_SRCID_MASK 0x000003c0 /* Xbridge only */ |
244 | #define XB_WID_STAT_REG_ACC_ERR 0x00000020 | 254 | #define XB_WID_STAT_REG_ACC_ERR 0x00000020 |
@@ -264,7 +274,7 @@ typedef volatile struct xbow_s { | |||
264 | #define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbridge */ | 274 | #define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbridge */ |
265 | #define XBOW_WIDGET_MFGR_NUM 0x0 | 275 | #define XBOW_WIDGET_MFGR_NUM 0x0 |
266 | #define XXBOW_WIDGET_MFGR_NUM 0x0 | 276 | #define XXBOW_WIDGET_MFGR_NUM 0x0 |
267 | #define PXBOW_WIDGET_PART_NUM 0xd100 /* PIC */ | 277 | #define PXBOW_WIDGET_PART_NUM 0xd100 /* PIC */ |
268 | 278 | ||
269 | #define XBOW_REV_1_0 0x1 /* xbow rev 1.0 is "1" */ | 279 | #define XBOW_REV_1_0 0x1 /* xbow rev 1.0 is "1" */ |
270 | #define XBOW_REV_1_1 0x2 /* xbow rev 1.1 is "2" */ | 280 | #define XBOW_REV_1_1 0x2 /* xbow rev 1.1 is "2" */ |
@@ -279,13 +289,13 @@ typedef volatile struct xbow_s { | |||
279 | #define XBOW_WID_ARB_RELOAD_INT 0x3f /* GBR reload interval */ | 289 | #define XBOW_WID_ARB_RELOAD_INT 0x3f /* GBR reload interval */ |
280 | 290 | ||
281 | #define IS_XBRIDGE_XBOW(wid) \ | 291 | #define IS_XBRIDGE_XBOW(wid) \ |
282 | (XWIDGET_PART_NUM(wid) == XXBOW_WIDGET_PART_NUM && \ | 292 | (XWIDGET_PART_NUM(wid) == XXBOW_WIDGET_PART_NUM && \ |
283 | XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM) | 293 | XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM) |
284 | 294 | ||
285 | #define IS_PIC_XBOW(wid) \ | 295 | #define IS_PIC_XBOW(wid) \ |
286 | (XWIDGET_PART_NUM(wid) == PXBOW_WIDGET_PART_NUM && \ | 296 | (XWIDGET_PART_NUM(wid) == PXBOW_WIDGET_PART_NUM && \ |
287 | XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM) | 297 | XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM) |
288 | 298 | ||
289 | #define XBOW_WAR_ENABLED(pv, widid) ((1 << XWIDGET_REV_NUM(widid)) & pv) | 299 | #define XBOW_WAR_ENABLED(pv, widid) ((1 << XWIDGET_REV_NUM(widid)) & pv) |
290 | 300 | ||
291 | #endif /* _ASM_IA64_SN_XTALK_XBOW_H */ | 301 | #endif /* _ASM_IA64_SN_XTALK_XBOW_H */ |
diff --git a/arch/ia64/sn/include/xtalk/xwidgetdev.h b/arch/ia64/sn/include/xtalk/xwidgetdev.h index c5f4bc5cc033..2800eda0fd68 100644 --- a/arch/ia64/sn/include/xtalk/xwidgetdev.h +++ b/arch/ia64/sn/include/xtalk/xwidgetdev.h | |||
@@ -25,28 +25,28 @@ | |||
25 | 25 | ||
26 | /* widget configuration registers */ | 26 | /* widget configuration registers */ |
27 | struct widget_cfg{ | 27 | struct widget_cfg{ |
28 | uint32_t w_id; /* 0x04 */ | 28 | u32 w_id; /* 0x04 */ |
29 | uint32_t w_pad_0; /* 0x00 */ | 29 | u32 w_pad_0; /* 0x00 */ |
30 | uint32_t w_status; /* 0x0c */ | 30 | u32 w_status; /* 0x0c */ |
31 | uint32_t w_pad_1; /* 0x08 */ | 31 | u32 w_pad_1; /* 0x08 */ |
32 | uint32_t w_err_upper_addr; /* 0x14 */ | 32 | u32 w_err_upper_addr; /* 0x14 */ |
33 | uint32_t w_pad_2; /* 0x10 */ | 33 | u32 w_pad_2; /* 0x10 */ |
34 | uint32_t w_err_lower_addr; /* 0x1c */ | 34 | u32 w_err_lower_addr; /* 0x1c */ |
35 | uint32_t w_pad_3; /* 0x18 */ | 35 | u32 w_pad_3; /* 0x18 */ |
36 | uint32_t w_control; /* 0x24 */ | 36 | u32 w_control; /* 0x24 */ |
37 | uint32_t w_pad_4; /* 0x20 */ | 37 | u32 w_pad_4; /* 0x20 */ |
38 | uint32_t w_req_timeout; /* 0x2c */ | 38 | u32 w_req_timeout; /* 0x2c */ |
39 | uint32_t w_pad_5; /* 0x28 */ | 39 | u32 w_pad_5; /* 0x28 */ |
40 | uint32_t w_intdest_upper_addr; /* 0x34 */ | 40 | u32 w_intdest_upper_addr; /* 0x34 */ |
41 | uint32_t w_pad_6; /* 0x30 */ | 41 | u32 w_pad_6; /* 0x30 */ |
42 | uint32_t w_intdest_lower_addr; /* 0x3c */ | 42 | u32 w_intdest_lower_addr; /* 0x3c */ |
43 | uint32_t w_pad_7; /* 0x38 */ | 43 | u32 w_pad_7; /* 0x38 */ |
44 | uint32_t w_err_cmd_word; /* 0x44 */ | 44 | u32 w_err_cmd_word; /* 0x44 */ |
45 | uint32_t w_pad_8; /* 0x40 */ | 45 | u32 w_pad_8; /* 0x40 */ |
46 | uint32_t w_llp_cfg; /* 0x4c */ | 46 | u32 w_llp_cfg; /* 0x4c */ |
47 | uint32_t w_pad_9; /* 0x48 */ | 47 | u32 w_pad_9; /* 0x48 */ |
48 | uint32_t w_tflush; /* 0x54 */ | 48 | u32 w_tflush; /* 0x54 */ |
49 | uint32_t w_pad_10; /* 0x50 */ | 49 | u32 w_pad_10; /* 0x50 */ |
50 | }; | 50 | }; |
51 | 51 | ||
52 | /* | 52 | /* |
@@ -63,7 +63,7 @@ struct xwidget_info{ | |||
63 | struct xwidget_hwid xwi_hwid; /* Widget Identification */ | 63 | struct xwidget_hwid xwi_hwid; /* Widget Identification */ |
64 | char xwi_masterxid; /* Hub's Widget Port Number */ | 64 | char xwi_masterxid; /* Hub's Widget Port Number */ |
65 | void *xwi_hubinfo; /* Hub's provider private info */ | 65 | void *xwi_hubinfo; /* Hub's provider private info */ |
66 | uint64_t *xwi_hub_provider; /* prom provider functions */ | 66 | u64 *xwi_hub_provider; /* prom provider functions */ |
67 | void *xwi_vertex; | 67 | void *xwi_vertex; |
68 | }; | 68 | }; |
69 | 69 | ||
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 | */ |
36 | void shub1_bte_error_handler(unsigned long _nodepda) | 36 | int 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 | */ | ||
134 | int 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..233d55115d33 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 | */ |
82 | static inline uint64_t | 82 | static inline u64 |
83 | sal_get_widget_dmaflush_list(u64 nasid, u64 widget_num, u64 address) | 83 | sal_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 | */ |
101 | static inline uint64_t sal_get_hubdev_info(u64 handle, u64 address) | 102 | static 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 | */ |
117 | static inline uint64_t sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) | 118 | static 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,9 +131,9 @@ 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 | */ |
133 | static inline uint64_t | 134 | static inline u64 |
134 | sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, | 135 | sal_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 | { |
137 | struct ia64_sal_retval ret_stuff; | 138 | struct ia64_sal_retval ret_stuff; |
138 | ret_stuff.status = 0; | 139 | ret_stuff.status = 0; |
@@ -140,7 +141,7 @@ sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, | |||
140 | 141 | ||
141 | SAL_CALL_NOLOCK(ret_stuff, | 142 | SAL_CALL_NOLOCK(ret_stuff, |
142 | (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, | 143 | (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, |
143 | (u64) segment, (u64) bus_number, (u64) devfn, | 144 | (u64) segment, (u64) bus_number, (u64) devfn, |
144 | (u64) pci_dev, | 145 | (u64) pci_dev, |
145 | sn_irq_info, 0, 0); | 146 | sn_irq_info, 0, 0); |
146 | return ret_stuff.v0; | 147 | return ret_stuff.v0; |
@@ -170,12 +171,12 @@ sn_pcidev_info_get(struct pci_dev *dev) | |||
170 | */ | 171 | */ |
171 | static void sn_fixup_ionodes(void) | 172 | static 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 | /* |
@@ -256,7 +268,7 @@ static void sn_fixup_ionodes(void) | |||
256 | */ | 268 | */ |
257 | static void | 269 | static void |
258 | sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, | 270 | sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, |
259 | int64_t * pci_addrs) | 271 | s64 * pci_addrs) |
260 | { | 272 | { |
261 | struct pci_controller *controller = PCI_CONTROLLER(dev->bus); | 273 | struct pci_controller *controller = PCI_CONTROLLER(dev->bus); |
262 | unsigned int i; | 274 | unsigned int i; |
@@ -316,7 +328,7 @@ void sn_pci_fixup_slot(struct pci_dev *dev) | |||
316 | struct pci_bus *host_pci_bus; | 328 | struct pci_bus *host_pci_bus; |
317 | struct pci_dev *host_pci_dev; | 329 | struct pci_dev *host_pci_dev; |
318 | struct pcidev_info *pcidev_info; | 330 | struct pcidev_info *pcidev_info; |
319 | int64_t pci_addrs[PCI_ROM_RESOURCE + 1]; | 331 | s64 pci_addrs[PCI_ROM_RESOURCE + 1]; |
320 | struct sn_irq_info *sn_irq_info; | 332 | struct sn_irq_info *sn_irq_info; |
321 | unsigned long size; | 333 | unsigned long size; |
322 | unsigned int bus_no, devfn; | 334 | unsigned int bus_no, devfn; |
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 01d18b7b5bb3..ec37084bdc17 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c | |||
@@ -28,7 +28,7 @@ extern int sn_ioif_inited; | |||
28 | static struct list_head **sn_irq_lh; | 28 | static struct list_head **sn_irq_lh; |
29 | static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ | 29 | static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ |
30 | 30 | ||
31 | static inline uint64_t sn_intr_alloc(nasid_t local_nasid, int local_widget, | 31 | static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, |
32 | u64 sn_irq_info, | 32 | u64 sn_irq_info, |
33 | int req_irq, nasid_t req_nasid, | 33 | int req_irq, nasid_t req_nasid, |
34 | int req_slice) | 34 | int req_slice) |
@@ -123,7 +123,7 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) | |||
123 | 123 | ||
124 | list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, | 124 | list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, |
125 | sn_irq_lh[irq], list) { | 125 | sn_irq_lh[irq], list) { |
126 | uint64_t bridge; | 126 | u64 bridge; |
127 | int local_widget, status; | 127 | int local_widget, status; |
128 | nasid_t local_nasid; | 128 | nasid_t local_nasid; |
129 | struct sn_irq_info *new_irq_info; | 129 | struct sn_irq_info *new_irq_info; |
@@ -134,7 +134,7 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) | |||
134 | break; | 134 | break; |
135 | memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); | 135 | memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); |
136 | 136 | ||
137 | bridge = (uint64_t) new_irq_info->irq_bridge; | 137 | bridge = (u64) new_irq_info->irq_bridge; |
138 | if (!bridge) { | 138 | if (!bridge) { |
139 | kfree(new_irq_info); | 139 | kfree(new_irq_info); |
140 | break; /* irq is not a device interrupt */ | 140 | break; /* irq is not a device interrupt */ |
@@ -349,10 +349,10 @@ static void force_interrupt(int irq) | |||
349 | */ | 349 | */ |
350 | static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) | 350 | static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) |
351 | { | 351 | { |
352 | uint64_t regval; | 352 | u64 regval; |
353 | int irr_reg_num; | 353 | int irr_reg_num; |
354 | int irr_bit; | 354 | int irr_bit; |
355 | uint64_t irr_reg; | 355 | u64 irr_reg; |
356 | struct pcidev_info *pcidev_info; | 356 | struct pcidev_info *pcidev_info; |
357 | struct pcibus_info *pcibus_info; | 357 | struct pcibus_info *pcibus_info; |
358 | 358 | ||
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index 493fb3f38dc3..d263d3e8fbb9 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c | |||
@@ -77,12 +77,6 @@ static void tiocx_bus_release(struct device *dev) | |||
77 | kfree(to_cx_dev(dev)); | 77 | kfree(to_cx_dev(dev)); |
78 | } | 78 | } |
79 | 79 | ||
80 | struct bus_type tiocx_bus_type = { | ||
81 | .name = "tiocx", | ||
82 | .match = tiocx_match, | ||
83 | .uevent = tiocx_uevent, | ||
84 | }; | ||
85 | |||
86 | /** | 80 | /** |
87 | * cx_device_match - Find cx_device in the id table. | 81 | * cx_device_match - Find cx_device in the id table. |
88 | * @ids: id table from driver | 82 | * @ids: id table from driver |
@@ -149,6 +143,14 @@ static int cx_driver_remove(struct device *dev) | |||
149 | return 0; | 143 | return 0; |
150 | } | 144 | } |
151 | 145 | ||
146 | struct bus_type tiocx_bus_type = { | ||
147 | .name = "tiocx", | ||
148 | .match = tiocx_match, | ||
149 | .uevent = tiocx_uevent, | ||
150 | .probe = cx_device_probe, | ||
151 | .remove = cx_driver_remove, | ||
152 | }; | ||
153 | |||
152 | /** | 154 | /** |
153 | * cx_driver_register - Register the driver. | 155 | * cx_driver_register - Register the driver. |
154 | * @cx_driver: driver table (cx_drv struct) from driver | 156 | * @cx_driver: driver table (cx_drv struct) from driver |
@@ -162,8 +164,6 @@ int cx_driver_register(struct cx_drv *cx_driver) | |||
162 | { | 164 | { |
163 | cx_driver->driver.name = cx_driver->name; | 165 | cx_driver->driver.name = cx_driver->name; |
164 | cx_driver->driver.bus = &tiocx_bus_type; | 166 | cx_driver->driver.bus = &tiocx_bus_type; |
165 | cx_driver->driver.probe = cx_device_probe; | ||
166 | cx_driver->driver.remove = cx_driver_remove; | ||
167 | 167 | ||
168 | return driver_register(&cx_driver->driver); | 168 | return driver_register(&cx_driver->driver); |
169 | } | 169 | } |
@@ -245,7 +245,7 @@ static int cx_device_reload(struct cx_dev *cx_dev) | |||
245 | cx_dev->bt); | 245 | cx_dev->bt); |
246 | } | 246 | } |
247 | 247 | ||
248 | static inline uint64_t tiocx_intr_alloc(nasid_t nasid, int widget, | 248 | static inline u64 tiocx_intr_alloc(nasid_t nasid, int widget, |
249 | u64 sn_irq_info, | 249 | u64 sn_irq_info, |
250 | int req_irq, nasid_t req_nasid, | 250 | int req_irq, nasid_t req_nasid, |
251 | int req_slice) | 251 | int req_slice) |
@@ -302,7 +302,7 @@ struct sn_irq_info *tiocx_irq_alloc(nasid_t nasid, int widget, int irq, | |||
302 | 302 | ||
303 | void tiocx_irq_free(struct sn_irq_info *sn_irq_info) | 303 | void tiocx_irq_free(struct sn_irq_info *sn_irq_info) |
304 | { | 304 | { |
305 | uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge; | 305 | u64 bridge = (u64) sn_irq_info->irq_bridge; |
306 | nasid_t nasid = NASID_GET(bridge); | 306 | nasid_t nasid = NASID_GET(bridge); |
307 | int widget; | 307 | int widget; |
308 | 308 | ||
@@ -313,12 +313,12 @@ void tiocx_irq_free(struct sn_irq_info *sn_irq_info) | |||
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
316 | uint64_t tiocx_dma_addr(uint64_t addr) | 316 | u64 tiocx_dma_addr(u64 addr) |
317 | { | 317 | { |
318 | return PHYS_TO_TIODMA(addr); | 318 | return PHYS_TO_TIODMA(addr); |
319 | } | 319 | } |
320 | 320 | ||
321 | uint64_t tiocx_swin_base(int nasid) | 321 | u64 tiocx_swin_base(int nasid) |
322 | { | 322 | { |
323 | return TIO_SWIN_BASE(nasid, TIOCX_CORELET); | 323 | return TIO_SWIN_BASE(nasid, TIOCX_CORELET); |
324 | } | 324 | } |
@@ -335,8 +335,8 @@ EXPORT_SYMBOL(tiocx_swin_base); | |||
335 | 335 | ||
336 | static void tio_conveyor_set(nasid_t nasid, int enable_flag) | 336 | static void tio_conveyor_set(nasid_t nasid, int enable_flag) |
337 | { | 337 | { |
338 | uint64_t ice_frz; | 338 | u64 ice_frz; |
339 | uint64_t disable_cb = (1ull << 61); | 339 | u64 disable_cb = (1ull << 61); |
340 | 340 | ||
341 | if (!(nasid & 1)) | 341 | if (!(nasid & 1)) |
342 | return; | 342 | return; |
@@ -388,7 +388,7 @@ static int is_fpga_tio(int nasid, int *bt) | |||
388 | 388 | ||
389 | static int bitstream_loaded(nasid_t nasid) | 389 | static int bitstream_loaded(nasid_t nasid) |
390 | { | 390 | { |
391 | uint64_t cx_credits; | 391 | u64 cx_credits; |
392 | 392 | ||
393 | cx_credits = REMOTE_HUB_L(nasid, TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3); | 393 | cx_credits = REMOTE_HUB_L(nasid, TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3); |
394 | cx_credits &= TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3_CREDIT_CNT_MASK; | 394 | cx_credits &= TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3_CREDIT_CNT_MASK; |
@@ -404,14 +404,14 @@ static int tiocx_reload(struct cx_dev *cx_dev) | |||
404 | nasid_t nasid = cx_dev->cx_id.nasid; | 404 | nasid_t nasid = cx_dev->cx_id.nasid; |
405 | 405 | ||
406 | if (bitstream_loaded(nasid)) { | 406 | if (bitstream_loaded(nasid)) { |
407 | uint64_t cx_id; | 407 | u64 cx_id; |
408 | int rv; | 408 | int rv; |
409 | 409 | ||
410 | rv = ia64_sn_sysctl_tio_clock_reset(nasid); | 410 | rv = ia64_sn_sysctl_tio_clock_reset(nasid); |
411 | if (rv) { | 411 | if (rv) { |
412 | printk(KERN_ALERT "CX port JTAG reset failed.\n"); | 412 | printk(KERN_ALERT "CX port JTAG reset failed.\n"); |
413 | } else { | 413 | } else { |
414 | cx_id = *(volatile uint64_t *) | 414 | cx_id = *(volatile u64 *) |
415 | (TIO_SWIN_BASE(nasid, TIOCX_CORELET) + | 415 | (TIO_SWIN_BASE(nasid, TIOCX_CORELET) + |
416 | WIDGET_ID); | 416 | WIDGET_ID); |
417 | part_num = XWIDGET_PART_NUM(cx_id); | 417 | part_num = XWIDGET_PART_NUM(cx_id); |
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h deleted file mode 100644 index 5483a9f227d4..000000000000 --- a/arch/ia64/sn/kernel/xpc.h +++ /dev/null | |||
@@ -1,1273 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | ||
7 | */ | ||
8 | |||
9 | |||
10 | /* | ||
11 | * Cross Partition Communication (XPC) structures and macros. | ||
12 | */ | ||
13 | |||
14 | #ifndef _IA64_SN_KERNEL_XPC_H | ||
15 | #define _IA64_SN_KERNEL_XPC_H | ||
16 | |||
17 | |||
18 | #include <linux/config.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/sysctl.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <asm/pgtable.h> | ||
23 | #include <asm/processor.h> | ||
24 | #include <asm/sn/bte.h> | ||
25 | #include <asm/sn/clksupport.h> | ||
26 | #include <asm/sn/addrs.h> | ||
27 | #include <asm/sn/mspec.h> | ||
28 | #include <asm/sn/shub_mmr.h> | ||
29 | #include <asm/sn/xp.h> | ||
30 | |||
31 | |||
32 | /* | ||
33 | * XPC Version numbers consist of a major and minor number. XPC can always | ||
34 | * talk to versions with same major #, and never talk to versions with a | ||
35 | * different major #. | ||
36 | */ | ||
37 | #define _XPC_VERSION(_maj, _min) (((_maj) << 4) | ((_min) & 0xf)) | ||
38 | #define XPC_VERSION_MAJOR(_v) ((_v) >> 4) | ||
39 | #define XPC_VERSION_MINOR(_v) ((_v) & 0xf) | ||
40 | |||
41 | |||
42 | /* | ||
43 | * The next macros define word or bit representations for given | ||
44 | * C-brick nasid in either the SAL provided bit array representing | ||
45 | * nasids in the partition/machine or the AMO_t array used for | ||
46 | * inter-partition initiation communications. | ||
47 | * | ||
48 | * For SN2 machines, C-Bricks are alway even numbered NASIDs. As | ||
49 | * such, some space will be saved by insisting that nasid information | ||
50 | * passed from SAL always be packed for C-Bricks and the | ||
51 | * cross-partition interrupts use the same packing scheme. | ||
52 | */ | ||
53 | #define XPC_NASID_W_INDEX(_n) (((_n) / 64) / 2) | ||
54 | #define XPC_NASID_B_INDEX(_n) (((_n) / 2) & (64 - 1)) | ||
55 | #define XPC_NASID_IN_ARRAY(_n, _p) ((_p)[XPC_NASID_W_INDEX(_n)] & \ | ||
56 | (1UL << XPC_NASID_B_INDEX(_n))) | ||
57 | #define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2) | ||
58 | |||
59 | #define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */ | ||
60 | #define XPC_HB_CHECK_DEFAULT_INTERVAL 20 /* check HB every x secs */ | ||
61 | |||
62 | /* define the process name of HB checker and the CPU it is pinned to */ | ||
63 | #define XPC_HB_CHECK_THREAD_NAME "xpc_hb" | ||
64 | #define XPC_HB_CHECK_CPU 0 | ||
65 | |||
66 | /* define the process name of the discovery thread */ | ||
67 | #define XPC_DISCOVERY_THREAD_NAME "xpc_discovery" | ||
68 | |||
69 | |||
70 | /* | ||
71 | * the reserved page | ||
72 | * | ||
73 | * SAL reserves one page of memory per partition for XPC. Though a full page | ||
74 | * in length (16384 bytes), its starting address is not page aligned, but it | ||
75 | * is cacheline aligned. The reserved page consists of the following: | ||
76 | * | ||
77 | * reserved page header | ||
78 | * | ||
79 | * The first cacheline of the reserved page contains the header | ||
80 | * (struct xpc_rsvd_page). Before SAL initialization has completed, | ||
81 | * SAL has set up the following fields of the reserved page header: | ||
82 | * SAL_signature, SAL_version, partid, and nasids_size. The other | ||
83 | * fields are set up by XPC. (xpc_rsvd_page points to the local | ||
84 | * partition's reserved page.) | ||
85 | * | ||
86 | * part_nasids mask | ||
87 | * mach_nasids mask | ||
88 | * | ||
89 | * SAL also sets up two bitmaps (or masks), one that reflects the actual | ||
90 | * nasids in this partition (part_nasids), and the other that reflects | ||
91 | * the actual nasids in the entire machine (mach_nasids). We're only | ||
92 | * interested in the even numbered nasids (which contain the processors | ||
93 | * and/or memory), so we only need half as many bits to represent the | ||
94 | * nasids. The part_nasids mask is located starting at the first cacheline | ||
95 | * following the reserved page header. The mach_nasids mask follows right | ||
96 | * after the part_nasids mask. The size in bytes of each mask is reflected | ||
97 | * by the reserved page header field 'nasids_size'. (Local partition's | ||
98 | * mask pointers are xpc_part_nasids and xpc_mach_nasids.) | ||
99 | * | ||
100 | * vars | ||
101 | * vars part | ||
102 | * | ||
103 | * Immediately following the mach_nasids mask are the XPC variables | ||
104 | * required by other partitions. First are those that are generic to all | ||
105 | * partitions (vars), followed on the next available cacheline by those | ||
106 | * which are partition specific (vars part). These are setup by XPC. | ||
107 | * (Local partition's vars pointers are xpc_vars and xpc_vars_part.) | ||
108 | * | ||
109 | * Note: Until vars_pa is set, the partition XPC code has not been initialized. | ||
110 | */ | ||
111 | struct xpc_rsvd_page { | ||
112 | u64 SAL_signature; /* SAL: unique signature */ | ||
113 | u64 SAL_version; /* SAL: version */ | ||
114 | u8 partid; /* SAL: partition ID */ | ||
115 | u8 version; | ||
116 | u8 pad1[6]; /* align to next u64 in cacheline */ | ||
117 | volatile u64 vars_pa; | ||
118 | struct timespec stamp; /* time when reserved page was setup by XPC */ | ||
119 | u64 pad2[9]; /* align to last u64 in cacheline */ | ||
120 | u64 nasids_size; /* SAL: size of each nasid mask in bytes */ | ||
121 | }; | ||
122 | |||
123 | #define XPC_RP_VERSION _XPC_VERSION(1,1) /* version 1.1 of the reserved page */ | ||
124 | |||
125 | #define XPC_SUPPORTS_RP_STAMP(_version) \ | ||
126 | (_version >= _XPC_VERSION(1,1)) | ||
127 | |||
128 | /* | ||
129 | * compare stamps - the return value is: | ||
130 | * | ||
131 | * < 0, if stamp1 < stamp2 | ||
132 | * = 0, if stamp1 == stamp2 | ||
133 | * > 0, if stamp1 > stamp2 | ||
134 | */ | ||
135 | static inline int | ||
136 | xpc_compare_stamps(struct timespec *stamp1, struct timespec *stamp2) | ||
137 | { | ||
138 | int ret; | ||
139 | |||
140 | |||
141 | if ((ret = stamp1->tv_sec - stamp2->tv_sec) == 0) { | ||
142 | ret = stamp1->tv_nsec - stamp2->tv_nsec; | ||
143 | } | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | |||
148 | /* | ||
149 | * Define the structures by which XPC variables can be exported to other | ||
150 | * partitions. (There are two: struct xpc_vars and struct xpc_vars_part) | ||
151 | */ | ||
152 | |||
153 | /* | ||
154 | * The following structure describes the partition generic variables | ||
155 | * needed by other partitions in order to properly initialize. | ||
156 | * | ||
157 | * struct xpc_vars version number also applies to struct xpc_vars_part. | ||
158 | * Changes to either structure and/or related functionality should be | ||
159 | * reflected by incrementing either the major or minor version numbers | ||
160 | * of struct xpc_vars. | ||
161 | */ | ||
162 | struct xpc_vars { | ||
163 | u8 version; | ||
164 | u64 heartbeat; | ||
165 | u64 heartbeating_to_mask; | ||
166 | u64 heartbeat_offline; /* if 0, heartbeat should be changing */ | ||
167 | int act_nasid; | ||
168 | int act_phys_cpuid; | ||
169 | u64 vars_part_pa; | ||
170 | u64 amos_page_pa; /* paddr of page of AMOs from MSPEC driver */ | ||
171 | AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */ | ||
172 | }; | ||
173 | |||
174 | #define XPC_V_VERSION _XPC_VERSION(3,1) /* version 3.1 of the cross vars */ | ||
175 | |||
176 | #define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \ | ||
177 | (_version >= _XPC_VERSION(3,1)) | ||
178 | |||
179 | |||
180 | static inline int | ||
181 | xpc_hb_allowed(partid_t partid, struct xpc_vars *vars) | ||
182 | { | ||
183 | return ((vars->heartbeating_to_mask & (1UL << partid)) != 0); | ||
184 | } | ||
185 | |||
186 | static inline void | ||
187 | xpc_allow_hb(partid_t partid, struct xpc_vars *vars) | ||
188 | { | ||
189 | u64 old_mask, new_mask; | ||
190 | |||
191 | do { | ||
192 | old_mask = vars->heartbeating_to_mask; | ||
193 | new_mask = (old_mask | (1UL << partid)); | ||
194 | } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) != | ||
195 | old_mask); | ||
196 | } | ||
197 | |||
198 | static inline void | ||
199 | xpc_disallow_hb(partid_t partid, struct xpc_vars *vars) | ||
200 | { | ||
201 | u64 old_mask, new_mask; | ||
202 | |||
203 | do { | ||
204 | old_mask = vars->heartbeating_to_mask; | ||
205 | new_mask = (old_mask & ~(1UL << partid)); | ||
206 | } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) != | ||
207 | old_mask); | ||
208 | } | ||
209 | |||
210 | |||
211 | /* | ||
212 | * The AMOs page consists of a number of AMO variables which are divided into | ||
213 | * four groups, The first two groups are used to identify an IRQ's sender. | ||
214 | * These two groups consist of 64 and 128 AMO variables respectively. The last | ||
215 | * two groups, consisting of just one AMO variable each, are used to identify | ||
216 | * the remote partitions that are currently engaged (from the viewpoint of | ||
217 | * the XPC running on the remote partition). | ||
218 | */ | ||
219 | #define XPC_NOTIFY_IRQ_AMOS 0 | ||
220 | #define XPC_ACTIVATE_IRQ_AMOS (XPC_NOTIFY_IRQ_AMOS + XP_MAX_PARTITIONS) | ||
221 | #define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS) | ||
222 | #define XPC_DISENGAGE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1) | ||
223 | |||
224 | |||
225 | /* | ||
226 | * The following structure describes the per partition specific variables. | ||
227 | * | ||
228 | * An array of these structures, one per partition, will be defined. As a | ||
229 | * partition becomes active XPC will copy the array entry corresponding to | ||
230 | * itself from that partition. It is desirable that the size of this | ||
231 | * structure evenly divide into a cacheline, such that none of the entries | ||
232 | * in this array crosses a cacheline boundary. As it is now, each entry | ||
233 | * occupies half a cacheline. | ||
234 | */ | ||
235 | struct xpc_vars_part { | ||
236 | volatile u64 magic; | ||
237 | |||
238 | u64 openclose_args_pa; /* physical address of open and close args */ | ||
239 | u64 GPs_pa; /* physical address of Get/Put values */ | ||
240 | |||
241 | u64 IPI_amo_pa; /* physical address of IPI AMO_t structure */ | ||
242 | int IPI_nasid; /* nasid of where to send IPIs */ | ||
243 | int IPI_phys_cpuid; /* physical CPU ID of where to send IPIs */ | ||
244 | |||
245 | u8 nchannels; /* #of defined channels supported */ | ||
246 | |||
247 | u8 reserved[23]; /* pad to a full 64 bytes */ | ||
248 | }; | ||
249 | |||
250 | /* | ||
251 | * The vars_part MAGIC numbers play a part in the first contact protocol. | ||
252 | * | ||
253 | * MAGIC1 indicates that the per partition specific variables for a remote | ||
254 | * partition have been initialized by this partition. | ||
255 | * | ||
256 | * MAGIC2 indicates that this partition has pulled the remote partititions | ||
257 | * per partition variables that pertain to this partition. | ||
258 | */ | ||
259 | #define XPC_VP_MAGIC1 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */ | ||
260 | #define XPC_VP_MAGIC2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */ | ||
261 | |||
262 | |||
263 | /* the reserved page sizes and offsets */ | ||
264 | |||
265 | #define XPC_RP_HEADER_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page)) | ||
266 | #define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars)) | ||
267 | |||
268 | #define XPC_RP_PART_NASIDS(_rp) (u64 *) ((u8 *) _rp + XPC_RP_HEADER_SIZE) | ||
269 | #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words) | ||
270 | #define XPC_RP_VARS(_rp) ((struct xpc_vars *) XPC_RP_MACH_NASIDS(_rp) + xp_nasid_mask_words) | ||
271 | #define XPC_RP_VARS_PART(_rp) (struct xpc_vars_part *) ((u8 *) XPC_RP_VARS(rp) + XPC_RP_VARS_SIZE) | ||
272 | |||
273 | |||
274 | /* | ||
275 | * Functions registered by add_timer() or called by kernel_thread() only | ||
276 | * allow for a single 64-bit argument. The following macros can be used to | ||
277 | * pack and unpack two (32-bit, 16-bit or 8-bit) arguments into or out from | ||
278 | * the passed argument. | ||
279 | */ | ||
280 | #define XPC_PACK_ARGS(_arg1, _arg2) \ | ||
281 | ((((u64) _arg1) & 0xffffffff) | \ | ||
282 | ((((u64) _arg2) & 0xffffffff) << 32)) | ||
283 | |||
284 | #define XPC_UNPACK_ARG1(_args) (((u64) _args) & 0xffffffff) | ||
285 | #define XPC_UNPACK_ARG2(_args) ((((u64) _args) >> 32) & 0xffffffff) | ||
286 | |||
287 | |||
288 | |||
289 | /* | ||
290 | * Define a Get/Put value pair (pointers) used with a message queue. | ||
291 | */ | ||
292 | struct xpc_gp { | ||
293 | volatile s64 get; /* Get value */ | ||
294 | volatile s64 put; /* Put value */ | ||
295 | }; | ||
296 | |||
297 | #define XPC_GP_SIZE \ | ||
298 | L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_NCHANNELS) | ||
299 | |||
300 | |||
301 | |||
302 | /* | ||
303 | * Define a structure that contains arguments associated with opening and | ||
304 | * closing a channel. | ||
305 | */ | ||
306 | struct xpc_openclose_args { | ||
307 | u16 reason; /* reason why channel is closing */ | ||
308 | u16 msg_size; /* sizeof each message entry */ | ||
309 | u16 remote_nentries; /* #of message entries in remote msg queue */ | ||
310 | u16 local_nentries; /* #of message entries in local msg queue */ | ||
311 | u64 local_msgqueue_pa; /* physical address of local message queue */ | ||
312 | }; | ||
313 | |||
314 | #define XPC_OPENCLOSE_ARGS_SIZE \ | ||
315 | L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * XPC_NCHANNELS) | ||
316 | |||
317 | |||
318 | |||
319 | /* struct xpc_msg flags */ | ||
320 | |||
321 | #define XPC_M_DONE 0x01 /* msg has been received/consumed */ | ||
322 | #define XPC_M_READY 0x02 /* msg is ready to be sent */ | ||
323 | #define XPC_M_INTERRUPT 0x04 /* send interrupt when msg consumed */ | ||
324 | |||
325 | |||
326 | #define XPC_MSG_ADDRESS(_payload) \ | ||
327 | ((struct xpc_msg *)((u8 *)(_payload) - XPC_MSG_PAYLOAD_OFFSET)) | ||
328 | |||
329 | |||
330 | |||
331 | /* | ||
332 | * Defines notify entry. | ||
333 | * | ||
334 | * This is used to notify a message's sender that their message was received | ||
335 | * and consumed by the intended recipient. | ||
336 | */ | ||
337 | struct xpc_notify { | ||
338 | struct semaphore sema; /* notify semaphore */ | ||
339 | volatile u8 type; /* type of notification */ | ||
340 | |||
341 | /* the following two fields are only used if type == XPC_N_CALL */ | ||
342 | xpc_notify_func func; /* user's notify function */ | ||
343 | void *key; /* pointer to user's key */ | ||
344 | }; | ||
345 | |||
346 | /* struct xpc_notify type of notification */ | ||
347 | |||
348 | #define XPC_N_CALL 0x01 /* notify function provided by user */ | ||
349 | |||
350 | |||
351 | |||
352 | /* | ||
353 | * Define the structure that manages all the stuff required by a channel. In | ||
354 | * particular, they are used to manage the messages sent across the channel. | ||
355 | * | ||
356 | * This structure is private to a partition, and is NOT shared across the | ||
357 | * partition boundary. | ||
358 | * | ||
359 | * There is an array of these structures for each remote partition. It is | ||
360 | * allocated at the time a partition becomes active. The array contains one | ||
361 | * of these structures for each potential channel connection to that partition. | ||
362 | * | ||
363 | * Each of these structures manages two message queues (circular buffers). | ||
364 | * They are allocated at the time a channel connection is made. One of | ||
365 | * these message queues (local_msgqueue) holds the locally created messages | ||
366 | * that are destined for the remote partition. The other of these message | ||
367 | * queues (remote_msgqueue) is a locally cached copy of the remote partition's | ||
368 | * own local_msgqueue. | ||
369 | * | ||
370 | * The following is a description of the Get/Put pointers used to manage these | ||
371 | * two message queues. Consider the local_msgqueue to be on one partition | ||
372 | * and the remote_msgqueue to be its cached copy on another partition. A | ||
373 | * description of what each of the lettered areas contains is included. | ||
374 | * | ||
375 | * | ||
376 | * local_msgqueue remote_msgqueue | ||
377 | * | ||
378 | * |/////////| |/////////| | ||
379 | * w_remote_GP.get --> +---------+ |/////////| | ||
380 | * | F | |/////////| | ||
381 | * remote_GP.get --> +---------+ +---------+ <-- local_GP->get | ||
382 | * | | | | | ||
383 | * | | | E | | ||
384 | * | | | | | ||
385 | * | | +---------+ <-- w_local_GP.get | ||
386 | * | B | |/////////| | ||
387 | * | | |////D////| | ||
388 | * | | |/////////| | ||
389 | * | | +---------+ <-- w_remote_GP.put | ||
390 | * | | |////C////| | ||
391 | * local_GP->put --> +---------+ +---------+ <-- remote_GP.put | ||
392 | * | | |/////////| | ||
393 | * | A | |/////////| | ||
394 | * | | |/////////| | ||
395 | * w_local_GP.put --> +---------+ |/////////| | ||
396 | * |/////////| |/////////| | ||
397 | * | ||
398 | * | ||
399 | * ( remote_GP.[get|put] are cached copies of the remote | ||
400 | * partition's local_GP->[get|put], and thus their values can | ||
401 | * lag behind their counterparts on the remote partition. ) | ||
402 | * | ||
403 | * | ||
404 | * A - Messages that have been allocated, but have not yet been sent to the | ||
405 | * remote partition. | ||
406 | * | ||
407 | * B - Messages that have been sent, but have not yet been acknowledged by the | ||
408 | * remote partition as having been received. | ||
409 | * | ||
410 | * C - Area that needs to be prepared for the copying of sent messages, by | ||
411 | * the clearing of the message flags of any previously received messages. | ||
412 | * | ||
413 | * D - Area into which sent messages are to be copied from the remote | ||
414 | * partition's local_msgqueue and then delivered to their intended | ||
415 | * recipients. [ To allow for a multi-message copy, another pointer | ||
416 | * (next_msg_to_pull) has been added to keep track of the next message | ||
417 | * number needing to be copied (pulled). It chases after w_remote_GP.put. | ||
418 | * Any messages lying between w_local_GP.get and next_msg_to_pull have | ||
419 | * been copied and are ready to be delivered. ] | ||
420 | * | ||
421 | * E - Messages that have been copied and delivered, but have not yet been | ||
422 | * acknowledged by the recipient as having been received. | ||
423 | * | ||
424 | * F - Messages that have been acknowledged, but XPC has not yet notified the | ||
425 | * sender that the message was received by its intended recipient. | ||
426 | * This is also an area that needs to be prepared for the allocating of | ||
427 | * new messages, by the clearing of the message flags of the acknowledged | ||
428 | * messages. | ||
429 | */ | ||
430 | struct xpc_channel { | ||
431 | partid_t partid; /* ID of remote partition connected */ | ||
432 | spinlock_t lock; /* lock for updating this structure */ | ||
433 | u32 flags; /* general flags */ | ||
434 | |||
435 | enum xpc_retval reason; /* reason why channel is disconnect'g */ | ||
436 | int reason_line; /* line# disconnect initiated from */ | ||
437 | |||
438 | u16 number; /* channel # */ | ||
439 | |||
440 | u16 msg_size; /* sizeof each msg entry */ | ||
441 | u16 local_nentries; /* #of msg entries in local msg queue */ | ||
442 | u16 remote_nentries; /* #of msg entries in remote msg queue*/ | ||
443 | |||
444 | void *local_msgqueue_base; /* base address of kmalloc'd space */ | ||
445 | struct xpc_msg *local_msgqueue; /* local message queue */ | ||
446 | void *remote_msgqueue_base; /* base address of kmalloc'd space */ | ||
447 | struct xpc_msg *remote_msgqueue;/* cached copy of remote partition's */ | ||
448 | /* local message queue */ | ||
449 | u64 remote_msgqueue_pa; /* phys addr of remote partition's */ | ||
450 | /* local message queue */ | ||
451 | |||
452 | atomic_t references; /* #of external references to queues */ | ||
453 | |||
454 | atomic_t n_on_msg_allocate_wq; /* #on msg allocation wait queue */ | ||
455 | wait_queue_head_t msg_allocate_wq; /* msg allocation wait queue */ | ||
456 | |||
457 | u8 delayed_IPI_flags; /* IPI flags received, but delayed */ | ||
458 | /* action until channel disconnected */ | ||
459 | |||
460 | /* queue of msg senders who want to be notified when msg received */ | ||
461 | |||
462 | atomic_t n_to_notify; /* #of msg senders to notify */ | ||
463 | struct xpc_notify *notify_queue;/* notify queue for messages sent */ | ||
464 | |||
465 | xpc_channel_func func; /* user's channel function */ | ||
466 | void *key; /* pointer to user's key */ | ||
467 | |||
468 | struct semaphore msg_to_pull_sema; /* next msg to pull serialization */ | ||
469 | struct semaphore wdisconnect_sema; /* wait for channel disconnect */ | ||
470 | |||
471 | struct xpc_openclose_args *local_openclose_args; /* args passed on */ | ||
472 | /* opening or closing of channel */ | ||
473 | |||
474 | /* various flavors of local and remote Get/Put values */ | ||
475 | |||
476 | struct xpc_gp *local_GP; /* local Get/Put values */ | ||
477 | struct xpc_gp remote_GP; /* remote Get/Put values */ | ||
478 | struct xpc_gp w_local_GP; /* working local Get/Put values */ | ||
479 | struct xpc_gp w_remote_GP; /* working remote Get/Put values */ | ||
480 | s64 next_msg_to_pull; /* Put value of next msg to pull */ | ||
481 | |||
482 | /* kthread management related fields */ | ||
483 | |||
484 | // >>> rethink having kthreads_assigned_limit and kthreads_idle_limit; perhaps | ||
485 | // >>> allow the assigned limit be unbounded and let the idle limit be dynamic | ||
486 | // >>> dependent on activity over the last interval of time | ||
487 | atomic_t kthreads_assigned; /* #of kthreads assigned to channel */ | ||
488 | u32 kthreads_assigned_limit; /* limit on #of kthreads assigned */ | ||
489 | atomic_t kthreads_idle; /* #of kthreads idle waiting for work */ | ||
490 | u32 kthreads_idle_limit; /* limit on #of kthreads idle */ | ||
491 | atomic_t kthreads_active; /* #of kthreads actively working */ | ||
492 | // >>> following field is temporary | ||
493 | u32 kthreads_created; /* total #of kthreads created */ | ||
494 | |||
495 | wait_queue_head_t idle_wq; /* idle kthread wait queue */ | ||
496 | |||
497 | } ____cacheline_aligned; | ||
498 | |||
499 | |||
500 | /* struct xpc_channel flags */ | ||
501 | |||
502 | #define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */ | ||
503 | |||
504 | #define XPC_C_ROPENREPLY 0x00000002 /* remote open channel reply */ | ||
505 | #define XPC_C_OPENREPLY 0x00000004 /* local open channel reply */ | ||
506 | #define XPC_C_ROPENREQUEST 0x00000008 /* remote open channel request */ | ||
507 | #define XPC_C_OPENREQUEST 0x00000010 /* local open channel request */ | ||
508 | |||
509 | #define XPC_C_SETUP 0x00000020 /* channel's msgqueues are alloc'd */ | ||
510 | #define XPC_C_CONNECTCALLOUT 0x00000040 /* channel connected callout made */ | ||
511 | #define XPC_C_CONNECTED 0x00000080 /* local channel is connected */ | ||
512 | #define XPC_C_CONNECTING 0x00000100 /* channel is being connected */ | ||
513 | |||
514 | #define XPC_C_RCLOSEREPLY 0x00000200 /* remote close channel reply */ | ||
515 | #define XPC_C_CLOSEREPLY 0x00000400 /* local close channel reply */ | ||
516 | #define XPC_C_RCLOSEREQUEST 0x00000800 /* remote close channel request */ | ||
517 | #define XPC_C_CLOSEREQUEST 0x00001000 /* local close channel request */ | ||
518 | |||
519 | #define XPC_C_DISCONNECTED 0x00002000 /* channel is disconnected */ | ||
520 | #define XPC_C_DISCONNECTING 0x00004000 /* channel is being disconnected */ | ||
521 | #define XPC_C_DISCONNECTCALLOUT 0x00008000 /* chan disconnected callout made */ | ||
522 | #define XPC_C_WDISCONNECT 0x00010000 /* waiting for channel disconnect */ | ||
523 | |||
524 | |||
525 | |||
526 | /* | ||
527 | * Manages channels on a partition basis. There is one of these structures | ||
528 | * for each partition (a partition will never utilize the structure that | ||
529 | * represents itself). | ||
530 | */ | ||
531 | struct xpc_partition { | ||
532 | |||
533 | /* XPC HB infrastructure */ | ||
534 | |||
535 | u8 remote_rp_version; /* version# of partition's rsvd pg */ | ||
536 | struct timespec remote_rp_stamp;/* time when rsvd pg was initialized */ | ||
537 | u64 remote_rp_pa; /* phys addr of partition's rsvd pg */ | ||
538 | u64 remote_vars_pa; /* phys addr of partition's vars */ | ||
539 | u64 remote_vars_part_pa; /* phys addr of partition's vars part */ | ||
540 | u64 last_heartbeat; /* HB at last read */ | ||
541 | u64 remote_amos_page_pa; /* phys addr of partition's amos page */ | ||
542 | int remote_act_nasid; /* active part's act/deact nasid */ | ||
543 | int remote_act_phys_cpuid; /* active part's act/deact phys cpuid */ | ||
544 | u32 act_IRQ_rcvd; /* IRQs since activation */ | ||
545 | spinlock_t act_lock; /* protect updating of act_state */ | ||
546 | u8 act_state; /* from XPC HB viewpoint */ | ||
547 | u8 remote_vars_version; /* version# of partition's vars */ | ||
548 | enum xpc_retval reason; /* reason partition is deactivating */ | ||
549 | int reason_line; /* line# deactivation initiated from */ | ||
550 | int reactivate_nasid; /* nasid in partition to reactivate */ | ||
551 | |||
552 | unsigned long disengage_request_timeout; /* timeout in jiffies */ | ||
553 | struct timer_list disengage_request_timer; | ||
554 | |||
555 | |||
556 | /* XPC infrastructure referencing and teardown control */ | ||
557 | |||
558 | volatile u8 setup_state; /* infrastructure setup state */ | ||
559 | wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */ | ||
560 | atomic_t references; /* #of references to infrastructure */ | ||
561 | |||
562 | |||
563 | /* | ||
564 | * NONE OF THE PRECEDING FIELDS OF THIS STRUCTURE WILL BE CLEARED WHEN | ||
565 | * XPC SETS UP THE NECESSARY INFRASTRUCTURE TO SUPPORT CROSS PARTITION | ||
566 | * COMMUNICATION. ALL OF THE FOLLOWING FIELDS WILL BE CLEARED. (THE | ||
567 | * 'nchannels' FIELD MUST BE THE FIRST OF THE FIELDS TO BE CLEARED.) | ||
568 | */ | ||
569 | |||
570 | |||
571 | u8 nchannels; /* #of defined channels supported */ | ||
572 | atomic_t nchannels_active; /* #of channels that are not DISCONNECTED */ | ||
573 | atomic_t nchannels_engaged;/* #of channels engaged with remote part */ | ||
574 | struct xpc_channel *channels;/* array of channel structures */ | ||
575 | |||
576 | void *local_GPs_base; /* base address of kmalloc'd space */ | ||
577 | struct xpc_gp *local_GPs; /* local Get/Put values */ | ||
578 | void *remote_GPs_base; /* base address of kmalloc'd space */ | ||
579 | struct xpc_gp *remote_GPs;/* copy of remote partition's local Get/Put */ | ||
580 | /* values */ | ||
581 | u64 remote_GPs_pa; /* phys address of remote partition's local */ | ||
582 | /* Get/Put values */ | ||
583 | |||
584 | |||
585 | /* fields used to pass args when opening or closing a channel */ | ||
586 | |||
587 | void *local_openclose_args_base; /* base address of kmalloc'd space */ | ||
588 | struct xpc_openclose_args *local_openclose_args; /* local's args */ | ||
589 | void *remote_openclose_args_base; /* base address of kmalloc'd space */ | ||
590 | struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */ | ||
591 | /* args */ | ||
592 | u64 remote_openclose_args_pa; /* phys addr of remote's args */ | ||
593 | |||
594 | |||
595 | /* IPI sending, receiving and handling related fields */ | ||
596 | |||
597 | int remote_IPI_nasid; /* nasid of where to send IPIs */ | ||
598 | int remote_IPI_phys_cpuid; /* phys CPU ID of where to send IPIs */ | ||
599 | AMO_t *remote_IPI_amo_va; /* address of remote IPI AMO_t structure */ | ||
600 | |||
601 | AMO_t *local_IPI_amo_va; /* address of IPI AMO_t structure */ | ||
602 | u64 local_IPI_amo; /* IPI amo flags yet to be handled */ | ||
603 | char IPI_owner[8]; /* IPI owner's name */ | ||
604 | struct timer_list dropped_IPI_timer; /* dropped IPI timer */ | ||
605 | |||
606 | spinlock_t IPI_lock; /* IPI handler lock */ | ||
607 | |||
608 | |||
609 | /* channel manager related fields */ | ||
610 | |||
611 | atomic_t channel_mgr_requests; /* #of requests to activate chan mgr */ | ||
612 | wait_queue_head_t channel_mgr_wq; /* channel mgr's wait queue */ | ||
613 | |||
614 | } ____cacheline_aligned; | ||
615 | |||
616 | |||
617 | /* struct xpc_partition act_state values (for XPC HB) */ | ||
618 | |||
619 | #define XPC_P_INACTIVE 0x00 /* partition is not active */ | ||
620 | #define XPC_P_ACTIVATION_REQ 0x01 /* created thread to activate */ | ||
621 | #define XPC_P_ACTIVATING 0x02 /* activation thread started */ | ||
622 | #define XPC_P_ACTIVE 0x03 /* xpc_partition_up() was called */ | ||
623 | #define XPC_P_DEACTIVATING 0x04 /* partition deactivation initiated */ | ||
624 | |||
625 | |||
626 | #define XPC_DEACTIVATE_PARTITION(_p, _reason) \ | ||
627 | xpc_deactivate_partition(__LINE__, (_p), (_reason)) | ||
628 | |||
629 | |||
630 | /* struct xpc_partition setup_state values */ | ||
631 | |||
632 | #define XPC_P_UNSET 0x00 /* infrastructure was never setup */ | ||
633 | #define XPC_P_SETUP 0x01 /* infrastructure is setup */ | ||
634 | #define XPC_P_WTEARDOWN 0x02 /* waiting to teardown infrastructure */ | ||
635 | #define XPC_P_TORNDOWN 0x03 /* infrastructure is torndown */ | ||
636 | |||
637 | |||
638 | |||
639 | /* | ||
640 | * struct xpc_partition IPI_timer #of seconds to wait before checking for | ||
641 | * dropped IPIs. These occur whenever an IPI amo write doesn't complete until | ||
642 | * after the IPI was received. | ||
643 | */ | ||
644 | #define XPC_P_DROPPED_IPI_WAIT (0.25 * HZ) | ||
645 | |||
646 | |||
647 | /* number of seconds to wait for other partitions to disengage */ | ||
648 | #define XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT 90 | ||
649 | |||
650 | /* interval in seconds to print 'waiting disengagement' messages */ | ||
651 | #define XPC_DISENGAGE_PRINTMSG_INTERVAL 10 | ||
652 | |||
653 | |||
654 | #define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0])) | ||
655 | |||
656 | |||
657 | |||
658 | /* found in xp_main.c */ | ||
659 | extern struct xpc_registration xpc_registrations[]; | ||
660 | |||
661 | |||
662 | /* found in xpc_main.c */ | ||
663 | extern struct device *xpc_part; | ||
664 | extern struct device *xpc_chan; | ||
665 | extern int xpc_disengage_request_timelimit; | ||
666 | extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *); | ||
667 | extern void xpc_dropped_IPI_check(struct xpc_partition *); | ||
668 | extern void xpc_activate_partition(struct xpc_partition *); | ||
669 | extern void xpc_activate_kthreads(struct xpc_channel *, int); | ||
670 | extern void xpc_create_kthreads(struct xpc_channel *, int); | ||
671 | extern void xpc_disconnect_wait(int); | ||
672 | |||
673 | |||
674 | /* found in xpc_partition.c */ | ||
675 | extern int xpc_exiting; | ||
676 | extern struct xpc_vars *xpc_vars; | ||
677 | extern struct xpc_rsvd_page *xpc_rsvd_page; | ||
678 | extern struct xpc_vars_part *xpc_vars_part; | ||
679 | extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1]; | ||
680 | extern char xpc_remote_copy_buffer[]; | ||
681 | extern struct xpc_rsvd_page *xpc_rsvd_page_init(void); | ||
682 | extern void xpc_allow_IPI_ops(void); | ||
683 | extern void xpc_restrict_IPI_ops(void); | ||
684 | extern int xpc_identify_act_IRQ_sender(void); | ||
685 | extern int xpc_partition_disengaged(struct xpc_partition *); | ||
686 | extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *); | ||
687 | extern void xpc_mark_partition_inactive(struct xpc_partition *); | ||
688 | extern void xpc_discovery(void); | ||
689 | extern void xpc_check_remote_hb(void); | ||
690 | extern void xpc_deactivate_partition(const int, struct xpc_partition *, | ||
691 | enum xpc_retval); | ||
692 | extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *); | ||
693 | |||
694 | |||
695 | /* found in xpc_channel.c */ | ||
696 | extern void xpc_initiate_connect(int); | ||
697 | extern void xpc_initiate_disconnect(int); | ||
698 | extern enum xpc_retval xpc_initiate_allocate(partid_t, int, u32, void **); | ||
699 | extern enum xpc_retval xpc_initiate_send(partid_t, int, void *); | ||
700 | extern enum xpc_retval xpc_initiate_send_notify(partid_t, int, void *, | ||
701 | xpc_notify_func, void *); | ||
702 | extern void xpc_initiate_received(partid_t, int, void *); | ||
703 | extern enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *); | ||
704 | extern enum xpc_retval xpc_pull_remote_vars_part(struct xpc_partition *); | ||
705 | extern void xpc_process_channel_activity(struct xpc_partition *); | ||
706 | extern void xpc_connected_callout(struct xpc_channel *); | ||
707 | extern void xpc_deliver_msg(struct xpc_channel *); | ||
708 | extern void xpc_disconnect_channel(const int, struct xpc_channel *, | ||
709 | enum xpc_retval, unsigned long *); | ||
710 | extern void xpc_disconnecting_callout(struct xpc_channel *); | ||
711 | extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval); | ||
712 | extern void xpc_teardown_infrastructure(struct xpc_partition *); | ||
713 | |||
714 | |||
715 | |||
716 | static inline void | ||
717 | xpc_wakeup_channel_mgr(struct xpc_partition *part) | ||
718 | { | ||
719 | if (atomic_inc_return(&part->channel_mgr_requests) == 1) { | ||
720 | wake_up(&part->channel_mgr_wq); | ||
721 | } | ||
722 | } | ||
723 | |||
724 | |||
725 | |||
726 | /* | ||
727 | * These next two inlines are used to keep us from tearing down a channel's | ||
728 | * msg queues while a thread may be referencing them. | ||
729 | */ | ||
730 | static inline void | ||
731 | xpc_msgqueue_ref(struct xpc_channel *ch) | ||
732 | { | ||
733 | atomic_inc(&ch->references); | ||
734 | } | ||
735 | |||
736 | static inline void | ||
737 | xpc_msgqueue_deref(struct xpc_channel *ch) | ||
738 | { | ||
739 | s32 refs = atomic_dec_return(&ch->references); | ||
740 | |||
741 | DBUG_ON(refs < 0); | ||
742 | if (refs == 0) { | ||
743 | xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]); | ||
744 | } | ||
745 | } | ||
746 | |||
747 | |||
748 | |||
749 | #define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \ | ||
750 | xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs) | ||
751 | |||
752 | |||
753 | /* | ||
754 | * These two inlines are used to keep us from tearing down a partition's | ||
755 | * setup infrastructure while a thread may be referencing it. | ||
756 | */ | ||
757 | static inline void | ||
758 | xpc_part_deref(struct xpc_partition *part) | ||
759 | { | ||
760 | s32 refs = atomic_dec_return(&part->references); | ||
761 | |||
762 | |||
763 | DBUG_ON(refs < 0); | ||
764 | if (refs == 0 && part->setup_state == XPC_P_WTEARDOWN) { | ||
765 | wake_up(&part->teardown_wq); | ||
766 | } | ||
767 | } | ||
768 | |||
769 | static inline int | ||
770 | xpc_part_ref(struct xpc_partition *part) | ||
771 | { | ||
772 | int setup; | ||
773 | |||
774 | |||
775 | atomic_inc(&part->references); | ||
776 | setup = (part->setup_state == XPC_P_SETUP); | ||
777 | if (!setup) { | ||
778 | xpc_part_deref(part); | ||
779 | } | ||
780 | return setup; | ||
781 | } | ||
782 | |||
783 | |||
784 | |||
785 | /* | ||
786 | * The following macro is to be used for the setting of the reason and | ||
787 | * reason_line fields in both the struct xpc_channel and struct xpc_partition | ||
788 | * structures. | ||
789 | */ | ||
790 | #define XPC_SET_REASON(_p, _reason, _line) \ | ||
791 | { \ | ||
792 | (_p)->reason = _reason; \ | ||
793 | (_p)->reason_line = _line; \ | ||
794 | } | ||
795 | |||
796 | |||
797 | |||
798 | /* | ||
799 | * This next set of inlines are used to keep track of when a partition is | ||
800 | * potentially engaged in accessing memory belonging to another partition. | ||
801 | */ | ||
802 | |||
803 | static inline void | ||
804 | xpc_mark_partition_engaged(struct xpc_partition *part) | ||
805 | { | ||
806 | unsigned long irq_flags; | ||
807 | AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + | ||
808 | (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t))); | ||
809 | |||
810 | |||
811 | local_irq_save(irq_flags); | ||
812 | |||
813 | /* set bit corresponding to our partid in remote partition's AMO */ | ||
814 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, | ||
815 | (1UL << sn_partition_id)); | ||
816 | /* | ||
817 | * We must always use the nofault function regardless of whether we | ||
818 | * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we | ||
819 | * didn't, we'd never know that the other partition is down and would | ||
820 | * keep sending IPIs and AMOs to it until the heartbeat times out. | ||
821 | */ | ||
822 | (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> | ||
823 | variable), xp_nofault_PIOR_target)); | ||
824 | |||
825 | local_irq_restore(irq_flags); | ||
826 | } | ||
827 | |||
828 | static inline void | ||
829 | xpc_mark_partition_disengaged(struct xpc_partition *part) | ||
830 | { | ||
831 | unsigned long irq_flags; | ||
832 | AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + | ||
833 | (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t))); | ||
834 | |||
835 | |||
836 | local_irq_save(irq_flags); | ||
837 | |||
838 | /* clear bit corresponding to our partid in remote partition's AMO */ | ||
839 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, | ||
840 | ~(1UL << sn_partition_id)); | ||
841 | /* | ||
842 | * We must always use the nofault function regardless of whether we | ||
843 | * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we | ||
844 | * didn't, we'd never know that the other partition is down and would | ||
845 | * keep sending IPIs and AMOs to it until the heartbeat times out. | ||
846 | */ | ||
847 | (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> | ||
848 | variable), xp_nofault_PIOR_target)); | ||
849 | |||
850 | local_irq_restore(irq_flags); | ||
851 | } | ||
852 | |||
853 | static inline void | ||
854 | xpc_request_partition_disengage(struct xpc_partition *part) | ||
855 | { | ||
856 | unsigned long irq_flags; | ||
857 | AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + | ||
858 | (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t))); | ||
859 | |||
860 | |||
861 | local_irq_save(irq_flags); | ||
862 | |||
863 | /* set bit corresponding to our partid in remote partition's AMO */ | ||
864 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, | ||
865 | (1UL << sn_partition_id)); | ||
866 | /* | ||
867 | * We must always use the nofault function regardless of whether we | ||
868 | * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we | ||
869 | * didn't, we'd never know that the other partition is down and would | ||
870 | * keep sending IPIs and AMOs to it until the heartbeat times out. | ||
871 | */ | ||
872 | (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> | ||
873 | variable), xp_nofault_PIOR_target)); | ||
874 | |||
875 | local_irq_restore(irq_flags); | ||
876 | } | ||
877 | |||
878 | static inline void | ||
879 | xpc_cancel_partition_disengage_request(struct xpc_partition *part) | ||
880 | { | ||
881 | unsigned long irq_flags; | ||
882 | AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + | ||
883 | (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t))); | ||
884 | |||
885 | |||
886 | local_irq_save(irq_flags); | ||
887 | |||
888 | /* clear bit corresponding to our partid in remote partition's AMO */ | ||
889 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, | ||
890 | ~(1UL << sn_partition_id)); | ||
891 | /* | ||
892 | * We must always use the nofault function regardless of whether we | ||
893 | * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we | ||
894 | * didn't, we'd never know that the other partition is down and would | ||
895 | * keep sending IPIs and AMOs to it until the heartbeat times out. | ||
896 | */ | ||
897 | (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> | ||
898 | variable), xp_nofault_PIOR_target)); | ||
899 | |||
900 | local_irq_restore(irq_flags); | ||
901 | } | ||
902 | |||
903 | static inline u64 | ||
904 | xpc_partition_engaged(u64 partid_mask) | ||
905 | { | ||
906 | AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; | ||
907 | |||
908 | |||
909 | /* return our partition's AMO variable ANDed with partid_mask */ | ||
910 | return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) & | ||
911 | partid_mask); | ||
912 | } | ||
913 | |||
914 | static inline u64 | ||
915 | xpc_partition_disengage_requested(u64 partid_mask) | ||
916 | { | ||
917 | AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO; | ||
918 | |||
919 | |||
920 | /* return our partition's AMO variable ANDed with partid_mask */ | ||
921 | return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) & | ||
922 | partid_mask); | ||
923 | } | ||
924 | |||
925 | static inline void | ||
926 | xpc_clear_partition_engaged(u64 partid_mask) | ||
927 | { | ||
928 | AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; | ||
929 | |||
930 | |||
931 | /* clear bit(s) based on partid_mask in our partition's AMO */ | ||
932 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, | ||
933 | ~partid_mask); | ||
934 | } | ||
935 | |||
936 | static inline void | ||
937 | xpc_clear_partition_disengage_request(u64 partid_mask) | ||
938 | { | ||
939 | AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO; | ||
940 | |||
941 | |||
942 | /* clear bit(s) based on partid_mask in our partition's AMO */ | ||
943 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, | ||
944 | ~partid_mask); | ||
945 | } | ||
946 | |||
947 | |||
948 | |||
949 | /* | ||
950 | * The following set of macros and inlines are used for the sending and | ||
951 | * receiving of IPIs (also known as IRQs). There are two flavors of IPIs, | ||
952 | * one that is associated with partition activity (SGI_XPC_ACTIVATE) and | ||
953 | * the other that is associated with channel activity (SGI_XPC_NOTIFY). | ||
954 | */ | ||
955 | |||
956 | static inline u64 | ||
957 | xpc_IPI_receive(AMO_t *amo) | ||
958 | { | ||
959 | return FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_CLEAR); | ||
960 | } | ||
961 | |||
962 | |||
963 | static inline enum xpc_retval | ||
964 | xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector) | ||
965 | { | ||
966 | int ret = 0; | ||
967 | unsigned long irq_flags; | ||
968 | |||
969 | |||
970 | local_irq_save(irq_flags); | ||
971 | |||
972 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, flag); | ||
973 | sn_send_IPI_phys(nasid, phys_cpuid, vector, 0); | ||
974 | |||
975 | /* | ||
976 | * We must always use the nofault function regardless of whether we | ||
977 | * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we | ||
978 | * didn't, we'd never know that the other partition is down and would | ||
979 | * keep sending IPIs and AMOs to it until the heartbeat times out. | ||
980 | */ | ||
981 | ret = xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->variable), | ||
982 | xp_nofault_PIOR_target)); | ||
983 | |||
984 | local_irq_restore(irq_flags); | ||
985 | |||
986 | return ((ret == 0) ? xpcSuccess : xpcPioReadError); | ||
987 | } | ||
988 | |||
989 | |||
990 | /* | ||
991 | * IPIs associated with SGI_XPC_ACTIVATE IRQ. | ||
992 | */ | ||
993 | |||
994 | /* | ||
995 | * Flag the appropriate AMO variable and send an IPI to the specified node. | ||
996 | */ | ||
997 | static inline void | ||
998 | xpc_activate_IRQ_send(u64 amos_page_pa, int from_nasid, int to_nasid, | ||
999 | int to_phys_cpuid) | ||
1000 | { | ||
1001 | int w_index = XPC_NASID_W_INDEX(from_nasid); | ||
1002 | int b_index = XPC_NASID_B_INDEX(from_nasid); | ||
1003 | AMO_t *amos = (AMO_t *) __va(amos_page_pa + | ||
1004 | (XPC_ACTIVATE_IRQ_AMOS * sizeof(AMO_t))); | ||
1005 | |||
1006 | |||
1007 | (void) xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid, | ||
1008 | to_phys_cpuid, SGI_XPC_ACTIVATE); | ||
1009 | } | ||
1010 | |||
1011 | static inline void | ||
1012 | xpc_IPI_send_activate(struct xpc_vars *vars) | ||
1013 | { | ||
1014 | xpc_activate_IRQ_send(vars->amos_page_pa, cnodeid_to_nasid(0), | ||
1015 | vars->act_nasid, vars->act_phys_cpuid); | ||
1016 | } | ||
1017 | |||
1018 | static inline void | ||
1019 | xpc_IPI_send_activated(struct xpc_partition *part) | ||
1020 | { | ||
1021 | xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0), | ||
1022 | part->remote_act_nasid, part->remote_act_phys_cpuid); | ||
1023 | } | ||
1024 | |||
1025 | static inline void | ||
1026 | xpc_IPI_send_reactivate(struct xpc_partition *part) | ||
1027 | { | ||
1028 | xpc_activate_IRQ_send(xpc_vars->amos_page_pa, part->reactivate_nasid, | ||
1029 | xpc_vars->act_nasid, xpc_vars->act_phys_cpuid); | ||
1030 | } | ||
1031 | |||
1032 | static inline void | ||
1033 | xpc_IPI_send_disengage(struct xpc_partition *part) | ||
1034 | { | ||
1035 | xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0), | ||
1036 | part->remote_act_nasid, part->remote_act_phys_cpuid); | ||
1037 | } | ||
1038 | |||
1039 | |||
1040 | /* | ||
1041 | * IPIs associated with SGI_XPC_NOTIFY IRQ. | ||
1042 | */ | ||
1043 | |||
1044 | /* | ||
1045 | * Send an IPI to the remote partition that is associated with the | ||
1046 | * specified channel. | ||
1047 | */ | ||
1048 | #define XPC_NOTIFY_IRQ_SEND(_ch, _ipi_f, _irq_f) \ | ||
1049 | xpc_notify_IRQ_send(_ch, _ipi_f, #_ipi_f, _irq_f) | ||
1050 | |||
1051 | static inline void | ||
1052 | xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string, | ||
1053 | unsigned long *irq_flags) | ||
1054 | { | ||
1055 | struct xpc_partition *part = &xpc_partitions[ch->partid]; | ||
1056 | enum xpc_retval ret; | ||
1057 | |||
1058 | |||
1059 | if (likely(part->act_state != XPC_P_DEACTIVATING)) { | ||
1060 | ret = xpc_IPI_send(part->remote_IPI_amo_va, | ||
1061 | (u64) ipi_flag << (ch->number * 8), | ||
1062 | part->remote_IPI_nasid, | ||
1063 | part->remote_IPI_phys_cpuid, | ||
1064 | SGI_XPC_NOTIFY); | ||
1065 | dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n", | ||
1066 | ipi_flag_string, ch->partid, ch->number, ret); | ||
1067 | if (unlikely(ret != xpcSuccess)) { | ||
1068 | if (irq_flags != NULL) { | ||
1069 | spin_unlock_irqrestore(&ch->lock, *irq_flags); | ||
1070 | } | ||
1071 | XPC_DEACTIVATE_PARTITION(part, ret); | ||
1072 | if (irq_flags != NULL) { | ||
1073 | spin_lock_irqsave(&ch->lock, *irq_flags); | ||
1074 | } | ||
1075 | } | ||
1076 | } | ||
1077 | } | ||
1078 | |||
1079 | |||
1080 | /* | ||
1081 | * Make it look like the remote partition, which is associated with the | ||
1082 | * specified channel, sent us an IPI. This faked IPI will be handled | ||
1083 | * by xpc_dropped_IPI_check(). | ||
1084 | */ | ||
1085 | #define XPC_NOTIFY_IRQ_SEND_LOCAL(_ch, _ipi_f) \ | ||
1086 | xpc_notify_IRQ_send_local(_ch, _ipi_f, #_ipi_f) | ||
1087 | |||
1088 | static inline void | ||
1089 | xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag, | ||
1090 | char *ipi_flag_string) | ||
1091 | { | ||
1092 | struct xpc_partition *part = &xpc_partitions[ch->partid]; | ||
1093 | |||
1094 | |||
1095 | FETCHOP_STORE_OP(TO_AMO((u64) &part->local_IPI_amo_va->variable), | ||
1096 | FETCHOP_OR, ((u64) ipi_flag << (ch->number * 8))); | ||
1097 | dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n", | ||
1098 | ipi_flag_string, ch->partid, ch->number); | ||
1099 | } | ||
1100 | |||
1101 | |||
1102 | /* | ||
1103 | * The sending and receiving of IPIs includes the setting of an AMO variable | ||
1104 | * to indicate the reason the IPI was sent. The 64-bit variable is divided | ||
1105 | * up into eight bytes, ordered from right to left. Byte zero pertains to | ||
1106 | * channel 0, byte one to channel 1, and so on. Each byte is described by | ||
1107 | * the following IPI flags. | ||
1108 | */ | ||
1109 | |||
1110 | #define XPC_IPI_CLOSEREQUEST 0x01 | ||
1111 | #define XPC_IPI_CLOSEREPLY 0x02 | ||
1112 | #define XPC_IPI_OPENREQUEST 0x04 | ||
1113 | #define XPC_IPI_OPENREPLY 0x08 | ||
1114 | #define XPC_IPI_MSGREQUEST 0x10 | ||
1115 | |||
1116 | |||
1117 | /* given an AMO variable and a channel#, get its associated IPI flags */ | ||
1118 | #define XPC_GET_IPI_FLAGS(_amo, _c) ((u8) (((_amo) >> ((_c) * 8)) & 0xff)) | ||
1119 | #define XPC_SET_IPI_FLAGS(_amo, _c, _f) (_amo) |= ((u64) (_f) << ((_c) * 8)) | ||
1120 | |||
1121 | #define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0f) | ||
1122 | #define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & 0x1010101010101010) | ||
1123 | |||
1124 | |||
1125 | static inline void | ||
1126 | xpc_IPI_send_closerequest(struct xpc_channel *ch, unsigned long *irq_flags) | ||
1127 | { | ||
1128 | struct xpc_openclose_args *args = ch->local_openclose_args; | ||
1129 | |||
1130 | |||
1131 | args->reason = ch->reason; | ||
1132 | |||
1133 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREQUEST, irq_flags); | ||
1134 | } | ||
1135 | |||
1136 | static inline void | ||
1137 | xpc_IPI_send_closereply(struct xpc_channel *ch, unsigned long *irq_flags) | ||
1138 | { | ||
1139 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREPLY, irq_flags); | ||
1140 | } | ||
1141 | |||
1142 | static inline void | ||
1143 | xpc_IPI_send_openrequest(struct xpc_channel *ch, unsigned long *irq_flags) | ||
1144 | { | ||
1145 | struct xpc_openclose_args *args = ch->local_openclose_args; | ||
1146 | |||
1147 | |||
1148 | args->msg_size = ch->msg_size; | ||
1149 | args->local_nentries = ch->local_nentries; | ||
1150 | |||
1151 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREQUEST, irq_flags); | ||
1152 | } | ||
1153 | |||
1154 | static inline void | ||
1155 | xpc_IPI_send_openreply(struct xpc_channel *ch, unsigned long *irq_flags) | ||
1156 | { | ||
1157 | struct xpc_openclose_args *args = ch->local_openclose_args; | ||
1158 | |||
1159 | |||
1160 | args->remote_nentries = ch->remote_nentries; | ||
1161 | args->local_nentries = ch->local_nentries; | ||
1162 | args->local_msgqueue_pa = __pa(ch->local_msgqueue); | ||
1163 | |||
1164 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREPLY, irq_flags); | ||
1165 | } | ||
1166 | |||
1167 | static inline void | ||
1168 | xpc_IPI_send_msgrequest(struct xpc_channel *ch) | ||
1169 | { | ||
1170 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_MSGREQUEST, NULL); | ||
1171 | } | ||
1172 | |||
1173 | static inline void | ||
1174 | xpc_IPI_send_local_msgrequest(struct xpc_channel *ch) | ||
1175 | { | ||
1176 | XPC_NOTIFY_IRQ_SEND_LOCAL(ch, XPC_IPI_MSGREQUEST); | ||
1177 | } | ||
1178 | |||
1179 | |||
1180 | /* | ||
1181 | * Memory for XPC's AMO variables is allocated by the MSPEC driver. These | ||
1182 | * pages are located in the lowest granule. The lowest granule uses 4k pages | ||
1183 | * for cached references and an alternate TLB handler to never provide a | ||
1184 | * cacheable mapping for the entire region. This will prevent speculative | ||
1185 | * reading of cached copies of our lines from being issued which will cause | ||
1186 | * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64 | ||
1187 | * AMO variables (based on XP_MAX_PARTITIONS) for message notification and an | ||
1188 | * additional 128 AMO variables (based on XP_NASID_MASK_WORDS) for partition | ||
1189 | * activation and 2 AMO variables for partition deactivation. | ||
1190 | */ | ||
1191 | static inline AMO_t * | ||
1192 | xpc_IPI_init(int index) | ||
1193 | { | ||
1194 | AMO_t *amo = xpc_vars->amos_page + index; | ||
1195 | |||
1196 | |||
1197 | (void) xpc_IPI_receive(amo); /* clear AMO variable */ | ||
1198 | return amo; | ||
1199 | } | ||
1200 | |||
1201 | |||
1202 | |||
1203 | static inline enum xpc_retval | ||
1204 | xpc_map_bte_errors(bte_result_t error) | ||
1205 | { | ||
1206 | switch (error) { | ||
1207 | case BTE_SUCCESS: return xpcSuccess; | ||
1208 | case BTEFAIL_DIR: return xpcBteDirectoryError; | ||
1209 | case BTEFAIL_POISON: return xpcBtePoisonError; | ||
1210 | case BTEFAIL_WERR: return xpcBteWriteError; | ||
1211 | case BTEFAIL_ACCESS: return xpcBteAccessError; | ||
1212 | case BTEFAIL_PWERR: return xpcBtePWriteError; | ||
1213 | case BTEFAIL_PRERR: return xpcBtePReadError; | ||
1214 | case BTEFAIL_TOUT: return xpcBteTimeOutError; | ||
1215 | case BTEFAIL_XTERR: return xpcBteXtalkError; | ||
1216 | case BTEFAIL_NOTAVAIL: return xpcBteNotAvailable; | ||
1217 | default: return xpcBteUnmappedError; | ||
1218 | } | ||
1219 | } | ||
1220 | |||
1221 | |||
1222 | |||
1223 | static inline void * | ||
1224 | xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base) | ||
1225 | { | ||
1226 | /* see if kmalloc will give us cachline aligned memory by default */ | ||
1227 | *base = kmalloc(size, flags); | ||
1228 | if (*base == NULL) { | ||
1229 | return NULL; | ||
1230 | } | ||
1231 | if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) { | ||
1232 | return *base; | ||
1233 | } | ||
1234 | kfree(*base); | ||
1235 | |||
1236 | /* nope, we'll have to do it ourselves */ | ||
1237 | *base = kmalloc(size + L1_CACHE_BYTES, flags); | ||
1238 | if (*base == NULL) { | ||
1239 | return NULL; | ||
1240 | } | ||
1241 | return (void *) L1_CACHE_ALIGN((u64) *base); | ||
1242 | } | ||
1243 | |||
1244 | |||
1245 | /* | ||
1246 | * Check to see if there is any channel activity to/from the specified | ||
1247 | * partition. | ||
1248 | */ | ||
1249 | static inline void | ||
1250 | xpc_check_for_channel_activity(struct xpc_partition *part) | ||
1251 | { | ||
1252 | u64 IPI_amo; | ||
1253 | unsigned long irq_flags; | ||
1254 | |||
1255 | |||
1256 | IPI_amo = xpc_IPI_receive(part->local_IPI_amo_va); | ||
1257 | if (IPI_amo == 0) { | ||
1258 | return; | ||
1259 | } | ||
1260 | |||
1261 | spin_lock_irqsave(&part->IPI_lock, irq_flags); | ||
1262 | part->local_IPI_amo |= IPI_amo; | ||
1263 | spin_unlock_irqrestore(&part->IPI_lock, irq_flags); | ||
1264 | |||
1265 | dev_dbg(xpc_chan, "received IPI from partid=%d, IPI_amo=0x%lx\n", | ||
1266 | XPC_PARTID(part), IPI_amo); | ||
1267 | |||
1268 | xpc_wakeup_channel_mgr(part); | ||
1269 | } | ||
1270 | |||
1271 | |||
1272 | #endif /* _IA64_SN_KERNEL_XPC_H */ | ||
1273 | |||
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 | ||
1647 | void | 1653 | void |
1648 | xpc_disconnecting_callout(struct xpc_channel *ch) | 1654 | xpc_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; | |||
82 | struct device *xpc_chan = &xpc_chan_dbg_subname; | 82 | struct device *xpc_chan = &xpc_chan_dbg_subname; |
83 | 83 | ||
84 | 84 | ||
85 | static int xpc_kdebug_ignore; | ||
86 | |||
87 | |||
85 | /* systune related variables for /proc/sys directories */ | 88 | /* systune related variables for /proc/sys directories */ |
86 | 89 | ||
87 | static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; | 90 | static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; |
@@ -162,6 +165,8 @@ static ctl_table xpc_sys_dir[] = { | |||
162 | }; | 165 | }; |
163 | static struct ctl_table_header *xpc_sysctl; | 166 | static struct ctl_table_header *xpc_sysctl; |
164 | 167 | ||
168 | /* non-zero if any remote partition disengage request was timed out */ | ||
169 | int xpc_disengage_request_timedout; | ||
165 | 170 | ||
166 | /* #of IRQs received */ | 171 | /* #of IRQs received */ |
167 | static atomic_t xpc_act_IRQ_rcvd; | 172 | static 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 | |||
921 | xpc_do_exit(enum xpc_retval reason) | 926 | xpc_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 | */ | ||
1052 | static int | ||
1053 | xpc_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 | */ |
1025 | static void | 1080 | static void |
1026 | xpc_die_disengage(void) | 1081 | xpc_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 | */ | ||
1082 | static int | ||
1083 | xpc_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 | */ |
1110 | static int | 1161 | static int |
1111 | xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) | 1162 | xpc_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); | |||
1344 | MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait " | 1409 | MODULE_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 | ||
1412 | module_param(xpc_kdebug_ignore, int, 0); | ||
1413 | MODULE_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_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c index d1647b863e61..aa3fa5152a32 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_ate.c | |||
@@ -18,10 +18,10 @@ int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */ | |||
18 | * mark_ate: Mark the ate as either free or inuse. | 18 | * mark_ate: Mark the ate as either free or inuse. |
19 | */ | 19 | */ |
20 | static void mark_ate(struct ate_resource *ate_resource, int start, int number, | 20 | static void mark_ate(struct ate_resource *ate_resource, int start, int number, |
21 | uint64_t value) | 21 | u64 value) |
22 | { | 22 | { |
23 | 23 | ||
24 | uint64_t *ate = ate_resource->ate; | 24 | u64 *ate = ate_resource->ate; |
25 | int index; | 25 | int index; |
26 | int length = 0; | 26 | int length = 0; |
27 | 27 | ||
@@ -38,7 +38,7 @@ static int find_free_ate(struct ate_resource *ate_resource, int start, | |||
38 | int count) | 38 | int count) |
39 | { | 39 | { |
40 | 40 | ||
41 | uint64_t *ate = ate_resource->ate; | 41 | u64 *ate = ate_resource->ate; |
42 | int index; | 42 | int index; |
43 | int start_free; | 43 | int start_free; |
44 | 44 | ||
@@ -119,7 +119,7 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource, | |||
119 | int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) | 119 | int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) |
120 | { | 120 | { |
121 | int status = 0; | 121 | int status = 0; |
122 | uint64_t flag; | 122 | u64 flag; |
123 | 123 | ||
124 | flag = pcibr_lock(pcibus_info); | 124 | flag = pcibr_lock(pcibus_info); |
125 | status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count); | 125 | status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count); |
@@ -139,7 +139,7 @@ int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) | |||
139 | * Setup an Address Translation Entry as specified. Use either the Bridge | 139 | * Setup an Address Translation Entry as specified. Use either the Bridge |
140 | * internal maps or the external map RAM, as appropriate. | 140 | * internal maps or the external map RAM, as appropriate. |
141 | */ | 141 | */ |
142 | static inline uint64_t *pcibr_ate_addr(struct pcibus_info *pcibus_info, | 142 | static inline u64 *pcibr_ate_addr(struct pcibus_info *pcibus_info, |
143 | int ate_index) | 143 | int ate_index) |
144 | { | 144 | { |
145 | if (ate_index < pcibus_info->pbi_int_ate_size) { | 145 | if (ate_index < pcibus_info->pbi_int_ate_size) { |
@@ -153,7 +153,7 @@ static inline uint64_t *pcibr_ate_addr(struct pcibus_info *pcibus_info, | |||
153 | */ | 153 | */ |
154 | void inline | 154 | void inline |
155 | ate_write(struct pcibus_info *pcibus_info, int ate_index, int count, | 155 | ate_write(struct pcibus_info *pcibus_info, int ate_index, int count, |
156 | volatile uint64_t ate) | 156 | volatile u64 ate) |
157 | { | 157 | { |
158 | while (count-- > 0) { | 158 | while (count-- > 0) { |
159 | if (ate_index < pcibus_info->pbi_int_ate_size) { | 159 | if (ate_index < pcibus_info->pbi_int_ate_size) { |
@@ -171,9 +171,9 @@ ate_write(struct pcibus_info *pcibus_info, int ate_index, int count, | |||
171 | void pcibr_ate_free(struct pcibus_info *pcibus_info, int index) | 171 | void pcibr_ate_free(struct pcibus_info *pcibus_info, int index) |
172 | { | 172 | { |
173 | 173 | ||
174 | volatile uint64_t ate; | 174 | volatile u64 ate; |
175 | int count; | 175 | int count; |
176 | uint64_t flags; | 176 | u64 flags; |
177 | 177 | ||
178 | if (pcibr_invalidate_ate) { | 178 | if (pcibr_invalidate_ate) { |
179 | /* For debugging purposes, clear the valid bit in the ATE */ | 179 | /* For debugging purposes, clear the valid bit in the ATE */ |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c index 34093476e965..54ce5b7ceed2 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c | |||
@@ -41,21 +41,21 @@ extern int sn_ioif_inited; | |||
41 | 41 | ||
42 | static dma_addr_t | 42 | static dma_addr_t |
43 | pcibr_dmamap_ate32(struct pcidev_info *info, | 43 | pcibr_dmamap_ate32(struct pcidev_info *info, |
44 | uint64_t paddr, size_t req_size, uint64_t flags) | 44 | u64 paddr, size_t req_size, u64 flags) |
45 | { | 45 | { |
46 | 46 | ||
47 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; | 47 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; |
48 | struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> | 48 | struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> |
49 | pdi_pcibus_info; | 49 | pdi_pcibus_info; |
50 | uint8_t internal_device = (PCI_SLOT(pcidev_info->pdi_host_pcidev_info-> | 50 | u8 internal_device = (PCI_SLOT(pcidev_info->pdi_host_pcidev_info-> |
51 | pdi_linux_pcidev->devfn)) - 1; | 51 | pdi_linux_pcidev->devfn)) - 1; |
52 | int ate_count; | 52 | int ate_count; |
53 | int ate_index; | 53 | int ate_index; |
54 | uint64_t ate_flags = flags | PCI32_ATE_V; | 54 | u64 ate_flags = flags | PCI32_ATE_V; |
55 | uint64_t ate; | 55 | u64 ate; |
56 | uint64_t pci_addr; | 56 | u64 pci_addr; |
57 | uint64_t xio_addr; | 57 | u64 xio_addr; |
58 | uint64_t offset; | 58 | u64 offset; |
59 | 59 | ||
60 | /* PIC in PCI-X mode does not supports 32bit PageMap mode */ | 60 | /* PIC in PCI-X mode does not supports 32bit PageMap mode */ |
61 | if (IS_PIC_SOFT(pcibus_info) && IS_PCIX(pcibus_info)) { | 61 | if (IS_PIC_SOFT(pcibus_info) && IS_PCIX(pcibus_info)) { |
@@ -109,12 +109,12 @@ pcibr_dmamap_ate32(struct pcidev_info *info, | |||
109 | } | 109 | } |
110 | 110 | ||
111 | static dma_addr_t | 111 | static dma_addr_t |
112 | pcibr_dmatrans_direct64(struct pcidev_info * info, uint64_t paddr, | 112 | pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, |
113 | uint64_t dma_attributes) | 113 | u64 dma_attributes) |
114 | { | 114 | { |
115 | struct pcibus_info *pcibus_info = (struct pcibus_info *) | 115 | struct pcibus_info *pcibus_info = (struct pcibus_info *) |
116 | ((info->pdi_host_pcidev_info)->pdi_pcibus_info); | 116 | ((info->pdi_host_pcidev_info)->pdi_pcibus_info); |
117 | uint64_t pci_addr; | 117 | u64 pci_addr; |
118 | 118 | ||
119 | /* Translate to Crosstalk View of Physical Address */ | 119 | /* Translate to Crosstalk View of Physical Address */ |
120 | pci_addr = (IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : | 120 | pci_addr = (IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : |
@@ -127,7 +127,7 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, uint64_t paddr, | |||
127 | /* Handle Bridge Chipset differences */ | 127 | /* Handle Bridge Chipset differences */ |
128 | if (IS_PIC_SOFT(pcibus_info)) { | 128 | if (IS_PIC_SOFT(pcibus_info)) { |
129 | pci_addr |= | 129 | pci_addr |= |
130 | ((uint64_t) pcibus_info-> | 130 | ((u64) pcibus_info-> |
131 | pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT); | 131 | pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT); |
132 | } else | 132 | } else |
133 | pci_addr |= TIOCP_PCI64_CMDTYPE_MEM; | 133 | pci_addr |= TIOCP_PCI64_CMDTYPE_MEM; |
@@ -142,17 +142,17 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, uint64_t paddr, | |||
142 | 142 | ||
143 | static dma_addr_t | 143 | static dma_addr_t |
144 | pcibr_dmatrans_direct32(struct pcidev_info * info, | 144 | pcibr_dmatrans_direct32(struct pcidev_info * info, |
145 | uint64_t paddr, size_t req_size, uint64_t flags) | 145 | u64 paddr, size_t req_size, u64 flags) |
146 | { | 146 | { |
147 | 147 | ||
148 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; | 148 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; |
149 | struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> | 149 | struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> |
150 | pdi_pcibus_info; | 150 | pdi_pcibus_info; |
151 | uint64_t xio_addr; | 151 | u64 xio_addr; |
152 | 152 | ||
153 | uint64_t xio_base; | 153 | u64 xio_base; |
154 | uint64_t offset; | 154 | u64 offset; |
155 | uint64_t endoff; | 155 | u64 endoff; |
156 | 156 | ||
157 | if (IS_PCIX(pcibus_info)) { | 157 | if (IS_PCIX(pcibus_info)) { |
158 | return 0; | 158 | return 0; |
@@ -209,16 +209,18 @@ pcibr_dma_unmap(struct pci_dev *hwdev, dma_addr_t dma_handle, int direction) | |||
209 | * unlike the PIC Device(x) Write Request Buffer Flush register. | 209 | * unlike the PIC Device(x) Write Request Buffer Flush register. |
210 | */ | 210 | */ |
211 | 211 | ||
212 | void sn_dma_flush(uint64_t addr) | 212 | void sn_dma_flush(u64 addr) |
213 | { | 213 | { |
214 | nasid_t nasid; | 214 | nasid_t nasid; |
215 | int is_tio; | 215 | int is_tio; |
216 | int wid_num; | 216 | int wid_num; |
217 | int i, j; | 217 | int i, j; |
218 | uint64_t flags; | 218 | u64 flags; |
219 | uint64_t itte; | 219 | u64 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. */ |
@@ -297,31 +299,31 @@ void sn_dma_flush(uint64_t addr) | |||
297 | * If CE ever needs the sn_dma_flush mechanism, we will have | 299 | * If CE ever needs the sn_dma_flush mechanism, we will have |
298 | * to account for that here and in tioce_bus_fixup(). | 300 | * to account for that here and in tioce_bus_fixup(). |
299 | */ | 301 | */ |
300 | uint32_t tio_id = HUB_L(TIO_IOSPACE_ADDR(nasid, TIO_NODE_ID)); | 302 | u32 tio_id = HUB_L(TIO_IOSPACE_ADDR(nasid, TIO_NODE_ID)); |
301 | uint32_t revnum = XWIDGET_PART_REV_NUM(tio_id); | 303 | u32 revnum = XWIDGET_PART_REV_NUM(tio_id); |
302 | 304 | ||
303 | /* TIOCP BRINGUP WAR (PV907516): Don't write buffer flush reg */ | 305 | /* TIOCP BRINGUP WAR (PV907516): Don't write buffer flush reg */ |
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 u32 *)(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..77a1262751d3 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c | |||
@@ -23,7 +23,7 @@ int | |||
23 | sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) | 23 | sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) |
24 | { | 24 | { |
25 | struct ia64_sal_retval ret_stuff; | 25 | struct ia64_sal_retval ret_stuff; |
26 | uint64_t busnum; | 26 | u64 busnum; |
27 | 27 | ||
28 | ret_stuff.status = 0; | 28 | ret_stuff.status = 0; |
29 | ret_stuff.v0 = 0; | 29 | ret_stuff.v0 = 0; |
@@ -40,7 +40,7 @@ sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action, | |||
40 | void *resp) | 40 | void *resp) |
41 | { | 41 | { |
42 | struct ia64_sal_retval ret_stuff; | 42 | struct ia64_sal_retval ret_stuff; |
43 | uint64_t busnum; | 43 | u64 busnum; |
44 | 44 | ||
45 | ret_stuff.status = 0; | 45 | ret_stuff.status = 0; |
46 | ret_stuff.v0 = 0; | 46 | ret_stuff.v0 = 0; |
@@ -56,7 +56,7 @@ sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action, | |||
56 | static int sal_pcibr_error_interrupt(struct pcibus_info *soft) | 56 | static int sal_pcibr_error_interrupt(struct pcibus_info *soft) |
57 | { | 57 | { |
58 | struct ia64_sal_retval ret_stuff; | 58 | struct ia64_sal_retval ret_stuff; |
59 | uint64_t busnum; | 59 | u64 busnum; |
60 | int segment; | 60 | int segment; |
61 | ret_stuff.status = 0; | 61 | ret_stuff.status = 0; |
62 | ret_stuff.v0 = 0; | 62 | ret_stuff.v0 = 0; |
@@ -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 | } |
@@ -159,9 +159,9 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
159 | /* Setup the PMU ATE map */ | 159 | /* Setup the PMU ATE map */ |
160 | soft->pbi_int_ate_resource.lowest_free_index = 0; | 160 | soft->pbi_int_ate_resource.lowest_free_index = 0; |
161 | soft->pbi_int_ate_resource.ate = | 161 | soft->pbi_int_ate_resource.ate = |
162 | kmalloc(soft->pbi_int_ate_size * sizeof(uint64_t), GFP_KERNEL); | 162 | kmalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL); |
163 | memset(soft->pbi_int_ate_resource.ate, 0, | 163 | memset(soft->pbi_int_ate_resource.ate, 0, |
164 | (soft->pbi_int_ate_size * sizeof(uint64_t))); | 164 | (soft->pbi_int_ate_size * sizeof(u64))); |
165 | 165 | ||
166 | if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) { | 166 | if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) { |
167 | /* TIO PCI Bridge: find nearest node with CPUs */ | 167 | /* TIO PCI Bridge: find nearest node with CPUs */ |
@@ -203,7 +203,7 @@ void pcibr_target_interrupt(struct sn_irq_info *sn_irq_info) | |||
203 | struct pcidev_info *pcidev_info; | 203 | struct pcidev_info *pcidev_info; |
204 | struct pcibus_info *pcibus_info; | 204 | struct pcibus_info *pcibus_info; |
205 | int bit = sn_irq_info->irq_int_bit; | 205 | int bit = sn_irq_info->irq_int_bit; |
206 | uint64_t xtalk_addr = sn_irq_info->irq_xtalkaddr; | 206 | u64 xtalk_addr = sn_irq_info->irq_xtalkaddr; |
207 | 207 | ||
208 | pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; | 208 | pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; |
209 | if (pcidev_info) { | 209 | if (pcidev_info) { |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c index 79fdb91d7259..8b8bbd51d433 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c | |||
@@ -23,7 +23,7 @@ union br_ptr { | |||
23 | /* | 23 | /* |
24 | * Control Register Access -- Read/Write 0000_0020 | 24 | * Control Register Access -- Read/Write 0000_0020 |
25 | */ | 25 | */ |
26 | void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) | 26 | void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, u64 bits) |
27 | { | 27 | { |
28 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 28 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
29 | 29 | ||
@@ -43,7 +43,7 @@ void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) | |||
43 | } | 43 | } |
44 | } | 44 | } |
45 | 45 | ||
46 | void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) | 46 | void pcireg_control_bit_set(struct pcibus_info *pcibus_info, u64 bits) |
47 | { | 47 | { |
48 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 48 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
49 | 49 | ||
@@ -66,10 +66,10 @@ void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) | |||
66 | /* | 66 | /* |
67 | * PCI/PCIX Target Flush Register Access -- Read Only 0000_0050 | 67 | * PCI/PCIX Target Flush Register Access -- Read Only 0000_0050 |
68 | */ | 68 | */ |
69 | uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info) | 69 | u64 pcireg_tflush_get(struct pcibus_info *pcibus_info) |
70 | { | 70 | { |
71 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 71 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
72 | uint64_t ret = 0; | 72 | u64 ret = 0; |
73 | 73 | ||
74 | if (pcibus_info) { | 74 | if (pcibus_info) { |
75 | switch (pcibus_info->pbi_bridge_type) { | 75 | switch (pcibus_info->pbi_bridge_type) { |
@@ -96,10 +96,10 @@ uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info) | |||
96 | /* | 96 | /* |
97 | * Interrupt Status Register Access -- Read Only 0000_0100 | 97 | * Interrupt Status Register Access -- Read Only 0000_0100 |
98 | */ | 98 | */ |
99 | uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info) | 99 | u64 pcireg_intr_status_get(struct pcibus_info * pcibus_info) |
100 | { | 100 | { |
101 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 101 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
102 | uint64_t ret = 0; | 102 | u64 ret = 0; |
103 | 103 | ||
104 | if (pcibus_info) { | 104 | if (pcibus_info) { |
105 | switch (pcibus_info->pbi_bridge_type) { | 105 | switch (pcibus_info->pbi_bridge_type) { |
@@ -121,7 +121,7 @@ uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info) | |||
121 | /* | 121 | /* |
122 | * Interrupt Enable Register Access -- Read/Write 0000_0108 | 122 | * Interrupt Enable Register Access -- Read/Write 0000_0108 |
123 | */ | 123 | */ |
124 | void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) | 124 | void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, u64 bits) |
125 | { | 125 | { |
126 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 126 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
127 | 127 | ||
@@ -141,7 +141,7 @@ void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) | |||
141 | } | 141 | } |
142 | } | 142 | } |
143 | 143 | ||
144 | void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) | 144 | void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, u64 bits) |
145 | { | 145 | { |
146 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 146 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
147 | 147 | ||
@@ -165,7 +165,7 @@ void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) | |||
165 | * Intr Host Address Register (int_addr) -- Read/Write 0000_0130 - 0000_0168 | 165 | * Intr Host Address Register (int_addr) -- Read/Write 0000_0130 - 0000_0168 |
166 | */ | 166 | */ |
167 | void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n, | 167 | void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n, |
168 | uint64_t addr) | 168 | u64 addr) |
169 | { | 169 | { |
170 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 170 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
171 | 171 | ||
@@ -217,10 +217,10 @@ void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n) | |||
217 | /* | 217 | /* |
218 | * Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258 | 218 | * Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258 |
219 | */ | 219 | */ |
220 | uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) | 220 | u64 pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) |
221 | { | 221 | { |
222 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 222 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
223 | uint64_t ret = 0; | 223 | u64 ret = 0; |
224 | 224 | ||
225 | if (pcibus_info) { | 225 | if (pcibus_info) { |
226 | switch (pcibus_info->pbi_bridge_type) { | 226 | switch (pcibus_info->pbi_bridge_type) { |
@@ -242,7 +242,7 @@ uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) | |||
242 | } | 242 | } |
243 | 243 | ||
244 | void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index, | 244 | void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index, |
245 | uint64_t val) | 245 | u64 val) |
246 | { | 246 | { |
247 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 247 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
248 | 248 | ||
@@ -262,10 +262,10 @@ void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index, | |||
262 | } | 262 | } |
263 | } | 263 | } |
264 | 264 | ||
265 | uint64_t __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index) | 265 | u64 __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index) |
266 | { | 266 | { |
267 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 267 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
268 | uint64_t __iomem *ret = NULL; | 268 | u64 __iomem *ret = NULL; |
269 | 269 | ||
270 | if (pcibus_info) { | 270 | if (pcibus_info) { |
271 | switch (pcibus_info->pbi_bridge_type) { | 271 | switch (pcibus_info->pbi_bridge_type) { |
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index 27aa1842dacc..7571a4025529 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <asm/sn/pcibus_provider_defs.h> | 16 | #include <asm/sn/pcibus_provider_defs.h> |
17 | #include <asm/sn/tioca_provider.h> | 17 | #include <asm/sn/tioca_provider.h> |
18 | 18 | ||
19 | uint32_t tioca_gart_found; | 19 | u32 tioca_gart_found; |
20 | EXPORT_SYMBOL(tioca_gart_found); /* used by agp-sgi */ | 20 | EXPORT_SYMBOL(tioca_gart_found); /* used by agp-sgi */ |
21 | 21 | ||
22 | LIST_HEAD(tioca_list); | 22 | LIST_HEAD(tioca_list); |
@@ -34,8 +34,8 @@ static int tioca_gart_init(struct tioca_kernel *); | |||
34 | static int | 34 | static int |
35 | tioca_gart_init(struct tioca_kernel *tioca_kern) | 35 | tioca_gart_init(struct tioca_kernel *tioca_kern) |
36 | { | 36 | { |
37 | uint64_t ap_reg; | 37 | u64 ap_reg; |
38 | uint64_t offset; | 38 | u64 offset; |
39 | struct page *tmp; | 39 | struct page *tmp; |
40 | struct tioca_common *tioca_common; | 40 | struct tioca_common *tioca_common; |
41 | struct tioca __iomem *ca_base; | 41 | struct tioca __iomem *ca_base; |
@@ -214,7 +214,7 @@ void | |||
214 | tioca_fastwrite_enable(struct tioca_kernel *tioca_kern) | 214 | tioca_fastwrite_enable(struct tioca_kernel *tioca_kern) |
215 | { | 215 | { |
216 | int cap_ptr; | 216 | int cap_ptr; |
217 | uint32_t reg; | 217 | u32 reg; |
218 | struct tioca __iomem *tioca_base; | 218 | struct tioca __iomem *tioca_base; |
219 | struct pci_dev *pdev; | 219 | struct pci_dev *pdev; |
220 | struct tioca_common *common; | 220 | struct tioca_common *common; |
@@ -276,7 +276,7 @@ EXPORT_SYMBOL(tioca_fastwrite_enable); /* used by agp-sgi */ | |||
276 | * We will always use 0x1 | 276 | * We will always use 0x1 |
277 | * 55:55 - Swap bytes Currently unused | 277 | * 55:55 - Swap bytes Currently unused |
278 | */ | 278 | */ |
279 | static uint64_t | 279 | static u64 |
280 | tioca_dma_d64(unsigned long paddr) | 280 | tioca_dma_d64(unsigned long paddr) |
281 | { | 281 | { |
282 | dma_addr_t bus_addr; | 282 | dma_addr_t bus_addr; |
@@ -318,15 +318,15 @@ tioca_dma_d64(unsigned long paddr) | |||
318 | * and so a given CA can only directly target nodes in the range | 318 | * and so a given CA can only directly target nodes in the range |
319 | * xxx - xxx+255. | 319 | * xxx - xxx+255. |
320 | */ | 320 | */ |
321 | static uint64_t | 321 | static u64 |
322 | tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) | 322 | tioca_dma_d48(struct pci_dev *pdev, u64 paddr) |
323 | { | 323 | { |
324 | struct tioca_common *tioca_common; | 324 | struct tioca_common *tioca_common; |
325 | struct tioca __iomem *ca_base; | 325 | struct tioca __iomem *ca_base; |
326 | uint64_t ct_addr; | 326 | u64 ct_addr; |
327 | dma_addr_t bus_addr; | 327 | dma_addr_t bus_addr; |
328 | uint32_t node_upper; | 328 | u32 node_upper; |
329 | uint64_t agp_dma_extn; | 329 | u64 agp_dma_extn; |
330 | struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev); | 330 | struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev); |
331 | 331 | ||
332 | tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info; | 332 | tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info; |
@@ -367,10 +367,10 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) | |||
367 | * dma_addr_t is guarenteed to be contiguous in CA bus space. | 367 | * dma_addr_t is guarenteed to be contiguous in CA bus space. |
368 | */ | 368 | */ |
369 | static dma_addr_t | 369 | static dma_addr_t |
370 | tioca_dma_mapped(struct pci_dev *pdev, uint64_t paddr, size_t req_size) | 370 | tioca_dma_mapped(struct pci_dev *pdev, u64 paddr, size_t req_size) |
371 | { | 371 | { |
372 | int i, ps, ps_shift, entry, entries, mapsize, last_entry; | 372 | int i, ps, ps_shift, entry, entries, mapsize, last_entry; |
373 | uint64_t xio_addr, end_xio_addr; | 373 | u64 xio_addr, end_xio_addr; |
374 | struct tioca_common *tioca_common; | 374 | struct tioca_common *tioca_common; |
375 | struct tioca_kernel *tioca_kern; | 375 | struct tioca_kernel *tioca_kern; |
376 | dma_addr_t bus_addr = 0; | 376 | dma_addr_t bus_addr = 0; |
@@ -514,10 +514,10 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) | |||
514 | * The mapping mode used is based on the devices dma_mask. As a last resort | 514 | * The mapping mode used is based on the devices dma_mask. As a last resort |
515 | * use the GART mapped mode. | 515 | * use the GART mapped mode. |
516 | */ | 516 | */ |
517 | static uint64_t | 517 | static u64 |
518 | tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) | 518 | tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count) |
519 | { | 519 | { |
520 | uint64_t mapaddr; | 520 | u64 mapaddr; |
521 | 521 | ||
522 | /* | 522 | /* |
523 | * If card is 64 or 48 bit addresable, use a direct mapping. 32 | 523 | * If card is 64 or 48 bit addresable, use a direct mapping. 32 |
@@ -554,8 +554,8 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt) | |||
554 | { | 554 | { |
555 | struct tioca_common *soft = arg; | 555 | struct tioca_common *soft = arg; |
556 | struct ia64_sal_retval ret_stuff; | 556 | struct ia64_sal_retval ret_stuff; |
557 | uint64_t segment; | 557 | u64 segment; |
558 | uint64_t busnum; | 558 | u64 busnum; |
559 | ret_stuff.status = 0; | 559 | ret_stuff.status = 0; |
560 | ret_stuff.v0 = 0; | 560 | ret_stuff.v0 = 0; |
561 | 561 | ||
@@ -620,7 +620,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
620 | INIT_LIST_HEAD(&tioca_kern->ca_dmamaps); | 620 | INIT_LIST_HEAD(&tioca_kern->ca_dmamaps); |
621 | tioca_kern->ca_closest_node = | 621 | tioca_kern->ca_closest_node = |
622 | nasid_to_cnodeid(tioca_common->ca_closest_nasid); | 622 | nasid_to_cnodeid(tioca_common->ca_closest_nasid); |
623 | tioca_common->ca_kernel_private = (uint64_t) tioca_kern; | 623 | tioca_common->ca_kernel_private = (u64) tioca_kern; |
624 | 624 | ||
625 | bus = pci_find_bus(tioca_common->ca_common.bs_persist_segment, | 625 | bus = pci_find_bus(tioca_common->ca_common.bs_persist_segment, |
626 | tioca_common->ca_common.bs_persist_busnum); | 626 | tioca_common->ca_common.bs_persist_busnum); |
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index dda196c9e324..e52831ed93eb 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c | |||
@@ -81,10 +81,10 @@ | |||
81 | * 61 - 0 since this is not an MSI transaction | 81 | * 61 - 0 since this is not an MSI transaction |
82 | * 60:54 - reserved, MBZ | 82 | * 60:54 - reserved, MBZ |
83 | */ | 83 | */ |
84 | static uint64_t | 84 | static u64 |
85 | tioce_dma_d64(unsigned long ct_addr) | 85 | tioce_dma_d64(unsigned long ct_addr) |
86 | { | 86 | { |
87 | uint64_t bus_addr; | 87 | u64 bus_addr; |
88 | 88 | ||
89 | bus_addr = ct_addr | (1UL << 63); | 89 | bus_addr = ct_addr | (1UL << 63); |
90 | 90 | ||
@@ -141,9 +141,9 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base, | |||
141 | * length, and if enough resources exist, fill in the ATE's and construct a | 141 | * length, and if enough resources exist, fill in the ATE's and construct a |
142 | * tioce_dmamap struct to track the mapping. | 142 | * tioce_dmamap struct to track the mapping. |
143 | */ | 143 | */ |
144 | static uint64_t | 144 | static u64 |
145 | tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | 145 | tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, |
146 | uint64_t ct_addr, int len) | 146 | u64 ct_addr, int len) |
147 | { | 147 | { |
148 | int i; | 148 | int i; |
149 | int j; | 149 | int j; |
@@ -152,11 +152,11 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
152 | int entries; | 152 | int entries; |
153 | int nates; | 153 | int nates; |
154 | int pagesize; | 154 | int pagesize; |
155 | uint64_t *ate_shadow; | 155 | u64 *ate_shadow; |
156 | uint64_t *ate_reg; | 156 | u64 *ate_reg; |
157 | uint64_t addr; | 157 | u64 addr; |
158 | struct tioce *ce_mmr; | 158 | struct tioce *ce_mmr; |
159 | uint64_t bus_base; | 159 | u64 bus_base; |
160 | struct tioce_dmamap *map; | 160 | struct tioce_dmamap *map; |
161 | 161 | ||
162 | ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base; | 162 | ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base; |
@@ -224,7 +224,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
224 | 224 | ||
225 | addr = ct_addr; | 225 | addr = ct_addr; |
226 | for (j = 0; j < nates; j++) { | 226 | for (j = 0; j < nates; j++) { |
227 | uint64_t ate; | 227 | u64 ate; |
228 | 228 | ||
229 | ate = ATE_MAKE(addr, pagesize); | 229 | ate = ATE_MAKE(addr, pagesize); |
230 | ate_shadow[i + j] = ate; | 230 | ate_shadow[i + j] = ate; |
@@ -252,15 +252,15 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
252 | * | 252 | * |
253 | * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info. | 253 | * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info. |
254 | */ | 254 | */ |
255 | static uint64_t | 255 | static u64 |
256 | tioce_dma_d32(struct pci_dev *pdev, uint64_t ct_addr) | 256 | tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr) |
257 | { | 257 | { |
258 | int dma_ok; | 258 | int dma_ok; |
259 | int port; | 259 | int port; |
260 | struct tioce *ce_mmr; | 260 | struct tioce *ce_mmr; |
261 | struct tioce_kernel *ce_kern; | 261 | struct tioce_kernel *ce_kern; |
262 | uint64_t ct_upper; | 262 | u64 ct_upper; |
263 | uint64_t ct_lower; | 263 | u64 ct_lower; |
264 | dma_addr_t bus_addr; | 264 | dma_addr_t bus_addr; |
265 | 265 | ||
266 | ct_upper = ct_addr & ~0x3fffffffUL; | 266 | ct_upper = ct_addr & ~0x3fffffffUL; |
@@ -269,7 +269,7 @@ tioce_dma_d32(struct pci_dev *pdev, uint64_t ct_addr) | |||
269 | pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port); | 269 | pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port); |
270 | 270 | ||
271 | if (ce_kern->ce_port[port].dirmap_refcnt == 0) { | 271 | if (ce_kern->ce_port[port].dirmap_refcnt == 0) { |
272 | uint64_t tmp; | 272 | u64 tmp; |
273 | 273 | ||
274 | ce_kern->ce_port[port].dirmap_shadow = ct_upper; | 274 | ce_kern->ce_port[port].dirmap_shadow = ct_upper; |
275 | writeq(ct_upper, &ce_mmr->ce_ure_dir_map[port]); | 275 | writeq(ct_upper, &ce_mmr->ce_ure_dir_map[port]); |
@@ -295,10 +295,10 @@ tioce_dma_d32(struct pci_dev *pdev, uint64_t ct_addr) | |||
295 | * Given a TIOCE bus address, set the appropriate bit to indicate barrier | 295 | * Given a TIOCE bus address, set the appropriate bit to indicate barrier |
296 | * attributes. | 296 | * attributes. |
297 | */ | 297 | */ |
298 | static uint64_t | 298 | static u64 |
299 | tioce_dma_barrier(uint64_t bus_addr, int on) | 299 | tioce_dma_barrier(u64 bus_addr, int on) |
300 | { | 300 | { |
301 | uint64_t barrier_bit; | 301 | u64 barrier_bit; |
302 | 302 | ||
303 | /* barrier not supported in M40/M40S mode */ | 303 | /* barrier not supported in M40/M40S mode */ |
304 | if (TIOCE_M40_ADDR(bus_addr) || TIOCE_M40S_ADDR(bus_addr)) | 304 | if (TIOCE_M40_ADDR(bus_addr) || TIOCE_M40S_ADDR(bus_addr)) |
@@ -351,7 +351,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) | |||
351 | 351 | ||
352 | list_for_each_entry(map, &ce_kern->ce_dmamap_list, | 352 | list_for_each_entry(map, &ce_kern->ce_dmamap_list, |
353 | ce_dmamap_list) { | 353 | ce_dmamap_list) { |
354 | uint64_t last; | 354 | u64 last; |
355 | 355 | ||
356 | last = map->pci_start + map->nbytes - 1; | 356 | last = map->pci_start + map->nbytes - 1; |
357 | if (bus_addr >= map->pci_start && bus_addr <= last) | 357 | if (bus_addr >= map->pci_start && bus_addr <= last) |
@@ -385,17 +385,17 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) | |||
385 | * This is the main wrapper for mapping host physical pages to CE PCI space. | 385 | * This is the main wrapper for mapping host physical pages to CE PCI space. |
386 | * The mapping mode used is based on the device's dma_mask. | 386 | * The mapping mode used is based on the device's dma_mask. |
387 | */ | 387 | */ |
388 | static uint64_t | 388 | static u64 |
389 | tioce_do_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count, | 389 | tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, |
390 | int barrier) | 390 | int barrier) |
391 | { | 391 | { |
392 | unsigned long flags; | 392 | unsigned long flags; |
393 | uint64_t ct_addr; | 393 | u64 ct_addr; |
394 | uint64_t mapaddr = 0; | 394 | u64 mapaddr = 0; |
395 | struct tioce_kernel *ce_kern; | 395 | struct tioce_kernel *ce_kern; |
396 | struct tioce_dmamap *map; | 396 | struct tioce_dmamap *map; |
397 | int port; | 397 | int port; |
398 | uint64_t dma_mask; | 398 | u64 dma_mask; |
399 | 399 | ||
400 | dma_mask = (barrier) ? pdev->dev.coherent_dma_mask : pdev->dma_mask; | 400 | dma_mask = (barrier) ? pdev->dev.coherent_dma_mask : pdev->dma_mask; |
401 | 401 | ||
@@ -425,7 +425,7 @@ tioce_do_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count, | |||
425 | * address bits than this device can support. | 425 | * address bits than this device can support. |
426 | */ | 426 | */ |
427 | list_for_each_entry(map, &ce_kern->ce_dmamap_list, ce_dmamap_list) { | 427 | list_for_each_entry(map, &ce_kern->ce_dmamap_list, ce_dmamap_list) { |
428 | uint64_t last; | 428 | u64 last; |
429 | 429 | ||
430 | last = map->ct_start + map->nbytes - 1; | 430 | last = map->ct_start + map->nbytes - 1; |
431 | if (ct_addr >= map->ct_start && | 431 | if (ct_addr >= map->ct_start && |
@@ -501,8 +501,8 @@ dma_map_done: | |||
501 | * Simply call tioce_do_dma_map() to create a map with the barrier bit clear | 501 | * Simply call tioce_do_dma_map() to create a map with the barrier bit clear |
502 | * in the address. | 502 | * in the address. |
503 | */ | 503 | */ |
504 | static uint64_t | 504 | static u64 |
505 | tioce_dma(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) | 505 | tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count) |
506 | { | 506 | { |
507 | return tioce_do_dma_map(pdev, paddr, byte_count, 0); | 507 | return tioce_do_dma_map(pdev, paddr, byte_count, 0); |
508 | } | 508 | } |
@@ -515,8 +515,8 @@ tioce_dma(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) | |||
515 | * | 515 | * |
516 | * Simply call tioce_do_dma_map() to create a map with the barrier bit set | 516 | * Simply call tioce_do_dma_map() to create a map with the barrier bit set |
517 | * in the address. | 517 | * in the address. |
518 | */ static uint64_t | 518 | */ static u64 |
519 | tioce_dma_consistent(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) | 519 | tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count) |
520 | { | 520 | { |
521 | return tioce_do_dma_map(pdev, paddr, byte_count, 1); | 521 | return tioce_do_dma_map(pdev, paddr, byte_count, 1); |
522 | } | 522 | } |
@@ -551,7 +551,7 @@ tioce_error_intr_handler(int irq, void *arg, struct pt_regs *pt) | |||
551 | tioce_kern_init(struct tioce_common *tioce_common) | 551 | tioce_kern_init(struct tioce_common *tioce_common) |
552 | { | 552 | { |
553 | int i; | 553 | int i; |
554 | uint32_t tmp; | 554 | u32 tmp; |
555 | struct tioce *tioce_mmr; | 555 | struct tioce *tioce_mmr; |
556 | struct tioce_kernel *tioce_kern; | 556 | struct tioce_kernel *tioce_kern; |
557 | 557 | ||
@@ -563,7 +563,7 @@ tioce_kern_init(struct tioce_common *tioce_common) | |||
563 | tioce_kern->ce_common = tioce_common; | 563 | tioce_kern->ce_common = tioce_common; |
564 | spin_lock_init(&tioce_kern->ce_lock); | 564 | spin_lock_init(&tioce_kern->ce_lock); |
565 | INIT_LIST_HEAD(&tioce_kern->ce_dmamap_list); | 565 | INIT_LIST_HEAD(&tioce_kern->ce_dmamap_list); |
566 | tioce_common->ce_kernel_private = (uint64_t) tioce_kern; | 566 | tioce_common->ce_kernel_private = (u64) tioce_kern; |
567 | 567 | ||
568 | /* | 568 | /* |
569 | * Determine the secondary bus number of the port2 logical PPB. | 569 | * Determine the secondary bus number of the port2 logical PPB. |
@@ -575,7 +575,7 @@ tioce_kern_init(struct tioce_common *tioce_common) | |||
575 | raw_pci_ops->read(tioce_common->ce_pcibus.bs_persist_segment, | 575 | raw_pci_ops->read(tioce_common->ce_pcibus.bs_persist_segment, |
576 | tioce_common->ce_pcibus.bs_persist_busnum, | 576 | tioce_common->ce_pcibus.bs_persist_busnum, |
577 | PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1, &tmp); | 577 | PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1, &tmp); |
578 | tioce_kern->ce_port1_secondary = (uint8_t) tmp; | 578 | tioce_kern->ce_port1_secondary = (u8) tmp; |
579 | 579 | ||
580 | /* | 580 | /* |
581 | * Set PMU pagesize to the largest size available, and zero out | 581 | * Set PMU pagesize to the largest size available, and zero out |
@@ -615,7 +615,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info) | |||
615 | struct pcidev_info *pcidev_info; | 615 | struct pcidev_info *pcidev_info; |
616 | struct tioce_common *ce_common; | 616 | struct tioce_common *ce_common; |
617 | struct tioce *ce_mmr; | 617 | struct tioce *ce_mmr; |
618 | uint64_t force_int_val; | 618 | u64 force_int_val; |
619 | 619 | ||
620 | if (!sn_irq_info->irq_bridge) | 620 | if (!sn_irq_info->irq_bridge) |
621 | return; | 621 | return; |
@@ -687,7 +687,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) | |||
687 | struct tioce_common *ce_common; | 687 | struct tioce_common *ce_common; |
688 | struct tioce *ce_mmr; | 688 | struct tioce *ce_mmr; |
689 | int bit; | 689 | int bit; |
690 | uint64_t vector; | 690 | u64 vector; |
691 | 691 | ||
692 | pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; | 692 | pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; |
693 | if (!pcidev_info) | 693 | if (!pcidev_info) |
@@ -699,7 +699,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) | |||
699 | bit = sn_irq_info->irq_int_bit; | 699 | bit = sn_irq_info->irq_int_bit; |
700 | 700 | ||
701 | __sn_setq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); | 701 | __sn_setq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); |
702 | vector = (uint64_t)sn_irq_info->irq_irq << INTR_VECTOR_SHFT; | 702 | vector = (u64)sn_irq_info->irq_irq << INTR_VECTOR_SHFT; |
703 | vector |= sn_irq_info->irq_xtalkaddr; | 703 | vector |= sn_irq_info->irq_xtalkaddr; |
704 | writeq(vector, &ce_mmr->ce_adm_int_dest[bit]); | 704 | writeq(vector, &ce_mmr->ce_adm_int_dest[bit]); |
705 | __sn_clrq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); | 705 | __sn_clrq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); |