1
2
3
4
5
6
7
8
9#include <linux/types.h>
10#include <linux/interrupt.h>
11#include <asm/delay.h>
12#include <asm/sn/sn_sal.h>
13#include "ioerror.h"
14#include <asm/sn/addrs.h>
15#include <asm/sn/shubio.h>
16#include <asm/sn/geo.h>
17#include "xtalk/xwidgetdev.h"
18#include "xtalk/hubdev.h"
19#include <asm/sn/bte.h>
20
21void hubiio_crb_error_handler(struct hubdev_info *hubdev_info);
22extern void bte_crb_error_handler(cnodeid_t, int, int, ioerror_t *,
23 int);
24static irqreturn_t hub_eint_handler(int irq, void *arg)
25{
26 struct hubdev_info *hubdev_info;
27 struct ia64_sal_retval ret_stuff;
28 nasid_t nasid;
29
30 ret_stuff.status = 0;
31 ret_stuff.v0 = 0;
32 hubdev_info = (struct hubdev_info *)arg;
33 nasid = hubdev_info->hdi_nasid;
34
35 if (is_shub1()) {
36 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT,
37 (u64) nasid, 0, 0, 0, 0, 0, 0);
38
39 if ((int)ret_stuff.v0)
40 panic("%s: Fatal %s Error", __func__,
41 ((nasid & 1) ? "TIO" : "HUBII"));
42
43 if (!(nasid & 1))
44 (void)hubiio_crb_error_handler(hubdev_info);
45 } else
46 if (nasid & 1) {
47 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT,
48 (u64) nasid, 0, 0, 0, 0, 0, 0);
49
50 if ((int)ret_stuff.v0)
51 panic("%s: Fatal TIO Error", __func__);
52 } else
53 bte_error_handler((unsigned long)NODEPDA(nasid_to_cnodeid(nasid)));
54
55 return IRQ_HANDLED;
56}
57
58
59
60
61
62
63
64
65
66
67
68
69void hubiio_crb_free(struct hubdev_info *hubdev_info, int crbnum)
70{
71 ii_icrb0_b_u_t icrbb;
72
73
74
75
76
77 icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(hubdev_info->hdi_nasid,
78 IIO_ICRB_B(crbnum));
79 icrbb.b_mark = 0;
80 REMOTE_HUB_S(hubdev_info->hdi_nasid, IIO_ICRB_B(crbnum),
81 icrbb.ii_icrb0_b_regval);
82
83
84
85 REMOTE_HUB_S(hubdev_info->hdi_nasid, IIO_ICDR, (IIO_ICDR_PND | crbnum));
86 while (REMOTE_HUB_L(hubdev_info->hdi_nasid, IIO_ICDR) & IIO_ICDR_PND)
87 cpu_relax();
88
89}
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112void hubiio_crb_error_handler(struct hubdev_info *hubdev_info)
113{
114 nasid_t nasid;
115 ii_icrb0_a_u_t icrba;
116 ii_icrb0_b_u_t icrbb;
117 ii_icrb0_c_u_t icrbc;
118 ii_icrb0_d_u_t icrbd;
119 ii_icrb0_e_u_t icrbe;
120 int i;
121 int num_errors = 0;
122 ioerror_t ioerror;
123
124 nasid = hubdev_info->hdi_nasid;
125
126
127
128
129
130
131
132
133 for (i = 0; i < IIO_NUM_CRBS; i++) {
134
135 icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(nasid, IIO_ICRB_B(i));
136
137 if (icrbb.b_mark == 0) {
138 continue;
139 }
140
141 icrba.ii_icrb0_a_regval = REMOTE_HUB_L(nasid, IIO_ICRB_A(i));
142
143 IOERROR_INIT(&ioerror);
144
145
146 icrbc.ii_icrb0_c_regval = REMOTE_HUB_L(nasid, IIO_ICRB_C(i));
147 icrbd.ii_icrb0_d_regval = REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
148 icrbe.ii_icrb0_e_regval = REMOTE_HUB_L(nasid, IIO_ICRB_E(i));
149
150 IOERROR_SETVALUE(&ioerror, errortype, icrbb.b_ecode);
151
152
153
154
155 if (icrbd.d_bteop ||
156 ((icrbb.b_initiator == IIO_ICRB_INIT_BTE0 ||
157 icrbb.b_initiator == IIO_ICRB_INIT_BTE1) &&
158 (icrbb.b_imsgtype == IIO_ICRB_IMSGT_BTE ||
159 icrbb.b_imsgtype == IIO_ICRB_IMSGT_SN1NET))) {
160
161 int bte_num;
162
163 if (icrbd.d_bteop)
164 bte_num = icrbc.c_btenum;
165 else
166 bte_num = (icrbb.b_initiator & 0x4) >> 2;
167
168 hubiio_crb_free(hubdev_info, i);
169
170 bte_crb_error_handler(nasid_to_cnodeid(nasid), bte_num,
171 i, &ioerror, icrbd.d_bteop);
172 num_errors++;
173 continue;
174 }
175 }
176}
177
178
179
180
181
182
183
184
185
186void hub_error_init(struct hubdev_info *hubdev_info)
187{
188
189 if (request_irq(SGI_II_ERROR, hub_eint_handler, IRQF_SHARED,
190 "SN_hub_error", hubdev_info)) {
191 printk(KERN_ERR "hub_error_init: Failed to request_irq for 0x%p\n",
192 hubdev_info);
193 return;
194 }
195 sn_set_err_irq_affinity(SGI_II_ERROR);
196}
197
198
199
200
201
202
203
204
205
206void ice_error_init(struct hubdev_info *hubdev_info)
207{
208
209 if (request_irq
210 (SGI_TIO_ERROR, (void *)hub_eint_handler, IRQF_SHARED, "SN_TIO_error",
211 (void *)hubdev_info)) {
212 printk("ice_error_init: request_irq() error hubdev_info 0x%p\n",
213 hubdev_info);
214 return;
215 }
216 sn_set_err_irq_affinity(SGI_TIO_ERROR);
217}
218
219