1 /* $NetBSD: ast.c,v 1.18 1995/06/26 04:08:04 cgd Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Charles Hannum. All rights reserved. 5 * 6 * This code is derived from public-domain software written by 7 * Roland McGrath. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Charles Hannum. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/device.h> 37 38 #include <machine/pio.h> 39 40 #include <dev/isa/isavar.h> 41 42 struct ast_softc { 43 struct device sc_dev; 44 void *sc_ih; 45 46 int sc_iobase; 47 int sc_alive; /* mask of slave units attached */ 48 void *sc_slaves[4]; /* com device unit numbers */ 49 }; 50 51 int astprobe(); 52 void astattach(); 53 int astintr __P((void *)); 54 55 struct cfdriver astcd = { 56 NULL, "ast", astprobe, astattach, DV_TTY, sizeof(struct ast_softc) 57 }; 58 59 int 60 astprobe(parent, self, aux) 61 struct device *parent, *self; 62 void *aux; 63 { 64 struct isa_attach_args *ia = aux; 65 66 /* 67 * Do the normal com probe for the first UART and assume 68 * its presence means there is a multiport board there. 69 * XXX Needs more robustness. 70 */ 71 ia->ia_iosize = 4 * 8; 72 return (comprobe1(ia->ia_iobase)); 73 } 74 75 struct ast_attach_args { 76 int aa_slave; 77 }; 78 79 int 80 astsubmatch(parent, match, aux) 81 struct device *parent; 82 void *match, *aux; 83 { 84 struct ast_softc *sc = (void *)parent; 85 struct cfdata *cf = match; 86 struct isa_attach_args *ia = aux; 87 struct ast_attach_args *aa = ia->ia_aux; 88 89 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != aa->aa_slave) 90 return (0); 91 return ((*cf->cf_driver->cd_match)(parent, match, ia)); 92 } 93 94 int 95 astprint(aux, ast) 96 void *aux; 97 char *ast; 98 { 99 struct isa_attach_args *ia = aux; 100 struct ast_attach_args *aa = ia->ia_aux; 101 102 printf(" slave %d", aa->aa_slave); 103 } 104 105 void 106 astattach(parent, self, aux) 107 struct device *parent, *self; 108 void *aux; 109 { 110 struct ast_softc *sc = (void *)self; 111 struct isa_attach_args *ia = aux; 112 struct ast_attach_args aa; 113 struct isa_attach_args isa; 114 int subunit; 115 116 sc->sc_iobase = ia->ia_iobase; 117 118 /* 119 * Enable the master interrupt. 120 */ 121 outb(sc->sc_iobase | 0x1f, 0x80); 122 123 printf("\n"); 124 125 isa.ia_aux = &aa; 126 for (aa.aa_slave = 0; aa.aa_slave < 4; aa.aa_slave++) { 127 struct cfdata *cf; 128 isa.ia_iobase = sc->sc_iobase + 8 * aa.aa_slave; 129 isa.ia_iosize = 0x666; 130 isa.ia_irq = IRQUNK; 131 isa.ia_drq = DRQUNK; 132 isa.ia_msize = 0; 133 if ((cf = config_search(astsubmatch, self, &isa)) != 0) { 134 subunit = cf->cf_unit; /* can change if unit == * */ 135 config_attach(self, cf, &isa, astprint); 136 sc->sc_slaves[aa.aa_slave] = 137 cf->cf_driver->cd_devs[subunit]; 138 sc->sc_alive |= 1 << aa.aa_slave; 139 } 140 } 141 142 sc->sc_ih = isa_intr_establish(ia->ia_irq, IST_EDGE, IPL_TTY, astintr, 143 sc); 144 } 145 146 int 147 astintr(arg) 148 void *arg; 149 { 150 struct ast_softc *sc = arg; 151 int iobase = sc->sc_iobase; 152 int alive = sc->sc_alive; 153 int bits; 154 155 bits = ~inb(iobase | 0x1f) & alive; 156 if (bits == 0) 157 return (0); 158 159 for (;;) { 160 #define TRY(n) \ 161 if (bits & (1 << (n))) \ 162 comintr(sc->sc_slaves[n]); 163 TRY(0); 164 TRY(1); 165 TRY(2); 166 TRY(3); 167 #undef TRY 168 bits = ~inb(iobase | 0x1f) & alive; 169 if (bits == 0) 170 return (1); 171 } 172 } 173