This source file includes following definitions.
- LIST_HEAD
- epaddcard
- ep_isa_probe
- ep_isa_attach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 #include "bpfilter.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/mbuf.h>
44 #include <sys/socket.h>
45 #include <sys/ioctl.h>
46 #include <sys/errno.h>
47 #include <sys/syslog.h>
48 #include <sys/selinfo.h>
49 #include <sys/timeout.h>
50 #include <sys/device.h>
51 #include <sys/queue.h>
52
53 #include <net/if.h>
54 #include <net/if_dl.h>
55 #include <net/if_types.h>
56 #include <net/netisr.h>
57 #include <net/if_media.h>
58
59 #ifdef INET
60 #include <netinet/in.h>
61 #include <netinet/in_systm.h>
62 #include <netinet/in_var.h>
63 #include <netinet/ip.h>
64 #include <netinet/if_ether.h>
65 #endif
66
67 #if NBPFILTER > 0
68 #include <net/bpf.h>
69 #endif
70
71 #include <machine/cpu.h>
72 #include <machine/bus.h>
73 #include <machine/intr.h>
74
75 #include <dev/mii/mii.h>
76 #include <dev/mii/miivar.h>
77
78 #include <dev/ic/elink3var.h>
79 #include <dev/ic/elink3reg.h>
80
81 #include <dev/isa/isavar.h>
82 #include <dev/isa/elink.h>
83
84 int ep_isa_probe(struct device *, void *, void *);
85 void ep_isa_attach(struct device *, struct device *, void *);
86
87 struct cfattach ep_isa_ca = {
88 sizeof(struct ep_softc), ep_isa_probe, ep_isa_attach
89 };
90
91 static void epaddcard(int, int, int, u_short);
92
93
94
95
96
97
98
99
100
101 struct ep_isa_done_probe {
102 LIST_ENTRY(ep_isa_done_probe) er_link;
103 int er_bus;
104 };
105 static LIST_HEAD(, ep_isa_done_probe) ep_isa_all_probes;
106 static int ep_isa_probes_initialized;
107
108 #define MAXEPCARDS 20
109
110 static struct epcard {
111 int bus;
112 int iobase;
113 int irq;
114 char available;
115 u_short model;
116 } epcards[MAXEPCARDS];
117 static int nepcards;
118
119 static void
120 epaddcard(bus, iobase, irq, model)
121 int bus, iobase, irq;
122 u_short model;
123 {
124
125 if (nepcards >= MAXEPCARDS)
126 return;
127 epcards[nepcards].bus = bus;
128 epcards[nepcards].iobase = iobase;
129 epcards[nepcards].irq = (irq == 2) ? 9 : irq;
130 epcards[nepcards].available = 1;
131 epcards[nepcards].model = model;
132 nepcards++;
133 }
134
135
136
137
138
139
140
141
142 int
143 ep_isa_probe(parent, match, aux)
144 struct device *parent;
145 void *match, *aux;
146 {
147 struct isa_attach_args *ia = aux;
148 bus_space_tag_t iot = ia->ia_iot;
149 bus_space_handle_t ioh;
150 int slot, iobase, irq, i, pnp;
151 u_int16_t vendor, model;
152 struct ep_isa_done_probe *er;
153 int bus = parent->dv_unit;
154
155 if (ep_isa_probes_initialized == 0) {
156 LIST_INIT(&ep_isa_all_probes);
157 ep_isa_probes_initialized = 1;
158 }
159
160
161
162
163 LIST_FOREACH(er, &ep_isa_all_probes, er_link)
164 if (er->er_bus == parent->dv_unit)
165 goto bus_probed;
166
167
168
169
170 er = (struct ep_isa_done_probe *)
171 malloc(sizeof(struct ep_isa_done_probe), M_DEVBUF, M_NOWAIT);
172 if (er == NULL)
173 panic("ep_isa_probe: can't allocate state storage");
174
175 er->er_bus = bus;
176 LIST_INSERT_HEAD(&ep_isa_all_probes, er, er_link);
177
178
179
180
181 if (bus_space_map(iot, ELINK_ID_PORT, 1, 0, &ioh)) {
182 printf("ep_isa_probe: can't map Etherlink ID port\n");
183 return 0;
184 }
185
186 for (slot = 0; slot < MAXEPCARDS; slot++) {
187 elink_reset(iot, ioh, parent->dv_unit);
188 elink_idseq(iot, ioh, ELINK_509_POLY);
189
190
191 if (slot == 0)
192 bus_space_write_1(iot, ioh, 0, TAG_ADAPTER + 0);
193
194 vendor = htons(epreadeeprom(iot, ioh, EEPROM_MFG_ID));
195 if (vendor != MFG_ID)
196 continue;
197
198 model = htons(epreadeeprom(iot, ioh, EEPROM_PROD_ID));
199 if ((model & 0xfff0) != PROD_ID_3C509) {
200 #ifndef trusted
201 printf("ep_isa_probe: ignoring model %04x\n",
202 model);
203 #endif
204 continue;
205 }
206
207 iobase = epreadeeprom(iot, ioh, EEPROM_ADDR_CFG);
208 iobase = (iobase & 0x1f) * 0x10 + 0x200;
209
210 irq = epreadeeprom(iot, ioh, EEPROM_RESOURCE_CFG);
211 irq >>= 12;
212
213 pnp = epreadeeprom(iot, ioh, EEPROM_PNP) & 8;
214
215
216 bus_space_write_1(iot, ioh, 0, TAG_ADAPTER + 1);
217
218 if ((model & 0xfff0) == PROD_ID_3C509 && pnp != 0)
219 continue;
220
221
222
223
224
225
226
227 bus_space_write_1(iot, ioh, 0, ACTIVATE_ADAPTER_TO_CONFIG);
228 epaddcard(bus, iobase, irq, model);
229 }
230
231
232 bus_space_unmap(iot, ioh, 1);
233
234 bus_probed:
235
236 for (i = 0; i < nepcards; i++) {
237 if (epcards[i].bus != bus)
238 continue;
239 if (epcards[i].available == 0)
240 continue;
241 if (ia->ia_iobase != IOBASEUNK &&
242 ia->ia_iobase != epcards[i].iobase)
243 continue;
244 if (ia->ia_irq != IRQUNK &&
245 ia->ia_irq != epcards[i].irq)
246 continue;
247 goto good;
248 }
249 return 0;
250
251 good:
252 epcards[i].available = 0;
253 ia->ia_iobase = epcards[i].iobase;
254 ia->ia_irq = epcards[i].irq;
255 ia->ia_iosize = 0x10;
256 ia->ia_msize = 0;
257 ia->ia_aux = (void *)(long)(epcards[i].model);
258 return 1;
259 }
260
261 void
262 ep_isa_attach(parent, self, aux)
263 struct device *parent, *self;
264 void *aux;
265 {
266 struct ep_softc *sc = (void *)self;
267 struct isa_attach_args *ia = aux;
268 bus_space_tag_t iot = ia->ia_iot;
269 bus_space_handle_t ioh;
270 int chipset;
271
272
273 if (bus_space_map(iot, ia->ia_iobase, ia->ia_iosize, 0, &ioh))
274 panic("ep_isa_attach: can't map i/o space");
275
276 sc->sc_iot = iot;
277 sc->sc_ioh = ioh;
278 sc->bustype = EP_BUS_ISA;
279
280 printf(":");
281
282 chipset = (int)(long)ia->ia_aux;
283 if ((chipset & 0xfff0) == PROD_ID_3C509) {
284 epconfig(sc, EP_CHIPSET_3C509, NULL);
285 } else {
286
287
288
289
290 epconfig(sc, EP_CHIPSET_UNKNOWN, NULL);
291 }
292
293 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
294 IPL_NET, epintr, sc, sc->sc_dev.dv_xname);
295 }