[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     ! 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