1 /* $NetBSD: ioat66.c,v 1.19 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
8 * Roland McGrath, and information provided by David Muir Sharnoff.
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: ioat66.c,v 1.19 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 unit numbers */
64 bus_space_handle_t sc_slaveioh
[NSLAVES
];
65 bus_space_handle_t sc_intmasq
;
68 int ioatbases
[NSLAVES
]={0x220,0x228,0x240,0x248,0x260,0x268};
69 #define IOAT66SHARED 0x208
71 int ioat66probe(device_t
, cfdata_t
, void *);
72 void ioat66attach(device_t
, device_t
, void *);
73 int ioat66intr(void *);
75 CFATTACH_DECL(ioat
, sizeof(struct ioat66_softc
),
76 ioat66probe
, ioat66attach
, NULL
, NULL
);
79 ioat66probe(device_t parent
, cfdata_t self
, void *aux
)
81 struct isa_attach_args
*ia
= aux
;
82 bus_space_tag_t iot
= ia
->ia_iot
;
83 bus_space_handle_t ioh
;
87 if (ia
->ia_niomem
< 1)
92 * Do the normal com probe for the first UART and assume
93 * its presence, and the ability to map the other UARTS,
94 * means there is a multiport board there.
95 * XXX Needs more robustness.
98 /* Disallow wildcarded i/o address. */
99 if (ia
->ia_io
[0].ir_addr
== ISA_UNKNOWN_PORT
)
102 if (ia
->ia_irq
[0].ir_irq
== ISA_UNKNOWN_IRQ
)
105 iobase
= ia
->ia_io
[0].ir_addr
;
106 /* if the first port is in use as console, then it. */
107 if (com_is_console(iot
, iobase
, 0))
110 if (bus_space_map(iot
, iobase
, COM_NPORTS
, 0, &ioh
)) {
114 rv
= comprobe1(iot
, ioh
);
115 bus_space_unmap(iot
, ioh
, COM_NPORTS
);
120 for (i
= 1; i
< NSLAVES
; i
++) {
121 iobase
= ioatbases
[i
];
123 if (com_is_console(iot
, iobase
, 0))
126 if (bus_space_map(iot
, iobase
, COM_NPORTS
, 0, &ioh
)) {
130 bus_space_unmap(iot
, ioh
, COM_NPORTS
);
136 ia
->ia_io
[0].ir_size
= NSLAVES
* COM_NPORTS
;
145 ioat66attach(device_t parent
, device_t self
, void *aux
)
147 struct ioat66_softc
*sc
= (void *)self
;
148 struct isa_attach_args
*ia
= aux
;
149 struct commulti_attach_args ca
;
150 bus_space_tag_t iot
= ia
->ia_iot
;
155 sc
->sc_iot
= ia
->ia_iot
;
156 sc
->sc_iobase
= ia
->ia_io
[0].ir_addr
;
157 irq
= ia
->ia_irq
[0].ir_irq
;
159 for (i
= 0; i
< NSLAVES
; i
++) {
160 iobase
= ioatbases
[i
];
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
);
169 if(bus_space_map(iot
, IOAT66SHARED
, 1, 0, &sc
->sc_intmasq
)) {
170 aprint_error_dev(&sc
->sc_dev
, "can't map shared interrupt mask\n");
174 for (i
= 0; i
< NSLAVES
; i
++) {
177 ca
.ca_iot
= sc
->sc_iot
;
178 ca
.ca_ioh
= sc
->sc_slaveioh
[i
];
179 ca
.ca_iobase
= ioatbases
[i
];
182 sc
->sc_slaves
[i
] = config_found(self
, &ca
, commultiprint
);
183 if (sc
->sc_slaves
[i
] != NULL
)
184 sc
->sc_alive
|= 1 << i
;
187 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, irq
, IST_EDGE
,
188 IPL_SERIAL
, ioat66intr
, sc
);
192 ioat66intr(void *arg
)
194 struct ioat66_softc
*sc
= arg
;
195 bus_space_tag_t iot
= sc
->sc_iot
;
196 int alive
= sc
->sc_alive
;
199 bits
= bus_space_read_1(iot
, sc
->sc_intmasq
, 0) & alive
;
205 if (bits & (1 << (n))) \
206 comintr(sc->sc_slaves[n]);
214 bits
= bus_space_read_1(iot
, sc
->sc_intmasq
, 0) & alive
;