kern_intr.c revision 65822
1/* 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/kern/kern_intr.c 65822 2000-09-13 18:33:25Z jhb $ 27 * 28 */ 29 30 31#include <sys/param.h> 32#include <sys/bus.h> 33#include <sys/rtprio.h> 34#include <sys/systm.h> 35#include <sys/malloc.h> 36 37#include <machine/ipl.h> 38 39#include <sys/interrupt.h> 40 41struct swilist { 42 swihand_t *sl_handler; 43 struct swilist *sl_next; 44}; 45 46static struct swilist swilists[NSWI]; 47 48void 49register_swi(intr, handler) 50 int intr; 51 swihand_t *handler; 52{ 53 struct swilist *slp, *slq; 54 int s; 55 56 if (intr < NHWI || intr >= NHWI + NSWI) 57 panic("register_swi: bad intr %d", intr); 58 if (handler == swi_generic || handler == swi_null) 59 panic("register_swi: bad handler %p", (void *)handler); 60 slp = &swilists[intr - NHWI]; 61 s = splhigh(); 62 if (ihandlers[intr] == swi_null) 63 ihandlers[intr] = handler; 64 else { 65 if (slp->sl_next == NULL) { 66 slp->sl_handler = ihandlers[intr]; 67 ihandlers[intr] = swi_generic; 68 } 69 slq = malloc(sizeof(*slq), M_DEVBUF, M_NOWAIT); 70 if (slq == NULL) 71 panic("register_swi: malloc failed"); 72 slq->sl_handler = handler; 73 slq->sl_next = NULL; 74 while (slp->sl_next != NULL) 75 slp = slp->sl_next; 76 slp->sl_next = slq; 77 } 78 splx(s); 79} 80 81void 82swi_dispatcher(intr) 83 int intr; 84{ 85 struct swilist *slp; 86 87 slp = &swilists[intr - NHWI]; 88 do { 89 (*slp->sl_handler)(); 90 slp = slp->sl_next; 91 } while (slp != NULL); 92} 93 94void 95unregister_swi(intr, handler) 96 int intr; 97 swihand_t *handler; 98{ 99 struct swilist *slfoundpred, *slp, *slq; 100 int s; 101 102 if (intr < NHWI || intr >= NHWI + NSWI) 103 panic("unregister_swi: bad intr %d", intr); 104 if (handler == swi_generic || handler == swi_null) 105 panic("unregister_swi: bad handler %p", (void *)handler); 106 slp = &swilists[intr - NHWI]; 107 s = splhigh(); 108 if (ihandlers[intr] == handler) 109 ihandlers[intr] = swi_null; 110 else if (slp->sl_next != NULL) { 111 slfoundpred = NULL; 112 for (slq = slp->sl_next; slq != NULL; 113 slp = slq, slq = slp->sl_next) 114 if (slq->sl_handler == handler) 115 slfoundpred = slp; 116 slp = &swilists[intr - NHWI]; 117 if (slfoundpred != NULL) { 118 slq = slfoundpred->sl_next; 119 slfoundpred->sl_next = slq->sl_next; 120 free(slq, M_DEVBUF); 121 } else if (slp->sl_handler == handler) { 122 slq = slp->sl_next; 123 slp->sl_next = slq->sl_next; 124 slp->sl_handler = slq->sl_handler; 125 free(slq, M_DEVBUF); 126 } 127 if (slp->sl_next == NULL) 128 ihandlers[intr] = slp->sl_handler; 129 } 130 splx(s); 131} 132 133int 134ithread_priority(flags) 135 int flags; 136{ 137 int pri; 138 139 switch (flags) { 140 case INTR_TYPE_TTY: /* keyboard or parallel port */ 141 pri = PI_TTYLOW; 142 break; 143 case (INTR_TYPE_TTY | INTR_FAST): /* sio */ 144 pri = PI_TTYHIGH; 145 break; 146 case INTR_TYPE_BIO: 147 /* 148 * XXX We need to refine this. BSD/OS distinguishes 149 * between tape and disk priorities. 150 */ 151 pri = PI_DISK; 152 break; 153 case INTR_TYPE_NET: 154 pri = PI_NET; 155 break; 156 case INTR_TYPE_CAM: 157 pri = PI_DISK; /* XXX or PI_CAM? */ 158 break; 159 case INTR_TYPE_MISC: 160 pri = PI_DULL; /* don't care */ 161 break; 162 /* We didn't specify an interrupt level. */ 163 default: 164 panic("ithread_priority: no interrupt type in flags"); 165 } 166 167 return pri; 168} 169 170