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