rtfps.c revision 1.13
1/* $NetBSD: rtfps.c,v 1.13 1995/06/26 04:12:01 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 42struct 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 52int rtfpsprobe(); 53void rtfpsattach(); 54int rtfpsintr __P((void *)); 55 56struct cfdriver rtfpscd = { 57 NULL, "rtfps", rtfpsprobe, rtfpsattach, DV_TTY, sizeof(struct rtfps_softc) 58}; 59 60int 61rtfpsprobe(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 76struct rtfps_attach_args { 77 int ra_slave; 78}; 79 80int 81rtfpssubmatch(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 95int 96rtfpsprint(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 106void 107rtfpsattach(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 int subunit; 122 123 sc->sc_iobase = ia->ia_iobase; 124 125 if (ia->ia_irq >= 16 || irqport[ia->ia_irq] == IOBASEUNK) 126 panic("rtfpsattach: invalid irq"); 127 sc->sc_irqport = irqport[ia->ia_irq]; 128 129 outb(sc->sc_irqport, 0); 130 131 printf("\n"); 132 133 isa.ia_aux = &ra; 134 for (ra.ra_slave = 0; ra.ra_slave < 4; ra.ra_slave++) { 135 struct cfdata *cf; 136 isa.ia_iobase = sc->sc_iobase + 8 * ra.ra_slave; 137 isa.ia_iosize = 0x666; 138 isa.ia_irq = IRQUNK; 139 isa.ia_drq = DRQUNK; 140 isa.ia_msize = 0; 141 if ((cf = config_search(rtfpssubmatch, self, &isa)) != 0) { 142 subunit = cf->cf_unit; /* can change if unit == * */ 143 config_attach(self, cf, &isa, rtfpsprint); 144 sc->sc_slaves[ra.ra_slave] = 145 cf->cf_driver->cd_devs[subunit]; 146 sc->sc_alive |= 1 << ra.ra_slave; 147 } 148 } 149 150 sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_EDGE, ISA_IPL_TTY, 151 rtfpsintr, sc); 152} 153 154int 155rtfpsintr(arg) 156 void *arg; 157{ 158 struct rtfps_softc *sc = arg; 159 int iobase = sc->sc_iobase; 160 int alive = sc->sc_alive; 161 162 outb(sc->sc_irqport, 0); 163 164#define TRY(n) \ 165 if (alive & (1 << (n))) \ 166 comintr(sc->sc_slaves[n]); 167 TRY(0); 168 TRY(1); 169 TRY(2); 170 TRY(3); 171#undef TRY 172 173 return (1); 174} 175