aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/sn')
-rw-r--r--arch/ia64/sn/include/xtalk/hubdev.h35
-rw-r--r--arch/ia64/sn/include/xtalk/xbow.h206
-rw-r--r--arch/ia64/sn/include/xtalk/xwidgetdev.h46
-rw-r--r--arch/ia64/sn/kernel/bte.c1
-rw-r--r--arch/ia64/sn/kernel/bte_error.c58
-rw-r--r--arch/ia64/sn/kernel/huberror.c9
-rw-r--r--arch/ia64/sn/kernel/io_init.c299
-rw-r--r--arch/ia64/sn/kernel/irq.c10
-rw-r--r--arch/ia64/sn/kernel/mca.c7
-rw-r--r--arch/ia64/sn/kernel/setup.c157
-rw-r--r--arch/ia64/sn/kernel/sn2/ptc_deadlock.S8
-rw-r--r--arch/ia64/sn/kernel/sn2/sn2_smp.c5
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c3
-rw-r--r--arch/ia64/sn/kernel/tiocx.c37
-rw-r--r--arch/ia64/sn/kernel/xp_main.c17
-rw-r--r--arch/ia64/sn/kernel/xpc.h1273
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c58
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c206
-rw-r--r--arch/ia64/sn/kernel/xpc_partition.c10
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_ate.c16
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_dma.c76
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c44
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_reg.c72
-rw-r--r--arch/ia64/sn/pci/tioca_provider.c48
-rw-r--r--arch/ia64/sn/pci/tioce_provider.c68
25 files changed, 985 insertions, 1784 deletions
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h
index 71c2b271b4..8182583c76 100644
--- a/arch/ia64/sn/include/xtalk/hubdev.h
+++ b/arch/ia64/sn/include/xtalk/hubdev.h
@@ -26,29 +26,46 @@
26#define IIO_NUM_ITTES 7 26#define IIO_NUM_ITTES 7
27#define HUB_NUM_BIG_WINDOW (IIO_NUM_ITTES - 1) 27#define HUB_NUM_BIG_WINDOW (IIO_NUM_ITTES - 1)
28 28
29struct sn_flush_device_list { 29/* This struct is shared between the PROM and the kernel.
30 * Changes to this struct will require corresponding changes to the kernel.
31 */
32struct sn_flush_device_common {
30 int sfdl_bus; 33 int sfdl_bus;
31 int sfdl_slot; 34 int sfdl_slot;
32 int sfdl_pin; 35 int sfdl_pin;
33 struct bar_list { 36 struct common_bar_list {
34 unsigned long start; 37 unsigned long start;
35 unsigned long end; 38 unsigned long end;
36 } sfdl_bar_list[6]; 39 } sfdl_bar_list[6];
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 */
49struct sn_flush_device_kernel {
43 spinlock_t sfdl_flush_lock; 50 spinlock_t sfdl_flush_lock;
51 struct sn_flush_device_common *common;
52};
53
54/* 01/16/06 This struct is the old PROM/kernel struct and needs to be included
55 * for older official PROMs to function on the new kernel base. This struct
56 * will be removed when the next official PROM release occurs. */
57
58struct sn_flush_device_war {
59 struct sn_flush_device_common common;
60 u32 filler; /* older PROMs expect the default size of a spinlock_t */
44}; 61};
45 62
46/* 63/*
47 * **widget_p - Used as an array[wid_num][device] of sn_flush_device_list. 64 * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel.
48 */ 65 */
49struct sn_flush_nasid_entry { 66struct sn_flush_nasid_entry {
50 struct sn_flush_device_list **widget_p; /* Used as a array of wid_num */ 67 struct sn_flush_device_kernel **widget_p; // Used as an array of wid_num
51 uint64_t iio_itte[8]; 68 u64 iio_itte[8];
52}; 69};
53 70
54struct hubdev_info { 71struct hubdev_info {
@@ -62,8 +79,8 @@ struct hubdev_info {
62 79
63 void *hdi_nodepda; 80 void *hdi_nodepda;
64 void *hdi_node_vertex; 81 void *hdi_node_vertex;
65 uint32_t max_segment_number; 82 u32 max_segment_number;
66 uint32_t max_pcibus_number; 83 u32 max_pcibus_number;
67}; 84};
68 85
69extern void hubdev_init_node(nodepda_t *, cnodeid_t); 86extern 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 ec56b3432f..90f37a4133 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 */
23typedef volatile struct xb_linkregs_s { 24typedef 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
47typedef volatile struct xbow_s { 48typedef 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 c5f4bc5cc0..2800eda0fd 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 */
27struct widget_cfg{ 27struct 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.c b/arch/ia64/sn/kernel/bte.c
index d71f4de44f..dd73c0cb75 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -137,6 +137,7 @@ retry_bteop:
137 bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index); 137 bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index);
138 138
139 if (bte == NULL) { 139 if (bte == NULL) {
140 nasid_index++;
140 continue; 141 continue;
141 } 142 }
142 143
diff --git a/arch/ia64/sn/kernel/bte_error.c b/arch/ia64/sn/kernel/bte_error.c
index fcbc748ae4..f1ec1370b3 100644
--- a/arch/ia64/sn/kernel/bte_error.c
+++ b/arch/ia64/sn/kernel/bte_error.c
@@ -33,7 +33,7 @@ void bte_error_handler(unsigned long);
33 * Wait until all BTE related CRBs are completed 33 * Wait until all BTE related CRBs are completed
34 * and then reset the interfaces. 34 * and then reset the interfaces.
35 */ 35 */
36void shub1_bte_error_handler(unsigned long _nodepda) 36int shub1_bte_error_handler(unsigned long _nodepda)
37{ 37{
38 struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda; 38 struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda;
39 struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer; 39 struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
@@ -53,7 +53,7 @@ void shub1_bte_error_handler(unsigned long _nodepda)
53 (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) { 53 (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) {
54 BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda, 54 BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda,
55 smp_processor_id())); 55 smp_processor_id()));
56 return; 56 return 1;
57 } 57 }
58 58
59 /* Determine information about our hub */ 59 /* Determine information about our hub */
@@ -81,7 +81,7 @@ void shub1_bte_error_handler(unsigned long _nodepda)
81 mod_timer(recovery_timer, HZ * 5); 81 mod_timer(recovery_timer, HZ * 5);
82 BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda, 82 BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
83 smp_processor_id())); 83 smp_processor_id()));
84 return; 84 return 1;
85 } 85 }
86 if (icmr.ii_icmr_fld_s.i_crb_vld != 0) { 86 if (icmr.ii_icmr_fld_s.i_crb_vld != 0) {
87 87
@@ -99,7 +99,7 @@ void shub1_bte_error_handler(unsigned long _nodepda)
99 BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n", 99 BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n",
100 err_nodepda, smp_processor_id(), 100 err_nodepda, smp_processor_id(),
101 i)); 101 i));
102 return; 102 return 1;
103 } 103 }
104 } 104 }
105 } 105 }
@@ -124,6 +124,42 @@ void shub1_bte_error_handler(unsigned long _nodepda)
124 REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval); 124 REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval);
125 125
126 del_timer(recovery_timer); 126 del_timer(recovery_timer);
127 return 0;
128}
129
130/*
131 * Wait until all BTE related CRBs are completed
132 * and then reset the interfaces.
133 */
134int shub2_bte_error_handler(unsigned long _nodepda)
135{
136 struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda;
137 struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
138 struct bteinfo_s *bte;
139 nasid_t nasid;
140 u64 status;
141 int i;
142
143 nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode);
144
145 /*
146 * Verify that all the BTEs are complete
147 */
148 for (i = 0; i < BTES_PER_NODE; i++) {
149 bte = &err_nodepda->bte_if[i];
150 status = BTE_LNSTAT_LOAD(bte);
151 if ((status & IBLS_ERROR) || !(status & IBLS_BUSY))
152 continue;
153 mod_timer(recovery_timer, HZ * 5);
154 BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
155 smp_processor_id()));
156 return 1;
157 }
158 if (ia64_sn_bte_recovery(nasid))
159 panic("bte_error_handler(): Fatal BTE Error");
160
161 del_timer(recovery_timer);
162 return 0;
127} 163}
128 164
129/* 165/*
@@ -135,7 +171,6 @@ void bte_error_handler(unsigned long _nodepda)
135 struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda; 171 struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda;
136 spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock; 172 spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock;
137 int i; 173 int i;
138 nasid_t nasid;
139 unsigned long irq_flags; 174 unsigned long irq_flags;
140 volatile u64 *notify; 175 volatile u64 *notify;
141 bte_result_t bh_error; 176 bte_result_t bh_error;
@@ -160,12 +195,15 @@ void bte_error_handler(unsigned long _nodepda)
160 } 195 }
161 196
162 if (is_shub1()) { 197 if (is_shub1()) {
163 shub1_bte_error_handler(_nodepda); 198 if (shub1_bte_error_handler(_nodepda)) {
199 spin_unlock_irqrestore(recovery_lock, irq_flags);
200 return;
201 }
164 } else { 202 } else {
165 nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode); 203 if (shub2_bte_error_handler(_nodepda)) {
166 204 spin_unlock_irqrestore(recovery_lock, irq_flags);
167 if (ia64_sn_bte_recovery(nasid)) 205 return;
168 panic("bte_error_handler(): Fatal BTE Error"); 206 }
169 } 207 }
170 208
171 for (i = 0; i < BTES_PER_NODE; i++) { 209 for (i = 0; i < BTES_PER_NODE; i++) {
diff --git a/arch/ia64/sn/kernel/huberror.c b/arch/ia64/sn/kernel/huberror.c
index 5c5eb01c50..56ab6bae00 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 05e4ea8899..00700f7e68 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.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) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved. 6 * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
7 */ 7 */
8 8
9#include <linux/bootmem.h> 9#include <linux/bootmem.h>
@@ -76,11 +76,12 @@ static struct sn_pcibus_provider sn_pci_default_provider = {
76}; 76};
77 77
78/* 78/*
79 * Retrieve the DMA Flush List given nasid. This list is needed 79 * Retrieve the DMA Flush List given nasid, widget, and device.
80 * to implement the WAR - Flush DMA data on PIO Reads. 80 * This list is needed to implement the WAR - Flush DMA data on PIO Reads.
81 */ 81 */
82static inline uint64_t 82static inline u64
83sal_get_widget_dmaflush_list(u64 nasid, u64 widget_num, u64 address) 83sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num,
84 u64 address)
84{ 85{
85 86
86 struct ia64_sal_retval ret_stuff; 87 struct ia64_sal_retval ret_stuff;
@@ -88,17 +89,17 @@ sal_get_widget_dmaflush_list(u64 nasid, u64 widget_num, u64 address)
88 ret_stuff.v0 = 0; 89 ret_stuff.v0 = 0;
89 90
90 SAL_CALL_NOLOCK(ret_stuff, 91 SAL_CALL_NOLOCK(ret_stuff,
91 (u64) SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, 92 (u64) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST,
92 (u64) nasid, (u64) widget_num, (u64) address, 0, 0, 0, 93 (u64) nasid, (u64) widget_num,
93 0); 94 (u64) device_num, (u64) address, 0, 0, 0);
94 return ret_stuff.v0; 95 return ret_stuff.status;
95 96
96} 97}
97 98
98/* 99/*
99 * Retrieve the hub device info structure for the given nasid. 100 * Retrieve the hub device info structure for the given nasid.
100 */ 101 */
101static inline uint64_t sal_get_hubdev_info(u64 handle, u64 address) 102static inline u64 sal_get_hubdev_info(u64 handle, u64 address)
102{ 103{
103 104
104 struct ia64_sal_retval ret_stuff; 105 struct ia64_sal_retval ret_stuff;
@@ -114,7 +115,7 @@ static inline uint64_t sal_get_hubdev_info(u64 handle, u64 address)
114/* 115/*
115 * Retrieve the pci bus information given the bus number. 116 * Retrieve the pci bus information given the bus number.
116 */ 117 */
117static inline uint64_t sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) 118static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address)
118{ 119{
119 120
120 struct ia64_sal_retval ret_stuff; 121 struct ia64_sal_retval ret_stuff;
@@ -130,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 */
133static inline uint64_t 134static inline u64
134sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, 135sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev,
135 u64 sn_irq_info) 136 u64 sn_irq_info)
136{ 137{
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,24 +141,79 @@ 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;
147} 148}
148 149
149/* 150/*
150 * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for 151 * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified
152 * device.
153 */
154inline struct pcidev_info *
155sn_pcidev_info_get(struct pci_dev *dev)
156{
157 struct pcidev_info *pcidev;
158
159 list_for_each_entry(pcidev,
160 &(SN_PCI_CONTROLLER(dev)->pcidev_info), pdi_list) {
161 if (pcidev->pdi_linux_pcidev == dev) {
162 return pcidev;
163 }
164 }
165 return NULL;
166}
167
168/* Older PROM flush WAR
169 *
170 * 01/16/06 -- This war will be in place until a new official PROM is released.
171 * Additionally note that the struct sn_flush_device_war also has to be
172 * removed from arch/ia64/sn/include/xtalk/hubdev.h
173 */
174static u8 war_implemented = 0;
175
176static void sn_device_fixup_war(u64 nasid, u64 widget, int device,
177 struct sn_flush_device_common *common)
178{
179 struct sn_flush_device_war *war_list;
180 struct sn_flush_device_war *dev_entry;
181 struct ia64_sal_retval isrv = {0,0,0,0};
182
183 if (!war_implemented) {
184 printk(KERN_WARNING "PROM version < 4.50 -- implementing old "
185 "PROM flush WAR\n");
186 war_implemented = 1;
187 }
188
189 war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
190 if (!war_list)
191 BUG();
192
193 SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST,
194 nasid, widget, __pa(war_list), 0, 0, 0 ,0);
195 if (isrv.status)
196 panic("sn_device_fixup_war failed: %s\n",
197 ia64_sal_strerror(isrv.status));
198
199 dev_entry = war_list + device;
200 memcpy(common,dev_entry, sizeof(*common));
201
202 kfree(war_list);
203}
204
205/*
206 * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
151 * each node in the system. 207 * each node in the system.
152 */ 208 */
153static void sn_fixup_ionodes(void) 209static void sn_fixup_ionodes(void)
154{ 210{
155 211 struct sn_flush_device_kernel *sn_flush_device_kernel;
156 struct sn_flush_device_list *sn_flush_device_list; 212 struct sn_flush_device_kernel *dev_entry;
157 struct hubdev_info *hubdev; 213 struct hubdev_info *hubdev;
158 uint64_t status; 214 u64 status;
159 uint64_t nasid; 215 u64 nasid;
160 int i, widget; 216 int i, widget, device;
161 217
162 /* 218 /*
163 * Get SGI Specific HUB chipset information. 219 * Get SGI Specific HUB chipset information.
@@ -168,7 +224,7 @@ static void sn_fixup_ionodes(void)
168 nasid = cnodeid_to_nasid(i); 224 nasid = cnodeid_to_nasid(i);
169 hubdev->max_segment_number = 0xffffffff; 225 hubdev->max_segment_number = 0xffffffff;
170 hubdev->max_pcibus_number = 0xff; 226 hubdev->max_pcibus_number = 0xff;
171 status = sal_get_hubdev_info(nasid, (uint64_t) __pa(hubdev)); 227 status = sal_get_hubdev_info(nasid, (u64) __pa(hubdev));
172 if (status) 228 if (status)
173 continue; 229 continue;
174 230
@@ -195,38 +251,104 @@ static void sn_fixup_ionodes(void)
195 251
196 hubdev->hdi_flush_nasid_list.widget_p = 252 hubdev->hdi_flush_nasid_list.widget_p =
197 kmalloc((HUB_WIDGET_ID_MAX + 1) * 253 kmalloc((HUB_WIDGET_ID_MAX + 1) *
198 sizeof(struct sn_flush_device_list *), GFP_KERNEL); 254 sizeof(struct sn_flush_device_kernel *),
199 255 GFP_KERNEL);
200 memset(hubdev->hdi_flush_nasid_list.widget_p, 0x0, 256 memset(hubdev->hdi_flush_nasid_list.widget_p, 0x0,
201 (HUB_WIDGET_ID_MAX + 1) * 257 (HUB_WIDGET_ID_MAX + 1) *
202 sizeof(struct sn_flush_device_list *)); 258 sizeof(struct sn_flush_device_kernel *));
203 259
204 for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { 260 for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) {
205 sn_flush_device_list = kmalloc(DEV_PER_WIDGET * 261 sn_flush_device_kernel = kmalloc(DEV_PER_WIDGET *
206 sizeof(struct 262 sizeof(struct
207 sn_flush_device_list), 263 sn_flush_device_kernel),
208 GFP_KERNEL); 264 GFP_KERNEL);
209 memset(sn_flush_device_list, 0x0, 265 if (!sn_flush_device_kernel)
266 BUG();
267 memset(sn_flush_device_kernel, 0x0,
210 DEV_PER_WIDGET * 268 DEV_PER_WIDGET *
211 sizeof(struct sn_flush_device_list)); 269 sizeof(struct sn_flush_device_kernel));
212 270
213 status = 271 dev_entry = sn_flush_device_kernel;
214 sal_get_widget_dmaflush_list(nasid, widget, 272 for (device = 0; device < DEV_PER_WIDGET;
215 (uint64_t) 273 device++,dev_entry++) {
216 __pa 274 dev_entry->common = kmalloc(sizeof(struct
217 (sn_flush_device_list)); 275 sn_flush_device_common),
218 if (status) { 276 GFP_KERNEL);
219 kfree(sn_flush_device_list); 277 if (!dev_entry->common)
220 continue; 278 BUG();
279 memset(dev_entry->common, 0x0, sizeof(struct
280 sn_flush_device_common));
281
282 status = sal_get_device_dmaflush_list(nasid,
283 widget,
284 device,
285 (u64)(dev_entry->common));
286 if (status) {
287 if (sn_sal_rev() < 0x0450) {
288 /* shortlived WAR for older
289 * PROM images
290 */
291 sn_device_fixup_war(nasid,
292 widget,
293 device,
294 dev_entry->common);
295 }
296 else
297 BUG();
298 }
299
300 spin_lock_init(&dev_entry->sfdl_flush_lock);
221 } 301 }
222 302
223 spin_lock_init(&sn_flush_device_list->sfdl_flush_lock); 303 if (sn_flush_device_kernel)
224 hubdev->hdi_flush_nasid_list.widget_p[widget] = 304 hubdev->hdi_flush_nasid_list.widget_p[widget] =
225 sn_flush_device_list; 305 sn_flush_device_kernel;
226 } 306 }
307 }
308}
309
310/*
311 * sn_pci_window_fixup() - Create a pci_window for each device resource.
312 * Until ACPI support is added, we need this code
313 * to setup pci_windows for use by
314 * pcibios_bus_to_resource(),
315 * pcibios_resource_to_bus(), etc.
316 */
317static void
318sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
319 s64 * pci_addrs)
320{
321 struct pci_controller *controller = PCI_CONTROLLER(dev->bus);
322 unsigned int i;
323 unsigned int idx;
324 unsigned int new_count;
325 struct pci_window *new_window;
326
327 if (count == 0)
328 return;
329 idx = controller->windows;
330 new_count = controller->windows + count;
331 new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL);
332 if (new_window == NULL)
333 BUG();
334 if (controller->window) {
335 memcpy(new_window, controller->window,
336 sizeof(struct pci_window) * controller->windows);
337 kfree(controller->window);
338 }
227 339
340 /* Setup a pci_window for each device resource. */
341 for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
342 if (pci_addrs[i] == -1)
343 continue;
344
345 new_window[idx].offset = dev->resource[i].start - pci_addrs[i];
346 new_window[idx].resource = dev->resource[i];
347 idx++;
228 } 348 }
229 349
350 controller->windows = new_count;
351 controller->window = new_window;
230} 352}
231 353
232void sn_pci_unfixup_slot(struct pci_dev *dev) 354void sn_pci_unfixup_slot(struct pci_dev *dev)
@@ -246,21 +368,23 @@ void sn_pci_unfixup_slot(struct pci_dev *dev)
246 */ 368 */
247void sn_pci_fixup_slot(struct pci_dev *dev) 369void sn_pci_fixup_slot(struct pci_dev *dev)
248{ 370{
371 unsigned int count = 0;
249 int idx; 372 int idx;
250 int segment = pci_domain_nr(dev->bus); 373 int segment = pci_domain_nr(dev->bus);
251 int status = 0; 374 int status = 0;
252 struct pcibus_bussoft *bs; 375 struct pcibus_bussoft *bs;
253 struct pci_bus *host_pci_bus; 376 struct pci_bus *host_pci_bus;
254 struct pci_dev *host_pci_dev; 377 struct pci_dev *host_pci_dev;
378 struct pcidev_info *pcidev_info;
379 s64 pci_addrs[PCI_ROM_RESOURCE + 1];
255 struct sn_irq_info *sn_irq_info; 380 struct sn_irq_info *sn_irq_info;
256 unsigned long size; 381 unsigned long size;
257 unsigned int bus_no, devfn; 382 unsigned int bus_no, devfn;
258 383
259 pci_dev_get(dev); /* for the sysdata pointer */ 384 pci_dev_get(dev); /* for the sysdata pointer */
260 dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL); 385 pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
261 if (SN_PCIDEV_INFO(dev) <= 0) 386 if (pcidev_info <= 0)
262 BUG(); /* Cannot afford to run out of memory */ 387 BUG(); /* Cannot afford to run out of memory */
263 memset(SN_PCIDEV_INFO(dev), 0, sizeof(struct pcidev_info));
264 388
265 sn_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_KERNEL); 389 sn_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
266 if (sn_irq_info <= 0) 390 if (sn_irq_info <= 0)
@@ -270,22 +394,34 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
270 /* Call to retrieve pci device information needed by kernel. */ 394 /* Call to retrieve pci device information needed by kernel. */
271 status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, 395 status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number,
272 dev->devfn, 396 dev->devfn,
273 (u64) __pa(SN_PCIDEV_INFO(dev)), 397 (u64) __pa(pcidev_info),
274 (u64) __pa(sn_irq_info)); 398 (u64) __pa(sn_irq_info));
275 if (status) 399 if (status)
276 BUG(); /* Cannot get platform pci device information */ 400 BUG(); /* Cannot get platform pci device information */
277 401
402 /* Add pcidev_info to list in sn_pci_controller struct */
403 list_add_tail(&pcidev_info->pdi_list,
404 &(SN_PCI_CONTROLLER(dev->bus)->pcidev_info));
405
278 /* Copy over PIO Mapped Addresses */ 406 /* Copy over PIO Mapped Addresses */
279 for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { 407 for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
280 unsigned long start, end, addr; 408 unsigned long start, end, addr;
281 409
282 if (!SN_PCIDEV_INFO(dev)->pdi_pio_mapped_addr[idx]) 410 if (!pcidev_info->pdi_pio_mapped_addr[idx]) {
411 pci_addrs[idx] = -1;
283 continue; 412 continue;
413 }
284 414
285 start = dev->resource[idx].start; 415 start = dev->resource[idx].start;
286 end = dev->resource[idx].end; 416 end = dev->resource[idx].end;
287 size = end - start; 417 size = end - start;
288 addr = SN_PCIDEV_INFO(dev)->pdi_pio_mapped_addr[idx]; 418 if (size == 0) {
419 pci_addrs[idx] = -1;
420 continue;
421 }
422 pci_addrs[idx] = start;
423 count++;
424 addr = pcidev_info->pdi_pio_mapped_addr[idx];
289 addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET; 425 addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET;
290 dev->resource[idx].start = addr; 426 dev->resource[idx].start = addr;
291 dev->resource[idx].end = addr + size; 427 dev->resource[idx].end = addr + size;
@@ -294,23 +430,27 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
294 else 430 else
295 dev->resource[idx].parent = &iomem_resource; 431 dev->resource[idx].parent = &iomem_resource;
296 } 432 }
433 /* Create a pci_window in the pci_controller struct for
434 * each device resource.
435 */
436 if (count > 0)
437 sn_pci_window_fixup(dev, count, pci_addrs);
297 438
298 /* 439 /*
299 * Using the PROMs values for the PCI host bus, get the Linux 440 * Using the PROMs values for the PCI host bus, get the Linux
300 * PCI host_pci_dev struct and set up host bus linkages 441 * PCI host_pci_dev struct and set up host bus linkages
301 */ 442 */
302 443
303 bus_no = (SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32) & 0xff; 444 bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff;
304 devfn = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle & 0xffffffff; 445 devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff;
305 host_pci_bus = pci_find_bus(segment, bus_no); 446 host_pci_bus = pci_find_bus(segment, bus_no);
306 host_pci_dev = pci_get_slot(host_pci_bus, devfn); 447 host_pci_dev = pci_get_slot(host_pci_bus, devfn);
307 448
308 SN_PCIDEV_INFO(dev)->host_pci_dev = host_pci_dev; 449 pcidev_info->host_pci_dev = host_pci_dev;
309 SN_PCIDEV_INFO(dev)->pdi_host_pcidev_info = 450 pcidev_info->pdi_linux_pcidev = dev;
310 SN_PCIDEV_INFO(host_pci_dev); 451 pcidev_info->pdi_host_pcidev_info = SN_PCIDEV_INFO(host_pci_dev);
311 SN_PCIDEV_INFO(dev)->pdi_linux_pcidev = dev;
312 bs = SN_PCIBUS_BUSSOFT(dev->bus); 452 bs = SN_PCIBUS_BUSSOFT(dev->bus);
313 SN_PCIDEV_INFO(dev)->pdi_pcibus_info = bs; 453 pcidev_info->pdi_pcibus_info = bs;
314 454
315 if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) { 455 if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) {
316 SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type]; 456 SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type];
@@ -320,11 +460,11 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
320 460
321 /* Only set up IRQ stuff if this device has a host bus context */ 461 /* Only set up IRQ stuff if this device has a host bus context */
322 if (bs && sn_irq_info->irq_irq) { 462 if (bs && sn_irq_info->irq_irq) {
323 SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = sn_irq_info; 463 pcidev_info->pdi_sn_irq_info = sn_irq_info;
324 dev->irq = SN_PCIDEV_INFO(dev)->pdi_sn_irq_info->irq_irq; 464 dev->irq = pcidev_info->pdi_sn_irq_info->irq_irq;
325 sn_irq_fixup(dev, sn_irq_info); 465 sn_irq_fixup(dev, sn_irq_info);
326 } else { 466 } else {
327 SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = NULL; 467 pcidev_info->pdi_sn_irq_info = NULL;
328 kfree(sn_irq_info); 468 kfree(sn_irq_info);
329 } 469 }
330} 470}
@@ -338,6 +478,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
338 int status = 0; 478 int status = 0;
339 int nasid, cnode; 479 int nasid, cnode;
340 struct pci_controller *controller; 480 struct pci_controller *controller;
481 struct sn_pci_controller *sn_controller;
341 struct pcibus_bussoft *prom_bussoft_ptr; 482 struct pcibus_bussoft *prom_bussoft_ptr;
342 struct hubdev_info *hubdev_info; 483 struct hubdev_info *hubdev_info;
343 void *provider_soft = NULL; 484 void *provider_soft = NULL;
@@ -349,10 +490,15 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
349 return; /*bus # does not exist */ 490 return; /*bus # does not exist */
350 prom_bussoft_ptr = __va(prom_bussoft_ptr); 491 prom_bussoft_ptr = __va(prom_bussoft_ptr);
351 492
352 controller = kzalloc(sizeof(struct pci_controller), GFP_KERNEL); 493 /* Allocate a sn_pci_controller, which has a pci_controller struct
494 * as the first member.
495 */
496 sn_controller = kzalloc(sizeof(struct sn_pci_controller), GFP_KERNEL);
497 if (!sn_controller)
498 BUG();
499 INIT_LIST_HEAD(&sn_controller->pcidev_info);
500 controller = &sn_controller->pci_controller;
353 controller->segment = segment; 501 controller->segment = segment;
354 if (!controller)
355 BUG();
356 502
357 if (bus == NULL) { 503 if (bus == NULL) {
358 bus = pci_scan_bus(busnum, &pci_root_ops, controller); 504 bus = pci_scan_bus(busnum, &pci_root_ops, controller);
@@ -390,6 +536,29 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
390 } 536 }
391 537
392 /* 538 /*
539 * Setup pci_windows for legacy IO and MEM space.
540 * (Temporary until ACPI support is in place.)
541 */
542 controller->window = kcalloc(2, sizeof(struct pci_window), GFP_KERNEL);
543 if (controller->window == NULL)
544 BUG();
545 controller->window[0].offset = prom_bussoft_ptr->bs_legacy_io;
546 controller->window[0].resource.name = "legacy_io";
547 controller->window[0].resource.flags = IORESOURCE_IO;
548 controller->window[0].resource.start = prom_bussoft_ptr->bs_legacy_io;
549 controller->window[0].resource.end =
550 controller->window[0].resource.start + 0xffff;
551 controller->window[0].resource.parent = &ioport_resource;
552 controller->window[1].offset = prom_bussoft_ptr->bs_legacy_mem;
553 controller->window[1].resource.name = "legacy_mem";
554 controller->window[1].resource.flags = IORESOURCE_MEM;
555 controller->window[1].resource.start = prom_bussoft_ptr->bs_legacy_mem;
556 controller->window[1].resource.end =
557 controller->window[1].resource.start + (1024 * 1024) - 1;
558 controller->window[1].resource.parent = &iomem_resource;
559 controller->windows = 2;
560
561 /*
393 * Generic bus fixup goes here. Don't reference prom_bussoft_ptr 562 * Generic bus fixup goes here. Don't reference prom_bussoft_ptr
394 * after this point. 563 * after this point.
395 */ 564 */
@@ -421,7 +590,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
421 590
422error_return: 591error_return:
423 592
424 kfree(controller); 593 kfree(sn_controller);
425 return; 594 return;
426} 595}
427 596
@@ -434,7 +603,7 @@ void sn_bus_store_sysdata(struct pci_dev *dev)
434 dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__); 603 dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__);
435 return; 604 return;
436 } 605 }
437 element->sysdata = dev->sysdata; 606 element->sysdata = SN_PCIDEV_INFO(dev);
438 list_add(&element->entry, &sn_sysdata_list); 607 list_add(&element->entry, &sn_sysdata_list);
439} 608}
440 609
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 01d18b7b5b..ec37084bdc 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -28,7 +28,7 @@ extern int sn_ioif_inited;
28static struct list_head **sn_irq_lh; 28static struct list_head **sn_irq_lh;
29static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ 29static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */
30 30
31static inline uint64_t sn_intr_alloc(nasid_t local_nasid, int local_widget, 31static 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 */
350static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) 350static 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/mca.c b/arch/ia64/sn/kernel/mca.c
index 6546db6abd..9ab684d1bb 100644
--- a/arch/ia64/sn/kernel/mca.c
+++ b/arch/ia64/sn/kernel/mca.c
@@ -10,6 +10,7 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/timer.h> 11#include <linux/timer.h>
12#include <linux/vmalloc.h> 12#include <linux/vmalloc.h>
13#include <linux/mutex.h>
13#include <asm/mca.h> 14#include <asm/mca.h>
14#include <asm/sal.h> 15#include <asm/sal.h>
15#include <asm/sn/sn_sal.h> 16#include <asm/sn/sn_sal.h>
@@ -27,7 +28,7 @@ void sn_init_cpei_timer(void);
27/* Printing oemdata from mca uses data that is not passed through SAL, it is 28/* Printing oemdata from mca uses data that is not passed through SAL, it is
28 * global. Only one user at a time. 29 * global. Only one user at a time.
29 */ 30 */
30static DECLARE_MUTEX(sn_oemdata_mutex); 31static DEFINE_MUTEX(sn_oemdata_mutex);
31static u8 **sn_oemdata; 32static u8 **sn_oemdata;
32static u64 *sn_oemdata_size, sn_oemdata_bufsize; 33static u64 *sn_oemdata_size, sn_oemdata_bufsize;
33 34
@@ -89,7 +90,7 @@ static int
89sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata, 90sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
90 u64 * oemdata_size) 91 u64 * oemdata_size)
91{ 92{
92 down(&sn_oemdata_mutex); 93 mutex_lock(&sn_oemdata_mutex);
93 sn_oemdata = oemdata; 94 sn_oemdata = oemdata;
94 sn_oemdata_size = oemdata_size; 95 sn_oemdata_size = oemdata_size;
95 sn_oemdata_bufsize = 0; 96 sn_oemdata_bufsize = 0;
@@ -107,7 +108,7 @@ sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
107 *sn_oemdata_size = 0; 108 *sn_oemdata_size = 0;
108 ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header); 109 ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
109 } 110 }
110 up(&sn_oemdata_mutex); 111 mutex_unlock(&sn_oemdata_mutex);
111 return 0; 112 return 0;
112} 113}
113 114
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 0fb579ef18..e510dce997 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -30,6 +30,7 @@
30#include <linux/root_dev.h> 30#include <linux/root_dev.h>
31#include <linux/nodemask.h> 31#include <linux/nodemask.h>
32#include <linux/pm.h> 32#include <linux/pm.h>
33#include <linux/efi.h>
33 34
34#include <asm/io.h> 35#include <asm/io.h>
35#include <asm/sal.h> 36#include <asm/sal.h>
@@ -242,6 +243,135 @@ static void __init sn_check_for_wars(void)
242 } 243 }
243} 244}
244 245
246/*
247 * Scan the EFI PCDP table (if it exists) for an acceptable VGA console
248 * output device. If one exists, pick it and set sn_legacy_{io,mem} to
249 * reflect the bus offsets needed to address it.
250 *
251 * Since pcdp support in SN is not supported in the 2.4 kernel (or at least
252 * the one lbs is based on) just declare the needed structs here.
253 *
254 * Reference spec http://www.dig64.org/specifications/DIG64_PCDPv20.pdf
255 *
256 * Returns 0 if no acceptable vga is found, !0 otherwise.
257 *
258 * Note: This stuff is duped here because Altix requires the PCDP to
259 * locate a usable VGA device due to lack of proper ACPI support. Structures
260 * could be used from drivers/firmware/pcdp.h, but it was decided that moving
261 * this file to a more public location just for Altix use was undesireable.
262 */
263
264struct hcdp_uart_desc {
265 u8 pad[45];
266};
267
268struct pcdp {
269 u8 signature[4]; /* should be 'HCDP' */
270 u32 length;
271 u8 rev; /* should be >=3 for pcdp, <3 for hcdp */
272 u8 sum;
273 u8 oem_id[6];
274 u64 oem_tableid;
275 u32 oem_rev;
276 u32 creator_id;
277 u32 creator_rev;
278 u32 num_type0;
279 struct hcdp_uart_desc uart[0]; /* num_type0 of these */
280 /* pcdp descriptors follow */
281} __attribute__((packed));
282
283struct pcdp_device_desc {
284 u8 type;
285 u8 primary;
286 u16 length;
287 u16 index;
288 /* interconnect specific structure follows */
289 /* device specific structure follows that */
290} __attribute__((packed));
291
292struct pcdp_interface_pci {
293 u8 type; /* 1 == pci */
294 u8 reserved;
295 u16 length;
296 u8 segment;
297 u8 bus;
298 u8 dev;
299 u8 fun;
300 u16 devid;
301 u16 vendid;
302 u32 acpi_interrupt;
303 u64 mmio_tra;
304 u64 ioport_tra;
305 u8 flags;
306 u8 translation;
307} __attribute__((packed));
308
309struct pcdp_vga_device {
310 u8 num_eas_desc;
311 /* ACPI Extended Address Space Desc follows */
312} __attribute__((packed));
313
314/* from pcdp_device_desc.primary */
315#define PCDP_PRIMARY_CONSOLE 0x01
316
317/* from pcdp_device_desc.type */
318#define PCDP_CONSOLE_INOUT 0x0
319#define PCDP_CONSOLE_DEBUG 0x1
320#define PCDP_CONSOLE_OUT 0x2
321#define PCDP_CONSOLE_IN 0x3
322#define PCDP_CONSOLE_TYPE_VGA 0x8
323
324#define PCDP_CONSOLE_VGA (PCDP_CONSOLE_TYPE_VGA | PCDP_CONSOLE_OUT)
325
326/* from pcdp_interface_pci.type */
327#define PCDP_IF_PCI 1
328
329/* from pcdp_interface_pci.translation */
330#define PCDP_PCI_TRANS_IOPORT 0x02
331#define PCDP_PCI_TRANS_MMIO 0x01
332
333static void
334sn_scan_pcdp(void)
335{
336 u8 *bp;
337 struct pcdp *pcdp;
338 struct pcdp_device_desc device;
339 struct pcdp_interface_pci if_pci;
340 extern struct efi efi;
341
342 pcdp = efi.hcdp;
343 if (! pcdp)
344 return; /* no hcdp/pcdp table */
345
346 if (pcdp->rev < 3)
347 return; /* only support PCDP (rev >= 3) */
348
349 for (bp = (u8 *)&pcdp->uart[pcdp->num_type0];
350 bp < (u8 *)pcdp + pcdp->length;
351 bp += device.length) {
352 memcpy(&device, bp, sizeof(device));
353 if (! (device.primary & PCDP_PRIMARY_CONSOLE))
354 continue; /* not primary console */
355
356 if (device.type != PCDP_CONSOLE_VGA)
357 continue; /* not VGA descriptor */
358
359 memcpy(&if_pci, bp+sizeof(device), sizeof(if_pci));
360 if (if_pci.type != PCDP_IF_PCI)
361 continue; /* not PCI interconnect */
362
363 if (if_pci.translation & PCDP_PCI_TRANS_IOPORT)
364 vga_console_iobase =
365 if_pci.ioport_tra | __IA64_UNCACHED_OFFSET;
366
367 if (if_pci.translation & PCDP_PCI_TRANS_MMIO)
368 vga_console_membase =
369 if_pci.mmio_tra | __IA64_UNCACHED_OFFSET;
370
371 break; /* once we find the primary, we're done */
372 }
373}
374
245/** 375/**
246 * sn_setup - SN platform setup routine 376 * sn_setup - SN platform setup routine
247 * @cmdline_p: kernel command line 377 * @cmdline_p: kernel command line
@@ -263,16 +393,35 @@ void __init sn_setup(char **cmdline_p)
263 393
264#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) 394#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
265 /* 395 /*
266 * If there was a primary vga adapter identified through the 396 * Handle SN vga console.
267 * EFI PCDP table, make it the preferred console. Otherwise 397 *
268 * zero out conswitchp. 398 * SN systems do not have enough ACPI table information
399 * being passed from prom to identify VGA adapters and the legacy
400 * addresses to access them. Until that is done, SN systems rely
401 * on the PCDP table to identify the primary VGA console if one
402 * exists.
403 *
404 * However, kernel PCDP support is optional, and even if it is built
405 * into the kernel, it will not be used if the boot cmdline contains
406 * console= directives.
407 *
408 * So, to work around this mess, we duplicate some of the PCDP code
409 * here so that the primary VGA console (as defined by PCDP) will
410 * work on SN systems even if a different console (e.g. serial) is
411 * selected on the boot line (or CONFIG_EFI_PCDP is off).
269 */ 412 */
270 413
414 if (! vga_console_membase)
415 sn_scan_pcdp();
416
271 if (vga_console_membase) { 417 if (vga_console_membase) {
272 /* usable vga ... make tty0 the preferred default console */ 418 /* usable vga ... make tty0 the preferred default console */
273 add_preferred_console("tty", 0, NULL); 419 if (!strstr(*cmdline_p, "console="))
420 add_preferred_console("tty", 0, NULL);
274 } else { 421 } else {
275 printk(KERN_DEBUG "SGI: Disabling VGA console\n"); 422 printk(KERN_DEBUG "SGI: Disabling VGA console\n");
423 if (!strstr(*cmdline_p, "console="))
424 add_preferred_console("ttySG", 0, NULL);
276#ifdef CONFIG_DUMMY_CONSOLE 425#ifdef CONFIG_DUMMY_CONSOLE
277 conswitchp = &dummy_con; 426 conswitchp = &dummy_con;
278#else 427#else
diff --git a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
index 3fa95065a4..bebbcc4f8d 100644
--- a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
+++ b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
@@ -39,9 +39,13 @@ sn2_ptc_deadlock_recovery_core:
39 mov r8=r0 39 mov r8=r0
40 40
411: 411:
42 cmp.ne p8,p9=r0,ptc1 // Test for shub type (ptc1 non-null on shub1)
43 // p8 = 1 if shub1, p9 = 1 if shub2
44
42 add scr2=ALIAS_OFFSET,piowc // Address of WRITE_STATUS alias register 45 add scr2=ALIAS_OFFSET,piowc // Address of WRITE_STATUS alias register
43 ;; 46 mov scr1=7;; // Clear DEADLOCK, WRITE_ERROR, MULTI_WRITE_ERROR
44 ld8.acq scr1=[scr2];; 47(p8) st8.rel [scr2]=scr1;;
48(p9) ld8.acq scr1=[scr2];;
45 49
465: ld8.acq scr1=[piowc];; // Wait for PIOs to complete. 505: ld8.acq scr1=[piowc];; // Wait for PIOs to complete.
47 hint @pause 51 hint @pause
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
index 49b530c39a..471bbaa65d 100644
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
@@ -202,7 +202,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
202 unsigned long end, unsigned long nbits) 202 unsigned long end, unsigned long nbits)
203{ 203{
204 int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0; 204 int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
205 int mymm = (mm == current->active_mm); 205 int mymm = (mm == current->active_mm && current->mm);
206 volatile unsigned long *ptc0, *ptc1; 206 volatile unsigned long *ptc0, *ptc1;
207 unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value; 207 unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value;
208 short nasids[MAX_NUMNODES], nix; 208 short nasids[MAX_NUMNODES], nix;
@@ -492,6 +492,9 @@ static struct proc_dir_entry *proc_sn2_ptc;
492 492
493static int __init sn2_ptc_init(void) 493static int __init sn2_ptc_init(void)
494{ 494{
495 if (!ia64_platform_is("sn2"))
496 return -ENOSYS;
497
495 if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) { 498 if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) {
496 printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME); 499 printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
497 return -EINVAL; 500 return -EINVAL;
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index 6c6fbca322..19b54fbcd7 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -743,13 +743,14 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg)
743 if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) { 743 if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
744 memset(p, 0, a.sz); 744 memset(p, 0, a.sz);
745 for (i = 0; i < nobj; i++) { 745 for (i = 0; i < nobj; i++) {
746 int cpuobj_index = 0;
746 if (!SN_HWPERF_IS_NODE(objs + i)) 747 if (!SN_HWPERF_IS_NODE(objs + i))
747 continue; 748 continue;
748 node = sn_hwperf_obj_to_cnode(objs + i); 749 node = sn_hwperf_obj_to_cnode(objs + i);
749 for_each_online_cpu(j) { 750 for_each_online_cpu(j) {
750 if (node != cpu_to_node(j)) 751 if (node != cpu_to_node(j))
751 continue; 752 continue;
752 cpuobj = (struct sn_hwperf_object_info *) p + j; 753 cpuobj = (struct sn_hwperf_object_info *) p + cpuobj_index++;
753 slice = 'a' + cpuid_to_slice(j); 754 slice = 'a' + cpuid_to_slice(j);
754 cdata = cpu_data(j); 755 cdata = cpu_data(j);
755 cpuobj->id = j; 756 cpuobj->id = j;
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index 0d8592a745..d263d3e8fb 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -11,6 +11,7 @@
11#include <linux/slab.h> 11#include <linux/slab.h>
12#include <linux/spinlock.h> 12#include <linux/spinlock.h>
13#include <linux/proc_fs.h> 13#include <linux/proc_fs.h>
14#include <linux/capability.h>
14#include <linux/device.h> 15#include <linux/device.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
16#include <asm/system.h> 17#include <asm/system.h>
@@ -65,7 +66,7 @@ static int tiocx_match(struct device *dev, struct device_driver *drv)
65 66
66} 67}
67 68
68static int tiocx_hotplug(struct device *dev, char **envp, int num_envp, 69static int tiocx_uevent(struct device *dev, char **envp, int num_envp,
69 char *buffer, int buffer_size) 70 char *buffer, int buffer_size)
70{ 71{
71 return -ENODEV; 72 return -ENODEV;
@@ -76,12 +77,6 @@ static void tiocx_bus_release(struct device *dev)
76 kfree(to_cx_dev(dev)); 77 kfree(to_cx_dev(dev));
77} 78}
78 79
79struct bus_type tiocx_bus_type = {
80 .name = "tiocx",
81 .match = tiocx_match,
82 .hotplug = tiocx_hotplug,
83};
84
85/** 80/**
86 * cx_device_match - Find cx_device in the id table. 81 * cx_device_match - Find cx_device in the id table.
87 * @ids: id table from driver 82 * @ids: id table from driver
@@ -148,6 +143,14 @@ static int cx_driver_remove(struct device *dev)
148 return 0; 143 return 0;
149} 144}
150 145
146struct 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
151/** 154/**
152 * cx_driver_register - Register the driver. 155 * cx_driver_register - Register the driver.
153 * @cx_driver: driver table (cx_drv struct) from driver 156 * @cx_driver: driver table (cx_drv struct) from driver
@@ -161,8 +164,6 @@ int cx_driver_register(struct cx_drv *cx_driver)
161{ 164{
162 cx_driver->driver.name = cx_driver->name; 165 cx_driver->driver.name = cx_driver->name;
163 cx_driver->driver.bus = &tiocx_bus_type; 166 cx_driver->driver.bus = &tiocx_bus_type;
164 cx_driver->driver.probe = cx_device_probe;
165 cx_driver->driver.remove = cx_driver_remove;
166 167
167 return driver_register(&cx_driver->driver); 168 return driver_register(&cx_driver->driver);
168} 169}
@@ -244,7 +245,7 @@ static int cx_device_reload(struct cx_dev *cx_dev)
244 cx_dev->bt); 245 cx_dev->bt);
245} 246}
246 247
247static inline uint64_t tiocx_intr_alloc(nasid_t nasid, int widget, 248static inline u64 tiocx_intr_alloc(nasid_t nasid, int widget,
248 u64 sn_irq_info, 249 u64 sn_irq_info,
249 int req_irq, nasid_t req_nasid, 250 int req_irq, nasid_t req_nasid,
250 int req_slice) 251 int req_slice)
@@ -301,7 +302,7 @@ struct sn_irq_info *tiocx_irq_alloc(nasid_t nasid, int widget, int irq,
301 302
302void tiocx_irq_free(struct sn_irq_info *sn_irq_info) 303void tiocx_irq_free(struct sn_irq_info *sn_irq_info)
303{ 304{
304 uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge; 305 u64 bridge = (u64) sn_irq_info->irq_bridge;
305 nasid_t nasid = NASID_GET(bridge); 306 nasid_t nasid = NASID_GET(bridge);
306 int widget; 307 int widget;
307 308
@@ -312,12 +313,12 @@ void tiocx_irq_free(struct sn_irq_info *sn_irq_info)
312 } 313 }
313} 314}
314 315
315uint64_t tiocx_dma_addr(uint64_t addr) 316u64 tiocx_dma_addr(u64 addr)
316{ 317{
317 return PHYS_TO_TIODMA(addr); 318 return PHYS_TO_TIODMA(addr);
318} 319}
319 320
320uint64_t tiocx_swin_base(int nasid) 321u64 tiocx_swin_base(int nasid)
321{ 322{
322 return TIO_SWIN_BASE(nasid, TIOCX_CORELET); 323 return TIO_SWIN_BASE(nasid, TIOCX_CORELET);
323} 324}
@@ -334,8 +335,8 @@ EXPORT_SYMBOL(tiocx_swin_base);
334 335
335static void tio_conveyor_set(nasid_t nasid, int enable_flag) 336static void tio_conveyor_set(nasid_t nasid, int enable_flag)
336{ 337{
337 uint64_t ice_frz; 338 u64 ice_frz;
338 uint64_t disable_cb = (1ull << 61); 339 u64 disable_cb = (1ull << 61);
339 340
340 if (!(nasid & 1)) 341 if (!(nasid & 1))
341 return; 342 return;
@@ -387,7 +388,7 @@ static int is_fpga_tio(int nasid, int *bt)
387 388
388static int bitstream_loaded(nasid_t nasid) 389static int bitstream_loaded(nasid_t nasid)
389{ 390{
390 uint64_t cx_credits; 391 u64 cx_credits;
391 392
392 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);
393 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;
@@ -403,14 +404,14 @@ static int tiocx_reload(struct cx_dev *cx_dev)
403 nasid_t nasid = cx_dev->cx_id.nasid; 404 nasid_t nasid = cx_dev->cx_id.nasid;
404 405
405 if (bitstream_loaded(nasid)) { 406 if (bitstream_loaded(nasid)) {
406 uint64_t cx_id; 407 u64 cx_id;
407 int rv; 408 int rv;
408 409
409 rv = ia64_sn_sysctl_tio_clock_reset(nasid); 410 rv = ia64_sn_sysctl_tio_clock_reset(nasid);
410 if (rv) { 411 if (rv) {
411 printk(KERN_ALERT "CX port JTAG reset failed.\n"); 412 printk(KERN_ALERT "CX port JTAG reset failed.\n");
412 } else { 413 } else {
413 cx_id = *(volatile uint64_t *) 414 cx_id = *(volatile u64 *)
414 (TIO_SWIN_BASE(nasid, TIOCX_CORELET) + 415 (TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
415 WIDGET_ID); 416 WIDGET_ID);
416 part_num = XWIDGET_PART_NUM(cx_id); 417 part_num = XWIDGET_PART_NUM(cx_id);
diff --git a/arch/ia64/sn/kernel/xp_main.c b/arch/ia64/sn/kernel/xp_main.c
index 3be52a34c8..b7ea46645e 100644
--- a/arch/ia64/sn/kernel/xp_main.c
+++ b/arch/ia64/sn/kernel/xp_main.c
@@ -19,6 +19,7 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/mutex.h>
22#include <asm/sn/intr.h> 23#include <asm/sn/intr.h>
23#include <asm/sn/sn_sal.h> 24#include <asm/sn/sn_sal.h>
24#include <asm/sn/xp.h> 25#include <asm/sn/xp.h>
@@ -136,13 +137,13 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
136 137
137 registration = &xpc_registrations[ch_number]; 138 registration = &xpc_registrations[ch_number];
138 139
139 if (down_interruptible(&registration->sema) != 0) { 140 if (mutex_lock_interruptible(&registration->mutex) != 0) {
140 return xpcInterrupted; 141 return xpcInterrupted;
141 } 142 }
142 143
143 /* if XPC_CHANNEL_REGISTERED(ch_number) */ 144 /* if XPC_CHANNEL_REGISTERED(ch_number) */
144 if (registration->func != NULL) { 145 if (registration->func != NULL) {
145 up(&registration->sema); 146 mutex_unlock(&registration->mutex);
146 return xpcAlreadyRegistered; 147 return xpcAlreadyRegistered;
147 } 148 }
148 149
@@ -154,7 +155,7 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
154 registration->key = key; 155 registration->key = key;
155 registration->func = func; 156 registration->func = func;
156 157
157 up(&registration->sema); 158 mutex_unlock(&registration->mutex);
158 159
159 xpc_interface.connect(ch_number); 160 xpc_interface.connect(ch_number);
160 161
@@ -190,11 +191,11 @@ xpc_disconnect(int ch_number)
190 * figured XPC's users will just turn around and call xpc_disconnect() 191 * figured XPC's users will just turn around and call xpc_disconnect()
191 * again anyways, so we might as well wait, if need be. 192 * again anyways, so we might as well wait, if need be.
192 */ 193 */
193 down(&registration->sema); 194 mutex_lock(&registration->mutex);
194 195
195 /* if !XPC_CHANNEL_REGISTERED(ch_number) */ 196 /* if !XPC_CHANNEL_REGISTERED(ch_number) */
196 if (registration->func == NULL) { 197 if (registration->func == NULL) {
197 up(&registration->sema); 198 mutex_unlock(&registration->mutex);
198 return; 199 return;
199 } 200 }
200 201
@@ -208,7 +209,7 @@ xpc_disconnect(int ch_number)
208 209
209 xpc_interface.disconnect(ch_number); 210 xpc_interface.disconnect(ch_number);
210 211
211 up(&registration->sema); 212 mutex_unlock(&registration->mutex);
212 213
213 return; 214 return;
214} 215}
@@ -250,9 +251,9 @@ xp_init(void)
250 xp_nofault_PIOR_target = SH1_IPI_ACCESS; 251 xp_nofault_PIOR_target = SH1_IPI_ACCESS;
251 } 252 }
252 253
253 /* initialize the connection registration semaphores */ 254 /* initialize the connection registration mutex */
254 for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) { 255 for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
255 sema_init(&xpc_registrations[ch_number].sema, 1); /* mutex */ 256 mutex_init(&xpc_registrations[ch_number].mutex);
256 } 257 }
257 258
258 return 0; 259 return 0;
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h
deleted file mode 100644
index 5483a9f227..0000000000
--- 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 */
111struct 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 */
135static inline int
136xpc_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 */
162struct 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
180static inline int
181xpc_hb_allowed(partid_t partid, struct xpc_vars *vars)
182{
183 return ((vars->heartbeating_to_mask & (1UL << partid)) != 0);
184}
185
186static inline void
187xpc_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
198static inline void
199xpc_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 */
235struct 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 */
292struct 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 */
306struct 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 */
337struct 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 */
430struct 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 */
531struct 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 */
659extern struct xpc_registration xpc_registrations[];
660
661
662/* found in xpc_main.c */
663extern struct device *xpc_part;
664extern struct device *xpc_chan;
665extern int xpc_disengage_request_timelimit;
666extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *);
667extern void xpc_dropped_IPI_check(struct xpc_partition *);
668extern void xpc_activate_partition(struct xpc_partition *);
669extern void xpc_activate_kthreads(struct xpc_channel *, int);
670extern void xpc_create_kthreads(struct xpc_channel *, int);
671extern void xpc_disconnect_wait(int);
672
673
674/* found in xpc_partition.c */
675extern int xpc_exiting;
676extern struct xpc_vars *xpc_vars;
677extern struct xpc_rsvd_page *xpc_rsvd_page;
678extern struct xpc_vars_part *xpc_vars_part;
679extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
680extern char xpc_remote_copy_buffer[];
681extern struct xpc_rsvd_page *xpc_rsvd_page_init(void);
682extern void xpc_allow_IPI_ops(void);
683extern void xpc_restrict_IPI_ops(void);
684extern int xpc_identify_act_IRQ_sender(void);
685extern int xpc_partition_disengaged(struct xpc_partition *);
686extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *);
687extern void xpc_mark_partition_inactive(struct xpc_partition *);
688extern void xpc_discovery(void);
689extern void xpc_check_remote_hb(void);
690extern void xpc_deactivate_partition(const int, struct xpc_partition *,
691 enum xpc_retval);
692extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *);
693
694
695/* found in xpc_channel.c */
696extern void xpc_initiate_connect(int);
697extern void xpc_initiate_disconnect(int);
698extern enum xpc_retval xpc_initiate_allocate(partid_t, int, u32, void **);
699extern enum xpc_retval xpc_initiate_send(partid_t, int, void *);
700extern enum xpc_retval xpc_initiate_send_notify(partid_t, int, void *,
701 xpc_notify_func, void *);
702extern void xpc_initiate_received(partid_t, int, void *);
703extern enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *);
704extern enum xpc_retval xpc_pull_remote_vars_part(struct xpc_partition *);
705extern void xpc_process_channel_activity(struct xpc_partition *);
706extern void xpc_connected_callout(struct xpc_channel *);
707extern void xpc_deliver_msg(struct xpc_channel *);
708extern void xpc_disconnect_channel(const int, struct xpc_channel *,
709 enum xpc_retval, unsigned long *);
710extern void xpc_disconnecting_callout(struct xpc_channel *);
711extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval);
712extern void xpc_teardown_infrastructure(struct xpc_partition *);
713
714
715
716static inline void
717xpc_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 */
730static inline void
731xpc_msgqueue_ref(struct xpc_channel *ch)
732{
733 atomic_inc(&ch->references);
734}
735
736static inline void
737xpc_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 */
757static inline void
758xpc_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
769static inline int
770xpc_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
803static inline void
804xpc_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
828static inline void
829xpc_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
853static inline void
854xpc_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
878static inline void
879xpc_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
903static inline u64
904xpc_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
914static inline u64
915xpc_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
925static inline void
926xpc_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
936static inline void
937xpc_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
956static inline u64
957xpc_IPI_receive(AMO_t *amo)
958{
959 return FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_CLEAR);
960}
961
962
963static inline enum xpc_retval
964xpc_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 */
997static inline void
998xpc_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
1011static inline void
1012xpc_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
1018static inline void
1019xpc_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
1025static inline void
1026xpc_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
1032static inline void
1033xpc_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
1051static inline void
1052xpc_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
1088static inline void
1089xpc_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
1125static inline void
1126xpc_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
1136static inline void
1137xpc_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
1142static inline void
1143xpc_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
1154static inline void
1155xpc_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
1167static inline void
1168xpc_IPI_send_msgrequest(struct xpc_channel *ch)
1169{
1170 XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_MSGREQUEST, NULL);
1171}
1172
1173static inline void
1174xpc_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 */
1191static inline AMO_t *
1192xpc_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
1203static inline enum xpc_retval
1204xpc_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
1223static inline void *
1224xpc_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 */
1249static inline void
1250xpc_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 abf4fc2a87..8d950c778b 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
@@ -22,9 +22,11 @@
22#include <linux/cache.h> 22#include <linux/cache.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/mutex.h>
26#include <linux/completion.h>
25#include <asm/sn/bte.h> 27#include <asm/sn/bte.h>
26#include <asm/sn/sn_sal.h> 28#include <asm/sn/sn_sal.h>
27#include "xpc.h" 29#include <asm/sn/xpc.h>
28 30
29 31
30/* 32/*
@@ -56,8 +58,8 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
56 atomic_set(&ch->n_to_notify, 0); 58 atomic_set(&ch->n_to_notify, 0);
57 59
58 spin_lock_init(&ch->lock); 60 spin_lock_init(&ch->lock);
59 sema_init(&ch->msg_to_pull_sema, 1); /* mutex */ 61 mutex_init(&ch->msg_to_pull_mutex);
60 sema_init(&ch->wdisconnect_sema, 0); /* event wait */ 62 init_completion(&ch->wdisconnect_wait);
61 63
62 atomic_set(&ch->n_on_msg_allocate_wq, 0); 64 atomic_set(&ch->n_on_msg_allocate_wq, 0);
63 init_waitqueue_head(&ch->msg_allocate_wq); 65 init_waitqueue_head(&ch->msg_allocate_wq);
@@ -534,7 +536,6 @@ static enum xpc_retval
534xpc_allocate_msgqueues(struct xpc_channel *ch) 536xpc_allocate_msgqueues(struct xpc_channel *ch)
535{ 537{
536 unsigned long irq_flags; 538 unsigned long irq_flags;
537 int i;
538 enum xpc_retval ret; 539 enum xpc_retval ret;
539 540
540 541
@@ -552,11 +553,6 @@ xpc_allocate_msgqueues(struct xpc_channel *ch)
552 return ret; 553 return ret;
553 } 554 }
554 555
555 for (i = 0; i < ch->local_nentries; i++) {
556 /* use a semaphore as an event wait queue */
557 sema_init(&ch->notify_queue[i].sema, 0);
558 }
559
560 spin_lock_irqsave(&ch->lock, irq_flags); 556 spin_lock_irqsave(&ch->lock, irq_flags);
561 ch->flags |= XPC_C_SETUP; 557 ch->flags |= XPC_C_SETUP;
562 spin_unlock_irqrestore(&ch->lock, irq_flags); 558 spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -779,6 +775,12 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
779 775
780 /* both sides are disconnected now */ 776 /* both sides are disconnected now */
781 777
778 if (ch->flags & XPC_C_CONNECTCALLOUT) {
779 spin_unlock_irqrestore(&ch->lock, *irq_flags);
780 xpc_disconnect_callout(ch, xpcDisconnected);
781 spin_lock_irqsave(&ch->lock, *irq_flags);
782 }
783
782 /* it's now safe to free the channel's message queues */ 784 /* it's now safe to free the channel's message queues */
783 xpc_free_msgqueues(ch); 785 xpc_free_msgqueues(ch);
784 786
@@ -793,10 +795,8 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
793 } 795 }
794 796
795 if (ch->flags & XPC_C_WDISCONNECT) { 797 if (ch->flags & XPC_C_WDISCONNECT) {
796 spin_unlock_irqrestore(&ch->lock, *irq_flags); 798 /* we won't lose the CPU since we're holding ch->lock */
797 up(&ch->wdisconnect_sema); 799 complete(&ch->wdisconnect_wait);
798 spin_lock_irqsave(&ch->lock, *irq_flags);
799
800 } else if (ch->delayed_IPI_flags) { 800 } else if (ch->delayed_IPI_flags) {
801 if (part->act_state != XPC_P_DEACTIVATING) { 801 if (part->act_state != XPC_P_DEACTIVATING) {
802 /* time to take action on any delayed IPI flags */ 802 /* time to take action on any delayed IPI flags */
@@ -1086,12 +1086,12 @@ xpc_connect_channel(struct xpc_channel *ch)
1086 struct xpc_registration *registration = &xpc_registrations[ch->number]; 1086 struct xpc_registration *registration = &xpc_registrations[ch->number];
1087 1087
1088 1088
1089 if (down_trylock(&registration->sema) != 0) { 1089 if (mutex_trylock(&registration->mutex) == 0) {
1090 return xpcRetry; 1090 return xpcRetry;
1091 } 1091 }
1092 1092
1093 if (!XPC_CHANNEL_REGISTERED(ch->number)) { 1093 if (!XPC_CHANNEL_REGISTERED(ch->number)) {
1094 up(&registration->sema); 1094 mutex_unlock(&registration->mutex);
1095 return xpcUnregistered; 1095 return xpcUnregistered;
1096 } 1096 }
1097 1097
@@ -1102,7 +1102,7 @@ xpc_connect_channel(struct xpc_channel *ch)
1102 1102
1103 if (ch->flags & XPC_C_DISCONNECTING) { 1103 if (ch->flags & XPC_C_DISCONNECTING) {
1104 spin_unlock_irqrestore(&ch->lock, irq_flags); 1104 spin_unlock_irqrestore(&ch->lock, irq_flags);
1105 up(&registration->sema); 1105 mutex_unlock(&registration->mutex);
1106 return ch->reason; 1106 return ch->reason;
1107 } 1107 }
1108 1108
@@ -1134,7 +1134,7 @@ xpc_connect_channel(struct xpc_channel *ch)
1134 * channel lock be locked and will unlock and relock 1134 * channel lock be locked and will unlock and relock
1135 * the channel lock as needed. 1135 * the channel lock as needed.
1136 */ 1136 */
1137 up(&registration->sema); 1137 mutex_unlock(&registration->mutex);
1138 XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes, 1138 XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
1139 &irq_flags); 1139 &irq_flags);
1140 spin_unlock_irqrestore(&ch->lock, irq_flags); 1140 spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -1149,7 +1149,7 @@ xpc_connect_channel(struct xpc_channel *ch)
1149 atomic_inc(&xpc_partitions[ch->partid].nchannels_active); 1149 atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
1150 } 1150 }
1151 1151
1152 up(&registration->sema); 1152 mutex_unlock(&registration->mutex);
1153 1153
1154 1154
1155 /* initiate the connection */ 1155 /* initiate the connection */
@@ -1645,7 +1645,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
1645 1645
1646 1646
1647void 1647void
1648xpc_disconnecting_callout(struct xpc_channel *ch) 1648xpc_disconnect_callout(struct xpc_channel *ch, enum xpc_retval reason)
1649{ 1649{
1650 /* 1650 /*
1651 * Let the channel's registerer know that the channel is being 1651 * Let the channel's registerer know that the channel is being
@@ -1654,15 +1654,13 @@ xpc_disconnecting_callout(struct xpc_channel *ch)
1654 */ 1654 */
1655 1655
1656 if (ch->func != NULL) { 1656 if (ch->func != NULL) {
1657 dev_dbg(xpc_chan, "ch->func() called, reason=xpcDisconnecting," 1657 dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, "
1658 " partid=%d, channel=%d\n", ch->partid, ch->number); 1658 "channel=%d\n", reason, ch->partid, ch->number);
1659 1659
1660 ch->func(xpcDisconnecting, ch->partid, ch->number, NULL, 1660 ch->func(reason, ch->partid, ch->number, NULL, ch->key);
1661 ch->key);
1662 1661
1663 dev_dbg(xpc_chan, "ch->func() returned, reason=" 1662 dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, "
1664 "xpcDisconnecting, partid=%d, channel=%d\n", 1663 "channel=%d\n", reason, ch->partid, ch->number);
1665 ch->partid, ch->number);
1666 } 1664 }
1667} 1665}
1668 1666
@@ -2085,7 +2083,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
2085 enum xpc_retval ret; 2083 enum xpc_retval ret;
2086 2084
2087 2085
2088 if (down_interruptible(&ch->msg_to_pull_sema) != 0) { 2086 if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) {
2089 /* we were interrupted by a signal */ 2087 /* we were interrupted by a signal */
2090 return NULL; 2088 return NULL;
2091 } 2089 }
@@ -2121,7 +2119,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
2121 2119
2122 XPC_DEACTIVATE_PARTITION(part, ret); 2120 XPC_DEACTIVATE_PARTITION(part, ret);
2123 2121
2124 up(&ch->msg_to_pull_sema); 2122 mutex_unlock(&ch->msg_to_pull_mutex);
2125 return NULL; 2123 return NULL;
2126 } 2124 }
2127 2125
@@ -2130,7 +2128,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
2130 ch->next_msg_to_pull += nmsgs; 2128 ch->next_msg_to_pull += nmsgs;
2131 } 2129 }
2132 2130
2133 up(&ch->msg_to_pull_sema); 2131 mutex_unlock(&ch->msg_to_pull_mutex);
2134 2132
2135 /* return the message we were looking for */ 2133 /* return the message we were looking for */
2136 msg_offset = (get % ch->remote_nentries) * ch->msg_size; 2134 msg_offset = (get % ch->remote_nentries) * ch->msg_size;
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index b617236524..c75f8aeefc 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
@@ -55,11 +55,12 @@
55#include <linux/slab.h> 55#include <linux/slab.h>
56#include <linux/delay.h> 56#include <linux/delay.h>
57#include <linux/reboot.h> 57#include <linux/reboot.h>
58#include <linux/completion.h>
58#include <asm/sn/intr.h> 59#include <asm/sn/intr.h>
59#include <asm/sn/sn_sal.h> 60#include <asm/sn/sn_sal.h>
60#include <asm/kdebug.h> 61#include <asm/kdebug.h>
61#include <asm/uaccess.h> 62#include <asm/uaccess.h>
62#include "xpc.h" 63#include <asm/sn/xpc.h>
63 64
64 65
65/* define two XPC debug device structures to be used with dev_dbg() et al */ 66/* define two XPC debug device structures to be used with dev_dbg() et al */
@@ -82,6 +83,9 @@ struct device *xpc_part = &xpc_part_dbg_subname;
82struct device *xpc_chan = &xpc_chan_dbg_subname; 83struct device *xpc_chan = &xpc_chan_dbg_subname;
83 84
84 85
86static int xpc_kdebug_ignore;
87
88
85/* systune related variables for /proc/sys directories */ 89/* systune related variables for /proc/sys directories */
86 90
87static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; 91static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL;
@@ -162,6 +166,8 @@ static ctl_table xpc_sys_dir[] = {
162}; 166};
163static struct ctl_table_header *xpc_sysctl; 167static struct ctl_table_header *xpc_sysctl;
164 168
169/* non-zero if any remote partition disengage request was timed out */
170int xpc_disengage_request_timedout;
165 171
166/* #of IRQs received */ 172/* #of IRQs received */
167static atomic_t xpc_act_IRQ_rcvd; 173static atomic_t xpc_act_IRQ_rcvd;
@@ -172,10 +178,10 @@ static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
172static unsigned long xpc_hb_check_timeout; 178static unsigned long xpc_hb_check_timeout;
173 179
174/* notification that the xpc_hb_checker thread has exited */ 180/* notification that the xpc_hb_checker thread has exited */
175static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited); 181static DECLARE_COMPLETION(xpc_hb_checker_exited);
176 182
177/* notification that the xpc_discovery thread has exited */ 183/* notification that the xpc_discovery thread has exited */
178static DECLARE_MUTEX_LOCKED(xpc_discovery_exited); 184static DECLARE_COMPLETION(xpc_discovery_exited);
179 185
180 186
181static struct timer_list xpc_hb_timer; 187static struct timer_list xpc_hb_timer;
@@ -316,7 +322,7 @@ xpc_hb_checker(void *ignore)
316 322
317 323
318 /* mark this thread as having exited */ 324 /* mark this thread as having exited */
319 up(&xpc_hb_checker_exited); 325 complete(&xpc_hb_checker_exited);
320 return 0; 326 return 0;
321} 327}
322 328
@@ -336,7 +342,7 @@ xpc_initiate_discovery(void *ignore)
336 dev_dbg(xpc_part, "discovery thread is exiting\n"); 342 dev_dbg(xpc_part, "discovery thread is exiting\n");
337 343
338 /* mark this thread as having exited */ 344 /* mark this thread as having exited */
339 up(&xpc_discovery_exited); 345 complete(&xpc_discovery_exited);
340 return 0; 346 return 0;
341} 347}
342 348
@@ -773,7 +779,7 @@ xpc_daemonize_kthread(void *args)
773 ch->flags |= XPC_C_DISCONNECTCALLOUT; 779 ch->flags |= XPC_C_DISCONNECTCALLOUT;
774 spin_unlock_irqrestore(&ch->lock, irq_flags); 780 spin_unlock_irqrestore(&ch->lock, irq_flags);
775 781
776 xpc_disconnecting_callout(ch); 782 xpc_disconnect_callout(ch, xpcDisconnecting);
777 } else { 783 } else {
778 spin_unlock_irqrestore(&ch->lock, irq_flags); 784 spin_unlock_irqrestore(&ch->lock, irq_flags);
779 } 785 }
@@ -888,7 +894,7 @@ xpc_disconnect_wait(int ch_number)
888 continue; 894 continue;
889 } 895 }
890 896
891 (void) down(&ch->wdisconnect_sema); 897 wait_for_completion(&ch->wdisconnect_wait);
892 898
893 spin_lock_irqsave(&ch->lock, irq_flags); 899 spin_lock_irqsave(&ch->lock, irq_flags);
894 DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED)); 900 DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
@@ -921,9 +927,9 @@ static void
921xpc_do_exit(enum xpc_retval reason) 927xpc_do_exit(enum xpc_retval reason)
922{ 928{
923 partid_t partid; 929 partid_t partid;
924 int active_part_count; 930 int active_part_count, printed_waiting_msg = 0;
925 struct xpc_partition *part; 931 struct xpc_partition *part;
926 unsigned long printmsg_time; 932 unsigned long printmsg_time, disengage_request_timeout = 0;
927 933
928 934
929 /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */ 935 /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */
@@ -941,10 +947,10 @@ xpc_do_exit(enum xpc_retval reason)
941 free_irq(SGI_XPC_ACTIVATE, NULL); 947 free_irq(SGI_XPC_ACTIVATE, NULL);
942 948
943 /* wait for the discovery thread to exit */ 949 /* wait for the discovery thread to exit */
944 down(&xpc_discovery_exited); 950 wait_for_completion(&xpc_discovery_exited);
945 951
946 /* wait for the heartbeat checker thread to exit */ 952 /* wait for the heartbeat checker thread to exit */
947 down(&xpc_hb_checker_exited); 953 wait_for_completion(&xpc_hb_checker_exited);
948 954
949 955
950 /* sleep for a 1/3 of a second or so */ 956 /* sleep for a 1/3 of a second or so */
@@ -953,7 +959,8 @@ xpc_do_exit(enum xpc_retval reason)
953 959
954 /* wait for all partitions to become inactive */ 960 /* wait for all partitions to become inactive */
955 961
956 printmsg_time = jiffies; 962 printmsg_time = jiffies + (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ);
963 xpc_disengage_request_timedout = 0;
957 964
958 do { 965 do {
959 active_part_count = 0; 966 active_part_count = 0;
@@ -969,20 +976,39 @@ xpc_do_exit(enum xpc_retval reason)
969 active_part_count++; 976 active_part_count++;
970 977
971 XPC_DEACTIVATE_PARTITION(part, reason); 978 XPC_DEACTIVATE_PARTITION(part, reason);
972 }
973 979
974 if (active_part_count == 0) { 980 if (part->disengage_request_timeout >
975 break; 981 disengage_request_timeout) {
982 disengage_request_timeout =
983 part->disengage_request_timeout;
984 }
976 } 985 }
977 986
978 if (jiffies >= printmsg_time) { 987 if (xpc_partition_engaged(-1UL)) {
979 dev_info(xpc_part, "waiting for partitions to " 988 if (time_after(jiffies, printmsg_time)) {
980 "deactivate/disengage, active count=%d, remote " 989 dev_info(xpc_part, "waiting for remote "
981 "engaged=0x%lx\n", active_part_count, 990 "partitions to disengage, timeout in "
982 xpc_partition_engaged(1UL << partid)); 991 "%ld seconds\n",
983 992 (disengage_request_timeout - jiffies)
984 printmsg_time = jiffies + 993 / HZ);
994 printmsg_time = jiffies +
985 (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); 995 (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ);
996 printed_waiting_msg = 1;
997 }
998
999 } else if (active_part_count > 0) {
1000 if (printed_waiting_msg) {
1001 dev_info(xpc_part, "waiting for local partition"
1002 " to disengage\n");
1003 printed_waiting_msg = 0;
1004 }
1005
1006 } else {
1007 if (!xpc_disengage_request_timedout) {
1008 dev_info(xpc_part, "all partitions have "
1009 "disengaged\n");
1010 }
1011 break;
986 } 1012 }
987 1013
988 /* sleep for a 1/3 of a second or so */ 1014 /* sleep for a 1/3 of a second or so */
@@ -1000,11 +1026,13 @@ xpc_do_exit(enum xpc_retval reason)
1000 del_timer_sync(&xpc_hb_timer); 1026 del_timer_sync(&xpc_hb_timer);
1001 DBUG_ON(xpc_vars->heartbeating_to_mask != 0); 1027 DBUG_ON(xpc_vars->heartbeating_to_mask != 0);
1002 1028
1003 /* take ourselves off of the reboot_notifier_list */ 1029 if (reason == xpcUnloading) {
1004 (void) unregister_reboot_notifier(&xpc_reboot_notifier); 1030 /* take ourselves off of the reboot_notifier_list */
1031 (void) unregister_reboot_notifier(&xpc_reboot_notifier);
1005 1032
1006 /* take ourselves off of the die_notifier list */ 1033 /* take ourselves off of the die_notifier list */
1007 (void) unregister_die_notifier(&xpc_die_notifier); 1034 (void) unregister_die_notifier(&xpc_die_notifier);
1035 }
1008 1036
1009 /* close down protections for IPI operations */ 1037 /* close down protections for IPI operations */
1010 xpc_restrict_IPI_ops(); 1038 xpc_restrict_IPI_ops();
@@ -1020,7 +1048,35 @@ xpc_do_exit(enum xpc_retval reason)
1020 1048
1021 1049
1022/* 1050/*
1023 * Called when the system is about to be either restarted or halted. 1051 * This function is called when the system is being rebooted.
1052 */
1053static int
1054xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
1055{
1056 enum xpc_retval reason;
1057
1058
1059 switch (event) {
1060 case SYS_RESTART:
1061 reason = xpcSystemReboot;
1062 break;
1063 case SYS_HALT:
1064 reason = xpcSystemHalt;
1065 break;
1066 case SYS_POWER_OFF:
1067 reason = xpcSystemPoweroff;
1068 break;
1069 default:
1070 reason = xpcSystemGoingDown;
1071 }
1072
1073 xpc_do_exit(reason);
1074 return NOTIFY_DONE;
1075}
1076
1077
1078/*
1079 * Notify other partitions to disengage from all references to our memory.
1024 */ 1080 */
1025static void 1081static void
1026xpc_die_disengage(void) 1082xpc_die_disengage(void)
@@ -1028,7 +1084,7 @@ xpc_die_disengage(void)
1028 struct xpc_partition *part; 1084 struct xpc_partition *part;
1029 partid_t partid; 1085 partid_t partid;
1030 unsigned long engaged; 1086 unsigned long engaged;
1031 long time, print_time, disengage_request_timeout; 1087 long time, printmsg_time, disengage_request_timeout;
1032 1088
1033 1089
1034 /* keep xpc_hb_checker thread from doing anything (just in case) */ 1090 /* keep xpc_hb_checker thread from doing anything (just in case) */
@@ -1055,57 +1111,53 @@ xpc_die_disengage(void)
1055 } 1111 }
1056 } 1112 }
1057 1113
1058 print_time = rtc_time(); 1114 time = rtc_time();
1059 disengage_request_timeout = print_time + 1115 printmsg_time = time +
1116 (XPC_DISENGAGE_PRINTMSG_INTERVAL * sn_rtc_cycles_per_second);
1117 disengage_request_timeout = time +
1060 (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second); 1118 (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second);
1061 1119
1062 /* wait for all other partitions to disengage from us */ 1120 /* wait for all other partitions to disengage from us */
1063 1121
1064 while ((engaged = xpc_partition_engaged(-1UL)) && 1122 while (1) {
1065 (time = rtc_time()) < disengage_request_timeout) { 1123 engaged = xpc_partition_engaged(-1UL);
1124 if (!engaged) {
1125 dev_info(xpc_part, "all partitions have disengaged\n");
1126 break;
1127 }
1066 1128
1067 if (time >= print_time) { 1129 time = rtc_time();
1130 if (time >= disengage_request_timeout) {
1131 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
1132 if (engaged & (1UL << partid)) {
1133 dev_info(xpc_part, "disengage from "
1134 "remote partition %d timed "
1135 "out\n", partid);
1136 }
1137 }
1138 break;
1139 }
1140
1141 if (time >= printmsg_time) {
1068 dev_info(xpc_part, "waiting for remote partitions to " 1142 dev_info(xpc_part, "waiting for remote partitions to "
1069 "disengage, engaged=0x%lx\n", engaged); 1143 "disengage, timeout in %ld seconds\n",
1070 print_time = time + (XPC_DISENGAGE_PRINTMSG_INTERVAL * 1144 (disengage_request_timeout - time) /
1145 sn_rtc_cycles_per_second);
1146 printmsg_time = time +
1147 (XPC_DISENGAGE_PRINTMSG_INTERVAL *
1071 sn_rtc_cycles_per_second); 1148 sn_rtc_cycles_per_second);
1072 } 1149 }
1073 } 1150 }
1074 dev_info(xpc_part, "finished waiting for remote partitions to "
1075 "disengage, engaged=0x%lx\n", engaged);
1076}
1077
1078
1079/*
1080 * This function is called when the system is being rebooted.
1081 */
1082static int
1083xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
1084{
1085 enum xpc_retval reason;
1086
1087
1088 switch (event) {
1089 case SYS_RESTART:
1090 reason = xpcSystemReboot;
1091 break;
1092 case SYS_HALT:
1093 reason = xpcSystemHalt;
1094 break;
1095 case SYS_POWER_OFF:
1096 reason = xpcSystemPoweroff;
1097 break;
1098 default:
1099 reason = xpcSystemGoingDown;
1100 }
1101
1102 xpc_do_exit(reason);
1103 return NOTIFY_DONE;
1104} 1151}
1105 1152
1106 1153
1107/* 1154/*
1108 * This function is called when the system is being rebooted. 1155 * This function is called when the system is being restarted or halted due
1156 * to some sort of system failure. If this is the case we need to notify the
1157 * other partitions to disengage from all references to our memory.
1158 * This function can also be called when our heartbeater could be offlined
1159 * for a time. In this case we need to notify other partitions to not worry
1160 * about the lack of a heartbeat.
1109 */ 1161 */
1110static int 1162static int
1111xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) 1163xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
@@ -1115,11 +1167,25 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
1115 case DIE_MACHINE_HALT: 1167 case DIE_MACHINE_HALT:
1116 xpc_die_disengage(); 1168 xpc_die_disengage();
1117 break; 1169 break;
1170
1171 case DIE_KDEBUG_ENTER:
1172 /* Should lack of heartbeat be ignored by other partitions? */
1173 if (!xpc_kdebug_ignore) {
1174 break;
1175 }
1176 /* fall through */
1118 case DIE_MCA_MONARCH_ENTER: 1177 case DIE_MCA_MONARCH_ENTER:
1119 case DIE_INIT_MONARCH_ENTER: 1178 case DIE_INIT_MONARCH_ENTER:
1120 xpc_vars->heartbeat++; 1179 xpc_vars->heartbeat++;
1121 xpc_vars->heartbeat_offline = 1; 1180 xpc_vars->heartbeat_offline = 1;
1122 break; 1181 break;
1182
1183 case DIE_KDEBUG_LEAVE:
1184 /* Is lack of heartbeat being ignored by other partitions? */
1185 if (!xpc_kdebug_ignore) {
1186 break;
1187 }
1188 /* fall through */
1123 case DIE_MCA_MONARCH_LEAVE: 1189 case DIE_MCA_MONARCH_LEAVE:
1124 case DIE_INIT_MONARCH_LEAVE: 1190 case DIE_INIT_MONARCH_LEAVE:
1125 xpc_vars->heartbeat++; 1191 xpc_vars->heartbeat++;
@@ -1302,7 +1368,7 @@ xpc_init(void)
1302 dev_err(xpc_part, "failed while forking discovery thread\n"); 1368 dev_err(xpc_part, "failed while forking discovery thread\n");
1303 1369
1304 /* mark this new thread as a non-starter */ 1370 /* mark this new thread as a non-starter */
1305 up(&xpc_discovery_exited); 1371 complete(&xpc_discovery_exited);
1306 1372
1307 xpc_do_exit(xpcUnloading); 1373 xpc_do_exit(xpcUnloading);
1308 return -EBUSY; 1374 return -EBUSY;
@@ -1344,3 +1410,7 @@ module_param(xpc_disengage_request_timelimit, int, 0);
1344MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait " 1410MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait "
1345 "for disengage request to complete."); 1411 "for disengage request to complete.");
1346 1412
1413module_param(xpc_kdebug_ignore, int, 0);
1414MODULE_PARM_DESC(xpc_kdebug_ignore, "Should lack of heartbeat be ignored by "
1415 "other partitions when dropping into kdebug.");
1416
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
index cdd6431853..88a730e6cf 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 d1647b863e..aa3fa5152a 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 */
20static void mark_ate(struct ate_resource *ate_resource, int start, int number, 20static 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,
119int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) 119int 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 */
142static inline uint64_t *pcibr_ate_addr(struct pcibus_info *pcibus_info, 142static 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 */
154void inline 154void inline
155ate_write(struct pcibus_info *pcibus_info, int ate_index, int count, 155ate_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,
171void pcibr_ate_free(struct pcibus_info *pcibus_info, int index) 171void 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 34093476e9..54ce5b7cee 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
42static dma_addr_t 42static dma_addr_t
43pcibr_dmamap_ate32(struct pcidev_info *info, 43pcibr_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
111static dma_addr_t 111static dma_addr_t
112pcibr_dmatrans_direct64(struct pcidev_info * info, uint64_t paddr, 112pcibr_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
143static dma_addr_t 143static dma_addr_t
144pcibr_dmatrans_direct32(struct pcidev_info * info, 144pcibr_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
212void sn_dma_flush(uint64_t addr) 212void 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 1f500c8100..2fac27049b 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -23,14 +23,16 @@ int
23sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) 23sal_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 u64 segment;
27 28
28 ret_stuff.status = 0; 29 ret_stuff.status = 0;
29 ret_stuff.v0 = 0; 30 ret_stuff.v0 = 0;
30 31
32 segment = soft->pbi_buscommon.bs_persist_segment;
31 busnum = soft->pbi_buscommon.bs_persist_busnum; 33 busnum = soft->pbi_buscommon.bs_persist_busnum;
32 SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, (u64) busnum, 34 SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, segment,
33 (u64) device, (u64) resp, 0, 0, 0, 0); 35 busnum, (u64) device, (u64) resp, 0, 0, 0);
34 36
35 return (int)ret_stuff.v0; 37 return (int)ret_stuff.v0;
36} 38}
@@ -40,15 +42,17 @@ sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action,
40 void *resp) 42 void *resp)
41{ 43{
42 struct ia64_sal_retval ret_stuff; 44 struct ia64_sal_retval ret_stuff;
43 uint64_t busnum; 45 u64 busnum;
46 u64 segment;
44 47
45 ret_stuff.status = 0; 48 ret_stuff.status = 0;
46 ret_stuff.v0 = 0; 49 ret_stuff.v0 = 0;
47 50
51 segment = soft->pbi_buscommon.bs_persist_segment;
48 busnum = soft->pbi_buscommon.bs_persist_busnum; 52 busnum = soft->pbi_buscommon.bs_persist_busnum;
49 SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE, 53 SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE,
50 (u64) busnum, (u64) device, (u64) action, 54 segment, busnum, (u64) device, (u64) action,
51 (u64) resp, 0, 0, 0); 55 (u64) resp, 0, 0);
52 56
53 return (int)ret_stuff.v0; 57 return (int)ret_stuff.v0;
54} 58}
@@ -56,7 +60,7 @@ sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action,
56static int sal_pcibr_error_interrupt(struct pcibus_info *soft) 60static int sal_pcibr_error_interrupt(struct pcibus_info *soft)
57{ 61{
58 struct ia64_sal_retval ret_stuff; 62 struct ia64_sal_retval ret_stuff;
59 uint64_t busnum; 63 u64 busnum;
60 int segment; 64 int segment;
61 ret_stuff.status = 0; 65 ret_stuff.status = 0;
62 ret_stuff.v0 = 0; 66 ret_stuff.v0 = 0;
@@ -92,7 +96,8 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
92 cnodeid_t near_cnode; 96 cnodeid_t near_cnode;
93 struct hubdev_info *hubdev_info; 97 struct hubdev_info *hubdev_info;
94 struct pcibus_info *soft; 98 struct pcibus_info *soft;
95 struct sn_flush_device_list *sn_flush_device_list; 99 struct sn_flush_device_kernel *sn_flush_device_kernel;
100 struct sn_flush_device_common *common;
96 101
97 if (! IS_PCI_BRIDGE_ASIC(prom_bussoft->bs_asic_type)) { 102 if (! IS_PCI_BRIDGE_ASIC(prom_bussoft->bs_asic_type)) {
98 return NULL; 103 return NULL;
@@ -137,20 +142,19 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
137 hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); 142 hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
138 143
139 if (hubdev_info->hdi_flush_nasid_list.widget_p) { 144 if (hubdev_info->hdi_flush_nasid_list.widget_p) {
140 sn_flush_device_list = hubdev_info->hdi_flush_nasid_list. 145 sn_flush_device_kernel = hubdev_info->hdi_flush_nasid_list.
141 widget_p[(int)soft->pbi_buscommon.bs_xid]; 146 widget_p[(int)soft->pbi_buscommon.bs_xid];
142 if (sn_flush_device_list) { 147 if (sn_flush_device_kernel) {
143 for (j = 0; j < DEV_PER_WIDGET; 148 for (j = 0; j < DEV_PER_WIDGET;
144 j++, sn_flush_device_list++) { 149 j++, sn_flush_device_kernel++) {
145 if (sn_flush_device_list->sfdl_slot == -1) 150 common = sn_flush_device_kernel->common;
151 if (common->sfdl_slot == -1)
146 continue; 152 continue;
147 if ((sn_flush_device_list-> 153 if ((common->sfdl_persistent_segment ==
148 sfdl_persistent_segment ==
149 soft->pbi_buscommon.bs_persist_segment) && 154 soft->pbi_buscommon.bs_persist_segment) &&
150 (sn_flush_device_list-> 155 (common->sfdl_persistent_busnum ==
151 sfdl_persistent_busnum ==
152 soft->pbi_buscommon.bs_persist_busnum)) 156 soft->pbi_buscommon.bs_persist_busnum))
153 sn_flush_device_list->sfdl_pcibus_info = 157 common->sfdl_pcibus_info =
154 soft; 158 soft;
155 } 159 }
156 } 160 }
@@ -159,9 +163,9 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
159 /* Setup the PMU ATE map */ 163 /* Setup the PMU ATE map */
160 soft->pbi_int_ate_resource.lowest_free_index = 0; 164 soft->pbi_int_ate_resource.lowest_free_index = 0;
161 soft->pbi_int_ate_resource.ate = 165 soft->pbi_int_ate_resource.ate =
162 kmalloc(soft->pbi_int_ate_size * sizeof(uint64_t), GFP_KERNEL); 166 kmalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL);
163 memset(soft->pbi_int_ate_resource.ate, 0, 167 memset(soft->pbi_int_ate_resource.ate, 0,
164 (soft->pbi_int_ate_size * sizeof(uint64_t))); 168 (soft->pbi_int_ate_size * sizeof(u64)));
165 169
166 if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) { 170 if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) {
167 /* TIO PCI Bridge: find nearest node with CPUs */ 171 /* TIO PCI Bridge: find nearest node with CPUs */
@@ -203,7 +207,7 @@ void pcibr_target_interrupt(struct sn_irq_info *sn_irq_info)
203 struct pcidev_info *pcidev_info; 207 struct pcidev_info *pcidev_info;
204 struct pcibus_info *pcibus_info; 208 struct pcibus_info *pcibus_info;
205 int bit = sn_irq_info->irq_int_bit; 209 int bit = sn_irq_info->irq_int_bit;
206 uint64_t xtalk_addr = sn_irq_info->irq_xtalkaddr; 210 u64 xtalk_addr = sn_irq_info->irq_xtalkaddr;
207 211
208 pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; 212 pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
209 if (pcidev_info) { 213 if (pcidev_info) {
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
index 5d53409126..8b8bbd51d4 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
@@ -23,9 +23,9 @@ union br_ptr {
23/* 23/*
24 * Control Register Access -- Read/Write 0000_0020 24 * Control Register Access -- Read/Write 0000_0020
25 */ 25 */
26void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) 26void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, u64 bits)
27{ 27{
28 union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; 28 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
29 29
30 if (pcibus_info) { 30 if (pcibus_info) {
31 switch (pcibus_info->pbi_bridge_type) { 31 switch (pcibus_info->pbi_bridge_type) {
@@ -38,14 +38,14 @@ void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits)
38 default: 38 default:
39 panic 39 panic
40 ("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p", 40 ("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p",
41 (void *)ptr); 41 ptr);
42 } 42 }
43 } 43 }
44} 44}
45 45
46void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) 46void pcireg_control_bit_set(struct pcibus_info *pcibus_info, u64 bits)
47{ 47{
48 union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; 48 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
49 49
50 if (pcibus_info) { 50 if (pcibus_info) {
51 switch (pcibus_info->pbi_bridge_type) { 51 switch (pcibus_info->pbi_bridge_type) {
@@ -58,7 +58,7 @@ void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits)
58 default: 58 default:
59 panic 59 panic
60 ("pcireg_control_bit_set: unknown bridgetype bridge 0x%p", 60 ("pcireg_control_bit_set: unknown bridgetype bridge 0x%p",
61 (void *)ptr); 61 ptr);
62 } 62 }
63 } 63 }
64} 64}
@@ -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 */
69uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info) 69u64 pcireg_tflush_get(struct pcibus_info *pcibus_info)
70{ 70{
71 union br_ptr *ptr = (union br_ptr *)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) {
@@ -82,7 +82,7 @@ uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info)
82 default: 82 default:
83 panic 83 panic
84 ("pcireg_tflush_get: unknown bridgetype bridge 0x%p", 84 ("pcireg_tflush_get: unknown bridgetype bridge 0x%p",
85 (void *)ptr); 85 ptr);
86 } 86 }
87 } 87 }
88 88
@@ -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 */
99uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info) 99u64 pcireg_intr_status_get(struct pcibus_info * pcibus_info)
100{ 100{
101 union br_ptr *ptr = (union br_ptr *)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) {
@@ -112,7 +112,7 @@ uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info)
112 default: 112 default:
113 panic 113 panic
114 ("pcireg_intr_status_get: unknown bridgetype bridge 0x%p", 114 ("pcireg_intr_status_get: unknown bridgetype bridge 0x%p",
115 (void *)ptr); 115 ptr);
116 } 116 }
117 } 117 }
118 return ret; 118 return ret;
@@ -121,9 +121,9 @@ 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 */
124void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) 124void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, u64 bits)
125{ 125{
126 union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; 126 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
127 127
128 if (pcibus_info) { 128 if (pcibus_info) {
129 switch (pcibus_info->pbi_bridge_type) { 129 switch (pcibus_info->pbi_bridge_type) {
@@ -136,14 +136,14 @@ void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits)
136 default: 136 default:
137 panic 137 panic
138 ("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p", 138 ("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p",
139 (void *)ptr); 139 ptr);
140 } 140 }
141 } 141 }
142} 142}
143 143
144void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) 144void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, u64 bits)
145{ 145{
146 union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; 146 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
147 147
148 if (pcibus_info) { 148 if (pcibus_info) {
149 switch (pcibus_info->pbi_bridge_type) { 149 switch (pcibus_info->pbi_bridge_type) {
@@ -156,7 +156,7 @@ void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits)
156 default: 156 default:
157 panic 157 panic
158 ("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p", 158 ("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p",
159 (void *)ptr); 159 ptr);
160 } 160 }
161 } 161 }
162} 162}
@@ -165,9 +165,9 @@ 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 */
167void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n, 167void 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 *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; 170 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
171 171
172 if (pcibus_info) { 172 if (pcibus_info) {
173 switch (pcibus_info->pbi_bridge_type) { 173 switch (pcibus_info->pbi_bridge_type) {
@@ -186,7 +186,7 @@ void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n,
186 default: 186 default:
187 panic 187 panic
188 ("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p", 188 ("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p",
189 (void *)ptr); 189 ptr);
190 } 190 }
191 } 191 }
192} 192}
@@ -196,7 +196,7 @@ void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n,
196 */ 196 */
197void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n) 197void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n)
198{ 198{
199 union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; 199 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
200 200
201 if (pcibus_info) { 201 if (pcibus_info) {
202 switch (pcibus_info->pbi_bridge_type) { 202 switch (pcibus_info->pbi_bridge_type) {
@@ -209,7 +209,7 @@ void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n)
209 default: 209 default:
210 panic 210 panic
211 ("pcireg_force_intr_set: unknown bridgetype bridge 0x%p", 211 ("pcireg_force_intr_set: unknown bridgetype bridge 0x%p",
212 (void *)ptr); 212 ptr);
213 } 213 }
214 } 214 }
215} 215}
@@ -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 */
220uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) 220u64 pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device)
221{ 221{
222 union br_ptr *ptr = (union br_ptr *)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) {
@@ -233,7 +233,7 @@ uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device)
233 __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]); 233 __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]);
234 break; 234 break;
235 default: 235 default:
236 panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", (void *)ptr); 236 panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", ptr);
237 } 237 }
238 238
239 } 239 }
@@ -242,9 +242,9 @@ uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device)
242} 242}
243 243
244void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index, 244void 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 *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; 247 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
248 248
249 if (pcibus_info) { 249 if (pcibus_info) {
250 switch (pcibus_info->pbi_bridge_type) { 250 switch (pcibus_info->pbi_bridge_type) {
@@ -257,15 +257,15 @@ void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index,
257 default: 257 default:
258 panic 258 panic
259 ("pcireg_int_ate_set: unknown bridgetype bridge 0x%p", 259 ("pcireg_int_ate_set: unknown bridgetype bridge 0x%p",
260 (void *)ptr); 260 ptr);
261 } 261 }
262 } 262 }
263} 263}
264 264
265uint64_t *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index) 265u64 __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index)
266{ 266{
267 union br_ptr *ptr = (union br_ptr *)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 *ret = (uint64_t *) 0; 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) {
@@ -278,7 +278,7 @@ uint64_t *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index)
278 default: 278 default:
279 panic 279 panic
280 ("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p", 280 ("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p",
281 (void *)ptr); 281 ptr);
282 } 282 }
283 } 283 }
284 return ret; 284 return ret;
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index 46b646a6d3..7571a40255 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
19uint32_t tioca_gart_found; 19u32 tioca_gart_found;
20EXPORT_SYMBOL(tioca_gart_found); /* used by agp-sgi */ 20EXPORT_SYMBOL(tioca_gart_found); /* used by agp-sgi */
21 21
22LIST_HEAD(tioca_list); 22LIST_HEAD(tioca_list);
@@ -34,14 +34,14 @@ static int tioca_gart_init(struct tioca_kernel *);
34static int 34static int
35tioca_gart_init(struct tioca_kernel *tioca_kern) 35tioca_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 *ca_base; 41 struct tioca __iomem *ca_base;
42 42
43 tioca_common = tioca_kern->ca_common; 43 tioca_common = tioca_kern->ca_common;
44 ca_base = (struct tioca *)tioca_common->ca_common.bs_base; 44 ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
45 45
46 if (list_empty(tioca_kern->ca_devices)) 46 if (list_empty(tioca_kern->ca_devices))
47 return 0; 47 return 0;
@@ -214,8 +214,8 @@ void
214tioca_fastwrite_enable(struct tioca_kernel *tioca_kern) 214tioca_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 *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;
221 221
@@ -257,7 +257,7 @@ tioca_fastwrite_enable(struct tioca_kernel *tioca_kern)
257 * Set ca's fw to match 257 * Set ca's fw to match
258 */ 258 */
259 259
260 tioca_base = (struct tioca *)common->ca_common.bs_base; 260 tioca_base = (struct tioca __iomem*)common->ca_common.bs_base;
261 __sn_setq_relaxed(&tioca_base->ca_control1, CA_AGP_FW_ENABLE); 261 __sn_setq_relaxed(&tioca_base->ca_control1, CA_AGP_FW_ENABLE);
262} 262}
263 263
@@ -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 */
279static uint64_t 279static u64
280tioca_dma_d64(unsigned long paddr) 280tioca_dma_d64(unsigned long paddr)
281{ 281{
282 dma_addr_t bus_addr; 282 dma_addr_t bus_addr;
@@ -318,19 +318,19 @@ 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 */
321static uint64_t 321static u64
322tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) 322tioca_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 *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;
333 ca_base = (struct tioca *)tioca_common->ca_common.bs_base; 333 ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
334 334
335 ct_addr = PHYS_TO_TIODMA(paddr); 335 ct_addr = PHYS_TO_TIODMA(paddr);
336 if (!ct_addr) 336 if (!ct_addr)
@@ -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 */
369static dma_addr_t 369static dma_addr_t
370tioca_dma_mapped(struct pci_dev *pdev, uint64_t paddr, size_t req_size) 370tioca_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 */
517static uint64_t 517static u64
518tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) 518tioca_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 dda196c9e3..e52831ed93 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 */
84static uint64_t 84static u64
85tioce_dma_d64(unsigned long ct_addr) 85tioce_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 */
144static uint64_t 144static u64
145tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, 145tioce_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 */
255static uint64_t 255static u64
256tioce_dma_d32(struct pci_dev *pdev, uint64_t ct_addr) 256tioce_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 */
298static uint64_t 298static u64
299tioce_dma_barrier(uint64_t bus_addr, int on) 299tioce_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 */
388static uint64_t 388static u64
389tioce_do_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count, 389tioce_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 */
504static uint64_t 504static u64
505tioce_dma(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) 505tioce_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
519tioce_dma_consistent(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) 519tioce_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)
551tioce_kern_init(struct tioce_common *tioce_common) 551tioce_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));