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