1 /* $NetBSD: tcom.c,v 1.18 2009/03/14 15:36:18 dsl Exp $ */
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1998 Jukka Marin. All rights reserved.
34 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
35 * Copyright (c) 1995 Charles Hannum. All rights reserved.
37 * This code is derived from public-domain software written by
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by Charles Hannum.
51 * 4. The name of the author may not be used to endorse or promote products
52 * derived from this software without specific prior written permission.
54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67 * NOTE: This driver has been tested in TCOM "UNIX mode" with base address
68 * set to 0x100 or 0x200 and baud rate jumpers to "normal". This code
69 * does NOT know about the 2x and 4x baud rates available on TCOM cards.
72 #include <sys/cdefs.h>
73 __KERNEL_RCSID(0, "$NetBSD: tcom.c,v 1.18 2009/03/14 15:36:18 dsl Exp $");
75 #include <sys/param.h>
76 #include <sys/systm.h>
77 #include <sys/device.h>
78 #include <sys/termios.h>
83 #include <dev/ic/comreg.h>
84 #include <dev/ic/comvar.h>
86 #include <dev/isa/isavar.h>
87 #include <dev/isa/com_multi.h>
89 #define NSLAVES 8 /* TCOM cards have 4 or 8 UARTs */
90 #define STATUS_OFFSET 0x40 /* offset from board base address */
91 #define STATUS_SIZE 8 /* 8 bytes reserved for irq status */
97 bus_space_tag_t sc_iot
;
100 int sc_alive
; /* mask of slave units attached */
101 void *sc_slaves
[NSLAVES
]; /* com device softc pointers */
102 bus_space_handle_t sc_slaveioh
[NSLAVES
];
103 bus_space_handle_t sc_statusioh
;
106 int tcomprobe(device_t
, cfdata_t
, void *);
107 void tcomattach(device_t
, device_t
, void *);
108 int tcomintr(void *);
110 CFATTACH_DECL_NEW(tcom
, sizeof(struct tcom_softc
),
111 tcomprobe
, tcomattach
, NULL
, NULL
);
114 tcomprobe(device_t parent
, cfdata_t self
, void *aux
)
116 struct isa_attach_args
*ia
= aux
;
117 bus_space_tag_t iot
= ia
->ia_iot
;
118 bus_space_handle_t ioh
;
119 int i
, iobase
, rv
= 1;
122 * Do the normal com probe for the first UART and assume
123 * its presence, and the ability to map the other UARTS,
124 * means there is a multiport board there.
125 * XXX Needs more robustness.
133 if (ISA_DIRECT_CONFIG(ia
))
136 /* Disallow wildcarded i/o address. */
137 if (ia
->ia_io
[0].ir_addr
== ISA_UNKNOWN_PORT
)
139 if (ia
->ia_irq
[0].ir_irq
== ISA_UNKNOWN_IRQ
)
142 /* if the first port is in use as console, then it. */
143 if (com_is_console(iot
, ia
->ia_io
[0].ir_addr
, 0))
146 if (bus_space_map(iot
, ia
->ia_io
[0].ir_addr
, COM_NPORTS
, 0, &ioh
)) {
150 rv
= comprobe1(iot
, ioh
);
151 bus_space_unmap(iot
, ioh
, COM_NPORTS
);
156 for (i
= 1, iobase
= ia
->ia_io
[0].ir_addr
; i
< NSLAVES
; i
++) {
157 iobase
+= COM_NPORTS
;
159 if (com_is_console(iot
, iobase
, 0))
162 if (bus_space_map(iot
, iobase
, COM_NPORTS
, 0, &ioh
)) {
166 bus_space_unmap(iot
, ioh
, COM_NPORTS
);
172 ia
->ia_io
[0].ir_size
= NSLAVES
* COM_NPORTS
;
183 tcomattach(device_t parent
, device_t self
, void *aux
)
185 struct tcom_softc
*sc
= device_private(self
);
186 struct isa_attach_args
*ia
= aux
;
187 struct commulti_attach_args ca
;
188 bus_space_tag_t iot
= ia
->ia_iot
;
195 sc
->sc_iot
= ia
->ia_iot
;
196 sc
->sc_iobase
= ia
->ia_io
[0].ir_addr
;
198 for (i
= 0; i
< NSLAVES
; i
++) {
199 iobase
= sc
->sc_iobase
+ i
* COM_NPORTS
;
200 if (!com_is_console(iot
, iobase
, &sc
->sc_slaveioh
[i
]) &&
201 bus_space_map(iot
, iobase
, COM_NPORTS
, 0,
202 &sc
->sc_slaveioh
[i
])) {
203 aprint_error_dev(sc
->sc_dev
, "can't map i/o space for slave %d\n", i
);
208 if (bus_space_map(iot
, sc
->sc_iobase
+ STATUS_OFFSET
, STATUS_SIZE
, 0,
209 &sc
->sc_statusioh
)) {
210 aprint_error_dev(sc
->sc_dev
, "can't map status space\n");
214 for (i
= 0; i
< NSLAVES
; i
++) {
216 ca
.ca_iot
= sc
->sc_iot
;
217 ca
.ca_ioh
= sc
->sc_slaveioh
[i
];
218 ca
.ca_iobase
= sc
->sc_iobase
+ i
* COM_NPORTS
;
221 slave
= config_found(self
, &ca
, commultiprint
);
223 sc
->sc_alive
|= 1 << i
;
224 sc
->sc_slaves
[i
] = device_private(slave
);
228 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, ia
->ia_irq
[0].ir_irq
,
229 IST_EDGE
, IPL_SERIAL
, tcomintr
, sc
);
235 struct tcom_softc
*sc
= arg
;
236 bus_space_tag_t iot
= sc
->sc_iot
;
237 int alive
= sc
->sc_alive
;
240 bits
= ~bus_space_read_1(iot
, sc
->sc_statusioh
, 0) & alive
;
246 if (bits & (1 << (n))) \
247 comintr(sc->sc_slaves[n]);
257 bits
= ~bus_space_read_1(iot
, sc
->sc_statusioh
, 0) & alive
;