[BACK]Return to shared_intr.c CVS log [TXT][DIR] Up to [local] / sys / arch / alpha / dev

Annotation of sys/arch/alpha/dev/shared_intr.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: shared_intr.c,v 1.15 2006/06/15 20:08:29 brad Exp $ */
        !             2: /* $NetBSD: shared_intr.c,v 1.13 2000/03/19 01:46:18 thorpej Exp $ */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1996 Carnegie-Mellon University.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Authors: Chris G. Demetriou
        !             9:  *
        !            10:  * Permission to use, copy, modify and distribute this software and
        !            11:  * its documentation is hereby granted, provided that both the copyright
        !            12:  * notice and this permission notice appear in all copies of the
        !            13:  * software, derivative works or modified versions, and any portions
        !            14:  * thereof, and that both notices appear in supporting documentation.
        !            15:  *
        !            16:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            17:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
        !            18:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            19:  *
        !            20:  * Carnegie Mellon requests users of this software to return to
        !            21:  *
        !            22:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
        !            23:  *  School of Computer Science
        !            24:  *  Carnegie Mellon University
        !            25:  *  Pittsburgh PA 15213-3890
        !            26:  *
        !            27:  * any improvements or extensions that they make and grant Carnegie the
        !            28:  * rights to redistribute these changes.
        !            29:  */
        !            30:
        !            31: /*
        !            32:  * Common shared-interrupt-line functionality.
        !            33:  */
        !            34:
        !            35: #include <sys/param.h>
        !            36: #include <sys/kernel.h>
        !            37: #include <sys/systm.h>
        !            38: #include <sys/malloc.h>
        !            39: #include <sys/syslog.h>
        !            40: #include <sys/queue.h>
        !            41:
        !            42: #include <machine/intr.h>
        !            43:
        !            44: static const char *intr_typename(int);
        !            45:
        !            46: static const char *
        !            47: intr_typename(type)
        !            48:        int type;
        !            49: {
        !            50:
        !            51:        switch (type) {
        !            52:        case IST_UNUSABLE:
        !            53:                return ("disabled");
        !            54:        case IST_NONE:
        !            55:                return ("none");
        !            56:        case IST_PULSE:
        !            57:                return ("pulsed");
        !            58:        case IST_EDGE:
        !            59:                return ("edge-triggered");
        !            60:        case IST_LEVEL:
        !            61:                return ("level-triggered");
        !            62:        }
        !            63:        panic("intr_typename: unknown type %d", type);
        !            64: }
        !            65:
        !            66: struct alpha_shared_intr *
        !            67: alpha_shared_intr_alloc(n)
        !            68:        unsigned int n;
        !            69: {
        !            70:        struct alpha_shared_intr *intr;
        !            71:        unsigned int i;
        !            72:
        !            73:        intr = malloc(n * sizeof (struct alpha_shared_intr), M_DEVBUF,
        !            74:            cold ? M_NOWAIT : M_WAITOK);
        !            75:        if (intr == NULL)
        !            76:                panic("alpha_shared_intr_alloc: couldn't malloc intr");
        !            77:
        !            78:        for (i = 0; i < n; i++) {
        !            79:                TAILQ_INIT(&intr[i].intr_q);
        !            80:                intr[i].intr_sharetype = IST_NONE;
        !            81:                intr[i].intr_dfltsharetype = IST_NONE;
        !            82:                intr[i].intr_nstrays = 0;
        !            83:                intr[i].intr_maxstrays = 5;
        !            84:                intr[i].intr_private = NULL;
        !            85:        }
        !            86:
        !            87:        return (intr);
        !            88: }
        !            89:
        !            90: int
        !            91: alpha_shared_intr_dispatch(intr, num)
        !            92:        struct alpha_shared_intr *intr;
        !            93:        unsigned int num;
        !            94: {
        !            95:        struct alpha_shared_intrhand *ih;
        !            96:        int rv, handled;
        !            97:
        !            98:        handled = 0;
        !            99:        TAILQ_FOREACH(ih, &intr[num].intr_q, ih_q) {
        !           100:                /*
        !           101:                 * The handler returns one of three values:
        !           102:                 *   0: This interrupt wasn't for me.
        !           103:                 *   1: This interrupt was for me.
        !           104:                 *  -1: This interrupt might have been for me, but I can't say
        !           105:                 *      for sure.
        !           106:                 */
        !           107:                if ((rv = (*ih->ih_fn)(ih->ih_arg)))
        !           108:                        ih->ih_count.ec_count++;
        !           109:
        !           110:                handled = handled || (rv != 0);
        !           111:        }
        !           112:
        !           113:        return (handled);
        !           114: }
        !           115:
        !           116: void *
        !           117: alpha_shared_intr_establish(intr, num, type, level, fn, arg, basename)
        !           118:        struct alpha_shared_intr *intr;
        !           119:        unsigned int num;
        !           120:        int type, level;
        !           121:        int (*fn)(void *);
        !           122:        void *arg;
        !           123:        const char *basename;
        !           124: {
        !           125:        struct alpha_shared_intrhand *ih;
        !           126:
        !           127:        if (intr[num].intr_sharetype == IST_UNUSABLE) {
        !           128:                printf("alpha_shared_intr_establish: %s %d: unusable\n",
        !           129:                    basename, num);
        !           130:                return NULL;
        !           131:        }
        !           132:
        !           133:        /* no point in sleeping unless someone can free memory. */
        !           134:        ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
        !           135:        if (ih == NULL)
        !           136:                panic("alpha_shared_intr_establish: can't malloc intrhand");
        !           137:
        !           138: #ifdef DIAGNOSTIC
        !           139:        if (type == IST_NONE)
        !           140:                panic("alpha_shared_intr_establish: bogus type");
        !           141: #endif
        !           142:
        !           143:        switch (intr[num].intr_sharetype) {
        !           144:        case IST_EDGE:
        !           145:        case IST_LEVEL:
        !           146:                if (type == intr[num].intr_sharetype)
        !           147:                        break;
        !           148:        case IST_PULSE:
        !           149:                if (type != IST_NONE) {
        !           150:                        if (TAILQ_EMPTY(&intr[num].intr_q)) {
        !           151:                                printf("alpha_shared_intr_establish: %s %d: warning: using %s on %s\n",
        !           152:                                    basename, num, intr_typename(type),
        !           153:                                    intr_typename(intr[num].intr_sharetype));
        !           154:                                type = intr[num].intr_sharetype;
        !           155:                        } else {
        !           156:                                panic("alpha_shared_intr_establish: %s %d: can't share %s with %s",
        !           157:                                    basename, num, intr_typename(type),
        !           158:                                    intr_typename(intr[num].intr_sharetype));
        !           159:                        }
        !           160:                }
        !           161:                break;
        !           162:
        !           163:        case IST_NONE:
        !           164:                /* not currently used; safe */
        !           165:                break;
        !           166:        }
        !           167:
        !           168:        ih->ih_intrhead = intr;
        !           169:        ih->ih_fn = fn;
        !           170:        ih->ih_arg = arg;
        !           171:        ih->ih_level = level;
        !           172:        ih->ih_num = num;
        !           173:        evcount_attach(&ih->ih_count, basename, (void *)&ih->ih_num,
        !           174:            &evcount_intr);
        !           175:
        !           176:        intr[num].intr_sharetype = type;
        !           177:        TAILQ_INSERT_TAIL(&intr[num].intr_q, ih, ih_q);
        !           178:
        !           179:        return (ih);
        !           180: }
        !           181:
        !           182: void
        !           183: alpha_shared_intr_disestablish(intr, cookie, basename)
        !           184:        struct alpha_shared_intr *intr;
        !           185:        void *cookie;
        !           186:        const char *basename;
        !           187: {
        !           188:        struct alpha_shared_intrhand *ih = cookie;
        !           189:        unsigned int num = ih->ih_num;
        !           190:
        !           191:        /*
        !           192:         * Just remove it from the list and free the entry.  We let
        !           193:         * the caller deal with resetting the share type, if appropriate.
        !           194:         */
        !           195:        evcount_detach(&ih->ih_count);
        !           196:        TAILQ_REMOVE(&intr[num].intr_q, ih, ih_q);
        !           197:        free(ih, M_DEVBUF);
        !           198: }
        !           199:
        !           200: int
        !           201: alpha_shared_intr_get_sharetype(intr, num)
        !           202:        struct alpha_shared_intr *intr;
        !           203:        unsigned int num;
        !           204: {
        !           205:
        !           206:        return (intr[num].intr_sharetype);
        !           207: }
        !           208:
        !           209: int
        !           210: alpha_shared_intr_isactive(intr, num)
        !           211:        struct alpha_shared_intr *intr;
        !           212:        unsigned int num;
        !           213: {
        !           214:
        !           215:        return (!TAILQ_EMPTY(&intr[num].intr_q));
        !           216: }
        !           217:
        !           218: int
        !           219: alpha_shared_intr_firstactive(struct alpha_shared_intr *intr, unsigned int num)
        !           220: {
        !           221:
        !           222:        return (!TAILQ_EMPTY(&intr[num].intr_q) &&
        !           223:                TAILQ_NEXT(intr[num].intr_q.tqh_first, ih_q) == NULL);
        !           224: }
        !           225:
        !           226: void
        !           227: alpha_shared_intr_set_dfltsharetype(intr, num, newdfltsharetype)
        !           228:        struct alpha_shared_intr *intr;
        !           229:        unsigned int num;
        !           230:        int newdfltsharetype;
        !           231: {
        !           232:
        !           233: #ifdef DIAGNOSTIC
        !           234:        if (alpha_shared_intr_isactive(intr, num))
        !           235:                panic("alpha_shared_intr_set_dfltsharetype on active intr");
        !           236: #endif
        !           237:
        !           238:        intr[num].intr_dfltsharetype = newdfltsharetype;
        !           239:        intr[num].intr_sharetype = intr[num].intr_dfltsharetype;
        !           240: }
        !           241:
        !           242: void
        !           243: alpha_shared_intr_set_maxstrays(intr, num, newmaxstrays)
        !           244:        struct alpha_shared_intr *intr;
        !           245:        unsigned int num;
        !           246:        int newmaxstrays;
        !           247: {
        !           248:        int s = splhigh();
        !           249:        intr[num].intr_maxstrays = newmaxstrays;
        !           250:        intr[num].intr_nstrays = 0;
        !           251:        splx(s);
        !           252: }
        !           253:
        !           254: void
        !           255: alpha_shared_intr_reset_strays(intr, num)
        !           256:        struct alpha_shared_intr *intr;
        !           257:        unsigned int num;
        !           258: {
        !           259:
        !           260:        /*
        !           261:         * Don't bother blocking interrupts; this doesn't have to be
        !           262:         * precise, but it does need to be fast.
        !           263:         */
        !           264:        intr[num].intr_nstrays = 0;
        !           265: }
        !           266:
        !           267: void
        !           268: alpha_shared_intr_stray(intr, num, basename)
        !           269:        struct alpha_shared_intr *intr;
        !           270:        unsigned int num;
        !           271:        const char *basename;
        !           272: {
        !           273:
        !           274:        intr[num].intr_nstrays++;
        !           275:
        !           276:        if (intr[num].intr_maxstrays == 0)
        !           277:                return;
        !           278:
        !           279:        if (intr[num].intr_nstrays <= intr[num].intr_maxstrays)
        !           280:                log(LOG_ERR, "stray %s %d%s\n", basename, num,
        !           281:                    intr[num].intr_nstrays >= intr[num].intr_maxstrays ?
        !           282:                      "; stopped logging" : "");
        !           283: }
        !           284:
        !           285: void
        !           286: alpha_shared_intr_set_private(intr, num, v)
        !           287:        struct alpha_shared_intr *intr;
        !           288:        unsigned int num;
        !           289:        void *v;
        !           290: {
        !           291:
        !           292:        intr[num].intr_private = v;
        !           293: }
        !           294:
        !           295: void *
        !           296: alpha_shared_intr_get_private(intr, num)
        !           297:        struct alpha_shared_intr *intr;
        !           298:        unsigned int num;
        !           299: {
        !           300:
        !           301:        return (intr[num].intr_private);
        !           302: }

CVSweb