rtfps.c revision 1.16
1/* $NetBSD: rtfps.c,v 1.16 1996/03/09 01:04: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#include <dev/isa/comreg.h> 42#include <dev/isa/comvar.h> 43 44#define NSLAVES 4 45 46struct rtfps_softc { 47 struct device sc_dev; 48 void *sc_ih; 49 50 int sc_iobase; 51 int sc_irqport; 52 int sc_alive; /* mask of slave units attached */ 53 void *sc_slaves[NSLAVES]; /* com device unit numbers */ 54}; 55 56int rtfpsprobe(); 57void rtfpsattach(); 58int rtfpsintr __P((void *)); 59 60struct cfdriver rtfpscd = { 61 NULL, "rtfps", rtfpsprobe, rtfpsattach, DV_TTY, sizeof(struct rtfps_softc) 62}; 63 64int 65rtfpsprobe(parent, self, aux) 66 struct device *parent, *self; 67 void *aux; 68{ 69 struct isa_attach_args *ia = aux; 70 71 /* 72 * Do the normal com probe for the first UART and assume 73 * its presence means there is a multiport board there. 74 * XXX Needs more robustness. 75 */ 76 ia->ia_iosize = NSLAVES * COM_NPORTS; 77 return (comprobe1(ia->ia_iobase)); 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 commulti_attach_args *ca = ia->ia_aux; 89 90 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ca->ca_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 commulti_attach_args *ca = ia->ia_aux; 102 103 printf(" slave %d", ca->ca_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 commulti_attach_args ca; 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 = &ca; 134 for (ca.ca_slave = 0; ca.ca_slave < NSLAVES; ca.ca_slave++) { 135 struct cfdata *cf; 136 isa.ia_iobase = sc->sc_iobase + COM_NPORTS * ca.ca_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[ca.ca_slave] = 145 cf->cf_driver->cd_devs[subunit]; 146 sc->sc_alive |= 1 << ca.ca_slave; 147 } 148 } 149 150 sc->sc_ih = isa_intr_establish(ia->ia_irq, IST_EDGE, IPL_TTY, rtfpsintr, 151 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