Annotation of sys/arch/vax/vxt/vxtbus.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: vxtbus.c,v 1.2 2006/08/30 19:23:57 miod Exp $ */
! 2: /*
! 3: * Copyright (c) 2006 Miodrag Vallat.
! 4: *
! 5: * Permission to use, copy, modify, and distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice, this permission notice, and the disclaimer below
! 8: * appear in all copies.
! 9: *
! 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 17: */
! 18:
! 19: #include <sys/param.h>
! 20: #include <sys/systm.h>
! 21: #include <sys/device.h>
! 22: #include <sys/malloc.h>
! 23: #include <sys/evcount.h>
! 24: #include <sys/queue.h>
! 25:
! 26: #include <machine/cpu.h>
! 27: #include <machine/nexus.h>
! 28: #include <machine/scb.h>
! 29:
! 30: #include <vax/vxt/vxtbusvar.h>
! 31:
! 32: struct vxtbus_softc {
! 33: struct device sc_dev;
! 34: LIST_HEAD(, vxtbus_ih) sc_intrlist;
! 35: };
! 36:
! 37: void vxtbus_attach(struct device *, struct device *, void *);
! 38: int vxtbus_match(struct device *, void*, void *);
! 39:
! 40: struct cfdriver vxtbus_cd = {
! 41: NULL, "vxtbus", DV_DULL
! 42: };
! 43:
! 44: struct cfattach vxtbus_ca = {
! 45: sizeof(struct vxtbus_softc), vxtbus_match, vxtbus_attach
! 46: };
! 47:
! 48: void vxtbus_intr(void *);
! 49: int vxtbus_print(void *, const char *);
! 50:
! 51: int
! 52: vxtbus_match(struct device *parent, void *vcf, void *aux)
! 53: {
! 54: struct mainbus_attach_args *maa = aux;
! 55:
! 56: return (maa->maa_bustype == VAX_VXTBUS ? 1 : 0);
! 57: }
! 58:
! 59: void
! 60: vxtbus_attach(struct device *parent, struct device *self, void *aux)
! 61: {
! 62: struct vxtbus_softc *sc = (void *)self;
! 63: struct bp_conf bp;
! 64:
! 65: LIST_INIT(&sc->sc_intrlist);
! 66: scb_vecalloc(VXT_INTRVEC, vxtbus_intr, sc, SCB_ISTACK, NULL);
! 67:
! 68: printf("\n");
! 69:
! 70: bp.type = "sgec";
! 71: config_found(self, &bp, vxtbus_print);
! 72:
! 73: bp.type = "qsc";
! 74: config_found(self, &bp, vxtbus_print);
! 75:
! 76: bp.type = "lcspx";
! 77: config_found(self, &bp, vxtbus_print);
! 78: }
! 79:
! 80: int
! 81: vxtbus_print(void *aux, const char *name)
! 82: {
! 83: struct bp_conf *bp = aux;
! 84:
! 85: if (name)
! 86: printf("%s at %s", bp->type, name);
! 87:
! 88: return (UNCONF);
! 89: }
! 90:
! 91: /*
! 92: * VXT2000 interrupt code.
! 93: *
! 94: * All device interrupts end up on the same vector, which is controllable
! 95: * by the SC26C94 chip.
! 96: *
! 97: * Interrupts are handled at spl4 (ipl 0x14).
! 98: *
! 99: * The following routines implement shared interrupts for vxtbus subdevices.
! 100: */
! 101:
! 102: struct vxtbus_ih {
! 103: LIST_ENTRY(vxtbus_ih) ih_link;
! 104: int (*ih_fn)(void *);
! 105: void * ih_arg;
! 106: int ih_vec;
! 107: struct evcount ih_cnt;
! 108: };
! 109:
! 110: void
! 111: vxtbus_intr_establish(const char *name, int ipl, int (*fn)(void *), void *arg)
! 112: {
! 113: struct vxtbus_softc *sc = (void *)vxtbus_cd.cd_devs[0];
! 114: struct vxtbus_ih *ih;
! 115:
! 116: ih = (struct vxtbus_ih *)malloc(sizeof(*ih), M_DEVBUF, M_WAITOK);
! 117:
! 118: ih->ih_fn = fn;
! 119: ih->ih_arg = arg;
! 120: ih->ih_vec = VXT_INTRVEC;
! 121: evcount_attach(&ih->ih_cnt, name, (void *)&ih->ih_vec, &evcount_intr);
! 122:
! 123: LIST_INSERT_HEAD(&sc->sc_intrlist, ih, ih_link);
! 124: }
! 125:
! 126: void
! 127: vxtbus_intr(void *arg)
! 128: {
! 129: struct vxtbus_softc *sc = arg;
! 130: struct vxtbus_ih *ih;
! 131: int rc;
! 132: #ifdef DIAGNOSTIC
! 133: int handled = 0;
! 134: static int strayintr = 0;
! 135: #endif
! 136:
! 137: LIST_FOREACH(ih, &sc->sc_intrlist, ih_link) {
! 138: rc = (*ih->ih_fn)(ih->ih_arg);
! 139: if (rc != 0) {
! 140: #ifdef DIAGNOSTIC
! 141: handled = 1;
! 142: #endif
! 143: ih->ih_cnt.ec_count++;
! 144: if (rc > 0)
! 145: break;
! 146: }
! 147: }
! 148:
! 149: #ifdef DIAGNOSTIC
! 150: if (handled == 0) {
! 151: if (++strayintr == 10)
! 152: panic("%s: too many stray interrupts",
! 153: sc->sc_dev.dv_xname);
! 154: else
! 155: printf("%s: stray interrupt\n", sc->sc_dev.dv_xname);
! 156: }
! 157: #endif
! 158: }
CVSweb