summaryrefslogtreecommitdiffstats
path: root/sys/dev/hfa/fore_intr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/hfa/fore_intr.c')
-rw-r--r--sys/dev/hfa/fore_intr.c268
1 files changed, 268 insertions, 0 deletions
diff --git a/sys/dev/hfa/fore_intr.c b/sys/dev/hfa/fore_intr.c
new file mode 100644
index 0000000..f295b62
--- /dev/null
+++ b/sys/dev/hfa/fore_intr.c
@@ -0,0 +1,268 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $Id: fore_intr.c,v 1.7 1997/05/06 22:09:48 mks Exp $
+ *
+ */
+
+/*
+ * FORE Systems 200-Series Adapter Support
+ * ---------------------------------------
+ *
+ * Interrupt processing
+ *
+ */
+
+#ifndef lint
+static char *RCSid = "@(#) $Id: fore_intr.c,v 1.7 1997/05/06 22:09:48 mks Exp $";
+#endif
+
+#include <dev/hfa/fore_include.h>
+
+#if defined(sun)
+/*
+ * Polling interrupt routine
+ *
+ * Polling interrupts are handled by calling all interrupt service
+ * routines for a given level until someone claims to have "handled" the
+ * interrupt.
+ *
+ * Called at interrupt level.
+ *
+ * Arguments:
+ * none
+ *
+ * Returns:
+ * 1 an interrupt has been serviced
+ * 0 no interrupts serviced
+ *
+ */
+int
+fore_poll()
+{
+ int serviced = 0;
+ int unit;
+
+ /*
+ * See if any of our devices are interrupting
+ */
+ for ( unit = 0; unit < fore_nunits; unit++ )
+ {
+ Fore_unit *fup = fore_units[unit];
+
+ if (fup == NULL)
+ continue;
+
+ serviced += fore_intr((void *)fup);
+ }
+
+ /*
+ * Indicate if we handled an interrupt
+ */
+ return (serviced ? 1 : 0);
+}
+#endif /* defined(sun) */
+
+
+/*
+ * Device interrupt routine
+ *
+ * Called at interrupt level.
+ *
+ * Arguments:
+ * arg pointer to device unit structure
+ *
+ * Returns:
+ * 1 device interrupt was serviced
+ * 0 no interrupts serviced
+ *
+ */
+#if (defined(BSD) && (BSD <= 199306))
+int
+#else
+void
+#endif
+fore_intr(arg)
+ void *arg;
+{
+ Fore_unit *fup = arg;
+ Aali *aap;
+#if (defined(BSD) && (BSD <= 199306))
+ int serviced = 0;
+#endif
+
+ /*
+ * Try to prevent stuff happening after we've paniced
+ */
+ if (panicstr) {
+ goto done;
+ }
+
+ /*
+ * Get to the microcode shared memory interface
+ */
+ if ((aap = fup->fu_aali) == NULL)
+ goto done;
+
+ /*
+ * Has this card issued an interrupt??
+ */
+#ifdef FORE_PCI
+ if (*fup->fu_psr) {
+#else
+ if (aap->aali_intr_sent) {
+#endif
+
+ /*
+ * Indicate that we've serviced an interrupt.
+ */
+#if (defined(BSD) && (BSD <= 199306))
+ serviced = 1;
+#endif
+
+ /*
+ * Clear the device interrupt
+ */
+ switch (fup->fu_config.ac_device) {
+
+#ifdef FORE_SBUS
+ case DEV_FORE_SBA200E:
+ SBA200E_HCR_SET(*fup->fu_ctlreg, SBA200E_CLR_SBUS_INTR);
+ break;
+
+ case DEV_FORE_SBA200:
+ *fup->fu_ctlreg = SBA200_CLR_SBUS_INTR;
+ break;
+#endif
+#ifdef FORE_PCI
+ case DEV_FORE_PCA200E:
+ PCA200E_HCR_SET(*fup->fu_ctlreg, PCA200E_CLR_HBUS_INT);
+ break;
+#endif
+
+ }
+ aap->aali_intr_sent = CP_WRITE(0);
+
+ /*
+ * Reset the watchdog timer
+ */
+ fup->fu_timer = FORE_WATCHDOG;
+
+ /*
+ * Device initialization handled separately
+ */
+ if ((fup->fu_flags & CUF_INITED) == 0) {
+
+ /*
+ * We're just initializing device now, so see if
+ * the initialization command has completed
+ */
+ if (CP_READ(aap->aali_init.init_status) &
+ QSTAT_COMPLETED)
+ fore_initialize_complete(fup);
+
+ /*
+ * If we're still not inited, none of the host
+ * queues are setup yet
+ */
+ if ((fup->fu_flags & CUF_INITED) == 0)
+ goto done;
+ }
+
+ /*
+ * Drain the queues of completed work
+ */
+ fore_cmd_drain(fup);
+ fore_recv_drain(fup);
+ fore_xmit_drain(fup);
+
+ /*
+ * Supply more buffers to the CP
+ */
+ fore_buf_supply(fup);
+ }
+
+done:
+#if (defined(BSD) && (BSD <= 199306))
+ return(serviced);
+#else
+ return;
+#endif
+}
+
+
+/*
+ * Watchdog timeout routine
+ *
+ * Called when we haven't heard from the card in a while. Just in case
+ * we missed an interrupt, we'll drain the queues and try to resupply the
+ * CP with more receive buffers. If the CP is partially wedged, hopefully
+ * this will be enough to get it going again.
+ *
+ * Called with interrupts locked out.
+ *
+ * Arguments:
+ * fup pointer to device unit structure
+ *
+ * Returns:
+ * none
+ *
+ */
+void
+fore_watchdog(fup)
+ Fore_unit *fup;
+{
+ /*
+ * Try to prevent stuff happening after we've paniced
+ */
+ if (panicstr) {
+ return;
+ }
+
+ /*
+ * Reset the watchdog timer
+ */
+ fup->fu_timer = FORE_WATCHDOG;
+
+ /*
+ * If the device is initialized, nudge it (wink, wink)
+ */
+ if (fup->fu_flags & CUF_INITED) {
+
+ /*
+ * Drain the queues of completed work
+ */
+ fore_cmd_drain(fup);
+ fore_recv_drain(fup);
+ fore_xmit_drain(fup);
+
+ /*
+ * Supply more buffers to the CP
+ */
+ fore_buf_supply(fup);
+ }
+
+ return;
+}
OpenPOWER on IntegriCloud