]>
Commit | Line | Data |
---|---|---|
6d2010ae A |
1 | /* |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights | |
7 | * Reserved. This file contains Original Code and/or Modifications of | |
8 | * Original Code as defined in and that are subject to the Apple Public | |
9 | * Source License Version 1.0 (the 'License'). You may not use this file | |
10 | * except in compliance with the License. Please obtain a copy of the | |
11 | * License at http://www.apple.com/publicsource and read it before using | |
12 | * this file. | |
13 | * | |
14 | * The Original Code and all software distributed under the License are | |
15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
19 | * License for the specific language governing rights and limitations | |
20 | * under the License." | |
21 | * | |
22 | * @APPLE_LICENSE_HEADER_END@ | |
23 | */ | |
24 | /* | |
25 | * Mach Operating System | |
26 | * Copyright (c) 1990 Carnegie-Mellon University | |
27 | * Copyright (c) 1989 Carnegie-Mellon University | |
28 | * Copyright (c) 1988 Carnegie-Mellon University | |
29 | * Copyright (c) 1987 Carnegie-Mellon University | |
30 | * All rights reserved. The CMU software License Agreement specifies | |
31 | * the terms and conditions for use and redistribution. | |
32 | */ | |
33 | ||
34 | /* | |
35 | * Copyright (c) 1980 Regents of the University of California. | |
36 | * All rights reserved. | |
37 | * | |
38 | * Redistribution and use in source and binary forms are permitted | |
39 | * provided that the above copyright notice and this paragraph are | |
40 | * duplicated in all such forms and that any documentation, | |
41 | * advertising materials, and other materials related to such | |
42 | * distribution and use acknowledge that the software was developed | |
43 | * by the University of California, Berkeley. The name of the | |
44 | * University may not be used to endorse or promote products derived | |
45 | * from this software without specific prior written permission. | |
46 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
47 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
48 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
49 | */ | |
50 | ||
51 | #include <stdio.h> | |
52 | #include <unistd.h> /* for unlink */ | |
53 | #include "parser.h" | |
54 | #include "config.h" | |
55 | ||
56 | /* | |
57 | * build the ioconf.c file | |
58 | */ | |
59 | char *intv(struct device *dev); | |
60 | char *intv2(struct device *dev); | |
61 | void i386_pseudo_inits(FILE *fp); /* XXX function in wrong block */ | |
62 | void check_vector(struct idlst *vec); | |
63 | void nrw_ioconf(void); | |
64 | void m88k_pseudo_inits(FILE *fp); | |
65 | void m98k_pseudo_inits(FILE *fp); | |
66 | char *m88k_dn(char *name); | |
67 | char *m98k_dn(char *name); | |
68 | char *concat3(char *buf, const char *p1, const char *p2, const char *p3); | |
69 | ||
70 | #if MACHINE_VAX | |
71 | ||
72 | void | |
73 | vax_ioconf(void) | |
74 | { | |
75 | register struct device *dp, *mp, *np; | |
76 | register int uba_n, slave; | |
77 | FILE *fp; | |
78 | ||
79 | fp = fopen(path("ioconf.c"), "w"); | |
80 | if (fp == 0) { | |
81 | perror(path("ioconf.c")); | |
82 | exit(1); | |
83 | } | |
84 | /*MACH_KERNEL*/ | |
85 | fprintf(fp, "#ifndef MACH_KERNEL\n"); | |
86 | /*MACH_KERNEL*/ | |
87 | fprintf(fp, "#include <machine/pte.h>\n"); | |
88 | fprintf(fp, "#include <sys/param.h>\n"); | |
89 | fprintf(fp, "#include <sys/buf.h>\n"); | |
90 | fprintf(fp, "#include <sys/map.h>\n"); | |
91 | fprintf(fp, "#include <sys/vm.h>\n"); | |
92 | /*MACH_KERNEL*/ | |
93 | fprintf(fp, "#endif MACH_KERNEL\n"); | |
94 | /*MACH_KERNEL*/ | |
95 | fprintf(fp, "\n"); | |
96 | fprintf(fp, "#include <vaxmba/mbavar.h>\n"); | |
97 | fprintf(fp, "#include <vaxuba/ubavar.h>\n\n"); | |
98 | fprintf(fp, "\n"); | |
99 | fprintf(fp, "#define C (caddr_t)\n\n"); | |
100 | /* | |
101 | * First print the mba initialization structures | |
102 | */ | |
103 | if (seen_mba) { | |
104 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
105 | mp = dp->d_conn; | |
106 | if (mp == 0 || mp == TO_NEXUS || | |
107 | !eq(mp->d_name, "mba")) | |
108 | continue; | |
109 | fprintf(fp, "extern struct mba_driver %sdriver;\n", | |
110 | dp->d_name); | |
111 | } | |
112 | fprintf(fp, "\nstruct mba_device mbdinit[] = {\n"); | |
113 | fprintf(fp, "\t/* Device, Unit, Mba, Drive, Dk */\n"); | |
114 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
115 | mp = dp->d_conn; | |
116 | if (dp->d_unit == QUES || mp == 0 || | |
117 | mp == TO_NEXUS || !eq(mp->d_name, "mba")) | |
118 | continue; | |
119 | if (dp->d_addr) { | |
120 | printf("can't specify csr address on mba for %s%d\n", | |
121 | dp->d_name, dp->d_unit); | |
122 | continue; | |
123 | } | |
124 | if (dp->d_vec != 0) { | |
125 | printf("can't specify vector for %s%d on mba\n", | |
126 | dp->d_name, dp->d_unit); | |
127 | continue; | |
128 | } | |
129 | if (dp->d_drive == UNKNOWN) { | |
130 | printf("drive not specified for %s%d\n", | |
131 | dp->d_name, dp->d_unit); | |
132 | continue; | |
133 | } | |
134 | if (dp->d_slave != UNKNOWN) { | |
135 | printf("can't specify slave number for %s%d\n", | |
136 | dp->d_name, dp->d_unit); | |
137 | continue; | |
138 | } | |
139 | fprintf(fp, "\t{ &%sdriver, %d, %s,", | |
140 | dp->d_name, dp->d_unit, qu(mp->d_unit)); | |
141 | fprintf(fp, " %s, %d },\n", | |
142 | qu(dp->d_drive), dp->d_dk); | |
143 | } | |
144 | fprintf(fp, "\t0\n};\n\n"); | |
145 | /* | |
146 | * Print the mbsinit structure | |
147 | * Driver Controller Unit Slave | |
148 | */ | |
149 | fprintf(fp, "struct mba_slave mbsinit [] = {\n"); | |
150 | fprintf(fp, "\t/* Driver, Ctlr, Unit, Slave */\n"); | |
151 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
152 | /* | |
153 | * All slaves are connected to something which | |
154 | * is connected to the massbus. | |
155 | */ | |
156 | if ((mp = dp->d_conn) == 0 || mp == TO_NEXUS) | |
157 | continue; | |
158 | np = mp->d_conn; | |
159 | if (np == 0 || np == TO_NEXUS || | |
160 | !eq(np->d_name, "mba")) | |
161 | continue; | |
162 | fprintf(fp, "\t{ &%sdriver, %s", | |
163 | mp->d_name, qu(mp->d_unit)); | |
164 | fprintf(fp, ", %2d, %s },\n", | |
165 | dp->d_unit, qu(dp->d_slave)); | |
166 | } | |
167 | fprintf(fp, "\t0\n};\n\n"); | |
168 | } | |
169 | /* | |
170 | * Now generate interrupt vectors for the unibus | |
171 | */ | |
172 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
173 | if (dp->d_vec != 0) { | |
174 | struct idlst *ip; | |
175 | mp = dp->d_conn; | |
176 | if (mp == 0 || mp == TO_NEXUS || | |
177 | !eq(mp->d_name, "uba")) | |
178 | continue; | |
179 | fprintf(fp, | |
180 | "extern struct uba_driver %sdriver;\n", | |
181 | dp->d_name); | |
182 | fprintf(fp, "extern "); | |
183 | ip = dp->d_vec; | |
184 | for (;;) { | |
185 | fprintf(fp, "X%s%d()", ip->id, dp->d_unit); | |
186 | ip = ip->id_next; | |
187 | if (ip == 0) | |
188 | break; | |
189 | fprintf(fp, ", "); | |
190 | } | |
191 | fprintf(fp, ";\n"); | |
192 | fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name, | |
193 | dp->d_unit); | |
194 | ip = dp->d_vec; | |
195 | for (;;) { | |
196 | fprintf(fp, "X%s%d", ip->id, dp->d_unit); | |
197 | ip = ip->id_next; | |
198 | if (ip == 0) | |
199 | break; | |
200 | fprintf(fp, ", "); | |
201 | } | |
202 | fprintf(fp, ", 0 } ;\n"); | |
203 | } | |
204 | } | |
205 | fprintf(fp, "\nstruct uba_ctlr ubminit[] = {\n"); | |
206 | fprintf(fp, "/*\t driver,\tctlr,\tubanum,\talive,\tintr,\taddr */\n"); | |
207 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
208 | mp = dp->d_conn; | |
209 | if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 || | |
210 | !eq(mp->d_name, "uba")) | |
211 | continue; | |
212 | if (dp->d_vec == 0) { | |
213 | printf("must specify vector for %s%d\n", | |
214 | dp->d_name, dp->d_unit); | |
215 | continue; | |
216 | } | |
217 | if (dp->d_addr == 0) { | |
218 | printf("must specify csr address for %s%d\n", | |
219 | dp->d_name, dp->d_unit); | |
220 | continue; | |
221 | } | |
222 | if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { | |
223 | printf("drives need their own entries; dont "); | |
224 | printf("specify drive or slave for %s%d\n", | |
225 | dp->d_name, dp->d_unit); | |
226 | continue; | |
227 | } | |
228 | if (dp->d_flags) { | |
229 | printf("controllers (e.g. %s%d) ", | |
230 | dp->d_name, dp->d_unit); | |
231 | printf("don't have flags, only devices do\n"); | |
232 | continue; | |
233 | } | |
234 | fprintf(fp, | |
235 | "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0%o },\n", | |
236 | dp->d_name, dp->d_unit, qu(mp->d_unit), | |
237 | dp->d_name, dp->d_unit, dp->d_addr); | |
238 | } | |
239 | fprintf(fp, "\t0\n};\n"); | |
240 | /* unibus devices */ | |
241 | fprintf(fp, "\nstruct uba_device ubdinit[] = {\n"); | |
242 | fprintf(fp, | |
243 | "\t/* driver, unit, ctlr, ubanum, slave, intr, addr, dk, flags*/\n"); | |
244 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
245 | mp = dp->d_conn; | |
246 | if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || | |
247 | mp == TO_NEXUS || mp->d_type == MASTER || | |
248 | eq(mp->d_name, "mba")) | |
249 | continue; | |
250 | np = mp->d_conn; | |
251 | if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba")) | |
252 | continue; | |
253 | np = 0; | |
254 | if (eq(mp->d_name, "uba")) { | |
255 | if (dp->d_vec == 0) { | |
256 | printf("must specify vector for device %s%d\n", | |
257 | dp->d_name, dp->d_unit); | |
258 | continue; | |
259 | } | |
260 | if (dp->d_addr == 0) { | |
261 | printf("must specify csr for device %s%d\n", | |
262 | dp->d_name, dp->d_unit); | |
263 | continue; | |
264 | } | |
265 | if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { | |
266 | printf("drives/slaves can be specified "); | |
267 | printf("only for controllers, "); | |
268 | printf("not for device %s%d\n", | |
269 | dp->d_name, dp->d_unit); | |
270 | continue; | |
271 | } | |
272 | uba_n = mp->d_unit; | |
273 | slave = QUES; | |
274 | } else { | |
275 | if ((np = mp->d_conn) == 0) { | |
276 | printf("%s%d isn't connected to anything ", | |
277 | mp->d_name, mp->d_unit); | |
278 | printf(", so %s%d is unattached\n", | |
279 | dp->d_name, dp->d_unit); | |
280 | continue; | |
281 | } | |
282 | uba_n = np->d_unit; | |
283 | if (dp->d_drive == UNKNOWN) { | |
284 | printf("must specify ``drive number'' "); | |
285 | printf("for %s%d\n", dp->d_name, dp->d_unit); | |
286 | continue; | |
287 | } | |
288 | /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */ | |
289 | /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */ | |
290 | if (dp->d_slave != UNKNOWN) { | |
291 | printf("slave numbers should be given only "); | |
292 | printf("for massbus tapes, not for %s%d\n", | |
293 | dp->d_name, dp->d_unit); | |
294 | continue; | |
295 | } | |
296 | if (dp->d_vec != 0) { | |
297 | printf("interrupt vectors should not be "); | |
298 | printf("given for drive %s%d\n", | |
299 | dp->d_name, dp->d_unit); | |
300 | continue; | |
301 | } | |
302 | if (dp->d_addr != 0) { | |
303 | printf("csr addresses should be given only "); | |
304 | printf("on controllers, not on %s%d\n", | |
305 | dp->d_name, dp->d_unit); | |
306 | continue; | |
307 | } | |
308 | slave = dp->d_drive; | |
309 | } | |
310 | fprintf(fp, "\t{ &%sdriver, %2d, %s,", | |
311 | eq(mp->d_name, "uba") ? dp->d_name : mp->d_name, dp->d_unit, | |
312 | eq(mp->d_name, "uba") ? " -1" : qu(mp->d_unit)); | |
313 | fprintf(fp, " %s, %2d, %s, C 0%-6o, %d, 0x%x },\n", | |
314 | qu(uba_n), slave, intv(dp), dp->d_addr, dp->d_dk, | |
315 | dp->d_flags); | |
316 | } | |
317 | fprintf(fp, "\t0\n};\n"); | |
318 | (void) fclose(fp); | |
319 | } | |
320 | #endif | |
321 | ||
322 | #if MACHINE_SUN | |
323 | #define SP_OBIO 0x0004 /* on board i/o (for sun/autoconf.h) */ | |
324 | ||
325 | #define VEC_LO 64 | |
326 | #define VEC_HI 255 | |
327 | ||
328 | void pseudo_inits(FILE *fp); | |
329 | ||
330 | void | |
331 | check_vector(struct idlst *vec) | |
332 | { | |
333 | ||
334 | if (vec->id_vec == 0) | |
335 | fprintf(stderr, "vector number for %s not given\n", vec->id); | |
336 | else if (vec->id_vec < VEC_LO || vec->id_vec > VEC_HI) | |
337 | fprintf(stderr, | |
338 | "vector number %d for %s is not between %d and %d\n", | |
339 | vec->id_vec, vec->id, VEC_LO, VEC_HI); | |
340 | } | |
341 | ||
342 | void | |
343 | sun_ioconf(void) | |
344 | { | |
345 | register struct device *dp, *mp; | |
346 | register int slave; | |
347 | register struct idlst *vp; | |
348 | FILE *fp; | |
349 | ||
350 | fp = fopen(path("ioconf.c"), "w"); | |
351 | if (fp == 0) { | |
352 | perror(path("ioconf.c")); | |
353 | exit(1); | |
354 | } | |
355 | /*MACH_KERNEL*/ | |
356 | fprintf(fp, "#ifndef MACH_KERNEL\n"); | |
357 | /*MACH_KERNEL*/ | |
358 | fprintf(fp, "#include <sys/param.h>\n"); | |
359 | fprintf(fp, "#include <sys/buf.h>\n"); | |
360 | fprintf(fp, "#include <sys/map.h>\n"); | |
361 | fprintf(fp, "#include <sys/vm.h>\n"); | |
362 | /*MACH_KERNEL*/ | |
363 | fprintf(fp, "#endif MACH_KERNEL\n"); | |
364 | /*MACH_KERNEL*/ | |
365 | fprintf(fp, "\n"); | |
366 | fprintf(fp, "#include <sundev/mbvar.h>\n"); | |
367 | fprintf(fp, "\n"); | |
368 | fprintf(fp, "#define C (caddr_t)\n\n"); | |
369 | fprintf(fp, "\n"); | |
370 | ||
371 | /* | |
372 | * Now generate interrupt vectors for the Mainbus | |
373 | */ | |
374 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
375 | mp = dp->d_conn; | |
376 | if (mp == TO_NEXUS || mp == 0 || mp->d_conn != TO_NEXUS) | |
377 | continue; | |
378 | fprintf(fp, "extern struct mb_driver %sdriver;\n", | |
379 | dp->d_name); | |
380 | if (dp->d_vec != 0) { | |
381 | if (dp->d_pri == 0) | |
382 | fprintf(stderr, | |
383 | "no priority specified for %s%d\n", | |
384 | dp->d_name, dp->d_unit); | |
385 | fprintf(fp, "extern "); | |
386 | for (vp = dp->d_vec;;) { | |
387 | if (machine == MACHINE_SUN4) | |
388 | fprintf(fp, "%s()", vp->id); | |
389 | else | |
390 | fprintf(fp, "X%s%d()", | |
391 | vp->id, dp->d_unit); | |
392 | vp = vp->id_next; | |
393 | if (vp == 0) | |
394 | break; | |
395 | fprintf(fp, ", "); | |
396 | } | |
397 | fprintf(fp, ";\n"); | |
398 | ||
399 | for (vp = dp->d_vec; vp; vp = vp->id_next) { | |
400 | fprintf(fp, "int V%s%d = %d;\n", | |
401 | vp->id, dp->d_unit, dp->d_unit); | |
402 | } | |
403 | ||
404 | fprintf(fp, "struct vec %s[] = { ", intv(dp)); | |
405 | for (vp = dp->d_vec; vp != 0; vp = vp->id_next) { | |
406 | if (machine == MACHINE_SUN4) | |
407 | fprintf(fp, "{ %s, %d, &V%s%d }, ", | |
408 | vp->id, vp->id_vec, | |
409 | vp->id, dp->d_unit); | |
410 | else | |
411 | fprintf(fp, "{ X%s%d, %d, &V%s%d }, ", | |
412 | vp->id, dp->d_unit, vp->id_vec, | |
413 | vp->id, dp->d_unit); | |
414 | check_vector(vp); | |
415 | } | |
416 | fprintf(fp, "0 };\n"); | |
417 | } | |
418 | } | |
419 | ||
420 | /* | |
421 | * Now spew forth the mb_ctlr structures | |
422 | */ | |
423 | fprintf(fp, "\nstruct mb_ctlr mbcinit[] = {\n"); | |
424 | fprintf(fp, | |
425 | "/* driver,\tctlr,\talive,\taddress,\tintpri,\t intr,\tspace */\n"); | |
426 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
427 | mp = dp->d_conn; | |
428 | if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 || | |
429 | mp->d_conn != TO_NEXUS) | |
430 | continue; | |
431 | if (dp->d_addr == UNKNOWN) { | |
432 | printf("must specify csr address for %s%d\n", | |
433 | dp->d_name, dp->d_unit); | |
434 | continue; | |
435 | } | |
436 | if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { | |
437 | printf("drives need their own entries; "); | |
438 | printf("don't specify drive or slave for %s%d\n", | |
439 | dp->d_name, dp->d_unit); | |
440 | continue; | |
441 | } | |
442 | if (dp->d_flags) { | |
443 | printf("controllers (e.g. %s%d) don't have flags, ", | |
444 | dp->d_name, dp->d_unit); | |
445 | printf("only devices do\n"); | |
446 | continue; | |
447 | } | |
448 | if (machine == MACHINE_SUN4) | |
449 | fprintf(fp, | |
450 | "{ &%sdriver,\t%d,\t0,\tC 0x%08x,\t%d,\t%s, 0x%x },\n", | |
451 | dp->d_name, dp->d_unit, dp->d_addr, | |
452 | (dp->d_bus==SP_OBIO) ? (dp->d_pri << 1) : (dp->d_pri<<1)-1, | |
453 | intv(dp), ((dp->d_mach << 16) | dp->d_bus)); | |
454 | else | |
455 | fprintf(fp, | |
456 | "{ &%sdriver,\t%d,\t0,\tC 0x%08x,\t%d,\t%s, 0x%x },\n", | |
457 | dp->d_name, dp->d_unit, dp->d_addr, | |
458 | dp->d_pri, intv(dp), ((dp->d_mach << 16) | dp->d_bus)); | |
459 | } | |
460 | fprintf(fp, "\t0\n};\n"); | |
461 | ||
462 | /* | |
463 | * Now we go for the mb_device stuff | |
464 | */ | |
465 | fprintf(fp, "\nstruct mb_device mbdinit[] = {\n"); | |
466 | fprintf(fp, | |
467 | "/* driver,\tunit, ctlr, slave, address, pri, dk, flags, intr, space */\n"); | |
468 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
469 | mp = dp->d_conn; | |
470 | if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || | |
471 | mp == TO_NEXUS || mp->d_type == MASTER) | |
472 | continue; | |
473 | if (mp->d_conn == TO_NEXUS) { | |
474 | if (dp->d_addr == UNKNOWN) { | |
475 | printf("must specify csr for device %s%d\n", | |
476 | dp->d_name, dp->d_unit); | |
477 | continue; | |
478 | } | |
479 | if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { | |
480 | printf("drives/slaves can be specified only "); | |
481 | printf("for controllers, not for device %s%d\n", | |
482 | dp->d_name, dp->d_unit); | |
483 | continue; | |
484 | } | |
485 | slave = QUES; | |
486 | } else { | |
487 | if (mp->d_conn == 0) { | |
488 | printf("%s%d isn't connected to anything, ", | |
489 | mp->d_name, mp->d_unit); | |
490 | printf("so %s%d is unattached\n", | |
491 | dp->d_name, dp->d_unit); | |
492 | continue; | |
493 | } | |
494 | if (dp->d_drive == UNKNOWN) { | |
495 | printf("must specify ``drive number'' for %s%d\n", | |
496 | dp->d_name, dp->d_unit); | |
497 | continue; | |
498 | } | |
499 | /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */ | |
500 | /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */ | |
501 | if (dp->d_slave != UNKNOWN) { | |
502 | printf("slave numbers should be given only "); | |
503 | printf("for massbus tapes, not for %s%d\n", | |
504 | dp->d_name, dp->d_unit); | |
505 | continue; | |
506 | } | |
507 | if (dp->d_pri != 0) { | |
508 | printf("interrupt priority should not be "); | |
509 | printf("given for drive %s%d\n", | |
510 | dp->d_name, dp->d_unit); | |
511 | continue; | |
512 | } | |
513 | if (dp->d_addr != UNKNOWN) { | |
514 | printf("csr addresses should be given only"); | |
515 | printf(" on controllers, not on %s%d\n", | |
516 | dp->d_name, dp->d_unit); | |
517 | continue; | |
518 | } | |
519 | slave = dp->d_drive; | |
520 | } | |
521 | if (machine == MACHINE_SUN4) | |
522 | fprintf(fp, | |
523 | "{ &%sdriver,\t%d, %s, %2d, C 0x%08x, %d, %d, 0x%x, %s, 0x%x },\n", | |
524 | mp->d_conn == TO_NEXUS? dp->d_name : mp->d_name, dp->d_unit, | |
525 | mp->d_conn == TO_NEXUS? " -1" : qu(mp->d_unit), | |
526 | slave, | |
527 | dp->d_addr == UNKNOWN? 0 : dp->d_addr, | |
528 | dp->d_pri * 2, dp->d_dk, dp->d_flags, intv(dp), | |
529 | ((dp->d_mach << 16) | dp->d_bus)); | |
530 | else | |
531 | fprintf(fp, | |
532 | "{ &%sdriver,\t%d, %s, %2d, C 0x%08x, %d, %d, 0x%x, %s, 0x%x },\n", | |
533 | mp->d_conn == TO_NEXUS? dp->d_name : mp->d_name, dp->d_unit, | |
534 | mp->d_conn == TO_NEXUS? " -1" : qu(mp->d_unit), | |
535 | slave, | |
536 | dp->d_addr == UNKNOWN? 0 : dp->d_addr, | |
537 | dp->d_pri, dp->d_dk, dp->d_flags, intv(dp), | |
538 | ((dp->d_mach << 16) | dp->d_bus)); | |
539 | } | |
540 | fprintf(fp, "\t0\n};\n"); | |
541 | pseudo_inits(fp); | |
542 | (void) fclose(fp); | |
543 | } | |
544 | ||
545 | void | |
546 | pseudo_inits(FILE *fp) | |
547 | { | |
548 | #ifdef notdef | |
549 | register struct device *dp; | |
550 | int count; | |
551 | ||
552 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
553 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
554 | continue; | |
555 | fprintf(fp, "extern int %s(int);\n", dp->d_init); | |
556 | } | |
557 | #endif notdef | |
558 | fprintf(fp, "struct pseudo_init {\n"); | |
559 | fprintf(fp, "\tint\tps_count;\n\tint\t(*ps_func)();\n"); | |
560 | fprintf(fp, "} pseudo_inits[] = {\n"); | |
561 | #ifdef notdef | |
562 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
563 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
564 | continue; | |
565 | count = dp->d_slave; | |
566 | if (count <= 0) | |
567 | count = 1; | |
568 | fprintf(fp, "\t{%d,\t%s},\n", count, dp->d_init); | |
569 | } | |
570 | #endif notdef | |
571 | fprintf(fp, "\t{0,\t0},\n};\n"); | |
572 | } | |
573 | #endif | |
574 | ||
575 | #if MACHINE_ROMP | |
576 | void | |
577 | romp_ioconf(void) | |
578 | { | |
579 | register struct device *dp, *mp; | |
580 | register int slave; | |
581 | FILE *fp; | |
582 | ||
583 | fp = fopen(path("ioconf.c"), "w"); | |
584 | if (fp == 0) { | |
585 | perror(path("ioconf.c")); | |
586 | exit(1); | |
587 | } | |
588 | /*MACH_KERNEL*/ | |
589 | fprintf(fp, "#ifndef MACH_KERNEL\n"); | |
590 | /*MACH_KERNEL*/ | |
591 | fprintf(fp, "#include <sys/param.h>\n"); | |
592 | fprintf(fp, "#include <sys/buf.h>\n"); | |
593 | fprintf(fp, "#include <sys/map.h>\n"); | |
594 | fprintf(fp, "#include <sys/vm.h>\n"); | |
595 | /*MACH_KERNEL*/ | |
596 | fprintf(fp, "#endif MACH_KERNEL\n"); | |
597 | /*MACH_KERNEL*/ | |
598 | fprintf(fp, "\n"); | |
599 | fprintf(fp, "#include <caio/ioccvar.h>\n"); | |
600 | fprintf(fp, "\n"); | |
601 | fprintf(fp, "#define C (caddr_t)\n\n"); | |
602 | fprintf(fp, "\n"); | |
603 | ||
604 | fprintf (fp, "struct iocc_hd iocc_hd[] = {{C 0xF0000000,}};\n"); | |
605 | /* | |
606 | * Now generate interrupt vectors for the Winnerbus | |
607 | */ | |
608 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
609 | if (dp->d_pri != 0) { | |
610 | mp = dp->d_conn; | |
611 | if (mp == 0 || mp == TO_NEXUS || | |
612 | !eq(mp->d_name, "iocc")) | |
613 | continue; | |
614 | fprintf(fp, "extern struct iocc_driver %sdriver;\n", | |
615 | dp->d_name); | |
616 | } | |
617 | } | |
618 | /* | |
619 | * Now spew forth the iocc_cinfo structure | |
620 | */ | |
621 | fprintf(fp, "\nstruct iocc_ctlr iocccinit[] = {\n"); | |
622 | fprintf(fp, "/*\t driver,\tctlr,\talive,\taddr,\tintpri */\n"); | |
623 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
624 | mp = dp->d_conn; | |
625 | if (dp->d_type != CONTROLLER) | |
626 | continue; | |
627 | if (mp == TO_NEXUS || mp == 0 || !eq(mp->d_name, "iocc")) | |
628 | continue; | |
629 | if (dp->d_unit == QUES && eq(dp->d_name,"hdc")) | |
630 | continue; | |
631 | if (dp->d_unit == QUES && eq(dp->d_name,"fdc")) | |
632 | continue; | |
633 | if (dp->d_pri == 0) { | |
634 | printf("must specify priority for %s%d\n", | |
635 | dp->d_name, dp->d_unit); | |
636 | continue; | |
637 | } | |
638 | if (dp->d_addr == 0) { | |
639 | printf("must specify csr address for %s%d\n", | |
640 | dp->d_name, dp->d_unit); | |
641 | continue; | |
642 | } | |
643 | if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { | |
644 | printf("drives need their own entries; "); | |
645 | printf("dont specify drive or slave for %s%d\n", | |
646 | dp->d_name, dp->d_unit); | |
647 | continue; | |
648 | } | |
649 | if (dp->d_flags) { | |
650 | printf("controllers (e.g. %s%d) don't have flags, ", | |
651 | dp->d_name, dp->d_unit); | |
652 | printf("only devices do\n"); | |
653 | continue; | |
654 | } | |
655 | fprintf(fp, "\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t%d },\n", | |
656 | dp->d_name, dp->d_unit, dp->d_addr, dp->d_pri); | |
657 | } | |
658 | fprintf(fp, "\t0\n};\n"); | |
659 | /* | |
660 | * Now we go for the iocc_device stuff | |
661 | */ | |
662 | fprintf(fp, "\nstruct iocc_device ioccdinit[] = {\n"); | |
663 | fprintf(fp, | |
664 | "\t/* driver, unit, ctlr, slave, addr, pri, dk, flags*/\n"); | |
665 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
666 | mp = dp->d_conn; | |
667 | if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || | |
668 | mp == TO_NEXUS || mp->d_type == MASTER || | |
669 | eq(mp->d_name, "iocca")) | |
670 | continue; | |
671 | if (eq(mp->d_name, "iocc")) { | |
672 | if (dp->d_pri == 0) { | |
673 | printf("must specify vector for device %s%d\n", | |
674 | dp->d_name, dp->d_unit); | |
675 | continue; | |
676 | } | |
677 | if (dp->d_addr == 0) { | |
678 | printf("must specify csr for device %s%d\n", | |
679 | dp->d_name, dp->d_unit); | |
680 | continue; | |
681 | } | |
682 | if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { | |
683 | printf("drives/slaves can be specified only "); | |
684 | printf("for controllers, not for device %s%d\n", | |
685 | dp->d_name, dp->d_unit); | |
686 | continue; | |
687 | } | |
688 | slave = QUES; | |
689 | } else { | |
690 | if (mp->d_conn == 0) { | |
691 | printf("%s%d isn't connected to anything, ", | |
692 | mp->d_name, mp->d_unit); | |
693 | printf("so %s%d is unattached\n", | |
694 | dp->d_name, dp->d_unit); | |
695 | continue; | |
696 | } | |
697 | if (dp->d_drive == UNKNOWN) { | |
698 | printf("must specify ``drive number'' for %s%d\n", | |
699 | dp->d_name, dp->d_unit); | |
700 | continue; | |
701 | } | |
702 | /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */ | |
703 | /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */ | |
704 | if (dp->d_slave != UNKNOWN) { | |
705 | printf("slave numbers should be given only "); | |
706 | printf("for massbus tapes, not for %s%d\n", | |
707 | dp->d_name, dp->d_unit); | |
708 | continue; | |
709 | } | |
710 | if (dp->d_pri != 0) { | |
711 | printf("interrupt priority should not be "); | |
712 | printf("given for drive %s%d\n", | |
713 | dp->d_name, dp->d_unit); | |
714 | continue; | |
715 | } | |
716 | if (dp->d_addr != 0) { | |
717 | printf("csr addresses should be given only"); | |
718 | printf("on controllers, not on %s%d\n", | |
719 | dp->d_name, dp->d_unit); | |
720 | continue; | |
721 | } | |
722 | slave = dp->d_drive; | |
723 | } | |
724 | fprintf(fp, | |
725 | "\t{ &%sdriver, %2d, %s, %2d, C 0x%x, %d, %d, 0x%x },\n", | |
726 | eq(mp->d_name, "iocc") ? dp->d_name : mp->d_name, dp->d_unit, | |
727 | eq(mp->d_name, "iocc") ? " -1" : qu(mp->d_unit), | |
728 | slave, dp->d_addr, dp->d_pri, dp->d_dk, dp->d_flags); | |
729 | } | |
730 | fprintf(fp, "\t0\n};\n"); | |
731 | (void) fclose(fp); | |
732 | } | |
733 | ||
734 | #endif MACHINE_ROMP | |
735 | ||
736 | #if MACHINE_MMAX | |
737 | void | |
738 | mmax_ioconf(void) | |
739 | { | |
740 | register struct device *dp, *dp1, *mp; | |
741 | FILE *fp; | |
742 | int unit; | |
743 | ||
744 | fp = fopen(path("ioconf.c"), "w"); | |
745 | if (fp == 0) { | |
746 | perror(path("ioconf.c")); | |
747 | exit(1); | |
748 | } | |
749 | fprintf(fp, "#include <mmaxio/io.h>\n\n"); | |
750 | ||
751 | /* | |
752 | * Multimax code is a little messy because we have to | |
753 | * scan the entire list for each device to generate the | |
754 | * structures correctly. We cheat and use the d->d_pri | |
755 | * field to avoid doing anything twice. -1000 is an obvious | |
756 | * bogus value for this field. | |
757 | */ | |
758 | ||
759 | for (dp1 = dtab; dp1 != 0; dp1 = dp1->d_next) { | |
760 | /* | |
761 | * If pri is not -1000, then haven't seen device yet. | |
762 | */ | |
763 | if (dp1->d_pri != -1000) switch (dp1->d_type) { | |
764 | ||
765 | case CONTROLLER: | |
766 | fprintf(fp,"struct devaddr %s_devaddr[] = {\n", | |
767 | dp1->d_name); | |
768 | /* | |
769 | * Now scan entire list and get all of them. Use | |
770 | * unit to make sure unit numbers are right. | |
771 | */ | |
772 | unit = 0; | |
773 | for (dp = dp1; dp != 0; dp = dp->d_next) { | |
774 | if (!strcmp(dp->d_name, dp1->d_name)) { | |
775 | mp = dp->d_conn; | |
776 | if (mp != TO_SLOT) { | |
777 | printf("%s%d: controller must be connected to slot.\n", | |
778 | dp->d_name, dp->d_unit); | |
779 | exit(1); | |
780 | } | |
781 | if (dp->d_vec != 0) { | |
782 | printf("%s%d: cannot configure multimax interrupt vectors.\n", | |
783 | dp->d_name, dp->d_unit); | |
784 | } | |
785 | if (dp->d_pri != 0) { | |
786 | printf("%s%d: interrupt priority is nonsense on multimax.\n", | |
787 | dp->d_name, dp->d_unit); | |
788 | } | |
789 | if ((dp->d_drive != UNKNOWN) || | |
790 | (dp->d_slave !=UNKNOWN)) { | |
791 | printf("%s%d: don't specify drive or slave for controller.\n", | |
792 | dp->d_name, dp->d_unit); | |
793 | } | |
794 | /* | |
795 | * Fix unit number if bogus | |
796 | */ | |
797 | if(dp->d_unit != unit) { | |
798 | printf("Warning: %s%d configured as %s%d -- fix config file.\n", | |
799 | dp->d_name,dp->d_unit,dp->d_name,unit); | |
800 | dp->d_unit = unit; | |
801 | } | |
802 | unit++; | |
803 | fprintf(fp,"\t{ %d, 0, 0},\n",dp->d_addr); | |
804 | dp->d_pri = -1000; /* done this one */ | |
805 | } | |
806 | } | |
807 | fprintf(fp,"} ;\n\n"); | |
808 | break; | |
809 | ||
810 | case DEVICE: | |
811 | fprintf(fp,"struct subdevaddr %s_subdevaddr[] = {\n", | |
812 | dp1->d_name); | |
813 | /* | |
814 | * Now scan entire list and get all of them. Use | |
815 | * unit to make sure unit numbers are right. | |
816 | */ | |
817 | unit = 0; | |
818 | for (dp = dp1; dp != 0; dp = dp->d_next) { | |
819 | if (!strcmp(dp->d_name, dp1->d_name)) { | |
820 | mp = dp->d_conn; | |
821 | if ( (mp == 0) || (mp == TO_SLOT) || | |
822 | (mp->d_type != CONTROLLER)) { | |
823 | printf("%s%d: device has no controller.\n", | |
824 | dp->d_name, dp->d_unit); | |
825 | exit(1); | |
826 | } | |
827 | if (dp->d_vec != 0) { | |
828 | printf("%s%d: cannot configure multimax interrupt vectors.\n", | |
829 | dp->d_name, dp->d_unit); | |
830 | } | |
831 | if (dp->d_pri != 0) { | |
832 | printf("%s%d: interrupt priority is nonsense on multimax.\n", | |
833 | dp->d_name, dp->d_unit); | |
834 | } | |
835 | if ((dp->d_drive != UNKNOWN) || | |
836 | (dp->d_slave !=UNKNOWN)) { | |
837 | printf("%s%d: use 'unit' instead of 'drive' or 'slave'.\n", | |
838 | dp->d_name, dp->d_unit); | |
839 | } | |
840 | /* | |
841 | * Fix unit number if bogus | |
842 | */ | |
843 | if(dp->d_unit != unit) { | |
844 | printf("Warning: %s%d configured as %s%d -- fix config file.\n", | |
845 | dp->d_name,dp->d_unit,dp->d_name,unit); | |
846 | dp->d_unit = unit; | |
847 | } | |
848 | unit++; | |
849 | if((dp->d_addr == 0) || (dp->d_addr == QUES)){ | |
850 | printf("%s%d: must specify logical unit number.\n", | |
851 | dp->d_name,dp->d_unit); | |
852 | exit(1); | |
853 | } | |
854 | fprintf(fp,"\t{ %d, %d, 0},\n",mp->d_unit, | |
855 | dp->d_addr); | |
856 | dp->d_pri = -1000; /* don't do this again */ | |
857 | } | |
858 | } | |
859 | fprintf(fp,"} ;\n\n"); | |
860 | break; | |
861 | ||
862 | case PSEUDO_DEVICE: | |
863 | /* | |
864 | * Doesn't exist as far as ioconf.c is concerned. | |
865 | */ | |
866 | break; | |
867 | ||
868 | default: | |
869 | printf("Bogus device type for %s\n", dp1->d_name); | |
870 | exit(1); | |
871 | break; | |
872 | } | |
873 | } | |
874 | ||
875 | (void) fclose(fp); | |
876 | } | |
877 | ||
878 | #endif MACHINE_MMAX | |
879 | ||
880 | #if MACHINE_SQT | |
881 | ||
882 | /* | |
883 | * Define prototype device spec lines. | |
884 | * | |
885 | * For now, have static set of controller prototypes. This should be | |
886 | * upgraded to using (eg) controllers.balance (ala Sequent /etc/config) | |
887 | * to support custom boards without need to edit this file. | |
888 | */ | |
889 | ||
890 | /* | |
891 | * flags for indicating presence of upper and lower bound values | |
892 | */ | |
893 | ||
894 | #define P_LB 1 | |
895 | #define P_UB 2 | |
896 | ||
897 | struct p_entry { | |
898 | const char *p_name; /* name of field */ | |
899 | long p_def; /* default value */ | |
900 | long p_lb; /* lower bound for field */ | |
901 | long p_ub; /* upper bound of field */ | |
902 | char p_flags; /* bound valid flags */ | |
903 | }; | |
904 | ||
905 | struct proto { | |
906 | const char *p_name; /* name of controller type */ | |
907 | struct p_entry p_fields[NFIELDS]; /* ordered list of fields */ | |
908 | int p_seen; /* any seen? */ | |
909 | }; | |
910 | ||
911 | /* | |
912 | * MULTIBUS Adapter: | |
913 | * type mbad index csr flags maps[0,256] bin[0,7] intr[0,7] | |
914 | */ | |
915 | ||
916 | static struct proto mbad_proto = { | |
917 | "mbad", | |
918 | {{ "index", 0, 0, 0, 0 }, | |
919 | { "csr", 0, 0, 0, 0 }, | |
920 | { "flags", 0, 0, 0, 0 }, | |
921 | { "maps", 0, 0, 256, P_LB|P_UB }, | |
922 | { "bin", 0, 0, 7, P_LB|P_UB }, | |
923 | { "intr", 0, 0, 7, P_LB|P_UB },}, | |
924 | 0 | |
925 | }; | |
926 | ||
927 | /* | |
928 | * SCSI/Ether Controller: | |
929 | * type sec flags bin[0,7] req doneq index target[0,7]=-1 unit | |
930 | */ | |
931 | ||
932 | static struct proto sec_proto = { | |
933 | "sec", | |
934 | {{ "flags", 0, 0, 0, 0 }, | |
935 | { "bin", 0, 0, 7, P_LB|P_UB } , | |
936 | { "req", 0, 0, 0, 0 }, | |
937 | { "doneq", 0, 0, 0, 0 }, | |
938 | { "index", 0, 0, 0, 0 }, | |
939 | { "target", -1, 0, 7, P_LB|P_UB }, | |
940 | { "unit", 0, 0, 0, 0 },}, | |
941 | 0 | |
942 | }; | |
943 | ||
944 | /* | |
945 | * "Zeke" (FAST) Disk Controller (Dual-Channel Disk Controller): | |
946 | * type zdc index[0,31] drive[-1,7] drive_type[-1,1] | |
947 | * | |
948 | * Levgal values for drive_type: | |
949 | * M2333K = 0 (swallow) | |
950 | * M2351A = 1 (eagle) | |
951 | * wildcard = -1 (run-time determined) | |
952 | */ | |
953 | ||
954 | static struct proto zdc_proto = { | |
955 | "zdc", | |
956 | {{ "index", 0, 0, 31, P_LB|P_UB }, | |
957 | { "drive", 0, -1, 7, P_LB|P_UB }, | |
958 | { "drive_type", 0, -1, 1, P_LB|P_UB },}, | |
959 | 0 | |
960 | }; | |
961 | ||
962 | static struct proto *ptab[] = { | |
963 | &mbad_proto, | |
964 | &sec_proto, | |
965 | &zdc_proto, | |
966 | (struct proto *) 0 | |
967 | }; | |
968 | ||
969 | /* | |
970 | * locate a prototype structure in the queue of such structures. | |
971 | * return NULL if not found. | |
972 | */ | |
973 | ||
974 | static struct proto * | |
975 | find_proto(const char *str) | |
976 | { | |
977 | register struct proto *ptp; | |
978 | register int ptbx; | |
979 | ||
980 | for (ptbx = 0; (ptp = ptab[ptbx]) != NULL; ptbx++) { | |
981 | if (eq(str, ptp->p_name)) | |
982 | return(ptp); | |
983 | } | |
984 | return(NULL); | |
985 | } | |
986 | ||
987 | void | |
988 | dev_param(struct device *dp, const char *str, long num) | |
989 | { | |
990 | register struct p_entry *entry; | |
991 | register struct proto *ptp; | |
992 | ||
993 | ptp = find_proto(dp->d_conn->d_name); | |
994 | if (ptp == NULL) { | |
995 | fprintf(stderr,"dev %s cont %s", dp->d_name, dp->d_conn->d_name); | |
996 | yyerror("invalid controller"); | |
997 | return; | |
998 | } | |
999 | ||
1000 | for (entry = ptp->p_fields; entry->p_name != NULL; entry++) { | |
1001 | if (eq(entry->p_name, str)) { | |
1002 | if ((entry->p_flags & P_LB) && (num < entry->p_lb)) { | |
1003 | yyerror("parameter below range"); | |
1004 | return; | |
1005 | } | |
1006 | if ((entry->p_flags & P_UB) && (num > entry->p_ub)) { | |
1007 | yyerror("parameter above range"); | |
1008 | return; | |
1009 | } | |
1010 | dp->d_fields[entry-ptp->p_fields] = num; | |
1011 | return; | |
1012 | } | |
1013 | } | |
1014 | ||
1015 | yyerror("invalid parameter"); | |
1016 | } | |
1017 | ||
1018 | void | |
1019 | sqt_ioconf(void) | |
1020 | { | |
1021 | register struct device *dp, *mp; | |
1022 | register int count; | |
1023 | const char *namep; | |
1024 | register struct proto *ptp; | |
1025 | register struct p_entry *entry; | |
1026 | FILE *fp; | |
1027 | int bin_table[8]; | |
1028 | int ptbx; | |
1029 | int found; | |
1030 | ||
1031 | for (count = 0; count < 8; count++) | |
1032 | bin_table[count] = 0; | |
1033 | fp = fopen(path("ioconf.c"), "w"); | |
1034 | if (fp == NULL) { | |
1035 | perror(path("ioconf.c")); | |
1036 | exit(1); | |
1037 | } | |
1038 | /*MACH_KERNEL*/ | |
1039 | fprintf(fp, "#ifndef MACH_KERNEL\n"); | |
1040 | /*MACH_KERNEL*/ | |
1041 | fprintf(fp, "#include <sys/param.h>\n"); | |
1042 | fprintf(fp, "#include <sys/systm.h>\n"); | |
1043 | /*MACH_KERNEL*/ | |
1044 | fprintf(fp, "#endif MACH_KERNEL\n"); | |
1045 | /*MACH_KERNEL*/ | |
1046 | fprintf(fp, "\n"); | |
1047 | fprintf(fp, "#include <machine/ioconf.h>\n"); | |
1048 | ||
1049 | fprintf(fp, "\nu_long\tMBAd_IOwindow =\t\t3*256*1024;\t/* top 1/4 Meg */\n\n"); | |
1050 | ||
1051 | for (ptbx = 0; (ptp = ptab[ptbx]) != NULL; ptbx++) { | |
1052 | ||
1053 | fprintf(fp, "/*\n"); | |
1054 | fprintf(fp, " * %s device configuration.\n", ptp->p_name); | |
1055 | fprintf(fp, " */\n\n"); | |
1056 | fprintf(fp, "\n"); | |
1057 | fprintf(fp, "#include <sqt%s/ioconf.h>\n", ptp->p_name); | |
1058 | fprintf(fp, "\n"); | |
1059 | ||
1060 | /* | |
1061 | * Generate dev structures for this controller | |
1062 | */ | |
1063 | for (dp = dtab, namep = NULL; dp != 0; dp = dp->d_next) { | |
1064 | mp = dp->d_conn; | |
1065 | if (mp == 0 || mp == TO_NEXUS || | |
1066 | !eq(mp->d_name, ptp->p_name) || | |
1067 | (namep != NULL && eq(dp->d_name, namep)) ) | |
1068 | continue; | |
1069 | fprintf(fp, "extern\tstruct\t%s_driver\t%s_driver;\n", | |
1070 | ptp->p_name, namep = dp->d_name); | |
1071 | ptp->p_seen = 1; | |
1072 | } | |
1073 | ||
1074 | found = 0; | |
1075 | for (dp = dtab, namep = NULL; dp != 0; dp = dp->d_next) { | |
1076 | mp = dp->d_conn; | |
1077 | if (mp == 0 || mp == TO_NEXUS || | |
1078 | !eq(mp->d_name, ptp->p_name)) | |
1079 | continue; | |
1080 | if (namep == NULL || !eq(namep, dp->d_name)) { | |
1081 | count = 0; | |
1082 | if (namep != NULL) | |
1083 | fprintf(fp, "};\n"); | |
1084 | found = 1; | |
1085 | fprintf(fp, "\nstruct\t%s_dev %s_%s[] = {\n", | |
1086 | ptp->p_name, | |
1087 | ptp->p_name, | |
1088 | namep = dp->d_name); | |
1089 | fprintf(fp, "/*"); | |
1090 | entry = ptp->p_fields; | |
1091 | for (; entry->p_name != NULL; entry++) | |
1092 | fprintf(fp, "\t%s",entry->p_name); | |
1093 | fprintf(fp, " */\n"); | |
1094 | } | |
1095 | if (dp->d_bin != UNKNOWN) | |
1096 | bin_table[dp->d_bin]++; | |
1097 | fprintf(fp, "{"); | |
1098 | for (entry = ptp->p_fields; entry->p_name != NULL; entry++) { | |
1099 | if (eq(entry->p_name,"index")) | |
1100 | fprintf(fp, "\t%d,", mp->d_unit); | |
1101 | else | |
1102 | fprintf(fp, "\t%lu,", | |
1103 | dp->d_fields[entry-ptp->p_fields]); | |
1104 | } | |
1105 | fprintf(fp, "\t},\t/* %s%d */\n", dp->d_name, count++); | |
1106 | } | |
1107 | if (found) | |
1108 | fprintf(fp, "};\n\n"); | |
1109 | ||
1110 | /* | |
1111 | * Generate conf array | |
1112 | */ | |
1113 | fprintf(fp, "/*\n"); | |
1114 | fprintf(fp, " * %s_conf array collects all %s devices\n", | |
1115 | ptp->p_name, ptp->p_name); | |
1116 | fprintf(fp, " */\n\n"); | |
1117 | fprintf(fp, "struct\t%s_conf %s_conf[] = {\n", | |
1118 | ptp->p_name, ptp->p_name); | |
1119 | fprintf(fp, "/*\tDriver\t\t#Entries\tDevices\t\t*/\n"); | |
1120 | for (dp = dtab, namep = NULL; dp != 0; dp = dp->d_next) { | |
1121 | mp = dp->d_conn; | |
1122 | if (mp == 0 || mp == TO_NEXUS || | |
1123 | !eq(mp->d_name, ptp->p_name)) | |
1124 | continue; | |
1125 | if (namep == NULL || !eq(namep, dp->d_name)) { | |
1126 | if (namep != NULL) | |
1127 | fprintf(fp, | |
1128 | "{\t&%s_driver,\t%d,\t\t%s_%s,\t},\t/* %s */\n", | |
1129 | namep, count, ptp->p_name, namep, namep); | |
1130 | count = 0; | |
1131 | namep = dp->d_name; | |
1132 | } | |
1133 | ++count; | |
1134 | } | |
1135 | if (namep != NULL) { | |
1136 | fprintf(fp, | |
1137 | "{\t&%s_driver,\t%d,\t\t%s_%s,\t},\t/* %s */\n", | |
1138 | namep, count, ptp->p_name, namep, namep); | |
1139 | } | |
1140 | fprintf(fp, "\t{ 0 },\n"); | |
1141 | fprintf(fp, "};\n\n"); | |
1142 | ||
1143 | } | |
1144 | ||
1145 | /* | |
1146 | * Pseudo's | |
1147 | */ | |
1148 | ||
1149 | fprintf(fp, "/*\n"); | |
1150 | fprintf(fp, " * Pseudo-device configuration\n"); | |
1151 | fprintf(fp, " */\n\n"); | |
1152 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1153 | if (dp->d_type == PSEUDO_DEVICE) { | |
1154 | fprintf(fp, "extern\tint\t%sboot();\n", dp->d_name); | |
1155 | } | |
1156 | } | |
1157 | fprintf(fp, "\nstruct\tpseudo_dev pseudo_dev[] = {\n"); | |
1158 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1159 | if (dp->d_type == PSEUDO_DEVICE) { | |
1160 | fprintf(fp, "\t{ \"%s\",\t%d,\t%sboot,\t},\n", | |
1161 | dp->d_name, | |
1162 | dp->d_slave == UNKNOWN ? 32 : dp->d_slave, | |
1163 | dp->d_name); | |
1164 | } | |
1165 | } | |
1166 | fprintf(fp, "\t{ 0 },\n"); | |
1167 | fprintf(fp, "};\n\n"); | |
1168 | ||
1169 | /* | |
1170 | * Bin interrupt table and misc | |
1171 | */ | |
1172 | ||
1173 | fprintf(fp, "/*\n"); | |
1174 | fprintf(fp, " * Interrupt table\n"); | |
1175 | fprintf(fp, " */\n\n"); | |
1176 | fprintf(fp, "int\tbin_intr[8] = {\n"); | |
1177 | fprintf(fp, "\t\t0,\t\t\t\t/* bin 0, always zero */\n"); | |
1178 | for (count=1; count < 8; count++) { | |
1179 | fprintf(fp, "\t\t%d,\t\t\t\t/* bin %d */\n", | |
1180 | bin_table[count], count); | |
1181 | } | |
1182 | fprintf(fp, "};\n"); | |
1183 | ||
1184 | /* | |
1185 | * b8k_cntlrs[] | |
1186 | */ | |
1187 | ||
1188 | fprintf(fp, "/*\n"); | |
1189 | fprintf(fp, " * b8k_cntlrs array collects all controller entries\n"); | |
1190 | fprintf(fp, " */\n\n"); | |
1191 | for (ptbx = 0; (ptp = ptab[ptbx]) != NULL; ptbx++) { | |
1192 | if (ptp->p_seen) | |
1193 | fprintf(fp, "extern int conf_%s(),\tprobe_%s_devices(),\t%s_map();\n", | |
1194 | ptp->p_name, ptp->p_name, ptp->p_name); | |
1195 | } | |
1196 | fprintf(fp, "\n\nstruct\tcntlrs b8k_cntlrs[] = {\n"); | |
1197 | fprintf(fp, "/*\tconf\t\tprobe_devs\t\tmap\t*/\n"); | |
1198 | ||
1199 | for (ptbx = 0; (ptp = ptab[ptbx]) != NULL; ptbx++) { | |
1200 | if (ptp->p_seen) | |
1201 | fprintf(fp, "{\tconf_%s,\tprobe_%s_devices,\t%s_map\t}, \n", | |
1202 | ptp->p_name, ptp->p_name, ptp->p_name); | |
1203 | } | |
1204 | fprintf(fp, "{\t0,\t},\n"); | |
1205 | fprintf(fp, "};\n"); | |
1206 | ||
1207 | (void) fclose(fp); | |
1208 | } | |
1209 | ||
1210 | #endif MACHINE_SQT | |
1211 | #if MACHINE_I386 | |
1212 | void | |
1213 | i386_ioconf(void) | |
1214 | { | |
1215 | FILE *fp; | |
1216 | ||
1217 | unlink(path("ioconf.c")); | |
1218 | fp = fopen(path("ioconf.c"), "w"); | |
1219 | if (fp == 0) { | |
1220 | perror(path("ioconf.c")); | |
1221 | exit(1); | |
1222 | } | |
1223 | fprintf(fp, "#include <dev/busvar.h>\n"); | |
1224 | fprintf(fp, "\n"); | |
1225 | fprintf(fp, "#define C (void *)\n"); | |
1226 | fprintf(fp, "\n"); | |
1227 | ||
1228 | i386_pseudo_inits (fp); | |
1229 | (void) fclose(fp); | |
1230 | } | |
1231 | #endif MACHINE_I386 | |
1232 | ||
1233 | #if MACHINE_MIPSY || MACHINE_MIPS | |
1234 | ||
1235 | void declare(const char *cp); | |
1236 | int is_declared(const char *cp); | |
1237 | ||
1238 | void | |
1239 | mips_ioconf(void) | |
1240 | { | |
1241 | register struct device *dp, *mp, *np; | |
1242 | register int slave; | |
1243 | FILE *fp; | |
1244 | char buf1[64], buf2[64]; | |
1245 | ||
1246 | unlink(path("ioconf.c")); | |
1247 | fp = fopen(path("ioconf.c"), "w"); | |
1248 | if (fp == 0) { | |
1249 | perror(path("ioconf.c")); | |
1250 | exit(1); | |
1251 | } | |
1252 | /*MACH_KERNEL*/ | |
1253 | fprintf(fp, "#ifndef MACH_KERNEL\n"); | |
1254 | /*MACH_KERNEL*/ | |
1255 | fprintf(fp, "#include <sys/param.h>\n"); | |
1256 | fprintf(fp, "#include <sys/buf.h>\n"); | |
1257 | fprintf(fp, "#include <sys/map.h>\n"); | |
1258 | fprintf(fp, "#include <sys/vm.h>\n"); | |
1259 | /*MACH_KERNEL*/ | |
1260 | fprintf(fp, "#endif MACH_KERNEL\n"); | |
1261 | /*MACH_KERNEL*/ | |
1262 | fprintf(fp, "\n"); | |
1263 | if (seen_mbii && seen_vme) { | |
1264 | printf("can't have both vme and mbii devices\n"); | |
1265 | exit(1); | |
1266 | } | |
1267 | if (seen_mbii) | |
1268 | fprintf(fp, "#include <mipsmbii/mbiivar.h>\n"); | |
1269 | if (seen_vme) | |
1270 | fprintf(fp, "#include <mipsvme/vmevar.h>\n"); | |
1271 | fprintf(fp, "\n"); | |
1272 | fprintf(fp, "#define C (caddr_t)\n"); | |
1273 | fprintf(fp, "#define NULL 0\n\n"); | |
1274 | if (!seen_mbii) | |
1275 | goto checkvme; | |
1276 | /* | |
1277 | * MBII stuff should go here | |
1278 | */ | |
1279 | ||
1280 | checkvme: | |
1281 | if (!seen_vme) | |
1282 | goto closefile; | |
1283 | /* | |
1284 | * Now generate interrupt vectors for the vme bus | |
1285 | */ | |
1286 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1287 | if (dp->d_vec != 0) { | |
1288 | struct idlst *ip; | |
1289 | mp = dp->d_conn; | |
1290 | if (mp == 0 || mp == TO_NEXUS || !eq(mp->d_name, "vme")) | |
1291 | continue; | |
1292 | if (is_declared(dp->d_name)) | |
1293 | continue; | |
1294 | declare(dp->d_name); | |
1295 | fprintf(fp, "extern struct vme_driver %sdriver;\n", | |
1296 | dp->d_name); | |
1297 | fprintf(fp, "extern "); | |
1298 | ip = dp->d_vec; | |
1299 | for (;;) { | |
1300 | fprintf(fp, "%s()", ip->id); | |
1301 | ip = ip->id_next; | |
1302 | if (ip == 0) | |
1303 | break; | |
1304 | fprintf(fp, ", "); | |
1305 | } | |
1306 | fprintf(fp, ";\n"); | |
1307 | fprintf(fp, "int (*_%sint%d[])() = { ", dp->d_name, | |
1308 | dp->d_unit); | |
1309 | ip = dp->d_vec; | |
1310 | for (;;) { | |
1311 | fprintf(fp, "%s", ip->id); | |
1312 | ip = ip->id_next; | |
1313 | if (ip == 0) | |
1314 | break; | |
1315 | fprintf(fp, ", "); | |
1316 | } | |
1317 | fprintf(fp, ", 0 } ;\n\n"); | |
1318 | } | |
1319 | } | |
1320 | fprintf(fp, "\nstruct vme_ctlr vmminit[] = {\n"); | |
1321 | fprintf(fp, | |
1322 | " /* driver ctlr alive intr addr am */\n"); | |
1323 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1324 | mp = dp->d_conn; | |
1325 | if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 || | |
1326 | !eq(mp->d_name, "vme")) | |
1327 | continue; | |
1328 | if (dp->d_vec == 0) { | |
1329 | printf("must specify vector for %s%d\n", | |
1330 | dp->d_name, dp->d_unit); | |
1331 | continue; | |
1332 | } | |
1333 | if (dp->d_addr == 0) { | |
1334 | printf("must specify csr address for %s%d\n", | |
1335 | dp->d_name, dp->d_unit); | |
1336 | continue; | |
1337 | } | |
1338 | if (dp->d_addrmod == 0) { | |
1339 | printf("must specify address modifier for %s%d\n", | |
1340 | dp->d_name, dp->d_unit); | |
1341 | continue; | |
1342 | } | |
1343 | if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { | |
1344 | printf("drives need their own entries; dont "); | |
1345 | printf("specify drive or slave for %s%d\n", | |
1346 | dp->d_name, dp->d_unit); | |
1347 | continue; | |
1348 | } | |
1349 | if (dp->d_flags) { | |
1350 | printf("controllers (e.g. %s%d) ", | |
1351 | dp->d_name, dp->d_unit); | |
1352 | printf("don't have flags, only devices do\n"); | |
1353 | continue; | |
1354 | } | |
1355 | fprintf(fp, | |
1356 | " { %14s, %3d, 0, %11s, C 0x%08x, 0x%02x },\n", | |
1357 | concat3(buf1, "&", dp->d_name, "driver"), | |
1358 | dp->d_unit, | |
1359 | concat3(buf2, "_", dp->d_name, "int"), | |
1360 | dp->d_addr, | |
1361 | dp->d_addrmod); | |
1362 | } | |
1363 | fprintf(fp, " { NULL }\n};\n"); | |
1364 | /* | |
1365 | * vme devices | |
1366 | */ | |
1367 | fprintf(fp, "\nstruct vme_device vmdinit[] = {\n"); | |
1368 | fprintf(fp, | |
1369 | "/* driver unit ctlr slave intr addr am dk flags */\n" | |
1370 | ); | |
1371 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1372 | mp = dp->d_conn; | |
1373 | if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || | |
1374 | mp == TO_NEXUS || mp->d_type == MASTER) | |
1375 | continue; | |
1376 | for (np = mp; np && np != TO_NEXUS; np = np->d_conn) | |
1377 | if (eq(np->d_name, "vme")) | |
1378 | break; | |
1379 | if (np != 0 && np != TO_NEXUS && !eq(np->d_name, "vme")) | |
1380 | continue; | |
1381 | np = 0; | |
1382 | if (eq(mp->d_name, "vme")) { | |
1383 | if (dp->d_vec == 0) { | |
1384 | printf("must specify vector for device %s%d\n", | |
1385 | dp->d_name, dp->d_unit); | |
1386 | continue; | |
1387 | } | |
1388 | if (dp->d_addr == 0) { | |
1389 | printf("must specify csr for device %s%d\n", | |
1390 | dp->d_name, dp->d_unit); | |
1391 | continue; | |
1392 | } | |
1393 | if (dp->d_addrmod == 0) { | |
1394 | printf( | |
1395 | "must specify address modifier for device %s%d\n", | |
1396 | dp->d_name, dp->d_unit); | |
1397 | continue; | |
1398 | } | |
1399 | if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { | |
1400 | printf("drives/slaves can be specified "); | |
1401 | printf("only for controllers, "); | |
1402 | printf("not for device %s%d\n", | |
1403 | dp->d_name, dp->d_unit); | |
1404 | continue; | |
1405 | } | |
1406 | slave = QUES; | |
1407 | } else { | |
1408 | if ((np = mp->d_conn) == 0) { | |
1409 | printf("%s%d isn't connected to anything ", | |
1410 | mp->d_name, mp->d_unit); | |
1411 | printf(", so %s%d is unattached\n", | |
1412 | dp->d_name, dp->d_unit); | |
1413 | continue; | |
1414 | } | |
1415 | if (dp->d_drive == UNKNOWN) { | |
1416 | printf("must specify ``drive number'' "); | |
1417 | printf("for %s%d\n", dp->d_name, dp->d_unit); | |
1418 | continue; | |
1419 | } | |
1420 | if (dp->d_slave != UNKNOWN) { | |
1421 | printf("slave numbers should be given only "); | |
1422 | printf("for massbus tapes, not for %s%d\n", | |
1423 | dp->d_name, dp->d_unit); | |
1424 | continue; | |
1425 | } | |
1426 | if (dp->d_vec != 0) { | |
1427 | printf("interrupt vectors should not be "); | |
1428 | printf("given for drive %s%d\n", | |
1429 | dp->d_name, dp->d_unit); | |
1430 | continue; | |
1431 | } | |
1432 | if (dp->d_addr != 0) { | |
1433 | printf("csr addresses should be given only "); | |
1434 | printf("on controllers, not on %s%d\n", | |
1435 | dp->d_name, dp->d_unit); | |
1436 | continue; | |
1437 | } | |
1438 | if (dp->d_addrmod != 0) { | |
1439 | printf("address modifiers should be given only "); | |
1440 | printf("on controllers, not on %s%d\n", | |
1441 | dp->d_name, dp->d_unit); | |
1442 | continue; | |
1443 | } | |
1444 | slave = dp->d_drive; | |
1445 | } | |
1446 | fprintf(fp, | |
1447 | "{%14s, %3d, %3s, %4d,%10s, C 0x%08x, 0x%02x, %1d, 0x%08x },\n", | |
1448 | concat3(buf1, "&", | |
1449 | eq(mp->d_name, "vme") ? dp->d_name : mp->d_name, | |
1450 | "driver"), | |
1451 | dp->d_unit, | |
1452 | eq(mp->d_name, "vme") ? "-1" : qu(mp->d_unit), | |
1453 | slave, | |
1454 | intv2(dp), | |
1455 | dp->d_addr, | |
1456 | dp->d_addrmod, | |
1457 | dp->d_dk, | |
1458 | dp->d_flags); | |
1459 | } | |
1460 | fprintf(fp, "{ NULL }\n};\n"); | |
1461 | closefile: | |
1462 | (void) fclose(fp); | |
1463 | } | |
1464 | ||
1465 | char * | |
1466 | intv2(struct device *dev) | |
1467 | { | |
1468 | static char buf[20]; | |
1469 | ||
1470 | if (dev->d_vec == 0) { | |
1471 | strcpy(buf, "NULL"); | |
1472 | } else { | |
1473 | (void) sprintf(buf, "_%sint", dev->d_name); | |
1474 | } | |
1475 | return (buf); | |
1476 | } | |
1477 | ||
1478 | char * | |
1479 | concat3(char *buf, const char *p1, const char *p2, const char *p3) | |
1480 | { | |
1481 | (void) sprintf(buf, "%s%s%s", p1, p2, p3); | |
1482 | return (buf); | |
1483 | } | |
1484 | ||
1485 | #define MAXDEVS 100 | |
1486 | #define DEVLEN 10 | |
1487 | char decl_devices[MAXDEVS][DEVLEN]; | |
1488 | ||
1489 | void | |
1490 | declare(const char *cp) | |
1491 | { | |
1492 | register int i; | |
1493 | ||
1494 | for (i = 0; i < MAXDEVS; i++) | |
1495 | if (decl_devices[i][0] == 0) { | |
1496 | strncpy(decl_devices[i], cp, DEVLEN); | |
1497 | return; | |
1498 | } | |
1499 | printf("device table full, fix mkioconf.c\n"); | |
1500 | exit(1); | |
1501 | } | |
1502 | ||
1503 | int | |
1504 | is_declared(const char *cp) | |
1505 | { | |
1506 | register int i; | |
1507 | ||
1508 | for (i = 0; i < MAXDEVS; i++) { | |
1509 | if (decl_devices[i][0] == 0) | |
1510 | return(0); | |
1511 | if (strncmp(decl_devices[i], cp, DEVLEN) == 0) | |
1512 | return(1); | |
1513 | } | |
1514 | return(0); | |
1515 | } | |
1516 | #endif MACHINE_MIPSY || MACHINE_MIPS | |
1517 | ||
1518 | #if MACHINE_M68K | |
1519 | char *m68k_dn(const char *name); | |
1520 | void m68k_pseudo_inits(FILE *fp); | |
1521 | ||
1522 | void | |
1523 | m68k_ioconf(void) | |
1524 | { | |
1525 | register struct device *dp, *mp; | |
1526 | register int slave; | |
1527 | FILE *fp; | |
1528 | ||
1529 | unlink(path("ioconf.c")); | |
1530 | fp = fopen(path("ioconf.c"), "w"); | |
1531 | if (fp == 0) { | |
1532 | perror(path("ioconf.c")); | |
1533 | exit(1); | |
1534 | } | |
1535 | fprintf(fp, "#include <dev/m68k/busvar.h>\n"); | |
1536 | fprintf(fp, "\n"); | |
1537 | fprintf(fp, "#define C (void *)\n"); | |
1538 | fprintf(fp, "\n"); | |
1539 | ||
1540 | /* | |
1541 | * Now generate interrupt vectors for the bus | |
1542 | */ | |
1543 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1544 | mp = dp->d_conn; | |
1545 | if (mp == TO_NEXUS || mp == 0 || mp->d_conn != TO_NEXUS) | |
1546 | continue; | |
1547 | fprintf(fp, "extern struct bus_driver %sdriver;\n", | |
1548 | dp->d_name); | |
1549 | } | |
1550 | ||
1551 | /* | |
1552 | * Now spew forth the bus_ctrl structures | |
1553 | */ | |
1554 | fprintf(fp, "\nstruct bus_ctrl bus_cinit[] = {\n"); | |
1555 | fprintf(fp, | |
1556 | " /* driver ctrl ipl address */\n"); | |
1557 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1558 | mp = dp->d_conn; | |
1559 | if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 || | |
1560 | mp->d_conn != TO_NEXUS || dp->d_unit == QUES) | |
1561 | continue; | |
1562 | if (dp->d_addr == UNKNOWN) { | |
1563 | printf("must specify csr address for %s%d\n", | |
1564 | dp->d_name, dp->d_unit); | |
1565 | continue; | |
1566 | } | |
1567 | if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { | |
1568 | printf("drives need their own entries; "); | |
1569 | printf("don't specify drive or slave for %s%d\n", | |
1570 | dp->d_name, dp->d_unit); | |
1571 | continue; | |
1572 | } | |
1573 | if (dp->d_flags) { | |
1574 | printf("controllers (e.g. %s%d) don't have flags, ", | |
1575 | dp->d_name, dp->d_unit); | |
1576 | printf("only devices do\n"); | |
1577 | continue; | |
1578 | } | |
1579 | fprintf(fp, | |
1580 | " { %-12s, %5d, %4d, C 0x%08x },\n", | |
1581 | m68k_dn(dp->d_name), dp->d_unit, dp->d_pri, dp->d_addr); | |
1582 | } | |
1583 | fprintf(fp, " 0\n};\n"); | |
1584 | ||
1585 | /* | |
1586 | * Now we go for the bus_device stuff | |
1587 | */ | |
1588 | fprintf(fp, "\nstruct bus_device bus_dinit[] = {\n"); | |
1589 | fprintf(fp, | |
1590 | " /* driver unit ctrl slave ipl dk flags address name */\n"); | |
1591 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1592 | mp = dp->d_conn; | |
1593 | if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || | |
1594 | mp == TO_NEXUS || mp->d_type == MASTER) | |
1595 | continue; | |
1596 | if (mp->d_conn == TO_NEXUS) { | |
1597 | if (dp->d_addr == UNKNOWN) { | |
1598 | printf("must specify csr for device %s%d\n", | |
1599 | dp->d_name, dp->d_unit); | |
1600 | continue; | |
1601 | } | |
1602 | if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { | |
1603 | printf("drives/slaves can be specified only "); | |
1604 | printf("for controllers, not for device %s%d\n", | |
1605 | dp->d_name, dp->d_unit); | |
1606 | continue; | |
1607 | } | |
1608 | slave = UNKNOWN; | |
1609 | } else { | |
1610 | if (mp->d_conn == 0) { | |
1611 | printf("%s%d isn't connected to anything, ", | |
1612 | mp->d_name, mp->d_unit); | |
1613 | printf("so %s%d is unattached\n", | |
1614 | dp->d_name, dp->d_unit); | |
1615 | continue; | |
1616 | } | |
1617 | if (dp->d_drive == UNKNOWN) { | |
1618 | printf("must specify ``drive number'' for %s%d\n", | |
1619 | dp->d_name, dp->d_unit); | |
1620 | continue; | |
1621 | } | |
1622 | /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */ | |
1623 | /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */ | |
1624 | if (dp->d_slave != UNKNOWN) { | |
1625 | printf("slave numbers should be given only "); | |
1626 | printf("for massbus tapes, not for %s%d\n", | |
1627 | dp->d_name, dp->d_unit); | |
1628 | continue; | |
1629 | } | |
1630 | if (dp->d_pri != 0) { | |
1631 | printf("interrupt priority should not be "); | |
1632 | printf("given for drive %s%d\n", | |
1633 | dp->d_name, dp->d_unit); | |
1634 | continue; | |
1635 | } | |
1636 | if (dp->d_addr != 0) { | |
1637 | printf("csr addresses should be given only"); | |
1638 | printf(" on controllers, not on %s%d\n", | |
1639 | dp->d_name, dp->d_unit); | |
1640 | continue; | |
1641 | } | |
1642 | slave = dp->d_drive; | |
1643 | } | |
1644 | fprintf(fp, | |
1645 | " { %-12s, %3d, %s, %s,%3d,%3d, %#10x, C 0x%08x, \"%s\" },\n", | |
1646 | m68k_dn(mp->d_conn == TO_NEXUS? dp->d_name : mp->d_name), | |
1647 | dp->d_unit, | |
1648 | mp->d_conn == TO_NEXUS? " -1" : qu(mp->d_unit), | |
1649 | qu(slave), | |
1650 | dp->d_pri, -dp->d_dk, dp->d_flags, | |
1651 | dp->d_addr == UNKNOWN? 0 : dp->d_addr, | |
1652 | dp->d_name); | |
1653 | } | |
1654 | fprintf(fp, " 0\n};\n"); | |
1655 | m68k_pseudo_inits (fp); | |
1656 | (void) fclose(fp); | |
1657 | } | |
1658 | ||
1659 | void | |
1660 | m68k_pseudo_inits(FILE *fp) | |
1661 | { | |
1662 | register struct device *dp; | |
1663 | int count; | |
1664 | ||
1665 | fprintf(fp, "\n"); | |
1666 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1667 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1668 | continue; | |
1669 | fprintf(fp, "extern int %s(int);\n", dp->d_init); | |
1670 | } | |
1671 | fprintf(fp, "\nstruct pseudo_init pseudo_inits[] = {\n"); | |
1672 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1673 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1674 | continue; | |
1675 | count = dp->d_slave; | |
1676 | if (count <= 0) | |
1677 | count = 1; | |
1678 | fprintf(fp, "\t{%d,\t%s},\n", count, dp->d_init); | |
1679 | } | |
1680 | fprintf(fp, "\t{0,\t0},\n};\n"); | |
1681 | } | |
1682 | ||
1683 | void | |
1684 | i386_pseudo_inits(FILE *fp) | |
1685 | { | |
1686 | register struct device *dp; | |
1687 | int count; | |
1688 | ||
1689 | fprintf(fp, "\n"); | |
1690 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1691 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1692 | continue; | |
1693 | fprintf(fp, "extern int %s(int);\n", dp->d_init); | |
1694 | } | |
1695 | fprintf(fp, "\nstruct pseudo_init pseudo_inits[] = {\n"); | |
1696 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1697 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1698 | continue; | |
1699 | count = dp->d_slave; | |
1700 | if (count <= 0) | |
1701 | count = 1; | |
1702 | fprintf(fp, "\t{%d,\t%s},\n", count, dp->d_init); | |
1703 | } | |
1704 | fprintf(fp, "\t{0,\t0},\n};\n"); | |
1705 | } | |
1706 | ||
1707 | char * | |
1708 | m68k_dn(const char *name) | |
1709 | { | |
1710 | sprintf(errbuf, "&%sdriver", name); return ns(errbuf); | |
1711 | } | |
1712 | #endif MACHINE_M68K | |
1713 | ||
1714 | #if MACHINE_M88K || MACHINE_M98K | |
1715 | char *nrw_dn(char *name); | |
1716 | void nrw_pseudo_inits(FILE *fp); | |
1717 | ||
1718 | void | |
1719 | nrw_ioconf(void) | |
1720 | { | |
1721 | FILE *fp; | |
1722 | ||
1723 | unlink(path("ioconf.c")); | |
1724 | fp = fopen(path("ioconf.c"), "w"); | |
1725 | if (fp == 0) { | |
1726 | perror(path("ioconf.c")); | |
1727 | exit(1); | |
1728 | } | |
1729 | fprintf(fp, "#include <dev/nrw/busvar.h>\n"); | |
1730 | fprintf(fp, "\n"); | |
1731 | nrw_pseudo_inits (fp); | |
1732 | (void) fclose(fp); | |
1733 | } | |
1734 | ||
1735 | void | |
1736 | nrw_pseudo_inits(FILE *fp) | |
1737 | { | |
1738 | register struct device *dp; | |
1739 | int count; | |
1740 | ||
1741 | fprintf(fp, "\n"); | |
1742 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1743 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1744 | continue; | |
1745 | fprintf(fp, "extern int %s(int);\n", dp->d_init); | |
1746 | } | |
1747 | fprintf(fp, "\nstruct pseudo_init pseudo_inits[] = {\n"); | |
1748 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1749 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1750 | continue; | |
1751 | count = dp->d_slave; | |
1752 | if (count <= 0) | |
1753 | count = 1; | |
1754 | fprintf(fp, "\t{%d,\t%s},\n", count, dp->d_init); | |
1755 | } | |
1756 | fprintf(fp, "\t{0,\t0},\n};\n"); | |
1757 | } | |
1758 | ||
1759 | char * | |
1760 | nrw_dn(char *name) | |
1761 | { | |
1762 | sprintf(errbuf, "&%sdriver,", name); | |
1763 | return(errbuf); | |
1764 | } | |
1765 | ||
1766 | void | |
1767 | m88k_ioconf(void) | |
1768 | { | |
1769 | nrw_ioconf(); | |
1770 | } | |
1771 | ||
1772 | void | |
1773 | m98k_ioconf(void) | |
1774 | { | |
1775 | nrw_ioconf(); | |
1776 | } | |
1777 | ||
1778 | void | |
1779 | m88k_pseudo_inits(FILE *fp) | |
1780 | { | |
1781 | nrw_pseudo_inits(fp); | |
1782 | } | |
1783 | ||
1784 | void | |
1785 | m98k_pseudo_inits(FILE *fp) | |
1786 | { | |
1787 | nrw_pseudo_inits(fp); | |
1788 | } | |
1789 | ||
1790 | char * | |
1791 | m88k_dn(char *name) | |
1792 | { | |
1793 | return(nrw_dn(name)); | |
1794 | } | |
1795 | ||
1796 | char * | |
1797 | m98k_dn(char *name) | |
1798 | { | |
1799 | return(nrw_dn(name)); | |
1800 | } | |
1801 | ||
1802 | ||
1803 | #endif MACHINE_M88K || MACHINE_M98K | |
1804 | ||
1805 | #ifdef MACHINE_HPPA | |
1806 | char *hppa_dn(char *name); | |
1807 | void hppa_pseudo_inits(FILE *fp); | |
1808 | ||
1809 | void | |
1810 | hppa_ioconf(void) | |
1811 | { | |
1812 | FILE *fp; | |
1813 | ||
1814 | unlink(path("ioconf.c")); | |
1815 | fp = fopen(path("ioconf.c"), "w"); | |
1816 | if (fp == 0) { | |
1817 | perror(path("ioconf.c")); | |
1818 | exit(1); | |
1819 | } | |
1820 | fprintf(fp, "#include <dev/hppa/busvar.h>\n"); | |
1821 | fprintf(fp, "\n"); | |
1822 | hppa_pseudo_inits (fp); | |
1823 | (void) fclose(fp); | |
1824 | } | |
1825 | ||
1826 | void | |
1827 | hppa_pseudo_inits(FILE *fp) | |
1828 | { | |
1829 | register struct device *dp; | |
1830 | int count; | |
1831 | ||
1832 | fprintf(fp, "\n"); | |
1833 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1834 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1835 | continue; | |
1836 | fprintf(fp, "extern int %s(int);\n", dp->d_init); | |
1837 | } | |
1838 | fprintf(fp, "\nstruct pseudo_init pseudo_inits[] = {\n"); | |
1839 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1840 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1841 | continue; | |
1842 | count = dp->d_slave; | |
1843 | if (count <= 0) | |
1844 | count = 1; | |
1845 | fprintf(fp, "\t{%d,\t%s},\n", count, dp->d_init); | |
1846 | } | |
1847 | fprintf(fp, "\t{0,\t0},\n};\n"); | |
1848 | } | |
1849 | ||
1850 | char * | |
1851 | hppa_dn(char *name) | |
1852 | { | |
1853 | sprintf(errbuf, "&%sdriver,", name); | |
1854 | ||
1855 | return (errbuf); | |
1856 | } | |
1857 | ||
1858 | #endif MACHINE_HPPA | |
1859 | ||
1860 | #ifdef MACHINE_SPARC | |
1861 | char *sparc_dn(char *name); | |
1862 | void sparc_pseudo_inits(FILE *fp); | |
1863 | ||
1864 | void | |
1865 | sparc_ioconf(void) | |
1866 | { | |
1867 | FILE *fp; | |
1868 | ||
1869 | unlink(path("ioconf.c")); | |
1870 | fp = fopen(path("ioconf.c"), "w"); | |
1871 | if (fp == 0) { | |
1872 | perror(path("ioconf.c")); | |
1873 | exit(1); | |
1874 | } | |
1875 | fprintf(fp, "#include <dev/busvar.h>\n"); | |
1876 | fprintf(fp, "\n"); | |
1877 | sparc_pseudo_inits (fp); | |
1878 | (void) fclose(fp); | |
1879 | } | |
1880 | ||
1881 | void | |
1882 | sparc_pseudo_inits(FILE *fp) | |
1883 | { | |
1884 | register struct device *dp; | |
1885 | int count; | |
1886 | ||
1887 | fprintf(fp, "\n"); | |
1888 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1889 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1890 | continue; | |
1891 | fprintf(fp, "extern int %s(int);\n", dp->d_init); | |
1892 | } | |
1893 | fprintf(fp, "\nstruct pseudo_init pseudo_inits[] = {\n"); | |
1894 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1895 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1896 | continue; | |
1897 | count = dp->d_slave; | |
1898 | if (count <= 0) | |
1899 | count = 1; | |
1900 | fprintf(fp, "\t{%d,\t%s},\n", count, dp->d_init); | |
1901 | } | |
1902 | fprintf(fp, "\t{0,\t0},\n};\n"); | |
1903 | } | |
1904 | ||
1905 | char * | |
1906 | sparc_dn(char *name) | |
1907 | { | |
1908 | sprintf(errbuf, "&%sdriver,", name); | |
1909 | return (errbuf); | |
1910 | } | |
1911 | ||
1912 | #endif MACHINE_SPARC | |
1913 | ||
1914 | #ifdef MACHINE_PPC | |
1915 | char *ppc_dn(char *name); | |
1916 | void ppc_pseudo_inits(FILE *fp); | |
1917 | ||
1918 | void | |
1919 | ppc_ioconf(void) | |
1920 | { | |
1921 | FILE *fp; | |
1922 | ||
1923 | unlink(path("ioconf.c")); | |
1924 | fp = fopen(path("ioconf.c"), "w"); | |
1925 | if (fp == 0) { | |
1926 | perror(path("ioconf.c")); | |
1927 | exit(1); | |
1928 | } | |
1929 | fprintf(fp, "#include <dev/busvar.h>\n"); | |
1930 | fprintf(fp, "\n"); | |
1931 | ppc_pseudo_inits (fp); | |
1932 | (void) fclose(fp); | |
1933 | } | |
1934 | ||
1935 | void | |
1936 | ppc_pseudo_inits(FILE *fp) | |
1937 | { | |
1938 | register struct device *dp; | |
1939 | int count; | |
1940 | ||
1941 | fprintf(fp, "\n"); | |
1942 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1943 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1944 | continue; | |
1945 | fprintf(fp, "extern int %s(int);\n", dp->d_init); | |
1946 | } | |
1947 | fprintf(fp, "\nstruct pseudo_init pseudo_inits[] = {\n"); | |
1948 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1949 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1950 | continue; | |
1951 | count = dp->d_slave; | |
1952 | if (count <= 0) | |
1953 | count = 1; | |
1954 | fprintf(fp, "\t{%d,\t%s},\n", count, dp->d_init); | |
1955 | } | |
1956 | fprintf(fp, "\t{0,\t0},\n};\n"); | |
1957 | } | |
1958 | ||
1959 | char * | |
1960 | ppc_dn(name) | |
1961 | char *name; | |
1962 | { | |
1963 | sprintf(errbuf, "&%sdriver,", name); | |
1964 | return (errbuf); | |
1965 | } | |
1966 | ||
1967 | #endif MACHINE_PPC | |
1968 | ||
1969 | #ifdef MACHINE_ARM | |
1970 | void arm_pseudo_inits(FILE *fp); | |
1971 | ||
1972 | void | |
1973 | arm_ioconf(void) | |
1974 | { | |
1975 | FILE *fp; | |
1976 | ||
1977 | unlink(path("ioconf.c")); | |
1978 | fp = fopen(path("ioconf.c"), "w"); | |
1979 | if (fp == 0) { | |
1980 | perror(path("ioconf.c")); | |
1981 | exit(1); | |
1982 | } | |
1983 | fprintf(fp, "#include <dev/busvar.h>\n"); | |
1984 | fprintf(fp, "\n"); | |
1985 | arm_pseudo_inits (fp); | |
1986 | (void) fclose(fp); | |
1987 | } | |
1988 | ||
1989 | void | |
1990 | arm_pseudo_inits(FILE *fp) | |
1991 | { | |
1992 | register struct device *dp; | |
1993 | int count; | |
1994 | ||
1995 | fprintf(fp, "\n"); | |
1996 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
1997 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
1998 | continue; | |
1999 | fprintf(fp, "extern int %s(int);\n", dp->d_init); | |
2000 | } | |
2001 | fprintf(fp, "\nstruct pseudo_init pseudo_inits[] = {\n"); | |
2002 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
2003 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
2004 | continue; | |
2005 | count = dp->d_slave; | |
2006 | if (count <= 0) | |
2007 | count = 1; | |
2008 | fprintf(fp, "\t{%d,\t%s},\n", count, dp->d_init); | |
2009 | } | |
2010 | fprintf(fp, "\t{0,\t0},\n};\n"); | |
2011 | } | |
2012 | ||
2013 | #endif /* MACHINE_ARM */ | |
2014 | ||
2015 | #ifdef MACHINE_X86_64 | |
2016 | void x86_64_pseudo_inits(FILE *fp); | |
2017 | ||
2018 | void | |
2019 | x86_64_ioconf(void) | |
2020 | { | |
2021 | FILE *fp; | |
2022 | ||
2023 | unlink(path("ioconf.c")); | |
2024 | fp = fopen(path("ioconf.c"), "w"); | |
2025 | if (fp == 0) { | |
2026 | perror(path("ioconf.c")); | |
2027 | exit(1); | |
2028 | } | |
2029 | fprintf(fp, "#include <dev/busvar.h>\n"); | |
2030 | fprintf(fp, "\n"); | |
2031 | x86_64_pseudo_inits (fp); | |
2032 | (void) fclose(fp); | |
2033 | } | |
2034 | ||
2035 | void | |
2036 | x86_64_pseudo_inits(FILE *fp) | |
2037 | { | |
2038 | register struct device *dp; | |
2039 | int count; | |
2040 | ||
2041 | fprintf(fp, "\n"); | |
2042 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
2043 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
2044 | continue; | |
2045 | fprintf(fp, "extern int %s(int);\n", dp->d_init); | |
2046 | } | |
2047 | fprintf(fp, "\nstruct pseudo_init pseudo_inits[] = {\n"); | |
2048 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
2049 | if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) | |
2050 | continue; | |
2051 | count = dp->d_slave; | |
2052 | if (count <= 0) | |
2053 | count = 1; | |
2054 | fprintf(fp, "\t{%d,\t%s},\n", count, dp->d_init); | |
2055 | } | |
2056 | fprintf(fp, "\t{0,\t0},\n};\n"); | |
2057 | } | |
2058 | ||
2059 | #endif /* MACHINE_X86_64 */ | |
2060 | ||
2061 | char * | |
2062 | intv(struct device *dev) | |
2063 | { | |
2064 | static char buf[20]; | |
2065 | ||
2066 | if (dev->d_vec == 0) { | |
2067 | strcpy(buf, " 0"); | |
2068 | } else { | |
2069 | (void) sprintf(buf, "%sint%d", dev->d_name, dev->d_unit); | |
2070 | } | |
2071 | return ns(buf); | |
2072 | } | |
2073 | ||
2074 | char * | |
2075 | qu(int num) | |
2076 | { | |
2077 | ||
2078 | if (num == QUES) { | |
2079 | strcpy(errbuf, "'?'"); | |
2080 | } else if (num == UNKNOWN) { | |
2081 | strcpy(errbuf, " -1"); | |
2082 | } else { | |
2083 | (void) sprintf(errbuf, "%3d", num); | |
2084 | } | |
2085 | return ns(errbuf); | |
2086 | } |