4 * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it would be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * Further, this software is distributed without any warranty that it is
15 * free of the rightful claim of any third person regarding infringement
16 * or the like. Any license provided herein, whether implied or
17 * otherwise, applies only to this software file. Patent licenses, if
18 * any, provided herein do not apply to combinations of this program with
19 * other software, or any other product whatsoever.
21 * You should have received a copy of the GNU General Public
22 * License along with this program; if not, write the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
25 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
26 * Mountain View, CA 94043, or:
30 * For further information regarding this notice, see:
32 * http://oss.sgi.com/projects/GenInfo/NoticeExplan
36 #include <linux/types.h>
37 #include <linux/slab.h>
39 #include <asm/sn/sgi.h>
40 #include <asm/sn/io.h>
41 #include <asm/sn/iograph.h>
42 #include <asm/sn/invent.h>
43 #include <asm/sn/hcl.h>
44 #include <asm/sn/labelcl.h>
45 #include <asm/sn/sn_private.h>
46 #include <asm/sn/klconfig.h>
47 #include <asm/sn/sn_cpuid.h>
48 #include <asm/sn/pci/pciio.h>
49 #include <asm/sn/pci/pcibr.h>
50 #include <asm/sn/xtalk/xtalk.h>
51 #include <asm/sn/pci/pcibr_private.h>
52 #include <asm/sn/intr.h>
53 #include <asm/sn/ioerror.h>
54 #include <asm/sn/sn2/shubio.h>
55 #include <asm/sn/bte.h>
59 * Bte error handling is done in two parts. The first captures
60 * any crb related errors. Since there can be multiple crbs per
61 * interface and multiple interfaces active, we need to wait until
62 * all active crbs are completed. This is the first job of the
63 * second part error handler. When all bte related CRBs are cleanly
64 * completed, it resets the interfaces and gets them ready for new
65 * transfers to be queued.
69 void bte_error_handler(unsigned long);
73 * First part error handler. This is called whenever any error CRB interrupt
74 * is generated by the II.
77 bte_crb_error_handler(vertex_hdl_t hub_v, int btenum,
78 int crbnum, ioerror_t * ioe, int bteop)
81 struct bteinfo_s *bte;
84 hubinfo_get(hub_v, &hinfo);
85 bte = &hinfo->h_nodepda->bte_if[btenum];
88 * The caller has already figured out the error type, we save that
89 * in the bte handle structure for the thread excercising the
90 * interface to consume.
92 switch (ioe->ie_errortype) {
93 case IIO_ICRB_ECODE_PERR:
94 bte->bh_error = BTEFAIL_POISON;
96 case IIO_ICRB_ECODE_WERR:
97 bte->bh_error = BTEFAIL_PROT;
99 case IIO_ICRB_ECODE_AERR:
100 bte->bh_error = BTEFAIL_ACCESS;
102 case IIO_ICRB_ECODE_TOUT:
103 bte->bh_error = BTEFAIL_TOUT;
105 case IIO_ICRB_ECODE_XTERR:
106 bte->bh_error = BTEFAIL_XTERR;
108 case IIO_ICRB_ECODE_DERR:
109 bte->bh_error = BTEFAIL_DIR;
111 case IIO_ICRB_ECODE_PWERR:
112 case IIO_ICRB_ECODE_PRERR:
115 bte->bh_error = BTEFAIL_ERROR;
118 bte->bte_error_count++;
120 BTE_PRINTK(("Got an error on cnode %d bte %d\n",
121 bte->bte_cnode, bte->bte_num));
122 bte_error_handler((unsigned long) hinfo->h_nodepda);
127 * Second part error handler. Wait until all BTE related CRBs are completed
128 * and then reset the interfaces.
131 bte_error_handler(unsigned long _nodepda)
133 struct nodepda_s *err_nodepda = (struct nodepda_s *) _nodepda;
134 spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock;
135 struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
139 unsigned long irq_flags;
140 volatile u64 *notify;
141 bte_result_t bh_error;
142 ii_imem_u_t imem; /* II IMEM Register */
143 ii_icrb0_d_u_t icrbd; /* II CRB Register D */
148 BTE_PRINTK(("bte_error_handler(%p) - %d\n", err_nodepda,
149 smp_processor_id()));
151 spin_lock_irqsave(recovery_lock, irq_flags);
153 if ((err_nodepda->bte_if[0].bh_error == BTE_SUCCESS) &&
154 (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) {
155 BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda,
156 smp_processor_id()));
157 spin_unlock_irqrestore(recovery_lock, irq_flags);
161 * Lock all interfaces on this node to prevent new transfers
164 for (i = 0; i < BTES_PER_NODE; i++) {
165 if (err_nodepda->bte_if[i].cleanup_active) {
168 spin_lock(&err_nodepda->bte_if[i].spinlock);
169 BTE_PRINTK(("eh:%p:%d locked %d\n", err_nodepda,
170 smp_processor_id(), i));
171 err_nodepda->bte_if[i].cleanup_active = 1;
174 /* Determine information about our hub */
175 nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode);
179 * A BTE transfer can use multiple CRBs. We need to make sure
180 * that all the BTE CRBs are complete (or timed out) before
181 * attempting to clean up the error. Resetting the BTE while
182 * there are still BTE CRBs active will hang the BTE.
183 * We should look at all the CRBs to see if they are allocated
184 * to the BTE and see if they are still active. When none
185 * are active, we can continue with the cleanup.
187 * We also want to make sure that the local NI port is up.
188 * When a router resets the NI port can go down, while it
189 * goes through the LLP handshake, but then comes back up.
191 icmr.ii_icmr_regval = REMOTE_HUB_L(nasid, IIO_ICMR);
192 if (icmr.ii_icmr_fld_s.i_crb_mark != 0) {
194 * There are errors which still need to be cleaned up by
195 * hubiio_crb_error_handler
197 mod_timer(recovery_timer, HZ * 5);
198 BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
199 smp_processor_id()));
200 spin_unlock_irqrestore(recovery_lock, irq_flags);
203 if (icmr.ii_icmr_fld_s.i_crb_vld != 0) {
205 valid_crbs = icmr.ii_icmr_fld_s.i_crb_vld;
207 for (i = 0; i < IIO_NUM_CRBS; i++) {
208 if (!((1 << i) & valid_crbs)) {
209 /* This crb was not marked as valid, ignore */
212 icrbd.ii_icrb0_d_regval =
213 REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
215 mod_timer(recovery_timer, HZ * 5);
216 BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n",
217 err_nodepda, smp_processor_id(), i));
218 spin_unlock_irqrestore(recovery_lock,
226 BTE_PRINTK(("eh:%p:%d Cleaning up\n", err_nodepda,
227 smp_processor_id()));
228 /* Reenable both bte interfaces */
229 imem.ii_imem_regval = REMOTE_HUB_L(nasid, IIO_IMEM);
230 imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1;
231 REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval);
233 /* Reinitialize both BTE state machines. */
234 ibcr.ii_ibcr_regval = REMOTE_HUB_L(nasid, IIO_IBCR);
235 ibcr.ii_ibcr_fld_s.i_soft_reset = 1;
236 REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval);
239 for (i = 0; i < BTES_PER_NODE; i++) {
240 bh_error = err_nodepda->bte_if[i].bh_error;
241 if (bh_error != BTE_SUCCESS) {
242 /* There is an error which needs to be notified */
243 notify = err_nodepda->bte_if[i].most_rcnt_na;
244 BTE_PRINTK(("cnode %d bte %d error=0x%lx\n",
245 err_nodepda->bte_if[i].bte_cnode,
246 err_nodepda->bte_if[i].bte_num,
247 IBLS_ERROR | (u64) bh_error));
248 *notify = IBLS_ERROR | bh_error;
249 err_nodepda->bte_if[i].bh_error = BTE_SUCCESS;
252 err_nodepda->bte_if[i].cleanup_active = 0;
253 BTE_PRINTK(("eh:%p:%d Unlocked %d\n", err_nodepda,
254 smp_processor_id(), i));
255 spin_unlock(&pda.cpu_bte_if[i]->spinlock);
258 del_timer(recovery_timer);
260 spin_unlock_irqrestore(recovery_lock, irq_flags);