Annotation of sys/arch/luna88k/luna88k/isr.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: isr.c,v 1.6 2005/12/12 19:15:19 miod Exp $ */
! 2: /* $NetBSD: isr.c,v 1.5 2000/07/09 08:08:20 nisimura Exp $ */
! 3:
! 4: /*-
! 5: * Copyright (c) 1996 The NetBSD Foundation, Inc.
! 6: * All rights reserved.
! 7: *
! 8: * This code is derived from software contributed to The NetBSD Foundation
! 9: * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe.
! 10: *
! 11: * Redistribution and use in source and binary forms, with or without
! 12: * modification, are permitted provided that the following conditions
! 13: * are met:
! 14: * 1. Redistributions of source code must retain the above copyright
! 15: * notice, this list of conditions and the following disclaimer.
! 16: * 2. Redistributions in binary form must reproduce the above copyright
! 17: * notice, this list of conditions and the following disclaimer in the
! 18: * documentation and/or other materials provided with the distribution.
! 19: * 3. All advertising materials mentioning features or use of this software
! 20: * must display the following acknowledgement:
! 21: * This product includes software developed by the NetBSD
! 22: * Foundation, Inc. and its contributors.
! 23: * 4. Neither the name of The NetBSD Foundation nor the names of its
! 24: * contributors may be used to endorse or promote products derived
! 25: * from this software without specific prior written permission.
! 26: *
! 27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 37: * POSSIBILITY OF SUCH DAMAGE.
! 38: */
! 39:
! 40: /*
! 41: * Link and dispatch interrupts.
! 42: */
! 43:
! 44: #include <sys/param.h>
! 45: #include <sys/systm.h>
! 46: #include <sys/malloc.h>
! 47: #include <sys/vmmeter.h>
! 48: #include <sys/evcount.h>
! 49:
! 50: #include <uvm/uvm_extern.h>
! 51:
! 52: #include <net/netisr.h>
! 53:
! 54: #include <machine/cpu.h>
! 55:
! 56: #include <luna88k/luna88k/isr.h>
! 57:
! 58: isr_autovec_list_t isr_autovec[NISRAUTOVEC];
! 59:
! 60: void
! 61: isrinit()
! 62: {
! 63: int i;
! 64:
! 65: /* Initialize the autovector lists. */
! 66: for (i = 0; i < NISRAUTOVEC; ++i) {
! 67: LIST_INIT(&isr_autovec[i]);
! 68: }
! 69: }
! 70:
! 71: /*
! 72: * Establish an autovectored interrupt handler.
! 73: * Called by driver attach functions.
! 74: */
! 75: void
! 76: isrlink_autovec(int (*func)(void *), void *arg, int ipl, int priority,
! 77: const char *name)
! 78: {
! 79: struct isr_autovec *newisr, *curisr;
! 80: isr_autovec_list_t *list;
! 81:
! 82: #ifdef DIAGNOSTIC
! 83: if (ipl < 0 || ipl >= NISRAUTOVEC)
! 84: panic("isrlink_autovec: bad ipl %d", ipl);
! 85: #endif
! 86:
! 87: newisr = (struct isr_autovec *)malloc(sizeof(struct isr_autovec),
! 88: M_DEVBUF, M_NOWAIT);
! 89: if (newisr == NULL)
! 90: panic("isrlink_autovec: can't allocate space for isr");
! 91:
! 92: /* Fill in the new entry. */
! 93: newisr->isr_func = func;
! 94: newisr->isr_arg = arg;
! 95: newisr->isr_ipl = ipl;
! 96: newisr->isr_priority = priority;
! 97: evcount_attach(&newisr->isr_count, name, (void *)&newisr->isr_ipl,
! 98: &evcount_intr);
! 99:
! 100: /*
! 101: * Some devices are particularly sensitive to interrupt
! 102: * handling latency. The SCC, for example, can lose many
! 103: * characters if its interrupt isn't handled with reasonable
! 104: * speed.
! 105: *
! 106: * To work around this problem, each device can give itself a
! 107: * "priority". An unbuffered SCC would give itself a higher
! 108: * priority than a SCSI device, for example.
! 109: *
! 110: * This solution was originally developed for the hp300, which
! 111: * has a flat spl scheme (by necessity). Thankfully, the
! 112: * MVME systems don't have this problem, though this may serve
! 113: * a useful purpose in any case.
! 114: */
! 115:
! 116: /*
! 117: * Get the appropriate ISR list. If the list is empty, no
! 118: * additional work is necessary; we simply insert ourselves
! 119: * at the head of the list.
! 120: */
! 121: list = &isr_autovec[ipl];
! 122: if (LIST_EMPTY(list)) {
! 123: LIST_INSERT_HEAD(list, newisr, isr_link);
! 124: return;
! 125: }
! 126:
! 127: /*
! 128: * A little extra work is required. We traverse the list
! 129: * and place ourselves after any ISRs with our current (or
! 130: * higher) priority.
! 131: */
! 132: for (curisr = LIST_FIRST(list); LIST_NEXT(curisr, isr_link) != NULL;
! 133: curisr = LIST_NEXT(curisr, isr_link)) {
! 134: if (newisr->isr_priority > curisr->isr_priority) {
! 135: LIST_INSERT_BEFORE(curisr, newisr, isr_link);
! 136: return;
! 137: }
! 138: }
! 139:
! 140: /*
! 141: * We're the least important entry, it seems. We just go
! 142: * on the end.
! 143: */
! 144: LIST_INSERT_AFTER(curisr, newisr, isr_link);
! 145: }
! 146:
! 147: /*
! 148: * This is the dispatcher called by the low-level
! 149: * assembly language autovectored interrupt routine.
! 150: */
! 151: void
! 152: isrdispatch_autovec(int ipl)
! 153: {
! 154: struct isr_autovec *isr;
! 155: isr_autovec_list_t *list;
! 156: int rc, handled = 0;
! 157: static int straycount, unexpected;
! 158:
! 159: #ifdef DIAGNOSTIC
! 160: if (ipl < 0 || ipl >= NISRAUTOVEC)
! 161: panic("isrdispatch_autovec: bad ipl 0x%d", ipl);
! 162: #endif
! 163:
! 164: #if 0 /* XXX: already counted in machdep.c */
! 165: uvmexp.intrs++;
! 166: #endif
! 167:
! 168: list = &isr_autovec[ipl];
! 169: if (LIST_EMPTY(list)) {
! 170: printf("isrdispatch_autovec: ipl %d unexpected\n", ipl);
! 171: if (++unexpected > 10)
! 172: panic("too many unexpected interrupts");
! 173: return;
! 174: }
! 175:
! 176: /* Give all the handlers a chance. */
! 177: LIST_FOREACH(isr, list, isr_link) {
! 178: rc = (*isr->isr_func)(isr->isr_arg);
! 179: if (rc != 0)
! 180: isr->isr_count.ec_count++;
! 181: handled |= rc;
! 182: }
! 183:
! 184: if (handled)
! 185: straycount = 0;
! 186: else if (++straycount > 50)
! 187: panic("isr_dispatch_autovec: too many stray interrupts");
! 188: else
! 189: printf("isrdispatch_autovec: stray level %d interrupt\n", ipl);
! 190: }
CVSweb