]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/sys/dev/hfa/fore_intr.c
merge fix for boot-time hang on centos' xen
[FreeBSD/FreeBSD.git] / 6 / sys / dev / hfa / fore_intr.c
1 /*-
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
8  * This Host ATM Research Platform ("HARP") file (the "Software") is
9  * made available by Network Computing Services, Inc. ("NetworkCS")
10  * "AS IS".  NetworkCS does not provide maintenance, improvements or
11  * support of any kind.
12  *
13  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17  * In no event shall NetworkCS be responsible for any damages, including
18  * but not limited to consequential damages, arising from or relating to
19  * any use of the Software or related support.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD$
27  *
28  */
29
30 /*
31  * FORE Systems 200-Series Adapter Support
32  * ---------------------------------------
33  *
34  * Interrupt processing
35  *
36  */
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/socket.h>
41 #include <net/if.h>
42 #include <netatm/port.h>
43 #include <netatm/queue.h>
44 #include <netatm/atm.h>
45 #include <netatm/atm_sys.h>
46 #include <netatm/atm_cm.h>
47 #include <netatm/atm_if.h>
48 #include <dev/pci/pcivar.h>
49 #include <dev/hfa/fore.h>
50 #include <dev/hfa/fore_aali.h>
51 #include <dev/hfa/fore_slave.h>
52 #include <dev/hfa/fore_stats.h>
53 #include <dev/hfa/fore_var.h>
54 #include <dev/hfa/fore_include.h>
55
56 #ifndef lint
57 __RCSID("@(#) $FreeBSD$");
58 #endif
59
60 #if defined(sun)
61 /*
62  * Polling interrupt routine
63  * 
64  * Polling interrupts are handled by calling all interrupt service 
65  * routines for a given level until someone claims to have "handled" the 
66  * interrupt.
67  *
68  * Called at interrupt level.
69  *
70  * Arguments:
71  *      none
72  *
73  * Returns:
74  *      1               an interrupt has been serviced
75  *      0               no interrupts serviced
76  *
77  */
78 int
79 fore_poll()
80 {
81         int     serviced = 0;
82         int     unit;
83
84         /*
85          * See if any of our devices are interrupting
86          */
87         for ( unit = 0; unit < fore_nunits; unit++ )
88         {
89                 Fore_unit       *fup = fore_units[unit];
90
91                 if (fup == NULL)
92                         continue;
93
94                 serviced += fore_intr((void *)fup);
95         }
96
97         /*
98          * Indicate if we handled an interrupt
99          */
100         return (serviced ? 1 : 0);
101 }
102 #endif  /* defined(sun) */
103
104
105 /*
106  * Device interrupt routine
107  * 
108  * Called at interrupt level.
109  *
110  * Arguments:
111  *      arg             pointer to device unit structure
112  *
113  * Returns:
114  *      1               device interrupt was serviced
115  *      0               no interrupts serviced
116  *
117  */
118 #if (defined(BSD) && (BSD <= 199306))
119 int
120 #else
121 void
122 #endif
123 fore_intr(arg)
124         void    *arg;
125 {
126         Fore_unit       *fup = arg;
127         Aali    *aap;
128 #if (defined(BSD) && (BSD <= 199306))
129         int     serviced = 0;
130 #endif
131
132         /*
133          * Try to prevent stuff happening after we've paniced
134          */
135         if (panicstr) {
136                 goto done;
137         }
138
139         /*
140          * Get to the microcode shared memory interface
141          */
142         if ((aap = fup->fu_aali) == NULL)
143                 goto done;
144
145         /*
146          * Has this card issued an interrupt??
147          */
148         if (*fup->fu_psr) {
149
150                 /*
151                  * Indicate that we've serviced an interrupt. 
152                  */
153 #if (defined(BSD) && (BSD <= 199306))
154                 serviced = 1;
155 #endif
156
157                 /*
158                  * Clear the device interrupt
159                  */
160                 if (fup->fu_config.ac_device == DEV_FORE_PCA200E)
161                         PCA200E_HCR_SET(*fup->fu_ctlreg, PCA200E_CLR_HBUS_INT);
162                 aap->aali_intr_sent = CP_WRITE(0);
163
164                 /*
165                  * Reset the watchdog timer
166                  */
167                 fup->fu_timer = FORE_WATCHDOG;
168
169                 /*
170                  * Device initialization handled separately
171                  */
172                 if ((fup->fu_flags & CUF_INITED) == 0) {
173
174                         if (fup->fu_ft4)
175                                 /* may not happen */
176                                 goto done;
177
178                         /*
179                          * We're just initializing device now, so see if
180                          * the initialization command has completed
181                          */
182                         if (CP_READ(aap->aali_init.init_status) & 
183                                                 QSTAT_COMPLETED)
184                                 fore_initialize_complete(fup);
185
186                         /*
187                          * If we're still not inited, none of the host
188                          * queues are setup yet
189                          */
190                         if ((fup->fu_flags & CUF_INITED) == 0)
191                                 goto done;
192                 }
193
194                 /*
195                  * Drain the queues of completed work
196                  */
197                 fore_cmd_drain(fup);
198                 fore_recv_drain(fup);
199                 fore_xmit_drain(fup);
200
201                 /*
202                  * Supply more buffers to the CP
203                  */
204                 fore_buf_supply(fup);
205         }
206
207 done:
208 #if (defined(BSD) && (BSD <= 199306))
209         return(serviced);
210 #else
211         return;
212 #endif
213 }
214
215
216 /*
217  * Watchdog timeout routine
218  * 
219  * Called when we haven't heard from the card in a while.  Just in case
220  * we missed an interrupt, we'll drain the queues and try to resupply the
221  * CP with more receive buffers.  If the CP is partially wedged, hopefully
222  * this will be enough to get it going again.
223  *
224  * Called with interrupts locked out.
225  *
226  * Arguments:
227  *      fup             pointer to device unit structure
228  *
229  * Returns:
230  *      none
231  *
232  */
233 void
234 fore_watchdog(fup)
235         Fore_unit       *fup;
236 {
237         /*
238          * Try to prevent stuff happening after we've paniced
239          */
240         if (panicstr) {
241                 return;
242         }
243
244         /*
245          * Reset the watchdog timer
246          */
247         fup->fu_timer = FORE_WATCHDOG;
248
249         /*
250          * If the device is initialized, nudge it (wink, wink)
251          */
252         if (fup->fu_flags & CUF_INITED) {
253
254                 /*
255                  * Drain the queues of completed work
256                  */
257                 fore_cmd_drain(fup);
258                 fore_recv_drain(fup);
259                 fore_xmit_drain(fup);
260
261                 /*
262                  * Supply more buffers to the CP
263                  */
264                 fore_buf_supply(fup);
265         }
266
267         return;
268 }