1 /* $NetBSD: ast.c,v 1.63 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: ast.c,v 1.63 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 int sc_alive
; /* mask of slave units attached */
63 void *sc_slaves
[NSLAVES
]; /* com device softc pointers */
64 bus_space_handle_t sc_slaveioh
[NSLAVES
];
67 int astprobe(device_t
, cfdata_t
, void *);
68 void astattach(device_t
, device_t
, void *);
71 CFATTACH_DECL(ast
, sizeof(struct ast_softc
),
72 astprobe
, astattach
, NULL
, NULL
);
75 astprobe(device_t parent
, cfdata_t self
, void *aux
)
77 struct isa_attach_args
*ia
= aux
;
78 bus_space_tag_t iot
= ia
->ia_iot
;
79 bus_space_handle_t ioh
;
80 int i
, iobase
, rv
= 1;
83 * Do the normal com probe for the first UART and assume
84 * its presence, and the ability to map the other UARTS,
85 * means there is a multiport board there.
86 * XXX Needs more robustness.
94 if (ISA_DIRECT_CONFIG(ia
))
97 /* Disallow wildcarded i/o address. */
98 if (ia
->ia_io
[0].ir_addr
== ISA_UNKNOWN_PORT
)
101 if (ia
->ia_irq
[0].ir_irq
== ISA_UNKNOWN_IRQ
)
104 /* if the first port is in use as console, then it. */
105 if (com_is_console(iot
, ia
->ia_io
[0].ir_addr
, 0))
108 if (bus_space_map(iot
, ia
->ia_io
[0].ir_addr
, COM_NPORTS
, 0, &ioh
)) {
112 rv
= comprobe1(iot
, ioh
);
113 bus_space_unmap(iot
, ioh
, COM_NPORTS
);
118 for (i
= 1, iobase
= ia
->ia_io
[0].ir_addr
; i
< NSLAVES
; i
++) {
119 iobase
+= COM_NPORTS
;
121 if (com_is_console(iot
, iobase
, 0))
124 if (bus_space_map(iot
, iobase
, COM_NPORTS
, 0, &ioh
)) {
128 bus_space_unmap(iot
, ioh
, COM_NPORTS
);
134 ia
->ia_io
[0].ir_size
= NSLAVES
* COM_NPORTS
;
145 astattach(device_t parent
, device_t self
, void *aux
)
147 struct ast_softc
*sc
= device_private(self
);
148 struct isa_attach_args
*ia
= aux
;
149 struct commulti_attach_args ca
;
150 bus_space_tag_t iot
= ia
->ia_iot
;
156 sc
->sc_iot
= ia
->ia_iot
;
157 sc
->sc_iobase
= ia
->ia_io
[0].ir_addr
;
159 for (i
= 0; i
< NSLAVES
; i
++) {
160 iobase
= sc
->sc_iobase
+ i
* COM_NPORTS
;
161 if (!com_is_console(iot
, iobase
, &sc
->sc_slaveioh
[i
]) &&
162 bus_space_map(iot
, iobase
, COM_NPORTS
, 0,
163 &sc
->sc_slaveioh
[i
])) {
164 aprint_error_dev(&sc
->sc_dev
, "can't map i/o space for slave %d\n", i
);
170 * Enable the master interrupt.
172 bus_space_write_1(iot
, sc
->sc_slaveioh
[3], com_scratch
, 0x80);
174 for (i
= 0; i
< NSLAVES
; i
++) {
176 ca
.ca_iot
= sc
->sc_iot
;
177 ca
.ca_ioh
= sc
->sc_slaveioh
[i
];
178 ca
.ca_iobase
= sc
->sc_iobase
+ i
* COM_NPORTS
;
181 slave
= config_found(self
, &ca
, commultiprint
);
183 sc
->sc_alive
|= 1 << i
;
184 sc
->sc_slaves
[i
] = device_private(slave
);
188 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, ia
->ia_irq
[0].ir_irq
,
189 IST_EDGE
, IPL_SERIAL
, astintr
, sc
);
195 struct ast_softc
*sc
= arg
;
196 bus_space_tag_t iot
= sc
->sc_iot
;
197 int alive
= sc
->sc_alive
;
200 bits
= ~bus_space_read_1(iot
, sc
->sc_slaveioh
[3], com_scratch
) & alive
;
206 if (bits & (1 << (n))) \
207 comintr(sc->sc_slaves[n]);
213 bits
= ~bus_space_read_1(iot
, sc
->sc_slaveioh
[3],
214 com_scratch
) & alive
;