Annotation of sys/dev/isa/addcom_isa.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: addcom_isa.c,v 1.6 2002/03/14 01:26:56 millert Exp $ */
! 2: /* $NetBSD: addcom_isa.c,v 1.2 2000/04/21 20:13:41 explorer Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 2000 Michael Graff. All rights reserved.
! 6: * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
! 7: * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
! 8: *
! 9: * This code is derived from public-domain software written by
! 10: * Roland McGrath, and information provided by David Muir Sharnoff.
! 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 Charles M. Hannum.
! 23: * 4. The name of the author may not be used to endorse or promote products
! 24: * derived from this software without specific prior written permission.
! 25: *
! 26: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 27: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 28: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 29: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 30: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 31: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 32: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 33: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 34: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 35: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 36: */
! 37:
! 38: /*
! 39: * This code was written and tested with the Addonics FlexPort 8S.
! 40: * It has 8 ports, using 16650-compatible chips, sharing a single
! 41: * interrupt.
! 42: *
! 43: * An interrupt status register exists at 0x240, according to the
! 44: * skimpy documentation supplied. It doesn't change depending on
! 45: * io base address, so only one of these cards can ever be used at
! 46: * a time.
! 47: *
! 48: * NOTE: the status register does not appear to work as advertised,
! 49: * so instead we depend on the slave devices being intelligent enough
! 50: * to determine whether they interrupted or not.
! 51: *
! 52: * This card is different from the boca or other cards in that ports
! 53: * 0..5 are from addresses 0x108..0x137, and 6..7 are from 0x200..0x20f,
! 54: * making a gap that the other cards do not have.
! 55: *
! 56: * The addresses which are documented are 0x108, 0x1108, 0x1d08, and
! 57: * 0x8508, for the base (port 0) address.
! 58: *
! 59: * --Michael <explorer@netbsd.org> -- April 21, 2000
! 60: */
! 61:
! 62: #include <sys/param.h>
! 63: #include <sys/systm.h>
! 64: #include <sys/device.h>
! 65: #include <sys/termios.h>
! 66:
! 67: #include <machine/bus.h>
! 68: #include <machine/intr.h>
! 69:
! 70: #include <dev/ic/comreg.h>
! 71: #include <dev/ic/comvar.h>
! 72:
! 73: #include <dev/isa/isavar.h>
! 74:
! 75: #define NSLAVES 8
! 76:
! 77: /*
! 78: * Grr. This card always uses 0x420 for the status register, regardless
! 79: * of io base address.
! 80: */
! 81: #define STATUS_IOADDR 0x420
! 82: #define STATUS_SIZE 8 /* May be bogus... */
! 83:
! 84: struct addcom_softc {
! 85: struct device sc_dev;
! 86: void *sc_ih;
! 87:
! 88: bus_space_tag_t sc_iot;
! 89: bus_addr_t sc_iobase;
! 90:
! 91: int sc_alive[NSLAVES];
! 92: void *sc_slaves[NSLAVES]; /* com device unit numbers */
! 93: bus_space_handle_t sc_slaveioh[NSLAVES];
! 94: bus_space_handle_t sc_statusioh;
! 95: };
! 96:
! 97: #define SLAVE_IOBASE_OFFSET 0x108
! 98: static int slave_iobases[8] = {
! 99: 0x108, /* port 0, base port */
! 100: 0x110,
! 101: 0x118,
! 102: 0x120,
! 103: 0x128,
! 104: 0x130,
! 105: 0x200, /* port 7, note address skip... */
! 106: 0x208
! 107: };
! 108:
! 109: int addcomprobe(struct device *, void *, void *);
! 110: void addcomattach(struct device *, struct device *, void *);
! 111: int addcomintr(void *);
! 112: int addcomprint(void *, const char *);
! 113:
! 114: struct cfattach addcom_isa_ca = {
! 115: sizeof(struct addcom_softc), addcomprobe, addcomattach,
! 116: };
! 117:
! 118: struct cfdriver addcom_cd = {
! 119: NULL, "addcom", DV_TTY
! 120: };
! 121:
! 122: int
! 123: addcomprobe(parent, self, aux)
! 124: struct device *parent;
! 125: void *self, *aux;
! 126: {
! 127: struct isa_attach_args *ia = aux;
! 128: int iobase = ia->ia_iobase;
! 129: bus_space_tag_t iot = ia->ia_iot;
! 130: bus_space_handle_t ioh;
! 131: int i, rv = 1;
! 132:
! 133: /*
! 134: * Do the normal com probe for the first UART and assume
! 135: * its presence, and the ability to map the other UARTS,
! 136: * means there is a multiport board there.
! 137: * XXX Needs more robustness.
! 138: */
! 139:
! 140: /* Disallow wildcarded i/o address. */
! 141: if (ia->ia_iobase == -1 /* ISACF_PORT_DEFAULT */)
! 142: return (0);
! 143:
! 144: /* if the first port is in use as console, then it. */
! 145: if (iobase == comconsaddr && !comconsattached)
! 146: goto checkmappings;
! 147:
! 148: if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh)) {
! 149: rv = 0;
! 150: goto out;
! 151: }
! 152: rv = comprobe1(iot, ioh);
! 153: bus_space_unmap(iot, ioh, COM_NPORTS);
! 154: if (rv == 0)
! 155: goto out;
! 156:
! 157: checkmappings:
! 158: for (i = 1; i < NSLAVES; i++) {
! 159: iobase += slave_iobases[i] - slave_iobases[i - 1];
! 160:
! 161: if (iobase == comconsaddr && !comconsattached)
! 162: continue;
! 163:
! 164: if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh)) {
! 165: rv = 0;
! 166: goto out;
! 167: }
! 168: bus_space_unmap(iot, ioh, COM_NPORTS);
! 169: }
! 170:
! 171: out:
! 172: if (rv)
! 173: ia->ia_iosize = NSLAVES * COM_NPORTS;
! 174: return (rv);
! 175: }
! 176:
! 177: int
! 178: addcomprint(aux, pnp)
! 179: void *aux;
! 180: const char *pnp;
! 181: {
! 182: struct commulti_attach_args *ca = aux;
! 183:
! 184: if (pnp)
! 185: printf("com at %s", pnp);
! 186: printf(" slave %d", ca->ca_slave);
! 187: return (UNCONF);
! 188: }
! 189:
! 190: void
! 191: addcomattach(parent, self, aux)
! 192: struct device *parent, *self;
! 193: void *aux;
! 194: {
! 195: struct addcom_softc *sc = (void *)self;
! 196: struct isa_attach_args *ia = aux;
! 197: struct commulti_attach_args ca;
! 198: bus_space_tag_t iot = ia->ia_iot;
! 199: bus_addr_t iobase;
! 200: int i;
! 201:
! 202: sc->sc_iot = ia->ia_iot;
! 203: sc->sc_iobase = ia->ia_iobase;
! 204:
! 205: /* Disallow wildcard interrupt. */
! 206: if (ia->ia_irq == IRQUNK) {
! 207: printf(": wildcard interrupt not supported\n");
! 208: return;
! 209: }
! 210:
! 211: sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
! 212: IPL_TTY, addcomintr, sc, sc->sc_dev.dv_xname);
! 213: if (sc->sc_ih == NULL) {
! 214: printf(": can't establish interrupt\n");
! 215: return;
! 216: }
! 217:
! 218: if (bus_space_map(iot, STATUS_IOADDR, STATUS_SIZE,
! 219: 0, &sc->sc_statusioh)) {
! 220: printf(": can't map status space\n");
! 221: return;
! 222: }
! 223:
! 224: for (i = 0; i < NSLAVES; i++) {
! 225: iobase = sc->sc_iobase
! 226: + slave_iobases[i]
! 227: - SLAVE_IOBASE_OFFSET;
! 228:
! 229: if ((!(iobase == comconsaddr && !comconsattached)) &&
! 230: bus_space_map(iot, iobase, COM_NPORTS, 0,
! 231: &sc->sc_slaveioh[i])) {
! 232: printf(": can't map i/o space for slave %d\n", i);
! 233: return;
! 234: }
! 235: }
! 236:
! 237: printf("\n");
! 238:
! 239: for (i = 0; i < NSLAVES; i++) {
! 240: ca.ca_slave = i;
! 241: ca.ca_iot = sc->sc_iot;
! 242: ca.ca_ioh = sc->sc_slaveioh[i];
! 243: ca.ca_iobase = sc->sc_iobase
! 244: + slave_iobases[i]
! 245: - SLAVE_IOBASE_OFFSET;
! 246: ca.ca_noien = 0;
! 247:
! 248: sc->sc_slaves[i] = config_found(self, &ca, addcomprint);
! 249: if (sc->sc_slaves[i] != NULL)
! 250: sc->sc_alive[i] = 1;
! 251: }
! 252:
! 253: }
! 254:
! 255: int
! 256: addcomintr(arg)
! 257: void *arg;
! 258: {
! 259: struct addcom_softc *sc = arg;
! 260: int intrd, r = 0, i;
! 261:
! 262: do {
! 263: intrd = 0;
! 264: for (i = 0; i < NSLAVES; i++)
! 265: if (sc->sc_alive[i] && comintr(sc->sc_slaves[i])) {
! 266: r = 1;
! 267: intrd = 1;
! 268: }
! 269: } while (intrd);
! 270:
! 271: return (r);
! 272: }
CVSweb