[BACK]Return to isr.c CVS log [TXT][DIR] Up to [local] / sys / arch / luna88k / luna88k

Annotation of sys/arch/luna88k/luna88k/isr.c, Revision 1.1.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