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

Annotation of sys/arch/alpha/pci/sio_pic.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: sio_pic.c,v 1.26 2006/06/15 20:08:29 brad Exp $       */
                      2: /* $NetBSD: sio_pic.c,v 1.28 2000/06/06 03:10:13 thorpej Exp $ */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
                     10:  * NASA Ames Research Center.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *     This product includes software developed by the NetBSD
                     23:  *     Foundation, Inc. and its contributors.
                     24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     25:  *    contributors may be used to endorse or promote products derived
                     26:  *    from this software without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     38:  * POSSIBILITY OF SUCH DAMAGE.
                     39:  */
                     40:
                     41: /*
                     42:  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
                     43:  * All rights reserved.
                     44:  *
                     45:  * Author: Chris G. Demetriou
                     46:  *
                     47:  * Permission to use, copy, modify and distribute this software and
                     48:  * its documentation is hereby granted, provided that both the copyright
                     49:  * notice and this permission notice appear in all copies of the
                     50:  * software, derivative works or modified versions, and any portions
                     51:  * thereof, and that both notices appear in supporting documentation.
                     52:  *
                     53:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     54:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
                     55:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     56:  *
                     57:  * Carnegie Mellon requests users of this software to return to
                     58:  *
                     59:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     60:  *  School of Computer Science
                     61:  *  Carnegie Mellon University
                     62:  *  Pittsburgh PA 15213-3890
                     63:  *
                     64:  * any improvements or extensions that they make and grant Carnegie the
                     65:  * rights to redistribute these changes.
                     66:  */
                     67:
                     68: #include <sys/param.h>
                     69: #include <sys/systm.h>
                     70:
                     71: #include <sys/device.h>
                     72: #include <sys/malloc.h>
                     73: #include <sys/syslog.h>
                     74:
                     75: #include <machine/intr.h>
                     76: #include <machine/bus.h>
                     77:
                     78: #include <dev/pci/pcireg.h>
                     79: #include <dev/pci/pcivar.h>
                     80: #include <dev/pci/pcidevs.h>
                     81:
                     82: #include <dev/pci/cy82c693reg.h>
                     83: #include <dev/pci/cy82c693var.h>
                     84:
                     85: #include <dev/isa/isareg.h>
                     86: #include <dev/isa/isavar.h>
                     87: #include <alpha/pci/siovar.h>
                     88:
                     89: #include "sio.h"
                     90:
                     91: /*
                     92:  * To add to the long history of wonderful PROM console traits,
                     93:  * AlphaStation PROMs don't reset themselves completely on boot!
                     94:  * Therefore, if an interrupt was turned on when the kernel was
                     95:  * started, we're not going to EVER turn it off...  I don't know
                     96:  * what will happen if new interrupts (that the PROM console doesn't
                     97:  * want) are turned on.  I'll burn that bridge when I come to it.
                     98:  */
                     99: #define        BROKEN_PROM_CONSOLE
                    100:
                    101: /*
                    102:  * Private functions and variables.
                    103:  */
                    104:
                    105: bus_space_tag_t sio_iot;
                    106: pci_chipset_tag_t sio_pc;
                    107: bus_space_handle_t sio_ioh_icu1, sio_ioh_icu2;
                    108:
                    109: #define        ICU_LEN         16              /* number of ISA IRQs */
                    110:
                    111: static struct alpha_shared_intr *sio_intr;
                    112:
                    113: #ifndef STRAY_MAX
                    114: #define        STRAY_MAX       5
                    115: #endif
                    116:
                    117: #ifdef BROKEN_PROM_CONSOLE
                    118: /*
                    119:  * If prom console is broken, must remember the initial interrupt
                    120:  * settings and enforce them.  WHEE!
                    121:  */
                    122: u_int8_t initial_ocw1[2];
                    123: u_int8_t initial_elcr[2];
                    124: #endif
                    125:
                    126: void           sio_setirqstat(int, int, int);
                    127: int            sio_intr_alloc(void *, int, int, int *);
                    128:
                    129: u_int8_t       (*sio_read_elcr)(int);
                    130: void           (*sio_write_elcr)(int, u_int8_t);
                    131: static void    specific_eoi(int);
                    132: #ifdef BROKEN_PROM_CONSOLE
                    133: void           sio_intr_shutdown(void *);
                    134: #endif
                    135:
                    136: /******************** i82378 SIO ELCR functions ********************/
                    137:
                    138: int            i82378_setup_elcr(void);
                    139: u_int8_t       i82378_read_elcr(int);
                    140: void           i82378_write_elcr(int, u_int8_t);
                    141:
                    142: bus_space_handle_t sio_ioh_elcr;
                    143:
                    144: int
                    145: i82378_setup_elcr()
                    146: {
                    147:        int rv;
                    148:
                    149:        /*
                    150:         * We could probe configuration space to see that there's
                    151:         * actually an SIO present, but we are using this as a
                    152:         * fall-back in case nothing else matches.
                    153:         */
                    154:
                    155:        rv = bus_space_map(sio_iot, 0x4d0, 2, 0, &sio_ioh_elcr);
                    156:
                    157:        if (rv == 0) {
                    158:                sio_read_elcr = i82378_read_elcr;
                    159:                sio_write_elcr = i82378_write_elcr;
                    160:        }
                    161:
                    162:        return (rv);
                    163: }
                    164:
                    165: u_int8_t
                    166: i82378_read_elcr(elcr)
                    167:        int elcr;
                    168: {
                    169:
                    170:        return (bus_space_read_1(sio_iot, sio_ioh_elcr, elcr));
                    171: }
                    172:
                    173: void
                    174: i82378_write_elcr(elcr, val)
                    175:        int elcr;
                    176:        u_int8_t val;
                    177: {
                    178:
                    179:        bus_space_write_1(sio_iot, sio_ioh_elcr, elcr, val);
                    180: }
                    181:
                    182: /******************** Cypress CY82C693 ELCR functions ********************/
                    183:
                    184: int            cy82c693_setup_elcr(void);
                    185: u_int8_t       cy82c693_read_elcr(int);
                    186: void           cy82c693_write_elcr(int, u_int8_t);
                    187:
                    188: const struct cy82c693_handle *sio_cy82c693_handle;
                    189:
                    190: int
                    191: cy82c693_setup_elcr()
                    192: {
                    193:        int device, maxndevs;
                    194:        pcitag_t tag;
                    195:        pcireg_t id;
                    196:
                    197:        /*
                    198:         * Search PCI configuration space for a Cypress CY82C693.
                    199:         *
                    200:         * Note we can make some assumptions about our bus number
                    201:         * here, because:
                    202:         *
                    203:         *      (1) there can be at most one ISA/EISA bridge per PCI bus, and
                    204:         *
                    205:         *      (2) any ISA/EISA bridges must be attached to primary PCI
                    206:         *          busses (i.e. bus zero).
                    207:         */
                    208:
                    209:        maxndevs = pci_bus_maxdevs(sio_pc, 0);
                    210:
                    211:        for (device = 0; device < maxndevs; device++) {
                    212:                tag = pci_make_tag(sio_pc, 0, device, 0);
                    213:                id = pci_conf_read(sio_pc, tag, PCI_ID_REG);
                    214:
                    215:                /* Invalid vendor ID value? */
                    216:                if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
                    217:                        continue;
                    218:                /* XXX Not invalid, but we've done this ~forever. */
                    219:                if (PCI_VENDOR(id) == 0)
                    220:                        continue;
                    221:
                    222:                if (PCI_VENDOR(id) != PCI_VENDOR_CONTAQ ||
                    223:                    PCI_PRODUCT(id) != PCI_PRODUCT_CONTAQ_82C693)
                    224:                        continue;
                    225:
                    226:                /*
                    227:                 * Found one!
                    228:                 */
                    229:
                    230: #if 0
                    231:                printf("cy82c693_setup_elcr: found 82C693 at device %d\n",
                    232:                    device);
                    233: #endif
                    234:
                    235:                sio_cy82c693_handle = cy82c693_init(sio_iot);
                    236:                sio_read_elcr = cy82c693_read_elcr;
                    237:                sio_write_elcr = cy82c693_write_elcr;
                    238:
                    239:                return (0);
                    240:        }
                    241:
                    242:        /*
                    243:         * Didn't find a CY82C693.
                    244:         */
                    245:        return (ENODEV);
                    246: }
                    247:
                    248: u_int8_t
                    249: cy82c693_read_elcr(elcr)
                    250:        int elcr;
                    251: {
                    252:
                    253:        return (cy82c693_read(sio_cy82c693_handle, CONFIG_ELCR1 + elcr));
                    254: }
                    255:
                    256: void
                    257: cy82c693_write_elcr(elcr, val)
                    258:        int elcr;
                    259:        u_int8_t val;
                    260: {
                    261:
                    262:        cy82c693_write(sio_cy82c693_handle, CONFIG_ELCR1 + elcr, val);
                    263: }
                    264:
                    265: /******************** ELCR access function configuration ********************/
                    266:
                    267: /*
                    268:  * Put the Intel SIO at the end, so we fall back on it if we don't
                    269:  * find anything else.  If any of the non-Intel functions find a
                    270:  * matching device, but are unable to map it for whatever reason,
                    271:  * they should panic.
                    272:  */
                    273:
                    274: int (*sio_elcr_setup_funcs[])(void) = {
                    275:        cy82c693_setup_elcr,
                    276:        i82378_setup_elcr,
                    277:        NULL,
                    278: };
                    279:
                    280: /******************** Shared SIO/Cypress functions ********************/
                    281:
                    282: void
                    283: sio_setirqstat(irq, enabled, type)
                    284:        int irq, enabled;
                    285:        int type;
                    286: {
                    287:        u_int8_t ocw1[2], elcr[2];
                    288:        int icu, bit;
                    289:
                    290: #if 0
                    291:        printf("sio_setirqstat: irq %d: %s, %s\n", irq,
                    292:            enabled ? "enabled" : "disabled", isa_intr_typename(type));
                    293: #endif
                    294:
                    295:        icu = irq / 8;
                    296:        bit = irq % 8;
                    297:
                    298:        ocw1[0] = bus_space_read_1(sio_iot, sio_ioh_icu1, 1);
                    299:        ocw1[1] = bus_space_read_1(sio_iot, sio_ioh_icu2, 1);
                    300:        elcr[0] = (*sio_read_elcr)(0);                          /* XXX */
                    301:        elcr[1] = (*sio_read_elcr)(1);                          /* XXX */
                    302:
                    303:        /*
                    304:         * interrupt enable: set bit to mask (disable) interrupt.
                    305:         */
                    306:        if (enabled)
                    307:                ocw1[icu] &= ~(1 << bit);
                    308:        else
                    309:                ocw1[icu] |= 1 << bit;
                    310:
                    311:        /*
                    312:         * interrupt type select: set bit to get level-triggered.
                    313:         */
                    314:        if (type == IST_LEVEL)
                    315:                elcr[icu] |= 1 << bit;
                    316:        else
                    317:                elcr[icu] &= ~(1 << bit);
                    318:
                    319: #ifdef not_here
                    320:        /* see the init function... */
                    321:        ocw1[0] &= ~0x04;               /* always enable IRQ2 on first PIC */
                    322:        elcr[0] &= ~0x07;               /* IRQ[0-2] must be edge-triggered */
                    323:        elcr[1] &= ~0x21;               /* IRQ[13,8] must be edge-triggered */
                    324: #endif
                    325:
                    326:        bus_space_write_1(sio_iot, sio_ioh_icu1, 1, ocw1[0]);
                    327:        bus_space_write_1(sio_iot, sio_ioh_icu2, 1, ocw1[1]);
                    328:        (*sio_write_elcr)(0, elcr[0]);                          /* XXX */
                    329:        (*sio_write_elcr)(1, elcr[1]);                          /* XXX */
                    330: }
                    331:
                    332: void
                    333: sio_intr_setup(pc, iot)
                    334:        pci_chipset_tag_t pc;
                    335:        bus_space_tag_t iot;
                    336: {
                    337: #ifdef notyet
                    338:        char *cp;
                    339: #endif
                    340:        int i;
                    341:
                    342:        sio_iot = iot;
                    343:        sio_pc = pc;
                    344:
                    345:        if (bus_space_map(sio_iot, IO_ICU1, 2, 0, &sio_ioh_icu1) ||
                    346:            bus_space_map(sio_iot, IO_ICU2, 2, 0, &sio_ioh_icu2))
                    347:                panic("sio_intr_setup: can't map ICU I/O ports");
                    348:
                    349:        for (i = 0; sio_elcr_setup_funcs[i] != NULL; i++)
                    350:                if ((*sio_elcr_setup_funcs[i])() == 0)
                    351:                        break;
                    352:        if (sio_elcr_setup_funcs[i] == NULL)
                    353:                panic("sio_intr_setup: can't map ELCR");
                    354:
                    355: #ifdef BROKEN_PROM_CONSOLE
                    356:        /*
                    357:         * Remember the initial values, so we can restore them later.
                    358:         */
                    359:        initial_ocw1[0] = bus_space_read_1(sio_iot, sio_ioh_icu1, 1);
                    360:        initial_ocw1[1] = bus_space_read_1(sio_iot, sio_ioh_icu2, 1);
                    361:        initial_elcr[0] = (*sio_read_elcr)(0);                  /* XXX */
                    362:        initial_elcr[1] = (*sio_read_elcr)(1);                  /* XXX */
                    363:        shutdownhook_establish(sio_intr_shutdown, 0);
                    364: #endif
                    365:
                    366:        sio_intr = alpha_shared_intr_alloc(ICU_LEN);
                    367:
                    368:        /*
                    369:         * set up initial values for interrupt enables.
                    370:         */
                    371:        for (i = 0; i < ICU_LEN; i++) {
                    372:                alpha_shared_intr_set_maxstrays(sio_intr, i, STRAY_MAX);
                    373:
                    374:                switch (i) {
                    375:                case 0:
                    376:                case 1:
                    377:                case 8:
                    378:                case 13:
                    379:                        /*
                    380:                         * IRQs 0, 1, 8, and 13 must always be
                    381:                         * edge-triggered.
                    382:                         */
                    383:                        sio_setirqstat(i, 0, IST_EDGE);
                    384:                        alpha_shared_intr_set_dfltsharetype(sio_intr, i,
                    385:                            IST_EDGE);
                    386:                        specific_eoi(i);
                    387:                        break;
                    388:
                    389:                case 2:
                    390:                        /*
                    391:                         * IRQ 2 must be edge-triggered, and should be
                    392:                         * enabled (otherwise IRQs 8-15 are ignored).
                    393:                         */
                    394:                        sio_setirqstat(i, 1, IST_EDGE);
                    395:                        alpha_shared_intr_set_dfltsharetype(sio_intr, i,
                    396:                            IST_UNUSABLE);
                    397:                        break;
                    398:
                    399:                default:
                    400:                        /*
                    401:                         * Otherwise, disable the IRQ and set its
                    402:                         * type to (effectively) "unknown."
                    403:                         */
                    404:                        sio_setirqstat(i, 0, IST_NONE);
                    405:                        alpha_shared_intr_set_dfltsharetype(sio_intr, i,
                    406:                            IST_NONE);
                    407:                        specific_eoi(i);
                    408:                        break;
                    409:                }
                    410:        }
                    411: }
                    412:
                    413: #ifdef BROKEN_PROM_CONSOLE
                    414: void
                    415: sio_intr_shutdown(arg)
                    416:        void *arg;
                    417: {
                    418:        /*
                    419:         * Restore the initial values, to make the PROM happy.
                    420:         */
                    421:        bus_space_write_1(sio_iot, sio_ioh_icu1, 1, initial_ocw1[0]);
                    422:        bus_space_write_1(sio_iot, sio_ioh_icu2, 1, initial_ocw1[1]);
                    423:        (*sio_write_elcr)(0, initial_elcr[0]);                  /* XXX */
                    424:        (*sio_write_elcr)(1, initial_elcr[1]);                  /* XXX */
                    425: }
                    426: #endif
                    427:
                    428: const char *
                    429: sio_intr_string(v, irq)
                    430:        void *v;
                    431:        int irq;
                    432: {
                    433:        static char irqstr[12];         /* 8 + 2 + NULL + sanity */
                    434:
                    435:        if (irq == 0 || irq >= ICU_LEN || irq == 2)
                    436:                panic("sio_intr_string: bogus isa irq 0x%x", irq);
                    437:
                    438:        snprintf(irqstr, sizeof irqstr, "isa irq %d", irq);
                    439:        return (irqstr);
                    440: }
                    441:
                    442: int
                    443: sio_intr_line(v, irq)
                    444:        void *v;
                    445:        int irq;
                    446: {
                    447:        return (irq);
                    448: }
                    449:
                    450: void *
                    451: sio_intr_establish(v, irq, type, level, fn, arg, name)
                    452:        void *v, *arg;
                    453:         int irq;
                    454:         int type;
                    455:         int level;
                    456:         int (*fn)(void *);
                    457:        char *name;
                    458: {
                    459:        void *cookie;
                    460:
                    461:        if (irq > ICU_LEN || type == IST_NONE)
                    462:                panic("sio_intr_establish: bogus irq or type");
                    463:
                    464:        cookie = alpha_shared_intr_establish(sio_intr, irq, type, level, fn,
                    465:            arg, name);
                    466:
                    467:        if (cookie != NULL &&
                    468:            alpha_shared_intr_firstactive(sio_intr, irq)) {
                    469:                scb_set(0x800 + SCB_IDXTOVEC(irq), sio_iointr, NULL);
                    470:                sio_setirqstat(irq, 1,
                    471:                    alpha_shared_intr_get_sharetype(sio_intr, irq));
                    472:        }
                    473:
                    474:        return (cookie);
                    475: }
                    476:
                    477: void
                    478: sio_intr_disestablish(v, cookie)
                    479:        void *v;
                    480:        void *cookie;
                    481: {
                    482:        struct alpha_shared_intrhand *ih = cookie;
                    483:        int s, ist, irq = ih->ih_num;
                    484:
                    485:        s = splhigh();
                    486:
                    487:        /* Remove it from the link. */
                    488:        alpha_shared_intr_disestablish(sio_intr, cookie, "isa irq");
                    489:
                    490:        /*
                    491:         * Decide if we should disable the interrupt.  We must ensure
                    492:         * that:
                    493:         *
                    494:         *      - An initially-enabled interrupt is never disabled.
                    495:         *      - An initially-LT interrupt is never untyped.
                    496:         */
                    497:        if (alpha_shared_intr_isactive(sio_intr, irq) == 0) {
                    498:                /*
                    499:                 * IRQs 0, 1, 8, and 13 must always be edge-triggered
                    500:                 * (see setup).
                    501:                 */
                    502:                switch (irq) {
                    503:                case 0:
                    504:                case 1:
                    505:                case 8:
                    506:                case 13:
                    507:                        /*
                    508:                         * If the interrupt was initially level-triggered
                    509:                         * a warning was printed in setup.
                    510:                         */
                    511:                        ist = IST_EDGE;
                    512:                        break;
                    513:
                    514:                default:
                    515:                        ist = IST_NONE;
                    516:                        break;
                    517:                }
                    518:                sio_setirqstat(irq, 0, ist);
                    519:                alpha_shared_intr_set_dfltsharetype(sio_intr, irq, ist);
                    520:
                    521:                /* Release our SCB vector. */
                    522:                scb_free(0x800 + SCB_IDXTOVEC(irq));
                    523:        }
                    524:
                    525:        splx(s);
                    526: }
                    527:
                    528: void
                    529: sio_iointr(arg, vec)
                    530:        void *arg;
                    531:        unsigned long vec;
                    532: {
                    533:        int irq;
                    534:
                    535:        irq = SCB_VECTOIDX(vec - 0x800);
                    536:
                    537: #ifdef DIAGNOSTIC
                    538:        if (irq >= ICU_LEN || irq < 0)
                    539:                panic("sio_iointr: irq out of range (%d)", irq);
                    540: #endif
                    541:
                    542:        if (!alpha_shared_intr_dispatch(sio_intr, irq))
                    543:                alpha_shared_intr_stray(sio_intr, irq, "isa irq");
                    544:        else
                    545:                alpha_shared_intr_reset_strays(sio_intr, irq);
                    546:
                    547:        /*
                    548:         * Some versions of the machines which use the SIO
                    549:         * (or is it some PALcode revisions on those machines?)
                    550:         * require the non-specific EOI to be fed to the PIC(s)
                    551:         * by the interrupt handler.
                    552:         */
                    553:        specific_eoi(irq);
                    554: }
                    555:
                    556: #define        LEGAL_IRQ(x)    ((x) >= 0 && (x) < ICU_LEN && (x) != 2)
                    557:
                    558: int
                    559: sio_intr_alloc(v, mask, type, irq)
                    560:        void *v;
                    561:        int mask;
                    562:        int type;
                    563:        int *irq;
                    564: {
                    565:        int i, tmp, bestirq, count;
                    566:        struct alpha_shared_intrhand **p, *q;
                    567:
                    568:        if (type == IST_NONE)
                    569:                panic("intr_alloc: bogus type");
                    570:
                    571:        bestirq = -1;
                    572:        count = -1;
                    573:
                    574:        /* some interrupts should never be dynamically allocated */
                    575:        mask &= 0xdef8;
                    576:
                    577:        /*
                    578:         * XXX some interrupts will be used later (6 for fdc, 12 for pms).
                    579:         * the right answer is to do "breadth-first" searching of devices.
                    580:         */
                    581:        mask &= 0xefbf;
                    582:
                    583:        for (i = 0; i < ICU_LEN; i++) {
                    584:                if (LEGAL_IRQ(i) == 0 || (mask & (1<<i)) == 0)
                    585:                        continue;
                    586:
                    587:                switch(sio_intr[i].intr_sharetype) {
                    588:                case IST_NONE:
                    589:                        /*
                    590:                         * if nothing's using the irq, just return it
                    591:                         */
                    592:                        *irq = i;
                    593:                        return (0);
                    594:
                    595:                case IST_EDGE:
                    596:                case IST_LEVEL:
                    597:                        if (type != sio_intr[i].intr_sharetype)
                    598:                                continue;
                    599:                        /*
                    600:                         * if the irq is shareable, count the number of other
                    601:                         * handlers, and if it's smaller than the last irq like
                    602:                         * this, remember it
                    603:                         *
                    604:                         * XXX We should probably also consider the
                    605:                         * interrupt level and stick IPL_TTY with other
                    606:                         * IPL_TTY, etc.
                    607:                         */
                    608:                        for (p = &TAILQ_FIRST(&sio_intr[i].intr_q), tmp = 0;
                    609:                             (q = *p) != NULL; p = &TAILQ_NEXT(q, ih_q), tmp++)
                    610:                                ;
                    611:                        if ((bestirq == -1) || (count > tmp)) {
                    612:                                bestirq = i;
                    613:                                count = tmp;
                    614:                        }
                    615:                        break;
                    616:
                    617:                case IST_PULSE:
                    618:                        /* this just isn't shareable */
                    619:                        continue;
                    620:                }
                    621:        }
                    622:
                    623:        if (bestirq == -1)
                    624:                return (1);
                    625:
                    626:        *irq = bestirq;
                    627:
                    628:        return (0);
                    629: }
                    630:
                    631: static void
                    632: specific_eoi(irq)
                    633:        int irq;
                    634: {
                    635:        if (irq > 7)
                    636:                bus_space_write_1(sio_iot,
                    637:                    sio_ioh_icu2, 0, 0x20 | (irq & 0x07));      /* XXX */
                    638:        bus_space_write_1(sio_iot, sio_ioh_icu1, 0, 0x20 | (irq > 7 ? 2 : irq));
                    639: }

CVSweb