[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

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