1 /* $NetBSD: rtfps.c,v 1.56 2009/05/12 08:44:19 cegger Exp $ */
4 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
5 * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
7 * This code is derived from public-domain software written by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Charles M. Hannum.
21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: rtfps.c,v 1.56 2009/05/12 08:44:19 cegger Exp $");
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/device.h>
42 #include <sys/termios.h>
47 #include <dev/ic/comreg.h>
48 #include <dev/ic/comvar.h>
50 #include <dev/isa/isavar.h>
51 #include <dev/isa/com_multi.h>
59 bus_space_tag_t sc_iot
;
62 bus_space_handle_t sc_irqioh
;
64 int sc_alive
; /* mask of slave units attached */
65 void *sc_slaves
[NSLAVES
]; /* com device unit numbers */
66 bus_space_handle_t sc_slaveioh
[NSLAVES
];
69 int rtfpsprobe(device_t
, cfdata_t
, void *);
70 void rtfpsattach(device_t
, device_t
, void *);
71 int rtfpsintr(void *);
73 CFATTACH_DECL(rtfps
, sizeof(struct rtfps_softc
),
74 rtfpsprobe
, rtfpsattach
, NULL
, NULL
);
77 rtfpsprobe(device_t parent
, cfdata_t self
, void *aux
)
79 struct isa_attach_args
*ia
= aux
;
80 bus_space_tag_t iot
= ia
->ia_iot
;
81 bus_space_handle_t ioh
;
82 int i
, iobase
, rv
= 1;
85 * Do the normal com probe for the first UART and assume
86 * its presence, and the ability to map the other UARTS,
87 * means there is a multiport board there.
88 * XXX Needs more robustness.
96 /* Disallow wildcarded i/o address. */
97 if (ia
->ia_io
[0].ir_addr
== ISA_UNKNOWN_PORT
)
99 if (ia
->ia_irq
[0].ir_irq
== ISA_UNKNOWN_IRQ
)
102 /* if the first port is in use as console, then it. */
103 if (com_is_console(iot
, ia
->ia_io
[0].ir_addr
, 0))
106 if (bus_space_map(iot
, ia
->ia_io
[0].ir_addr
, COM_NPORTS
, 0, &ioh
)) {
110 rv
= comprobe1(iot
, ioh
);
111 bus_space_unmap(iot
, ioh
, COM_NPORTS
);
116 for (i
= 1, iobase
= ia
->ia_io
[0].ir_addr
; i
< NSLAVES
; i
++) {
117 iobase
+= COM_NPORTS
;
119 if (com_is_console(iot
, iobase
, 0))
122 if (bus_space_map(iot
, iobase
, COM_NPORTS
, 0, &ioh
)) {
126 bus_space_unmap(iot
, ioh
, COM_NPORTS
);
132 ia
->ia_io
[0].ir_size
= NSLAVES
* COM_NPORTS
;
143 rtfpsattach(device_t parent
, device_t self
, void *aux
)
145 struct rtfps_softc
*sc
= (void *)self
;
146 struct isa_attach_args
*ia
= aux
;
147 struct commulti_attach_args ca
;
148 static int irqport
[] = {
149 -1, -1, -1, -1, -1, -1, -1, -1,
150 -1, 0x2f2, 0x6f2, 0x6f3, -1, -1, -1, -1
152 bus_space_tag_t iot
= ia
->ia_iot
;
157 sc
->sc_iot
= ia
->ia_iot
;
158 sc
->sc_iobase
= ia
->ia_io
[0].ir_addr
;
159 irq
= ia
->ia_irq
[0].ir_irq
;
161 if (irq
>= 16 || irqport
[irq
] == -1) {
162 printf("%s: invalid irq\n", device_xname(&sc
->sc_dev
));
165 sc
->sc_irqport
= irqport
[irq
];
167 for (i
= 0; i
< NSLAVES
; i
++) {
168 iobase
= sc
->sc_iobase
+ i
* COM_NPORTS
;
169 if (!com_is_console(iot
, iobase
, &sc
->sc_slaveioh
[i
]) &&
170 bus_space_map(iot
, iobase
, COM_NPORTS
, 0,
171 &sc
->sc_slaveioh
[i
])) {
172 aprint_error_dev(&sc
->sc_dev
, "can't map i/o space for slave %d\n", i
);
176 if (bus_space_map(iot
, sc
->sc_irqport
, 1, 0, &sc
->sc_irqioh
)) {
177 aprint_error_dev(&sc
->sc_dev
, "can't map irq port at 0x%x\n",
182 bus_space_write_1(iot
, sc
->sc_irqioh
, 0, 0);
184 for (i
= 0; i
< NSLAVES
; i
++) {
186 ca
.ca_iot
= sc
->sc_iot
;
187 ca
.ca_ioh
= sc
->sc_slaveioh
[i
];
188 ca
.ca_iobase
= sc
->sc_iobase
+ i
* COM_NPORTS
;
191 sc
->sc_slaves
[i
] = config_found(self
, &ca
, commultiprint
);
192 if (sc
->sc_slaves
[i
] != NULL
)
193 sc
->sc_alive
|= 1 << i
;
196 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, irq
, IST_EDGE
,
197 IPL_SERIAL
, rtfpsintr
, sc
);
203 struct rtfps_softc
*sc
= arg
;
204 bus_space_tag_t iot
= sc
->sc_iot
;
205 int alive
= sc
->sc_alive
;
207 bus_space_write_1(iot
, sc
->sc_irqioh
, 0, 0);
210 if (alive & (1 << (n))) \
211 comintr(sc->sc_slaves[n]);