[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

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