autoconf.c revision 1.3 1 1.3 tsutsui /* $NetBSD: autoconf.c,v 1.3 2013/01/14 01:37:57 tsutsui Exp $ */
2 1.1 tsutsui
3 1.1 tsutsui /*
4 1.1 tsutsui * Copyright (c) 1992 OMRON Corporation.
5 1.1 tsutsui *
6 1.1 tsutsui * This code is derived from software contributed to Berkeley by
7 1.1 tsutsui * OMRON Corporation.
8 1.1 tsutsui *
9 1.1 tsutsui * Redistribution and use in source and binary forms, with or without
10 1.1 tsutsui * modification, are permitted provided that the following conditions
11 1.1 tsutsui * are met:
12 1.1 tsutsui * 1. Redistributions of source code must retain the above copyright
13 1.1 tsutsui * notice, this list of conditions and the following disclaimer.
14 1.1 tsutsui * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 tsutsui * notice, this list of conditions and the following disclaimer in the
16 1.1 tsutsui * documentation and/or other materials provided with the distribution.
17 1.1 tsutsui * 3. All advertising materials mentioning features or use of this software
18 1.1 tsutsui * must display the following acknowledgement:
19 1.1 tsutsui * This product includes software developed by the University of
20 1.1 tsutsui * California, Berkeley and its contributors.
21 1.1 tsutsui * 4. Neither the name of the University nor the names of its contributors
22 1.1 tsutsui * may be used to endorse or promote products derived from this software
23 1.1 tsutsui * without specific prior written permission.
24 1.1 tsutsui *
25 1.1 tsutsui * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 1.1 tsutsui * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 1.1 tsutsui * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 1.1 tsutsui * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 1.1 tsutsui * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 1.1 tsutsui * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 1.1 tsutsui * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 1.1 tsutsui * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 1.1 tsutsui * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 1.1 tsutsui * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 1.1 tsutsui * SUCH DAMAGE.
36 1.1 tsutsui *
37 1.1 tsutsui * @(#)autoconf.c 8.1 (Berkeley) 6/10/93
38 1.1 tsutsui */
39 1.1 tsutsui /*
40 1.1 tsutsui * Copyright (c) 1992, 1993
41 1.1 tsutsui * The Regents of the University of California. All rights reserved.
42 1.1 tsutsui *
43 1.1 tsutsui * This code is derived from software contributed to Berkeley by
44 1.1 tsutsui * OMRON Corporation.
45 1.1 tsutsui *
46 1.1 tsutsui * Redistribution and use in source and binary forms, with or without
47 1.1 tsutsui * modification, are permitted provided that the following conditions
48 1.1 tsutsui * are met:
49 1.1 tsutsui * 1. Redistributions of source code must retain the above copyright
50 1.1 tsutsui * notice, this list of conditions and the following disclaimer.
51 1.1 tsutsui * 2. Redistributions in binary form must reproduce the above copyright
52 1.1 tsutsui * notice, this list of conditions and the following disclaimer in the
53 1.1 tsutsui * documentation and/or other materials provided with the distribution.
54 1.1 tsutsui * 3. Neither the name of the University nor the names of its contributors
55 1.1 tsutsui * may be used to endorse or promote products derived from this software
56 1.1 tsutsui * without specific prior written permission.
57 1.1 tsutsui *
58 1.1 tsutsui * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 1.1 tsutsui * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 1.1 tsutsui * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 1.1 tsutsui * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 1.1 tsutsui * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 1.1 tsutsui * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 1.1 tsutsui * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 1.1 tsutsui * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 1.1 tsutsui * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 1.1 tsutsui * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 1.1 tsutsui * SUCH DAMAGE.
69 1.1 tsutsui *
70 1.1 tsutsui * @(#)autoconf.c 8.1 (Berkeley) 6/10/93
71 1.1 tsutsui */
72 1.1 tsutsui
73 1.1 tsutsui /*
74 1.1 tsutsui * autoconf.c -- Determine mass storage and memory configuration for a machine.
75 1.1 tsutsui * by A.Fujita, NOV-30-1991
76 1.1 tsutsui *
77 1.1 tsutsui * Modified by A.Fujita, FEB-04-1992
78 1.1 tsutsui */
79 1.1 tsutsui
80 1.1 tsutsui
81 1.1 tsutsui #include <sys/param.h>
82 1.1 tsutsui #include <sys/dkstat.h>
83 1.3 tsutsui #include <machine/cpu.h>
84 1.1 tsutsui #include <lib/libkern/libkern.h>
85 1.1 tsutsui #include <luna68k/stand/boot/samachdep.h>
86 1.1 tsutsui #include <luna68k/stand/boot/device.h>
87 1.1 tsutsui
88 1.1 tsutsui int dkn; /* number of iostat dk numbers assigned so far */
89 1.1 tsutsui struct hp_hw sc_table[MAX_CTLR];
90 1.1 tsutsui
91 1.1 tsutsui #ifdef DEBUG
92 1.1 tsutsui int acdebug = 1;
93 1.1 tsutsui #endif
94 1.1 tsutsui
95 1.1 tsutsui static int find_controller(struct hp_hw *);
96 1.1 tsutsui static int find_device(struct hp_hw *);
97 1.1 tsutsui static void find_slaves(struct hp_ctlr *);
98 1.1 tsutsui static int same_hw_device(struct hp_hw *, struct hp_device *);
99 1.1 tsutsui
100 1.1 tsutsui /*
101 1.1 tsutsui * Determine mass storage and memory configuration for a machine.
102 1.1 tsutsui */
103 1.1 tsutsui void
104 1.1 tsutsui configure(void)
105 1.1 tsutsui {
106 1.1 tsutsui struct hp_hw *hw;
107 1.1 tsutsui int found;
108 1.1 tsutsui
109 1.1 tsutsui /*
110 1.1 tsutsui * Look over each hardware device actually found and attempt
111 1.1 tsutsui * to match it with an ioconf.c table entry.
112 1.1 tsutsui */
113 1.1 tsutsui for (hw = sc_table; hw->hw_type; hw++) {
114 1.1 tsutsui if (hw->hw_type & CONTROLLER)
115 1.1 tsutsui found = find_controller(hw);
116 1.1 tsutsui else
117 1.1 tsutsui found = find_device(hw);
118 1.1 tsutsui #ifdef DEBUG
119 1.1 tsutsui if (!found) {
120 1.1 tsutsui printf("unconfigured %s ", hw->hw_name);
121 1.2 tsutsui printf("at 0x%x\n", (u_int)hw->hw_addr);
122 1.1 tsutsui }
123 1.1 tsutsui #endif
124 1.1 tsutsui }
125 1.1 tsutsui
126 1.1 tsutsui }
127 1.1 tsutsui
128 1.1 tsutsui #define dr_type(d, s) \
129 1.1 tsutsui (strcmp((d)->d_name, (s)) == 0)
130 1.1 tsutsui
131 1.1 tsutsui #define same_hw_ctlr(hw, hc) \
132 1.1 tsutsui ((hw)->hw_type == SCSI && dr_type((hc)->hp_driver, "sc"))
133 1.1 tsutsui
134 1.1 tsutsui int
135 1.1 tsutsui find_controller(struct hp_hw *hw)
136 1.1 tsutsui {
137 1.1 tsutsui struct hp_ctlr *hc;
138 1.1 tsutsui struct hp_ctlr *match_c;
139 1.1 tsutsui uint8_t *oaddr;
140 1.1 tsutsui int sc;
141 1.1 tsutsui
142 1.1 tsutsui #ifdef DEBUG
143 1.1 tsutsui if (acdebug)
144 1.1 tsutsui printf("find_controller: hw: %s at sc%d (%x), type %x...",
145 1.2 tsutsui hw->hw_name, hw->hw_sc, (u_int)hw->hw_addr, hw->hw_type);
146 1.1 tsutsui #endif
147 1.1 tsutsui sc = hw->hw_sc;
148 1.1 tsutsui match_c = NULL;
149 1.1 tsutsui for (hc = hp_cinit; hc->hp_driver; hc++) {
150 1.1 tsutsui if (hc->hp_alive)
151 1.1 tsutsui continue;
152 1.1 tsutsui /*
153 1.1 tsutsui * Make sure we are looking at the right
154 1.1 tsutsui * controller type.
155 1.1 tsutsui */
156 1.1 tsutsui if (!same_hw_ctlr(hw, hc))
157 1.1 tsutsui continue;
158 1.1 tsutsui /*
159 1.1 tsutsui * Exact match; all done
160 1.1 tsutsui */
161 1.1 tsutsui if ((int)hc->hp_addr == sc) {
162 1.1 tsutsui match_c = hc;
163 1.1 tsutsui break;
164 1.1 tsutsui }
165 1.1 tsutsui /*
166 1.1 tsutsui * Wildcard; possible match so remember first instance
167 1.1 tsutsui * but continue looking for exact match.
168 1.1 tsutsui */
169 1.1 tsutsui if ((int)hc->hp_addr == WILD_CARD_CTLR && match_c == NULL)
170 1.1 tsutsui match_c = hc;
171 1.1 tsutsui }
172 1.1 tsutsui #ifdef DEBUG
173 1.1 tsutsui if (acdebug) {
174 1.1 tsutsui if (match_c)
175 1.1 tsutsui printf("found %s%d\n",
176 1.1 tsutsui match_c->hp_driver->d_name,
177 1.1 tsutsui match_c->hp_unit);
178 1.1 tsutsui else
179 1.1 tsutsui printf("not found\n");
180 1.1 tsutsui }
181 1.1 tsutsui #endif
182 1.1 tsutsui /*
183 1.1 tsutsui * Didn't find an ioconf entry for this piece of hardware,
184 1.1 tsutsui * just ignore it.
185 1.1 tsutsui */
186 1.1 tsutsui if (match_c == NULL)
187 1.1 tsutsui return(0);
188 1.1 tsutsui /*
189 1.1 tsutsui * Found a match, attempt to initialize and configure all attached
190 1.1 tsutsui * slaves. Note, we can still fail if HW won't initialize.
191 1.1 tsutsui */
192 1.1 tsutsui hc = match_c;
193 1.1 tsutsui oaddr = hc->hp_addr;
194 1.1 tsutsui hc->hp_addr = hw->hw_addr;
195 1.1 tsutsui if ((*hc->hp_driver->d_init)(hc)) {
196 1.1 tsutsui hc->hp_alive = 1;
197 1.1 tsutsui printf("%s%d", hc->hp_driver->d_name, hc->hp_unit);
198 1.1 tsutsui printf(" at %p,", hc->hp_addr);
199 1.1 tsutsui printf(" ipl %d", hc->hp_ipl);
200 1.1 tsutsui if (hc->hp_flags)
201 1.1 tsutsui printf(" flags 0x%x", hc->hp_flags);
202 1.1 tsutsui printf("\n");
203 1.1 tsutsui find_slaves(hc);
204 1.1 tsutsui } else
205 1.1 tsutsui hc->hp_addr = oaddr;
206 1.1 tsutsui return(1);
207 1.1 tsutsui }
208 1.1 tsutsui
209 1.1 tsutsui int
210 1.1 tsutsui find_device(struct hp_hw *hw)
211 1.1 tsutsui {
212 1.1 tsutsui struct hp_device *hd;
213 1.1 tsutsui struct hp_device *match_d;
214 1.1 tsutsui uint8_t *oaddr;
215 1.1 tsutsui int sc;
216 1.1 tsutsui
217 1.1 tsutsui #ifdef DEBUG
218 1.1 tsutsui if (acdebug)
219 1.1 tsutsui printf("find_device: hw: %s at sc%d (%x), type %x...",
220 1.2 tsutsui hw->hw_name, hw->hw_sc, (u_int)hw->hw_addr, hw->hw_type);
221 1.1 tsutsui #endif
222 1.1 tsutsui match_d = NULL;
223 1.1 tsutsui for (hd = hp_dinit; hd->hp_driver; hd++) {
224 1.1 tsutsui if (hd->hp_alive)
225 1.1 tsutsui continue;
226 1.1 tsutsui /* Must not be a slave */
227 1.1 tsutsui if (hd->hp_cdriver)
228 1.1 tsutsui continue;
229 1.1 tsutsui sc = (int) hd->hp_addr;
230 1.1 tsutsui /*
231 1.1 tsutsui * Exact match; all done.
232 1.1 tsutsui */
233 1.1 tsutsui if (sc > 0 && sc == hw->hw_sc) {
234 1.1 tsutsui match_d = hd;
235 1.1 tsutsui break;
236 1.1 tsutsui }
237 1.1 tsutsui /*
238 1.1 tsutsui * Wildcard; possible match so remember first instance
239 1.1 tsutsui * but continue looking for exact match.
240 1.1 tsutsui */
241 1.1 tsutsui if (sc == 0 && same_hw_device(hw, hd) && match_d == NULL)
242 1.1 tsutsui match_d = hd;
243 1.1 tsutsui }
244 1.1 tsutsui #ifdef DEBUG
245 1.1 tsutsui if (acdebug) {
246 1.1 tsutsui if (match_d)
247 1.1 tsutsui printf("found %s%d\n",
248 1.1 tsutsui match_d->hp_driver->d_name,
249 1.1 tsutsui match_d->hp_unit);
250 1.1 tsutsui else
251 1.1 tsutsui printf("not found\n");
252 1.1 tsutsui }
253 1.1 tsutsui #endif
254 1.1 tsutsui /*
255 1.1 tsutsui * Didn't find an ioconf entry for this piece
256 1.1 tsutsui * of hardware, just ignore it.
257 1.1 tsutsui */
258 1.1 tsutsui if (match_d == NULL)
259 1.1 tsutsui return(0);
260 1.1 tsutsui /*
261 1.1 tsutsui * Found a match, attempt to initialize.
262 1.1 tsutsui * Note, we can still fail if HW won't initialize.
263 1.1 tsutsui */
264 1.1 tsutsui hd = match_d;
265 1.1 tsutsui oaddr = hd->hp_addr;
266 1.1 tsutsui hd->hp_addr = hw->hw_addr;
267 1.1 tsutsui if ((*hd->hp_driver->d_init)(hd)) {
268 1.1 tsutsui hd->hp_alive = 1;
269 1.1 tsutsui printf("%s%d", hd->hp_driver->d_name, hd->hp_unit);
270 1.1 tsutsui printf(" at %p", hd->hp_addr);
271 1.1 tsutsui if (hd->hp_ipl)
272 1.1 tsutsui printf(", ipl %d", hd->hp_ipl);
273 1.1 tsutsui if (hd->hp_flags)
274 1.1 tsutsui printf(", flags 0x%x", hd->hp_flags);
275 1.1 tsutsui printf("\n");
276 1.1 tsutsui } else
277 1.1 tsutsui hd->hp_addr = oaddr;
278 1.1 tsutsui return(1);
279 1.1 tsutsui }
280 1.1 tsutsui
281 1.1 tsutsui /*
282 1.1 tsutsui * Search each BUS controller found for slaves attached to it.
283 1.1 tsutsui * The bad news is that we don't know how to uniquely identify all slaves
284 1.1 tsutsui * (e.g. PPI devices on HP-IB). The good news is that we can at least
285 1.1 tsutsui * differentiate those from slaves we can identify. At worst (a totally
286 1.1 tsutsui * wildcarded entry) this will cause us to locate such a slave at the first
287 1.1 tsutsui * unused position instead of where it really is. To save grief, non-
288 1.1 tsutsui * identifing devices should always be fully qualified.
289 1.1 tsutsui */
290 1.1 tsutsui void
291 1.1 tsutsui find_slaves(struct hp_ctlr *hc)
292 1.1 tsutsui {
293 1.1 tsutsui int s;
294 1.1 tsutsui struct hp_device *hd;
295 1.1 tsutsui struct hp_device *match_s;
296 1.1 tsutsui int maxslaves = MAXSLAVES-1;
297 1.1 tsutsui int new_s, new_c, old_s, old_c;
298 1.1 tsutsui int rescan;
299 1.1 tsutsui
300 1.1 tsutsui #ifdef DEBUG
301 1.1 tsutsui if (acdebug)
302 1.1 tsutsui printf("find_slaves: for %s%d\n",
303 1.1 tsutsui hc->hp_driver->d_name, hc->hp_unit);
304 1.1 tsutsui #endif
305 1.1 tsutsui for (s = 0; s < maxslaves; s++) {
306 1.1 tsutsui rescan = 1;
307 1.1 tsutsui match_s = NULL;
308 1.1 tsutsui for (hd = hp_dinit; hd->hp_driver; hd++) {
309 1.1 tsutsui /*
310 1.1 tsutsui * Rule out the easy ones:
311 1.1 tsutsui * 1. slave already assigned or not a slave
312 1.1 tsutsui * 2. not of the proper type
313 1.1 tsutsui * 3. controller specified but not this one
314 1.1 tsutsui * 4. slave specified but not this one
315 1.1 tsutsui */
316 1.1 tsutsui if (hd->hp_alive || hd->hp_cdriver == NULL)
317 1.1 tsutsui continue;
318 1.1 tsutsui if (!dr_type(hc->hp_driver, hd->hp_cdriver->d_name))
319 1.1 tsutsui continue;
320 1.1 tsutsui if (hd->hp_ctlr >= 0 && hd->hp_ctlr != hc->hp_unit)
321 1.1 tsutsui continue;
322 1.1 tsutsui if (hd->hp_slave >= 0 && hd->hp_slave != s)
323 1.1 tsutsui continue;
324 1.1 tsutsui /*
325 1.1 tsutsui * Case 0: first possible match.
326 1.1 tsutsui * Remember it and keep looking for better.
327 1.1 tsutsui */
328 1.1 tsutsui if (match_s == NULL) {
329 1.1 tsutsui match_s = hd;
330 1.1 tsutsui new_c = hc->hp_unit;
331 1.1 tsutsui new_s = s;
332 1.1 tsutsui continue;
333 1.1 tsutsui }
334 1.1 tsutsui /*
335 1.1 tsutsui * Case 1: exact match.
336 1.1 tsutsui * All done. Note that we do not attempt any other
337 1.1 tsutsui * matches if this one fails. This allows us to
338 1.1 tsutsui * "reserve" locations for dynamic addition of
339 1.1 tsutsui * disk/tape drives by fully qualifing the location.
340 1.1 tsutsui */
341 1.1 tsutsui if (hd->hp_slave == s && hd->hp_ctlr == hc->hp_unit) {
342 1.1 tsutsui match_s = hd;
343 1.1 tsutsui rescan = 0;
344 1.1 tsutsui break;
345 1.1 tsutsui }
346 1.1 tsutsui /*
347 1.1 tsutsui * Case 2: right controller, wildcarded slave.
348 1.1 tsutsui * Remember first and keep looking for an exact match.
349 1.1 tsutsui */
350 1.1 tsutsui if (hd->hp_ctlr == hc->hp_unit &&
351 1.1 tsutsui match_s->hp_ctlr < 0) {
352 1.1 tsutsui match_s = hd;
353 1.1 tsutsui new_s = s;
354 1.1 tsutsui continue;
355 1.1 tsutsui }
356 1.1 tsutsui /*
357 1.1 tsutsui * Case 3: right slave, wildcarded controller.
358 1.1 tsutsui * Remember and keep looking for a better match.
359 1.1 tsutsui */
360 1.1 tsutsui if (hd->hp_slave == s &&
361 1.1 tsutsui match_s->hp_ctlr < 0 && match_s->hp_slave < 0) {
362 1.1 tsutsui match_s = hd;
363 1.1 tsutsui new_c = hc->hp_unit;
364 1.1 tsutsui continue;
365 1.1 tsutsui }
366 1.1 tsutsui /*
367 1.1 tsutsui * OW: we had a totally wildcarded spec.
368 1.1 tsutsui * If we got this far, we have found a possible
369 1.1 tsutsui * match already (match_s != NULL) so there is no
370 1.1 tsutsui * reason to remember this one.
371 1.1 tsutsui */
372 1.1 tsutsui continue;
373 1.1 tsutsui }
374 1.1 tsutsui /*
375 1.1 tsutsui * Found a match. We need to set hp_ctlr/hp_slave properly
376 1.1 tsutsui * for the init routines but we also need to remember all
377 1.1 tsutsui * the old values in case this doesn't pan out.
378 1.1 tsutsui */
379 1.1 tsutsui if (match_s) {
380 1.1 tsutsui hd = match_s;
381 1.1 tsutsui old_c = hd->hp_ctlr;
382 1.1 tsutsui old_s = hd->hp_slave;
383 1.1 tsutsui if (hd->hp_ctlr < 0)
384 1.1 tsutsui hd->hp_ctlr = new_c;
385 1.1 tsutsui if (hd->hp_slave < 0)
386 1.1 tsutsui hd->hp_slave = new_s;
387 1.1 tsutsui #ifdef DEBUG
388 1.1 tsutsui if (acdebug)
389 1.1 tsutsui printf("looking for %s%d at slave %d...",
390 1.1 tsutsui hd->hp_driver->d_name,
391 1.1 tsutsui hd->hp_unit, hd->hp_slave);
392 1.1 tsutsui #endif
393 1.1 tsutsui
394 1.1 tsutsui if ((*hd->hp_driver->d_init)(hd)) {
395 1.1 tsutsui #ifdef DEBUG
396 1.1 tsutsui if (acdebug)
397 1.1 tsutsui printf("found\n");
398 1.1 tsutsui #endif
399 1.1 tsutsui printf("%s%d at %s%d, slave %d",
400 1.1 tsutsui hd->hp_driver->d_name, hd->hp_unit,
401 1.1 tsutsui hc->hp_driver->d_name, hd->hp_ctlr,
402 1.1 tsutsui hd->hp_slave);
403 1.1 tsutsui if (hd->hp_flags)
404 1.1 tsutsui printf(" flags 0x%x", hd->hp_flags);
405 1.1 tsutsui printf("\n");
406 1.1 tsutsui hd->hp_alive = 1;
407 1.1 tsutsui if (hd->hp_dk && dkn < DK_NDRIVE)
408 1.1 tsutsui hd->hp_dk = dkn++;
409 1.1 tsutsui else
410 1.1 tsutsui hd->hp_dk = -1;
411 1.1 tsutsui rescan = 1;
412 1.1 tsutsui } else {
413 1.1 tsutsui #ifdef DEBUG
414 1.1 tsutsui if (acdebug)
415 1.1 tsutsui printf("not found\n");
416 1.1 tsutsui #endif
417 1.1 tsutsui hd->hp_ctlr = old_c;
418 1.1 tsutsui hd->hp_slave = old_s;
419 1.1 tsutsui }
420 1.1 tsutsui /*
421 1.1 tsutsui * XXX: This should be handled better.
422 1.1 tsutsui * Re-scan a slave. There are two reasons to do this.
423 1.1 tsutsui * 1. It is possible to have both a tape and disk
424 1.1 tsutsui * (e.g. 7946) or two disks (e.g. 9122) at the
425 1.1 tsutsui * same slave address. Here we need to rescan
426 1.1 tsutsui * looking only at entries with a different
427 1.1 tsutsui * physical unit number (hp_flags).
428 1.1 tsutsui * 2. It is possible that an init failed because the
429 1.1 tsutsui * slave was there but of the wrong type. In this
430 1.1 tsutsui * case it may still be possible to match the slave
431 1.1 tsutsui * to another ioconf entry of a different type.
432 1.1 tsutsui * Here we need to rescan looking only at entries
433 1.1 tsutsui * of different types.
434 1.1 tsutsui * In both cases we avoid looking at undesirable
435 1.1 tsutsui * ioconf entries of the same type by setting their
436 1.1 tsutsui * alive fields to -1.
437 1.1 tsutsui */
438 1.1 tsutsui if (rescan) {
439 1.1 tsutsui for (hd = hp_dinit; hd->hp_driver; hd++) {
440 1.1 tsutsui if (hd->hp_alive)
441 1.1 tsutsui continue;
442 1.1 tsutsui if (match_s->hp_alive == 1) { /* 1 */
443 1.1 tsutsui if (hd->hp_flags == match_s->hp_flags)
444 1.1 tsutsui hd->hp_alive = -1;
445 1.1 tsutsui } else { /* 2 */
446 1.1 tsutsui if (hd->hp_driver == match_s->hp_driver)
447 1.1 tsutsui hd->hp_alive = -1;
448 1.1 tsutsui }
449 1.1 tsutsui }
450 1.1 tsutsui s--;
451 1.1 tsutsui continue;
452 1.1 tsutsui }
453 1.1 tsutsui }
454 1.1 tsutsui /*
455 1.1 tsutsui * Reset bogon alive fields prior to attempting next slave
456 1.1 tsutsui */
457 1.1 tsutsui for (hd = hp_dinit; hd->hp_driver; hd++)
458 1.1 tsutsui if (hd->hp_alive == -1)
459 1.1 tsutsui hd->hp_alive = 0;
460 1.1 tsutsui }
461 1.1 tsutsui }
462 1.1 tsutsui
463 1.1 tsutsui int
464 1.1 tsutsui same_hw_device(struct hp_hw *hw, struct hp_device *hd)
465 1.1 tsutsui {
466 1.1 tsutsui int found = 0;
467 1.1 tsutsui
468 1.1 tsutsui switch (hw->hw_type) {
469 1.1 tsutsui case NET:
470 1.1 tsutsui found = dr_type(hd->hp_driver, "le");
471 1.1 tsutsui break;
472 1.1 tsutsui case SCSI:
473 1.1 tsutsui found = dr_type(hd->hp_driver, "scsi");
474 1.1 tsutsui break;
475 1.1 tsutsui case VME:
476 1.1 tsutsui case MISC:
477 1.1 tsutsui break;
478 1.1 tsutsui }
479 1.1 tsutsui return(found);
480 1.1 tsutsui }
481 1.1 tsutsui
482 1.1 tsutsui #define setup_hw(hw, addr, sc, type, id, name) \
483 1.1 tsutsui (hw)->hw_addr = addr; \
484 1.1 tsutsui (hw)->hw_sc = sc; \
485 1.1 tsutsui (hw)->hw_type = type; \
486 1.1 tsutsui (hw)->hw_id = id; \
487 1.1 tsutsui (hw)->hw_name = name
488 1.1 tsutsui
489 1.1 tsutsui void
490 1.1 tsutsui find_devs(void)
491 1.1 tsutsui {
492 1.1 tsutsui struct hp_hw *hw = sc_table;
493 1.1 tsutsui
494 1.1 tsutsui setup_hw(hw, (char *) 0x51000000, 0x5, SIO, 0x5, "uPD7201A (SIO)");
495 1.1 tsutsui hw->hw_id2 = 0; hw++;
496 1.1 tsutsui
497 1.1 tsutsui setup_hw(hw, (char *) 0x51000004, 0x5, KEYBOARD, 0x5, "uPD7201A (KBD)");
498 1.1 tsutsui hw->hw_id2 = 1; hw++;
499 1.1 tsutsui
500 1.1 tsutsui setup_hw(hw, (char *) 0xe1000000, 0xe, SCSI, 0xe, "MB89352 (SPC)");
501 1.1 tsutsui hw++;
502 1.1 tsutsui
503 1.3 tsutsui if (machtype == LUNA_II && !badaddr((void *) 0xe1000040)) {
504 1.3 tsutsui setup_hw(hw, (char *) 0xe1000040, 0xe, SCSI, 0xe, "MB89352 (SPC)");
505 1.3 tsutsui hw++;
506 1.3 tsutsui }
507 1.1 tsutsui if (!badaddr((void *) 0xf1000000)) {
508 1.1 tsutsui setup_hw(hw, (char *) 0xf1000000, 0xf, NET, 0xf, "Am7990 (LANCE)");
509 1.1 tsutsui hw++;
510 1.1 tsutsui }
511 1.1 tsutsui }
512