i82365_isa.c revision 1.10 1 /* $NetBSD: i82365_isa.c,v 1.10 1998/06/07 18:28:31 sommerfe Exp $ */
2
3 #define PCICISADEBUG
4
5 /*
6 * Copyright (c) 1997 Marc Horowitz. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Marc Horowitz.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38 #include <sys/extent.h>
39 #include <sys/malloc.h>
40
41 #include <vm/vm.h>
42
43 #include <machine/bus.h>
44 #include <machine/intr.h>
45
46 #include <dev/isa/isareg.h>
47 #include <dev/isa/isavar.h>
48
49 #include <dev/pcmcia/pcmciareg.h>
50 #include <dev/pcmcia/pcmciavar.h>
51 #include <dev/pcmcia/pcmciachip.h>
52
53 #include <dev/ic/i82365reg.h>
54 #include <dev/ic/i82365var.h>
55 #include <dev/isa/i82365_isavar.h>
56
57 #ifdef PCICISADEBUG
58 int pcicisa_debug = 0 /* XXX */ ;
59 #define DPRINTF(arg) if (pcicisa_debug) printf arg;
60 #else
61 #define DPRINTF(arg)
62 #endif
63
64 #ifdef __BROKEN_INDIRECT_CONFIG
65 int pcic_isa_probe __P((struct device *, void *, void *));
66 #else
67 int pcic_isa_probe __P((struct device *, struct cfdata *, void *));
68 #endif
69 void pcic_isa_attach __P((struct device *, struct device *, void *));
70
71 void *pcic_isa_chip_intr_establish __P((pcmcia_chipset_handle_t,
72 struct pcmcia_function *, int, int (*) (void *), void *));
73 void pcic_isa_chip_intr_disestablish __P((pcmcia_chipset_handle_t, void *));
74
75 struct cfattach pcic_isa_ca = {
76 sizeof(struct pcic_softc), pcic_isa_probe, pcic_isa_attach
77 };
78
79 static struct pcmcia_chip_functions pcic_isa_functions = {
80 pcic_chip_mem_alloc,
81 pcic_chip_mem_free,
82 pcic_chip_mem_map,
83 pcic_chip_mem_unmap,
84
85 pcic_chip_io_alloc,
86 pcic_chip_io_free,
87 pcic_chip_io_map,
88 pcic_chip_io_unmap,
89
90 pcic_isa_chip_intr_establish,
91 pcic_isa_chip_intr_disestablish,
92
93 pcic_chip_socket_enable,
94 pcic_chip_socket_disable,
95 };
96
97 int
98 pcic_isa_probe(parent, match, aux)
99 struct device *parent;
100 #ifdef __BROKEN_INDIRECT_CONFIG
101 void *match;
102 #else
103 struct cfdata *match;
104 #endif
105 void *aux;
106 {
107 struct isa_attach_args *ia = aux;
108 bus_space_tag_t iot = ia->ia_iot;
109 bus_space_handle_t ioh, memh;
110 int val, found;
111
112 /* Disallow wildcarded i/o address. */
113 if (ia->ia_iobase == ISACF_PORT_DEFAULT)
114 return (0);
115
116 if (bus_space_map(iot, ia->ia_iobase, PCIC_IOSIZE, 0, &ioh))
117 return (0);
118
119 if (ia->ia_msize == -1)
120 ia->ia_msize = PCIC_MEMSIZE;
121
122 if (bus_space_map(ia->ia_memt, ia->ia_maddr, ia->ia_msize, 0, &memh))
123 return (0);
124
125 found = 0;
126
127 /*
128 * this could be done with a loop, but it would violate the
129 * abstraction
130 */
131
132 bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C0SA + PCIC_IDENT);
133
134 val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
135
136 if (pcic_ident_ok(val))
137 found++;
138
139
140 bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C0SB + PCIC_IDENT);
141
142 val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
143
144 if (pcic_ident_ok(val))
145 found++;
146
147
148 bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C1SA + PCIC_IDENT);
149
150 val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
151
152 if (pcic_ident_ok(val))
153 found++;
154
155
156 bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C1SB + PCIC_IDENT);
157
158 val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
159
160 if (pcic_ident_ok(val))
161 found++;
162
163
164 bus_space_unmap(iot, ioh, PCIC_IOSIZE);
165 bus_space_unmap(ia->ia_memt, memh, ia->ia_msize);
166
167 if (!found)
168 return (0);
169
170 ia->ia_iosize = PCIC_IOSIZE;
171
172 return (1);
173 }
174
175 void
176 pcic_isa_attach(parent, self, aux)
177 struct device *parent, *self;
178 void *aux;
179 {
180 struct pcic_softc *sc = (void *) self;
181 struct isa_attach_args *ia = aux;
182 isa_chipset_tag_t ic = ia->ia_ic;
183 bus_space_tag_t iot = ia->ia_iot;
184 bus_space_tag_t memt = ia->ia_memt;
185 bus_space_handle_t ioh;
186 bus_space_handle_t memh;
187
188 /* Map i/o space. */
189 if (bus_space_map(iot, ia->ia_iobase, ia->ia_iosize, 0, &ioh)) {
190 printf(": can't map i/o space\n");
191 return;
192 }
193
194 /* Map mem space. */
195 if (bus_space_map(memt, ia->ia_maddr, ia->ia_msize, 0, &memh)) {
196 printf(": can't map mem space\n");
197 return;
198 }
199
200 sc->membase = ia->ia_maddr;
201 sc->subregionmask = (1 << (ia->ia_msize / PCIC_MEM_PAGESIZE)) - 1;
202
203 sc->intr_est = ic;
204 sc->pct = (pcmcia_chipset_tag_t) & pcic_isa_functions;
205
206 sc->iot = iot;
207 sc->ioh = ioh;
208 sc->memt = memt;
209 sc->memh = memh;
210
211 /*
212 * allocate an irq. it will be used by both controllers. I could
213 * use two different interrupts, but interrupts are relatively
214 * scarce, shareable, and for PCIC controllers, very infrequent.
215 */
216
217 if ((sc->irq = ia->ia_irq) == IRQUNK) {
218 if (isa_intr_alloc(ic,
219 PCIC_CSC_INTR_IRQ_VALIDMASK & pcic_isa_intr_alloc_mask,
220 IST_EDGE, &sc->irq)) {
221 printf("\n%s: can't allocate interrupt\n",
222 sc->dev.dv_xname);
223 return;
224 }
225 printf(": using irq %d", sc->irq);
226 }
227 printf("\n");
228
229 pcic_attach(sc);
230
231 pcic_isa_bus_width_probe (sc, iot, ioh, ia->ia_iobase, ia->ia_iosize);
232
233 sc->ih = isa_intr_establish(ic, sc->irq, IST_EDGE, IPL_TTY,
234 pcic_intr, sc);
235 if (sc->ih == NULL) {
236 printf("%s: can't establish interrupt\n", sc->dev.dv_xname);
237 return;
238 }
239
240 pcic_attach_sockets(sc);
241 }
242