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

Annotation of sys/arch/alpha/pci/pci_kn20aa.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: pci_kn20aa.c,v 1.22 2006/06/15 20:08:29 brad Exp $    */
        !             2: /*     $NetBSD: pci_kn20aa.c,v 1.21 1996/11/17 02:05:27 cgd Exp $      */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Author: 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: #include <sys/types.h>
        !            32: #include <sys/param.h>
        !            33: #include <sys/time.h>
        !            34: #include <sys/systm.h>
        !            35: #include <sys/errno.h>
        !            36: #include <sys/malloc.h>
        !            37: #include <sys/device.h>
        !            38: #include <sys/syslog.h>
        !            39:
        !            40: #include <uvm/uvm_extern.h>
        !            41:
        !            42: #include <machine/autoconf.h>
        !            43:
        !            44: #include <dev/pci/pcireg.h>
        !            45: #include <dev/pci/pcivar.h>
        !            46:
        !            47: #include <alpha/pci/ciareg.h>
        !            48: #include <alpha/pci/ciavar.h>
        !            49:
        !            50: #include <alpha/pci/pci_kn20aa.h>
        !            51:
        !            52: #include "sio.h"
        !            53: #if NSIO
        !            54: #include <alpha/pci/siovar.h>
        !            55: #endif
        !            56:
        !            57: int    dec_kn20aa_intr_map(void *, pcitag_t, int, int,
        !            58:            pci_intr_handle_t *);
        !            59: const char *dec_kn20aa_intr_string(void *, pci_intr_handle_t);
        !            60: int    dec_kn20aa_intr_line(void *, pci_intr_handle_t);
        !            61: void   *dec_kn20aa_intr_establish(void *, pci_intr_handle_t,
        !            62:            int, int (*func)(void *), void *, char *);
        !            63: void   dec_kn20aa_intr_disestablish(void *, void *);
        !            64:
        !            65: #define        KN20AA_PCEB_IRQ 31
        !            66: #define        KN20AA_MAX_IRQ  32
        !            67: #define        PCI_STRAY_MAX   5
        !            68:
        !            69: struct alpha_shared_intr *kn20aa_pci_intr;
        !            70: struct evcount kn20aa_intr_count;
        !            71:
        !            72: void   kn20aa_iointr(void *arg, unsigned long vec);
        !            73: void   kn20aa_enable_intr(int irq);
        !            74: void   kn20aa_disable_intr(int irq);
        !            75:
        !            76: void
        !            77: pci_kn20aa_pickintr(ccp)
        !            78:        struct cia_config *ccp;
        !            79: {
        !            80:        int i;
        !            81:        bus_space_tag_t iot = &ccp->cc_iot;
        !            82:        pci_chipset_tag_t pc = &ccp->cc_pc;
        !            83:
        !            84:         pc->pc_intr_v = ccp;
        !            85:         pc->pc_intr_map = dec_kn20aa_intr_map;
        !            86:         pc->pc_intr_string = dec_kn20aa_intr_string;
        !            87:         pc->pc_intr_line = dec_kn20aa_intr_line;
        !            88:         pc->pc_intr_establish = dec_kn20aa_intr_establish;
        !            89:         pc->pc_intr_disestablish = dec_kn20aa_intr_disestablish;
        !            90:
        !            91:         /* Not supported on KN20AA. */
        !            92:         pc->pc_pciide_compat_intr_establish = NULL;
        !            93:         pc->pc_pciide_compat_intr_disestablish = NULL;
        !            94:
        !            95:        kn20aa_pci_intr = alpha_shared_intr_alloc(KN20AA_MAX_IRQ);
        !            96:        for (i = 0; i < KN20AA_MAX_IRQ; i++)
        !            97:                alpha_shared_intr_set_maxstrays(kn20aa_pci_intr, i,
        !            98:                    PCI_STRAY_MAX);
        !            99:
        !           100: #if NSIO
        !           101:        sio_intr_setup(pc, iot);
        !           102:        kn20aa_enable_intr(KN20AA_PCEB_IRQ);
        !           103: #endif
        !           104: }
        !           105:
        !           106: int
        !           107: dec_kn20aa_intr_map(ccv, bustag, buspin, line, ihp)
        !           108:         void *ccv;
        !           109:         pcitag_t bustag;
        !           110:         int buspin, line;
        !           111:         pci_intr_handle_t *ihp;
        !           112: {
        !           113:        struct cia_config *ccp = ccv;
        !           114:        pci_chipset_tag_t pc = &ccp->cc_pc;
        !           115:        int device;
        !           116:        int kn20aa_irq;
        !           117:
        !           118:         if (buspin == 0) {
        !           119:                 /* No IRQ used. */
        !           120:                 return 1;
        !           121:         }
        !           122:         if (buspin > 4) {
        !           123:                 printf("pci_map_int: bad interrupt pin %d\n", buspin);
        !           124:                 return 1;
        !           125:         }
        !           126:
        !           127:        /*
        !           128:         * Slot->interrupt translation.  Appears to work, though it
        !           129:         * may not hold up forever.
        !           130:         *
        !           131:         * The DEC engineers who did this hardware obviously engaged
        !           132:         * in random drug testing.
        !           133:         */
        !           134:        pci_decompose_tag(pc, bustag, NULL, &device, NULL);
        !           135:        switch (device) {
        !           136:        case 11:
        !           137:        case 12:
        !           138:                kn20aa_irq = ((device - 11) + 0) * 4;
        !           139:                break;
        !           140:
        !           141:        case 7:
        !           142:                kn20aa_irq = 8;
        !           143:                break;
        !           144:
        !           145:        case 9:
        !           146:                kn20aa_irq = 12;
        !           147:                break;
        !           148:
        !           149:        case 6:                                 /* 21040 on AlphaStation 500 */
        !           150:                kn20aa_irq = 13;
        !           151:                break;
        !           152:
        !           153:        case 8:
        !           154:                kn20aa_irq = 16;
        !           155:                break;
        !           156:
        !           157:        default:
        !           158:                 printf("dec_kn20aa_intr_map: weird device number %d\n",
        !           159:                    device);
        !           160:                 return 1;
        !           161:        }
        !           162:
        !           163:        kn20aa_irq += buspin - 1;
        !           164:        if (kn20aa_irq > KN20AA_MAX_IRQ)
        !           165:                panic("pci_kn20aa_map_int: kn20aa_irq too large (%d)",
        !           166:                    kn20aa_irq);
        !           167:
        !           168:        *ihp = kn20aa_irq;
        !           169:        return (0);
        !           170: }
        !           171:
        !           172: const char *
        !           173: dec_kn20aa_intr_string(ccv, ih)
        !           174:        void *ccv;
        !           175:        pci_intr_handle_t ih;
        !           176: {
        !           177:         static char irqstr[15];          /* 11 + 2 + NULL + sanity */
        !           178:
        !           179:         if (ih > KN20AA_MAX_IRQ)
        !           180:                panic("dec_kn20aa_intr_string: bogus kn20aa IRQ 0x%x", ih);
        !           181:
        !           182:         snprintf(irqstr, sizeof irqstr, "kn20aa irq %ld", ih);
        !           183:         return (irqstr);
        !           184: }
        !           185:
        !           186: int
        !           187: dec_kn20aa_intr_line(ccv, ih)
        !           188:        void *ccv;
        !           189:        pci_intr_handle_t ih;
        !           190: {
        !           191:        return (ih);
        !           192: }
        !           193:
        !           194: void *
        !           195: dec_kn20aa_intr_establish(ccv, ih, level, func, arg, name)
        !           196:         void *ccv, *arg;
        !           197:         pci_intr_handle_t ih;
        !           198:         int level;
        !           199:         int (*func)(void *);
        !           200:        char *name;
        !           201: {
        !           202:        void *cookie;
        !           203:
        !           204:         if (ih > KN20AA_MAX_IRQ)
        !           205:                 panic("dec_kn20aa_intr_establish: bogus kn20aa IRQ 0x%x",
        !           206:                    ih);
        !           207:
        !           208:        cookie = alpha_shared_intr_establish(kn20aa_pci_intr, ih, IST_LEVEL,
        !           209:            level, func, arg, name);
        !           210:
        !           211:        if (cookie != NULL &&
        !           212:            alpha_shared_intr_firstactive(kn20aa_pci_intr, ih)) {
        !           213:                scb_set(0x900 + SCB_IDXTOVEC(ih), kn20aa_iointr, NULL);
        !           214:                kn20aa_enable_intr(ih);
        !           215:        }
        !           216:        return (cookie);
        !           217: }
        !           218:
        !           219: void
        !           220: dec_kn20aa_intr_disestablish(ccv, cookie)
        !           221:         void *ccv, *cookie;
        !           222: {
        !           223:        struct alpha_shared_intrhand *ih = cookie;
        !           224:        unsigned int irq = ih->ih_num;
        !           225:        int s;
        !           226:
        !           227:        s = splhigh();
        !           228:
        !           229:        alpha_shared_intr_disestablish(kn20aa_pci_intr, cookie,
        !           230:            "kn20aa irq");
        !           231:        if (alpha_shared_intr_isactive(kn20aa_pci_intr, irq) == 0) {
        !           232:                kn20aa_disable_intr(irq);
        !           233:                alpha_shared_intr_set_dfltsharetype(kn20aa_pci_intr, irq,
        !           234:                    IST_NONE);
        !           235:                scb_free(0x900 + SCB_IDXTOVEC(irq));
        !           236:        }
        !           237:        splx(s);
        !           238: }
        !           239:
        !           240: void
        !           241: kn20aa_iointr(arg, vec)
        !           242:        void *arg;
        !           243:        unsigned long vec;
        !           244: {
        !           245:        int irq;
        !           246:
        !           247:        irq = SCB_VECTOIDX(vec - 0x900);
        !           248:
        !           249:        if (!alpha_shared_intr_dispatch(kn20aa_pci_intr, irq)) {
        !           250:                alpha_shared_intr_stray(kn20aa_pci_intr, irq,
        !           251:                    "kn20aa irq");
        !           252:                if (ALPHA_SHARED_INTR_DISABLE(kn20aa_pci_intr, irq))
        !           253:                        kn20aa_disable_intr(irq);
        !           254:        } else
        !           255:                alpha_shared_intr_reset_strays(kn20aa_pci_intr, irq);
        !           256: }
        !           257:
        !           258: void
        !           259: kn20aa_enable_intr(irq)
        !           260:        int irq;
        !           261: {
        !           262:
        !           263:        /*
        !           264:         * From disassembling small bits of the OSF/1 kernel:
        !           265:         * the following appears to enable a given interrupt request.
        !           266:         * "blech."  I'd give valuable body parts for better docs or
        !           267:         * for a good decompiler.
        !           268:         */
        !           269:        alpha_mb();
        !           270:        REGVAL(0x8780000000L + 0x40L) |= (1 << irq);    /* XXX */
        !           271:        alpha_mb();
        !           272: }
        !           273:
        !           274: void
        !           275: kn20aa_disable_intr(irq)
        !           276:        int irq;
        !           277: {
        !           278:
        !           279:        alpha_mb();
        !           280:        REGVAL(0x8780000000L + 0x40L) &= ~(1 << irq);   /* XXX */
        !           281:        alpha_mb();
        !           282: }

CVSweb