1 /* $NetBSD: rtfps.c,v 1.12 1995/04/17 12:09:22 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 rtfps_softc { 43 struct device sc_dev; 44 void *sc_ih; 45 46 int sc_iobase; 47 int sc_irqport; 48 int sc_alive; /* mask of slave units attached */ 49 void *sc_slaves[4]; /* com device unit numbers */ 50 }; 51 52 int rtfpsprobe(); 53 void rtfpsattach(); 54 int rtfpsintr __P((void *)); 55 56 struct cfdriver rtfpscd = { 57 NULL, "rtfps", rtfpsprobe, rtfpsattach, DV_TTY, sizeof(struct rtfps_softc) 58 }; 59 60 int 61 rtfpsprobe(parent, self, aux) 62 struct device *parent, *self; 63 void *aux; 64 { 65 struct isa_attach_args *ia = aux; 66 67 /* 68 * Do the normal com probe for the first UART and assume 69 * its presence means there is a multiport board there. 70 * XXX Needs more robustness. 71 */ 72 ia->ia_iosize = 4 * 8; 73 return comprobe1(ia->ia_iobase); 74 } 75 76 struct rtfps_attach_args { 77 int ra_slave; 78 }; 79 80 int 81 rtfpssubmatch(parent, match, aux) 82 struct device *parent; 83 void *match, *aux; 84 { 85 struct rtfps_softc *sc = (void *)parent; 86 struct cfdata *cf = match; 87 struct isa_attach_args *ia = aux; 88 struct rtfps_attach_args *ra = ia->ia_aux; 89 90 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ra->ra_slave) 91 return (0); 92 return ((*cf->cf_driver->cd_match)(parent, match, ia)); 93 } 94 95 int 96 rtfpsprint(aux, rtfps) 97 void *aux; 98 char *rtfps; 99 { 100 struct isa_attach_args *ia = aux; 101 struct rtfps_attach_args *ra = ia->ia_aux; 102 103 printf(" slave %d", ra->ra_slave); 104 } 105 106 void 107 rtfpsattach(parent, self, aux) 108 struct device *parent, *self; 109 void *aux; 110 { 111 struct rtfps_softc *sc = (void *)self; 112 struct isa_attach_args *ia = aux; 113 struct rtfps_attach_args ra; 114 struct isa_attach_args isa; 115 static int irqport[] = { 116 IOBASEUNK, IOBASEUNK, IOBASEUNK, IOBASEUNK, 117 IOBASEUNK, IOBASEUNK, IOBASEUNK, IOBASEUNK, 118 IOBASEUNK, 0x2f2, 0x6f2, 0x6f3, 119 IOBASEUNK, IOBASEUNK, IOBASEUNK, IOBASEUNK 120 }; 121 122 sc->sc_iobase = ia->ia_iobase; 123 124 if (ia->ia_irq >= 16 || irqport[ia->ia_irq] == IOBASEUNK) 125 panic("rtfpsattach: invalid irq"); 126 sc->sc_irqport = irqport[ia->ia_irq]; 127 128 outb(sc->sc_irqport, 0); 129 130 printf("\n"); 131 132 isa.ia_aux = &ra; 133 for (ra.ra_slave = 0; ra.ra_slave < 4; ra.ra_slave++) { 134 struct cfdata *cf; 135 isa.ia_iobase = sc->sc_iobase + 8 * ra.ra_slave; 136 isa.ia_iosize = 0x666; 137 isa.ia_irq = IRQUNK; 138 isa.ia_drq = DRQUNK; 139 isa.ia_msize = 0; 140 if ((cf = config_search(rtfpssubmatch, self, &isa)) != 0) { 141 config_attach(self, cf, &isa, rtfpsprint); 142 sc->sc_slaves[ra.ra_slave] = 143 cf->cf_driver->cd_devs[cf->cf_unit]; 144 sc->sc_alive |= 1 << ra.ra_slave; 145 } 146 } 147 148 sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_EDGE, ISA_IPL_TTY, 149 rtfpsintr, sc); 150 } 151 152 int 153 rtfpsintr(arg) 154 void *arg; 155 { 156 struct rtfps_softc *sc = arg; 157 int iobase = sc->sc_iobase; 158 int alive = sc->sc_alive; 159 160 outb(sc->sc_irqport, 0); 161 162 #define TRY(n) \ 163 if (alive & (1 << (n))) \ 164 comintr(sc->sc_slaves[n]); 165 TRY(0); 166 TRY(1); 167 TRY(2); 168 TRY(3); 169 #undef TRY 170 171 return (1); 172 } 173