[PATCH] irq-flags: IA64: Use the new IRQF_ constants
[deliverable/linux.git] / arch / ia64 / sn / kernel / huberror.c
CommitLineData
1da177e4
LT
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 *
93a07d0a 6 * Copyright (C) 1992 - 1997, 2000,2002-2005 Silicon Graphics, Inc. All rights reserved.
1da177e4
LT
7 */
8
9#include <linux/types.h>
10#include <linux/interrupt.h>
11#include <linux/pci.h>
12#include <asm/delay.h>
13#include <asm/sn/sn_sal.h>
14#include "ioerror.h"
15#include <asm/sn/addrs.h>
16#include <asm/sn/shubio.h>
17#include <asm/sn/geo.h>
18#include "xtalk/xwidgetdev.h"
19#include "xtalk/hubdev.h"
20#include <asm/sn/bte.h>
21
22void hubiio_crb_error_handler(struct hubdev_info *hubdev_info);
23extern void bte_crb_error_handler(cnodeid_t, int, int, ioerror_t *,
24 int);
25static irqreturn_t hub_eint_handler(int irq, void *arg, struct pt_regs *ep)
26{
27 struct hubdev_info *hubdev_info;
28 struct ia64_sal_retval ret_stuff;
29 nasid_t nasid;
30
31 ret_stuff.status = 0;
32 ret_stuff.v0 = 0;
33 hubdev_info = (struct hubdev_info *)arg;
34 nasid = hubdev_info->hdi_nasid;
17e8ce0e
RA
35
36 if (is_shub1()) {
37 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT,
1da177e4
LT
38 (u64) nasid, 0, 0, 0, 0, 0, 0);
39
17e8ce0e
RA
40 if ((int)ret_stuff.v0)
41 panic("hubii_eint_handler(): Fatal TIO Error");
1da177e4 42
93a07d0a
RA
43 if (!(nasid & 1)) /* Not a TIO, handle CRB errors */
44 (void)hubiio_crb_error_handler(hubdev_info);
45 } else
46 bte_error_handler((unsigned long)NODEPDA(nasid_to_cnodeid(nasid)));
1da177e4
LT
47
48 return IRQ_HANDLED;
49}
50
51/*
52 * Free the hub CRB "crbnum" which encountered an error.
53 * Assumption is, error handling was successfully done,
54 * and we now want to return the CRB back to Hub for normal usage.
55 *
56 * In order to free the CRB, all that's needed is to de-allocate it
57 *
58 * Assumption:
59 * No other processor is mucking around with the hub control register.
60 * So, upper layer has to single thread this.
61 */
62void hubiio_crb_free(struct hubdev_info *hubdev_info, int crbnum)
63{
64 ii_icrb0_b_u_t icrbb;
65
66 /*
67 * The hardware does NOT clear the mark bit, so it must get cleared
68 * here to be sure the error is not processed twice.
69 */
70 icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(hubdev_info->hdi_nasid,
71 IIO_ICRB_B(crbnum));
72 icrbb.b_mark = 0;
73 REMOTE_HUB_S(hubdev_info->hdi_nasid, IIO_ICRB_B(crbnum),
74 icrbb.ii_icrb0_b_regval);
75 /*
76 * Deallocate the register wait till hub indicates it's done.
77 */
78 REMOTE_HUB_S(hubdev_info->hdi_nasid, IIO_ICDR, (IIO_ICDR_PND | crbnum));
79 while (REMOTE_HUB_L(hubdev_info->hdi_nasid, IIO_ICDR) & IIO_ICDR_PND)
68b9753f 80 cpu_relax();
1da177e4
LT
81
82}
83
84/*
85 * hubiio_crb_error_handler
86 *
87 * This routine gets invoked when a hub gets an error
88 * interrupt. So, the routine is running in interrupt context
89 * at error interrupt level.
90 * Action:
91 * It's responsible for identifying ALL the CRBs that are marked
92 * with error, and process them.
93 *
94 * If you find the CRB that's marked with error, map this to the
95 * reason it caused error, and invoke appropriate error handler.
96 *
97 * XXX Be aware of the information in the context register.
98 *
99 * NOTE:
100 * Use REMOTE_HUB_* macro instead of LOCAL_HUB_* so that the interrupt
101 * handler can be run on any node. (not necessarily the node
102 * corresponding to the hub that encountered error).
103 */
104
105void hubiio_crb_error_handler(struct hubdev_info *hubdev_info)
106{
107 nasid_t nasid;
108 ii_icrb0_a_u_t icrba; /* II CRB Register A */
109 ii_icrb0_b_u_t icrbb; /* II CRB Register B */
110 ii_icrb0_c_u_t icrbc; /* II CRB Register C */
111 ii_icrb0_d_u_t icrbd; /* II CRB Register D */
112 ii_icrb0_e_u_t icrbe; /* II CRB Register D */
113 int i;
114 int num_errors = 0; /* Num of errors handled */
115 ioerror_t ioerror;
116
117 nasid = hubdev_info->hdi_nasid;
118
119 /*
120 * XXX - Add locking for any recovery actions
121 */
122 /*
123 * Scan through all CRBs in the Hub, and handle the errors
124 * in any of the CRBs marked.
125 */
126 for (i = 0; i < IIO_NUM_CRBS; i++) {
127 /* Check this crb entry to see if it is in error. */
128 icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(nasid, IIO_ICRB_B(i));
129
130 if (icrbb.b_mark == 0) {
131 continue;
132 }
133
134 icrba.ii_icrb0_a_regval = REMOTE_HUB_L(nasid, IIO_ICRB_A(i));
135
136 IOERROR_INIT(&ioerror);
137
138 /* read other CRB error registers. */
139 icrbc.ii_icrb0_c_regval = REMOTE_HUB_L(nasid, IIO_ICRB_C(i));
140 icrbd.ii_icrb0_d_regval = REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
141 icrbe.ii_icrb0_e_regval = REMOTE_HUB_L(nasid, IIO_ICRB_E(i));
142
143 IOERROR_SETVALUE(&ioerror, errortype, icrbb.b_ecode);
144
145 /* Check if this error is due to BTE operation,
146 * and handle it separately.
147 */
148 if (icrbd.d_bteop ||
149 ((icrbb.b_initiator == IIO_ICRB_INIT_BTE0 ||
150 icrbb.b_initiator == IIO_ICRB_INIT_BTE1) &&
151 (icrbb.b_imsgtype == IIO_ICRB_IMSGT_BTE ||
152 icrbb.b_imsgtype == IIO_ICRB_IMSGT_SN1NET))) {
153
154 int bte_num;
155
156 if (icrbd.d_bteop)
157 bte_num = icrbc.c_btenum;
158 else /* b_initiator bit 2 gives BTE number */
159 bte_num = (icrbb.b_initiator & 0x4) >> 2;
160
161 hubiio_crb_free(hubdev_info, i);
162
163 bte_crb_error_handler(nasid_to_cnodeid(nasid), bte_num,
164 i, &ioerror, icrbd.d_bteop);
165 num_errors++;
166 continue;
167 }
168 }
169}
170
171/*
172 * Function : hub_error_init
173 * Purpose : initialize the error handling requirements for a given hub.
174 * Parameters : cnode, the compact nodeid.
175 * Assumptions : Called only once per hub, either by a local cpu. Or by a
176 * remote cpu, when this hub is headless.(cpuless)
177 * Returns : None
178 */
179void hub_error_init(struct hubdev_info *hubdev_info)
180{
121a4226 181 if (request_irq(SGI_II_ERROR, (void *)hub_eint_handler, IRQF_SHARED,
1da177e4
LT
182 "SN_hub_error", (void *)hubdev_info))
183 printk("hub_error_init: Failed to request_irq for 0x%p\n",
184 hubdev_info);
185 return;
186}
187
188
189/*
190 * Function : ice_error_init
191 * Purpose : initialize the error handling requirements for a given tio.
192 * Parameters : cnode, the compact nodeid.
193 * Assumptions : Called only once per tio.
194 * Returns : None
195 */
196void ice_error_init(struct hubdev_info *hubdev_info)
197{
198 if (request_irq
121a4226 199 (SGI_TIO_ERROR, (void *)hub_eint_handler, IRQF_SHARED, "SN_TIO_error",
1da177e4
LT
200 (void *)hubdev_info))
201 printk("ice_error_init: request_irq() error hubdev_info 0x%p\n",
202 hubdev_info);
203 return;
204}
205
This page took 0.233676 seconds and 5 git commands to generate.