xref: /original-bsd/usr.sbin/config/mkioconf.c (revision 333da485)
1 /*
2  * Copyright (c) 1980, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)mkioconf.c	8.2 (Berkeley) 01/21/94";
10 #endif /* not lint */
11 
12 #include <stdio.h>
13 #include "y.tab.h"
14 #include "config.h"
15 
16 /*
17  * build the ioconf.c file
18  */
19 char	*qu();
20 char	*intv();
21 char	*wnum();
22 void	pseudo_ioconf();
23 
24 #if MACHINE_VAX
25 vax_ioconf()
26 {
27 	register struct device *dp, *mp, *np;
28 	register int uba_n, slave;
29 	FILE *fp;
30 
31 	fp = fopen(path("ioconf.c"), "w");
32 	if (fp == 0) {
33 		perror(path("ioconf.c"));
34 		exit(1);
35 	}
36 	fprintf(fp, "#include \"vax/include/pte.h\"\n");
37 	fprintf(fp, "#include \"sys/param.h\"\n");
38 	fprintf(fp, "#include \"sys/buf.h\"\n");
39 	fprintf(fp, "#include \"sys/map.h\"\n");
40 	fprintf(fp, "\n");
41 	fprintf(fp, "#include \"vax/mba/mbavar.h\"\n");
42 	fprintf(fp, "#include \"vax/uba/ubavar.h\"\n\n");
43 	fprintf(fp, "\n");
44 	fprintf(fp, "#define C (caddr_t)\n\n");
45 	/*
46 	 * First print the mba initialization structures
47 	 */
48 	if (seen_mba) {
49 		for (dp = dtab; dp != 0; dp = dp->d_next) {
50 			mp = dp->d_conn;
51 			if (mp == 0 || mp == TO_NEXUS ||
52 			    !eq(mp->d_name, "mba"))
53 				continue;
54 			fprintf(fp, "extern struct mba_driver %sdriver;\n",
55 			    dp->d_name);
56 		}
57 		fprintf(fp, "\nstruct mba_device mbdinit[] = {\n");
58 		fprintf(fp, "\t/* Device,  Unit, Mba, Drive, Dk */\n");
59 		for (dp = dtab; dp != 0; dp = dp->d_next) {
60 			mp = dp->d_conn;
61 			if (dp->d_unit == QUES || mp == 0 ||
62 			    mp == TO_NEXUS || !eq(mp->d_name, "mba"))
63 				continue;
64 			if (dp->d_addr) {
65 				printf("can't specify csr address on mba for %s%d\n",
66 				    dp->d_name, dp->d_unit);
67 				continue;
68 			}
69 			if (dp->d_vec != 0) {
70 				printf("can't specify vector for %s%d on mba\n",
71 				    dp->d_name, dp->d_unit);
72 				continue;
73 			}
74 			if (dp->d_drive == UNKNOWN) {
75 				printf("drive not specified for %s%d\n",
76 				    dp->d_name, dp->d_unit);
77 				continue;
78 			}
79 			if (dp->d_slave != UNKNOWN) {
80 				printf("can't specify slave number for %s%d\n",
81 				    dp->d_name, dp->d_unit);
82 				continue;
83 			}
84 			fprintf(fp, "\t{ &%sdriver, %d,   %s,",
85 				dp->d_name, dp->d_unit, qu(mp->d_unit));
86 			fprintf(fp, "  %s,  %d },\n",
87 				qu(dp->d_drive), dp->d_dk);
88 		}
89 		fprintf(fp, "\t0\n};\n\n");
90 		/*
91 		 * Print the mbsinit structure
92 		 * Driver Controller Unit Slave
93 		 */
94 		fprintf(fp, "struct mba_slave mbsinit [] = {\n");
95 		fprintf(fp, "\t/* Driver,  Ctlr, Unit, Slave */\n");
96 		for (dp = dtab; dp != 0; dp = dp->d_next) {
97 			/*
98 			 * All slaves are connected to something which
99 			 * is connected to the massbus.
100 			 */
101 			if ((mp = dp->d_conn) == 0 || mp == TO_NEXUS)
102 				continue;
103 			np = mp->d_conn;
104 			if (np == 0 || np == TO_NEXUS ||
105 			    !eq(np->d_name, "mba"))
106 				continue;
107 			fprintf(fp, "\t{ &%sdriver, %s",
108 			    mp->d_name, qu(mp->d_unit));
109 			fprintf(fp, ",  %2d,    %s },\n",
110 			    dp->d_unit, qu(dp->d_slave));
111 		}
112 		fprintf(fp, "\t0\n};\n\n");
113 	}
114 	/*
115 	 * Now generate interrupt vectors for the unibus
116 	 */
117 	for (dp = dtab; dp != 0; dp = dp->d_next) {
118 		if (dp->d_vec != 0) {
119 			struct idlst *ip;
120 			mp = dp->d_conn;
121 			if (mp == 0 || mp == TO_NEXUS ||
122 			    (!eq(mp->d_name, "uba") && !eq(mp->d_name, "bi")))
123 				continue;
124 			fprintf(fp,
125 			    "extern struct uba_driver %sdriver;\n",
126 			    dp->d_name);
127 			fprintf(fp, "extern ");
128 			ip = dp->d_vec;
129 			for (;;) {
130 				fprintf(fp, "X%s%d()", ip->id, dp->d_unit);
131 				ip = ip->id_next;
132 				if (ip == 0)
133 					break;
134 				fprintf(fp, ", ");
135 			}
136 			fprintf(fp, ";\n");
137 			fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name,
138 			    dp->d_unit);
139 			ip = dp->d_vec;
140 			for (;;) {
141 				fprintf(fp, "X%s%d", ip->id, dp->d_unit);
142 				ip = ip->id_next;
143 				if (ip == 0)
144 					break;
145 				fprintf(fp, ", ");
146 			}
147 			fprintf(fp, ", 0 } ;\n");
148 		}
149 	}
150 	fprintf(fp, "\nstruct uba_ctlr ubminit[] = {\n");
151 	fprintf(fp, "/*\t driver,\tctlr,\tubanum,\talive,\tintr,\taddr */\n");
152 	for (dp = dtab; dp != 0; dp = dp->d_next) {
153 		mp = dp->d_conn;
154 		if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 ||
155 		    !eq(mp->d_name, "uba"))
156 			continue;
157 		if (dp->d_vec == 0) {
158 			printf("must specify vector for %s%d\n",
159 			    dp->d_name, dp->d_unit);
160 			continue;
161 		}
162 		if (dp->d_addr == 0) {
163 			printf("must specify csr address for %s%d\n",
164 			    dp->d_name, dp->d_unit);
165 			continue;
166 		}
167 		if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
168 			printf("drives need their own entries; dont ");
169 			printf("specify drive or slave for %s%d\n",
170 			    dp->d_name, dp->d_unit);
171 			continue;
172 		}
173 		if (dp->d_flags) {
174 			printf("controllers (e.g. %s%d) ",
175 			    dp->d_name, dp->d_unit);
176 			printf("don't have flags, only devices do\n");
177 			continue;
178 		}
179 		fprintf(fp,
180 		    "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0%o },\n",
181 		    dp->d_name, dp->d_unit, qu(mp->d_unit),
182 		    dp->d_name, dp->d_unit, dp->d_addr);
183 	}
184 	fprintf(fp, "\t0\n};\n");
185 /* unibus devices */
186 	fprintf(fp, "\nstruct uba_device ubdinit[] = {\n");
187 	fprintf(fp,
188 "\t/* driver,  unit, ctlr,  ubanum, slave,   intr,    addr,    dk, flags*/\n");
189 	for (dp = dtab; dp != 0; dp = dp->d_next) {
190 		mp = dp->d_conn;
191 		if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 ||
192 		    mp == TO_NEXUS || mp->d_type == MASTER ||
193 		    eq(mp->d_name, "mba"))
194 			continue;
195 		np = mp->d_conn;
196 		if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba"))
197 			continue;
198 		np = 0;
199 		if (eq(mp->d_name, "uba")) {
200 			if (dp->d_vec == 0) {
201 				printf("must specify vector for device %s%d\n",
202 				    dp->d_name, dp->d_unit);
203 				continue;
204 			}
205 			if (dp->d_addr == 0) {
206 				printf("must specify csr for device %s%d\n",
207 				    dp->d_name, dp->d_unit);
208 				continue;
209 			}
210 			if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
211 				printf("drives/slaves can be specified ");
212 				printf("only for controllers, ");
213 				printf("not for device %s%d\n",
214 				    dp->d_name, dp->d_unit);
215 				continue;
216 			}
217 			uba_n = mp->d_unit;
218 			slave = QUES;
219 		} else {
220 			if ((np = mp->d_conn) == 0) {
221 				printf("%s%d isn't connected to anything ",
222 				    mp->d_name, mp->d_unit);
223 				printf(", so %s%d is unattached\n",
224 				    dp->d_name, dp->d_unit);
225 				continue;
226 			}
227 			uba_n = np->d_unit;
228 			if (dp->d_drive == UNKNOWN) {
229 				printf("must specify ``drive number'' ");
230 				printf("for %s%d\n", dp->d_name, dp->d_unit);
231 				continue;
232 			}
233 			/* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */
234 			/* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */
235 			if (dp->d_slave != UNKNOWN) {
236 				printf("slave numbers should be given only ");
237 				printf("for massbus tapes, not for %s%d\n",
238 				    dp->d_name, dp->d_unit);
239 				continue;
240 			}
241 			if (dp->d_vec != 0) {
242 				printf("interrupt vectors should not be ");
243 				printf("given for drive %s%d\n",
244 				    dp->d_name, dp->d_unit);
245 				continue;
246 			}
247 			if (dp->d_addr != 0) {
248 				printf("csr addresses should be given only ");
249 				printf("on controllers, not on %s%d\n",
250 				    dp->d_name, dp->d_unit);
251 				continue;
252 			}
253 			slave = dp->d_drive;
254 		}
255 		fprintf(fp, "\t{ &%sdriver,  %2d,   %s,",
256 		    eq(mp->d_name, "uba") ? dp->d_name : mp->d_name, dp->d_unit,
257 		    eq(mp->d_name, "uba") ? " -1" : qu(mp->d_unit));
258 		fprintf(fp, "  %s,    %2d,   %s, C 0%-6o,  %d,  0x%x },\n",
259 		    qu(uba_n), slave, intv(dp), dp->d_addr, dp->d_dk,
260 		    dp->d_flags);
261 	}
262 	fprintf(fp, "\t0\n};\n");
263 	pseudo_ioconf(fp);
264 	(void) fclose(fp);
265 }
266 #endif
267 
268 #if MACHINE_TAHOE
269 tahoe_ioconf()
270 {
271 	register struct device *dp, *mp, *np;
272 	register int vba_n, slave;
273 	FILE *fp;
274 
275 	fp = fopen(path("ioconf.c"), "w");
276 	if (fp == 0) {
277 		perror(path("ioconf.c"));
278 		exit(1);
279 	}
280 	fprintf(fp, "#include \"sys/param.h\"\n");
281 	fprintf(fp, "#include \"tahoe/include/pte.h\"\n");
282 	fprintf(fp, "#include \"sys/buf.h\"\n");
283 	fprintf(fp, "#include \"sys/map.h\"\n");
284 	fprintf(fp, "\n");
285 	fprintf(fp, "#include \"tahoe/vba/vbavar.h\"\n");
286 	fprintf(fp, "\n");
287 	fprintf(fp, "#define C (caddr_t)\n\n");
288 	/*
289 	 * Now generate interrupt vectors for the versabus
290 	 */
291 	for (dp = dtab; dp != 0; dp = dp->d_next) {
292 		mp = dp->d_conn;
293 		if (mp == 0 || mp == TO_NEXUS || !eq(mp->d_name, "vba"))
294 			continue;
295 		if (dp->d_vec != 0) {
296 			struct idlst *ip;
297 			fprintf(fp,
298 			    "extern struct vba_driver %sdriver;\n",
299 			    dp->d_name);
300 			fprintf(fp, "extern ");
301 			ip = dp->d_vec;
302 			for (;;) {
303 				fprintf(fp, "X%s%d()", ip->id, dp->d_unit);
304 				ip = ip->id_next;
305 				if (ip == 0)
306 					break;
307 				fprintf(fp, ", ");
308 			}
309 			fprintf(fp, ";\n");
310 			fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name,
311 			    dp->d_unit);
312 			ip = dp->d_vec;
313 			for (;;) {
314 				fprintf(fp, "X%s%d", ip->id, dp->d_unit);
315 				ip = ip->id_next;
316 				if (ip == 0)
317 					break;
318 				fprintf(fp, ", ");
319 			}
320 			fprintf(fp, ", 0 } ;\n");
321 		} else if (dp->d_type == DRIVER)  /* devices w/o interrupts */
322 			fprintf(fp,
323 			    "extern struct vba_driver %sdriver;\n",
324 			    dp->d_name);
325 	}
326 	fprintf(fp, "\nstruct vba_ctlr vbminit[] = {\n");
327 	fprintf(fp, "/*\t driver,\tctlr,\tvbanum,\talive,\tintr,\taddr */\n");
328 	for (dp = dtab; dp != 0; dp = dp->d_next) {
329 		mp = dp->d_conn;
330 		if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 ||
331 		    !eq(mp->d_name, "vba"))
332 			continue;
333 		if (dp->d_vec == 0) {
334 			printf("must specify vector for %s%d\n",
335 			    dp->d_name, dp->d_unit);
336 			continue;
337 		}
338 		if (dp->d_addr == 0) {
339 			printf("must specify csr address for %s%d\n",
340 			    dp->d_name, dp->d_unit);
341 			continue;
342 		}
343 		if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
344 			printf("drives need their own entries; dont ");
345 			printf("specify drive or slave for %s%d\n",
346 			    dp->d_name, dp->d_unit);
347 			continue;
348 		}
349 		if (dp->d_flags) {
350 			printf("controllers (e.g. %s%d) ",
351 			    dp->d_name, dp->d_unit);
352 			printf("don't have flags, only devices do\n");
353 			continue;
354 		}
355 		fprintf(fp,
356 		    "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0x%x },\n",
357 		    dp->d_name, dp->d_unit, qu(mp->d_unit),
358 		    dp->d_name, dp->d_unit, dp->d_addr);
359 	}
360 	fprintf(fp, "\t0\n};\n");
361 /* versabus devices */
362 	fprintf(fp, "\nstruct vba_device vbdinit[] = {\n");
363 	fprintf(fp,
364 "\t/* driver,  unit, ctlr,  vbanum, slave,   intr,    addr,    dk, flags*/\n");
365 	for (dp = dtab; dp != 0; dp = dp->d_next) {
366 		mp = dp->d_conn;
367 		if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 ||
368 		    mp == TO_NEXUS || mp->d_type == MASTER ||
369 		    eq(mp->d_name, "mba"))
370 			continue;
371 		np = mp->d_conn;
372 		if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba"))
373 			continue;
374 		np = 0;
375 		if (eq(mp->d_name, "vba")) {
376 			if (dp->d_vec == 0)
377 				printf(
378 		"Warning, no interrupt vector specified for device %s%d\n",
379 				    dp->d_name, dp->d_unit);
380 			if (dp->d_addr == 0) {
381 				printf("must specify csr for device %s%d\n",
382 				    dp->d_name, dp->d_unit);
383 				continue;
384 			}
385 			if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
386 				printf("drives/slaves can be specified ");
387 				printf("only for controllers, ");
388 				printf("not for device %s%d\n",
389 				    dp->d_name, dp->d_unit);
390 				continue;
391 			}
392 			vba_n = mp->d_unit;
393 			slave = QUES;
394 		} else {
395 			if ((np = mp->d_conn) == 0) {
396 				printf("%s%d isn't connected to anything ",
397 				    mp->d_name, mp->d_unit);
398 				printf(", so %s%d is unattached\n",
399 				    dp->d_name, dp->d_unit);
400 				continue;
401 			}
402 			vba_n = np->d_unit;
403 			if (dp->d_drive == UNKNOWN) {
404 				printf("must specify ``drive number'' ");
405 				printf("for %s%d\n", dp->d_name, dp->d_unit);
406 				continue;
407 			}
408 			/* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */
409 			/* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */
410 			if (dp->d_slave != UNKNOWN) {
411 				printf("slave numbers should be given only ");
412 				printf("for massbus tapes, not for %s%d\n",
413 				    dp->d_name, dp->d_unit);
414 				continue;
415 			}
416 			if (dp->d_vec != 0) {
417 				printf("interrupt vectors should not be ");
418 				printf("given for drive %s%d\n",
419 				    dp->d_name, dp->d_unit);
420 				continue;
421 			}
422 			if (dp->d_addr != 0) {
423 				printf("csr addresses should be given only ");
424 				printf("on controllers, not on %s%d\n",
425 				    dp->d_name, dp->d_unit);
426 				continue;
427 			}
428 			slave = dp->d_drive;
429 		}
430 		fprintf(fp, "\t{ &%sdriver,  %2d,   %s,",
431 		    eq(mp->d_name, "vba") ? dp->d_name : mp->d_name, dp->d_unit,
432 		    eq(mp->d_name, "vba") ? " -1" : qu(mp->d_unit));
433 		fprintf(fp, "  %s,    %2d,   %s, C 0x%-6x,  %d,  0x%x },\n",
434 		    qu(vba_n), slave, intv(dp), dp->d_addr, dp->d_dk,
435 		    dp->d_flags);
436 	}
437 	fprintf(fp, "\t0\n};\n");
438 	pseudo_ioconf(fp);
439 	(void) fclose(fp);
440 }
441 #endif
442 
443 #if MACHINE_HP300 || MACHINE_LUNA68K
444 hp300_ioconf()
445 {
446 	register struct device *dp, *mp;
447 	register int hpib, slave;
448 	FILE *fp;
449 
450 	fp = fopen(path("ioconf.c"), "w");
451 	if (fp == 0) {
452 		perror(path("ioconf.c"));
453 		exit(1);
454 	}
455 	fprintf(fp, "#include \"sys/param.h\"\n");
456 	fprintf(fp, "#include \"sys/buf.h\"\n");
457 	fprintf(fp, "#include \"sys/map.h\"\n");
458 	fprintf(fp, "\n");
459 	if (machine == MACHINE_HP300)
460 		fprintf(fp, "#include \"hp/dev/device.h\"\n\n");
461 	else
462 		fprintf(fp, "#include \"luna68k/dev/device.h\"\n\n");
463 	fprintf(fp, "\n");
464 	fprintf(fp, "#define C (caddr_t)\n");
465 	fprintf(fp, "#define D (struct driver *)\n\n");
466 	/*
467 	 * First print the hpib controller initialization structures
468 	 */
469 	for (dp = dtab; dp != 0; dp = dp->d_next) {
470 		mp = dp->d_conn;
471 		if (dp->d_unit == QUES || mp == 0)
472 			continue;
473 		fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name);
474 	}
475 	fprintf(fp, "\nstruct hp_ctlr hp_cinit[] = {\n");
476 	fprintf(fp, "/*\tdriver,\t\tunit,\talive,\taddr,\tflags */\n");
477 	for (dp = dtab; dp != 0; dp = dp->d_next) {
478 		mp = dp->d_conn;
479 		if (dp->d_unit == QUES ||
480 			dp->d_type != MASTER && dp->d_type != CONTROLLER)
481 			continue;
482 		if (mp != TO_NEXUS) {
483 			printf("%s%s must be attached to an sc (nexus)\n",
484 				dp->d_name, wnum(dp->d_unit));
485 			continue;
486 		}
487 		if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
488 			printf("can't specify drive/slave for %s%s\n",
489 				dp->d_name, wnum(dp->d_unit));
490 			continue;
491 		}
492 		fprintf(fp,
493 			"\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t0x%x },\n",
494 			dp->d_name, dp->d_unit, dp->d_addr, dp->d_flags);
495 	}
496 	fprintf(fp, "\t0\n};\n");
497 /* devices */
498 	fprintf(fp, "\nstruct hp_device hp_dinit[] = {\n");
499 	fprintf(fp,
500 	   "/*driver,\tcdriver,\tunit,\tctlr,\tslave,\taddr,\tdk,\tflags*/\n");
501 	for (dp = dtab; dp != 0; dp = dp->d_next) {
502 		mp = dp->d_conn;
503 		if (mp == 0 || dp->d_type != DEVICE || hpbadslave(mp, dp))
504 			continue;
505 		if (mp == TO_NEXUS) {
506 			if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
507 				printf("can't specify drive/slave for %s%s\n",
508 					dp->d_name, wnum(dp->d_unit));
509 				continue;
510 			}
511 			slave = QUES;
512 			hpib = QUES;
513 		} else {
514 			if (dp->d_addr != 0) {
515 				printf("can't specify sc for device %s%s\n",
516 					dp->d_name, wnum(dp->d_unit));
517 				continue;
518 			}
519 			if (mp->d_type == CONTROLLER) {
520 				if (dp->d_drive == UNKNOWN) {
521 					printf("must specify drive for %s%s\n",
522 						dp->d_name, wnum(dp->d_unit));
523 					continue;
524 				}
525 				slave = dp->d_drive;
526 			} else {
527 				if (dp->d_slave == UNKNOWN) {
528 					printf("must specify slave for %s%s\n",
529 						dp->d_name, wnum(dp->d_unit));
530 					continue;
531 				}
532 				slave = dp->d_slave;
533 			}
534 			hpib = mp->d_unit;
535 		}
536 		fprintf(fp, "{ &%sdriver,\t", dp->d_name);
537 		if (mp == TO_NEXUS)
538 			fprintf(fp, "D 0x0,\t");
539 		else
540 			fprintf(fp, "&%sdriver,", mp->d_name);
541 		fprintf(fp, "\t%d,\t%d,\t%d,\tC 0x%x,\t%d,\t0x%x },\n",
542 			dp->d_unit, hpib, slave,
543 			dp->d_addr, dp->d_dk, dp->d_flags);
544 	}
545 	fprintf(fp, "0\n};\n");
546 	pseudo_ioconf(fp);
547 	(void) fclose(fp);
548 }
549 
550 #define ishpibdev(n) (eq(n,"rd") || eq(n,"ct") || eq(n,"mt") || eq(n,"ppi"))
551 #define isscsidev(n) (eq(n,"sd") || eq(n,"st") || eq(n,"ac"))
552 
553 hpbadslave(mp, dp)
554 	register struct device *dp, *mp;
555 {
556 
557 	if (mp == TO_NEXUS && ishpibdev(dp->d_name) ||
558 	    mp != TO_NEXUS && eq(mp->d_name, "hpib") &&
559 	    !ishpibdev(dp->d_name)) {
560 		printf("%s%s must be attached to an hpib\n",
561 		       dp->d_name, wnum(dp->d_unit));
562 		return (1);
563 	}
564 	if (mp == TO_NEXUS && isscsidev(dp->d_name) ||
565 	    mp != TO_NEXUS && eq(mp->d_name, "scsi") &&
566 	    !isscsidev(dp->d_name)) {
567 		printf("%s%s must be attached to a scsi\n",
568 		       dp->d_name, wnum(dp->d_unit));
569 		return (1);
570 	}
571 	return (0);
572 }
573 #endif
574 
575 #if MACHINE_I386
576 char *sirq();
577 
578 i386_ioconf()
579 {
580 	register struct device *dp, *mp, *np;
581 	register int uba_n, slave;
582 	FILE *fp;
583 
584 	fp = fopen(path("ioconf.c"), "w");
585 	if (fp == 0) {
586 		perror(path("ioconf.c"));
587 		exit(1);
588 	}
589 	fprintf(fp, "/*\n");
590 	fprintf(fp, " * ioconf.c \n");
591 	fprintf(fp, " * Generated by config program\n");
592 	fprintf(fp, " */\n\n");
593 	fprintf(fp, "#include \"machine/pte.h\"\n");
594 	fprintf(fp, "#include \"sys/param.h\"\n");
595 	fprintf(fp, "#include \"sys/buf.h\"\n");
596 	fprintf(fp, "#include \"sys/map.h\"\n");
597 	fprintf(fp, "\n");
598 	fprintf(fp, "#define V(s)	__CONCAT(V,s)\n");
599 	fprintf(fp, "#define C (caddr_t)\n\n");
600 	/*
601 	 * First print the isa initialization structures
602 	 */
603 	if (seen_isa) {
604 
605 		fprintf(fp, "/*\n");
606 		fprintf(fp, " * ISA devices\n");
607 		fprintf(fp, " */\n\n");
608 		fprintf(fp, "#include \"i386/isa/isa_device.h\"\n");
609 		fprintf(fp, "#include \"i386/isa/isa.h\"\n");
610 		fprintf(fp, "#include \"i386/isa/icu.h\"\n\n");
611 
612 		for (dp = dtab; dp != 0; dp = dp->d_next) {
613 			mp = dp->d_conn;
614 			if (mp == 0 || mp == TO_NEXUS ||
615 			    !eq(mp->d_name, "isa"))
616 				continue;
617 			fprintf(fp,
618 "extern struct isa_driver %sdriver; extern V(%s%d)();\n",
619 			    dp->d_name, dp->d_name, dp->d_unit);
620 		}
621 		fprintf(fp, "\nstruct isa_device isa_devtab_bio[] = {\n");
622 		fprintf(fp, "\
623 /* driver 	iobase	irq   drq     maddr    msiz    intr   unit */\n");
624 		for (dp = dtab; dp != 0; dp = dp->d_next) {
625 			mp = dp->d_conn;
626 			if (dp->d_unit == QUES || mp == 0 ||
627 			    mp == TO_NEXUS || !eq(mp->d_name, "isa"))
628 				continue;
629 			if (!eq(dp->d_mask, "bio")) continue;
630 			if (dp->d_port)
631 		 fprintf(fp, "{ &%sdriver,  %8.8s,", dp->d_name, dp->d_port);
632 			else
633 	 fprintf(fp, "{ &%sdriver,     0x%03x,", dp->d_name, dp->d_portn);
634 		fprintf(fp, " %5.5s, %2d,  C 0x%05X, %5d, V(%s%d),  %2d },\n",
635 			 	sirq(dp->d_irq), dp->d_drq, dp->d_maddr,
636 			 dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit);
637 		}
638 		fprintf(fp, "0\n};\n");
639 
640 		fprintf(fp, "struct isa_device isa_devtab_tty[] = {\n");
641 		fprintf(fp, "\
642 /* driver 	iobase	irq   drq     maddr    msiz    intr   unit */\n");
643 		for (dp = dtab; dp != 0; dp = dp->d_next) {
644 			mp = dp->d_conn;
645 			if (dp->d_unit == QUES || mp == 0 ||
646 			    mp == TO_NEXUS || !eq(mp->d_name, "isa"))
647 				continue;
648 			if (!eq(dp->d_mask, "tty")) continue;
649 			if (dp->d_port)
650 		 fprintf(fp, "{ &%sdriver,  %8.8s,", dp->d_name, dp->d_port);
651 			else
652 	 fprintf(fp, "{ &%sdriver,     0x%03x,", dp->d_name, dp->d_portn);
653 		fprintf(fp, " %5.5s, %2d,  C 0x%05X, %5d, V(%s%d),  %2d },\n",
654 			 	sirq(dp->d_irq), dp->d_drq, dp->d_maddr,
655 			 dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit);
656 		}
657 		fprintf(fp, "0\n};\n\n");
658 
659 		fprintf(fp, "struct isa_device isa_devtab_net[] = {\n");
660 		fprintf(fp, "\
661 /* driver 	iobase	irq   drq     maddr    msiz    intr   unit */\n");
662 		for (dp = dtab; dp != 0; dp = dp->d_next) {
663 			mp = dp->d_conn;
664 			if (dp->d_unit == QUES || mp == 0 ||
665 			    mp == TO_NEXUS || !eq(mp->d_name, "isa"))
666 				continue;
667 			if (!eq(dp->d_mask, "net")) continue;
668 			if (dp->d_port)
669 		 fprintf(fp, "{ &%sdriver,  %8.8s,", dp->d_name, dp->d_port);
670 			else
671 	 fprintf(fp, "{ &%sdriver,     0x%03x,", dp->d_name, dp->d_portn);
672 		fprintf(fp, " %5.5s, %2d,  C 0x%05X, %5d, V(%s%d),  %2d },\n",
673 			 	sirq(dp->d_irq), dp->d_drq, dp->d_maddr,
674 			 dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit);
675 		}
676 		fprintf(fp, "0\n};\n\n");
677 
678 		fprintf(fp, "struct isa_device isa_devtab_null[] = {\n");
679 		fprintf(fp, "\
680 /* driver 	iobase	irq   drq     maddr    msiz    intr   unit */\n");
681 		for (dp = dtab; dp != 0; dp = dp->d_next) {
682 			mp = dp->d_conn;
683 			if (dp->d_unit == QUES || mp == 0 ||
684 			    mp == TO_NEXUS || !eq(mp->d_name, "isa"))
685 				continue;
686 			if (!eq(dp->d_mask, "null")) continue;
687 			if (dp->d_port)
688 		 fprintf(fp, "{ &%sdriver,  %8.8s,", dp->d_name, dp->d_port);
689 			else
690 	 fprintf(fp, "{ &%sdriver,     0x%03x,", dp->d_name, dp->d_portn);
691 		fprintf(fp, " %5.5s, %2d,  C 0x%05X, %5d, V(%s%d),  %2d },\n",
692 			 	sirq(dp->d_irq), dp->d_drq, dp->d_maddr,
693 			 dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit);
694 		}
695 		fprintf(fp, "0\n};\n\n");
696 	}
697 	pseudo_ioconf(fp);
698 	(void) fclose(fp);
699 }
700 
701 char *
702 sirq(num)
703 {
704 
705 	if (num == -1)
706 		return ("0");
707 	sprintf(errbuf, "IRQ%d", num);
708 	return (errbuf);
709 }
710 #endif
711 
712 #if MACHINE_PMAX
713 pmax_ioconf()
714 {
715 	register struct device *dp, *mp;
716 	FILE *fp;
717 
718 	fp = fopen(path("ioconf.c"), "w");
719 	if (fp == 0) {
720 		perror(path("ioconf.c"));
721 		exit(1);
722 	}
723 	fprintf(fp, "#include \"sys/types.h\"\n");
724 	fprintf(fp, "#include \"sys/time.h\"\n");
725 	fprintf(fp, "#include \"pmax/dev/device.h\"\n\n");
726 	fprintf(fp, "#define C (char *)\n\n");
727 
728 	/* print controller initialization structures */
729 	for (dp = dtab; dp != 0; dp = dp->d_next) {
730 		if (dp->d_type == PSEUDO_DEVICE)
731 			continue;
732 		fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name);
733 	}
734 	fprintf(fp, "\nstruct pmax_ctlr pmax_cinit[] = {\n");
735 	fprintf(fp, "/*\tdriver,\t\tunit,\taddr,\t\tpri,\tflags */\n");
736 	for (dp = dtab; dp != 0; dp = dp->d_next) {
737 		if (dp->d_type != CONTROLLER && dp->d_type != MASTER)
738 			continue;
739 		if (dp->d_conn != TO_NEXUS) {
740 			printf("%s%s must be attached to a nexus (internal bus)\n",
741 				dp->d_name, wnum(dp->d_unit));
742 			continue;
743 		}
744 		if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
745 			printf("can't specify drive/slave for %s%s\n",
746 				dp->d_name, wnum(dp->d_unit));
747 			continue;
748 		}
749 		if (dp->d_unit == UNKNOWN || dp->d_unit == QUES)
750 			dp->d_unit = 0;
751 		fprintf(fp,
752 			"\t{ &%sdriver,\t%d,\tC 0x%x,\t%d,\t0x%x },\n",
753 			dp->d_name, dp->d_unit, dp->d_addr, dp->d_pri,
754 			dp->d_flags);
755 	}
756 	fprintf(fp, "\t0\n};\n");
757 
758 	/* print devices connected to other controllers */
759 	fprintf(fp, "\nstruct scsi_device scsi_dinit[] = {\n");
760 	fprintf(fp,
761 	   "/*driver,\tcdriver,\tunit,\tctlr,\tdrive,\tslave,\tdk,\tflags*/\n");
762 	for (dp = dtab; dp != 0; dp = dp->d_next) {
763 		if (dp->d_type == CONTROLLER || dp->d_type == MASTER ||
764 		    dp->d_type == PSEUDO_DEVICE)
765 			continue;
766 		mp = dp->d_conn;
767 		if (mp == 0 ||
768 		    !eq(mp->d_name, "asc") && !eq(mp->d_name, "sii")) {
769 			printf("%s%s: devices must be attached to a SCSI (asc or sii) controller\n",
770 				dp->d_name, wnum(dp->d_unit));
771 			continue;
772 		}
773 		if ((unsigned)dp->d_drive > 6) {
774 			printf("%s%s: SCSI drive must be in the range 0..6\n",
775 				dp->d_name, wnum(dp->d_unit));
776 			continue;
777 		}
778 		/* may want to allow QUES later */
779 		if ((unsigned)dp->d_slave > 7) {
780 			printf("%s%s: SCSI slave (LUN) must be in the range 0..7\n",
781 				dp->d_name, wnum(dp->d_unit));
782 			continue;
783 		}
784 		fprintf(fp, "{ &%sdriver,\t&%sdriver,", dp->d_name, mp->d_name);
785 		fprintf(fp, "\t%d,\t%d,\t%d,\t%d,\t%d,\t0x%x },\n",
786 			dp->d_unit, mp->d_unit, dp->d_drive, dp->d_slave,
787 			dp->d_dk, dp->d_flags);
788 	}
789 	fprintf(fp, "0\n};\n");
790 	pseudo_ioconf(fp);
791 	(void) fclose(fp);
792 }
793 #endif
794 
795 #if MACHINE_NEWS3400
796 int have_iop = 0;
797 int have_hb = 0;
798 int have_vme = 0;
799 
800 news_ioconf()
801 {
802 	register struct device *dp, *mp;
803 	register int slave;
804 	FILE *fp;
805 
806 	fp = fopen(path("ioconf.c"), "w");
807 	if (fp == 0) {
808 		perror(path("ioconf.c"));
809 		exit(1);
810 	}
811 	fprintf(fp, "#include \"sys/param.h\"\n");
812 	fprintf(fp, "#include \"sys/buf.h\"\n");
813 	fprintf(fp, "#include \"sys/map.h\"\n");
814 	fprintf(fp, "#include \"vm/vm.h\"\n");
815 	fprintf(fp, "#include \"iop.h\"\n");
816 	fprintf(fp, "#include \"hb.h\"\n");
817 	fprintf(fp, "\n");
818 	fprintf(fp, "#if NIOP > 0\n");
819 	fprintf(fp, "#include \"news3400/iop/iopvar.h\"\n");
820 	fprintf(fp, "#endif\n");
821 	fprintf(fp, "#if NHB > 0\n");
822 	fprintf(fp, "#include \"news3400/hbdev/hbvar.h\"\n");
823 	fprintf(fp, "#endif\n");
824 	fprintf(fp, "\n");
825 	fprintf(fp, "#define C (caddr_t)\n\n");
826 	fprintf(fp, "\n");
827 
828 /* BEGIN HB */
829 	fprintf(fp, "#if NHB > 0\n");
830 	/*
831 	 * Now generate interrupt vectors for the HYPER-BUS
832 	 */
833 	for (dp = dtab; dp != 0; dp = dp->d_next) {
834 		if (dp->d_pri >= 0) {
835 			mp = dp->d_conn;
836 			if (mp == 0 || mp == TO_NEXUS ||
837 			    !eq(mp->d_name, "hb"))
838 				continue;
839 			fprintf(fp, "extern struct hb_driver %sdriver;\n",
840 			    dp->d_name);
841 			have_hb++;
842 		}
843 	}
844 	/*
845 	 * Now spew forth the hb_cinfo structure
846 	 */
847 	fprintf(fp, "\nstruct hb_ctlr hminit[] = {\n");
848 	fprintf(fp, "/*\t driver,\tctlr,\talive,\taddr,\tintpri */\n");
849 	for (dp = dtab; dp != 0; dp = dp->d_next) {
850 		mp = dp->d_conn;
851 		if ((dp->d_type != MASTER && dp->d_type != CONTROLLER)
852 		    || mp == TO_NEXUS || mp == 0 ||
853 		    !eq(mp->d_name, "hb"))
854 			continue;
855 		if (dp->d_pri < 0) {
856 			printf("must specify priority for %s%d\n",
857 			    dp->d_name, dp->d_unit);
858 			continue;
859 		}
860 		if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
861 			printf("drives need their own entries; ");
862 			printf("dont specify drive or slave for %s%d\n",
863 			    dp->d_name, dp->d_unit);
864 			continue;
865 		}
866 		if (dp->d_flags) {
867 			printf("controllers (e.g. %s%d) don't have flags, ");
868 			printf("only devices do\n",
869 			    dp->d_name, dp->d_unit);
870 			continue;
871 		}
872 		fprintf(fp, "\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t%d },\n",
873 		    dp->d_name, dp->d_unit, dp->d_addr, dp->d_pri);
874 	}
875 	fprintf(fp, "\t0\n};\n");
876 	/*
877 	 * Now we go for the hb_device stuff
878 	 */
879 	fprintf(fp, "\nstruct hb_device hdinit[] = {\n");
880 	fprintf(fp,
881 "\t/* driver,  unit, ctlr,  slave,   addr,    pri,    dk, flags*/\n");
882 	for (dp = dtab; dp != 0; dp = dp->d_next) {
883 		mp = dp->d_conn;
884 		if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 ||
885 		    mp == TO_NEXUS || /* mp->d_type == MASTER || */
886 		    eq(mp->d_name, "iop") || eq(mp->d_name, "vme"))
887 			continue;
888 		if (eq(mp->d_name, "hb")) {
889 			if (dp->d_pri < 0) {
890 				printf("must specify vector for device %s%d\n",
891 				    dp->d_name, dp->d_unit);
892 				continue;
893 			}
894 			if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
895 				printf("drives/slaves can be specified only ");
896 				printf("for controllers, not for device %s%d\n",
897 				    dp->d_name, dp->d_unit);
898 				continue;
899 			}
900 			slave = QUES;
901 		} else {
902 			if (mp->d_conn == 0) {
903 				printf("%s%d isn't connected to anything, ",
904 				    mp->d_name, mp->d_unit);
905 				printf("so %s%d is unattached\n",
906 				    dp->d_name, dp->d_unit);
907 				continue;
908 			}
909 			if (dp->d_drive == UNKNOWN) {
910 				printf("must specify ``drive number'' for %s%d\n",
911 				   dp->d_name, dp->d_unit);
912 				continue;
913 			}
914 			/* NOTE THAT ON THE IOP ``drive'' IS STORED IN */
915 			/* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */
916 			if (dp->d_slave != UNKNOWN) {
917 				printf("slave numbers should be given only ");
918 				printf("for massbus tapes, not for %s%d\n",
919 				    dp->d_name, dp->d_unit);
920 				continue;
921 			}
922 			if (dp->d_pri >= 0) {
923 				printf("interrupt priority should not be ");
924 				printf("given for drive %s%d\n",
925 				    dp->d_name, dp->d_unit);
926 				continue;
927 			}
928 			if (dp->d_addr != 0) {
929 				printf("csr addresses should be given only");
930 				printf("on controllers, not on %s%d\n",
931 				    dp->d_name, dp->d_unit);
932 				continue;
933 			}
934 			slave = dp->d_drive;
935 		}
936 		fprintf(fp,
937 "\t{ &%sdriver,  %2d,   %s,    %2d,   C 0x%x, %d,  %d,  0x%x },\n",
938 		    eq(mp->d_name, "hb") ? dp->d_name : mp->d_name, dp->d_unit,
939 		    eq(mp->d_name, "hb") ? " -1" : qu(mp->d_unit),
940 		    slave, dp->d_addr, dp->d_pri, dp->d_dk, dp->d_flags);
941 	}
942 	fprintf(fp, "\t0\n};\n\n");
943 	fprintf(fp, "#endif\n\n");
944 /* END HB */
945 	pseudo_ioconf(fp);
946 	(void) fclose(fp);
947 }
948 #endif
949 
950 char *
951 intv(dev)
952 	register struct device *dev;
953 {
954 	static char buf[20];
955 
956 	if (dev->d_vec == 0)
957 		return ("     0");
958 	(void) sprintf(buf, "%sint%d", dev->d_name, dev->d_unit);
959 	return (buf);
960 }
961 
962 char *
963 qu(num)
964 {
965 
966 	if (num == QUES)
967 		return ("'?'");
968 	if (num == UNKNOWN)
969 		return (" -1");
970 	(void) sprintf(errbuf, "%3d", num);
971 	return (errbuf);
972 }
973 
974 char *
975 wnum(num)
976 {
977 
978 	if (num == QUES || num == UNKNOWN)
979 		return ("?");
980 	(void) sprintf(errbuf, "%d", num);
981 	return (errbuf);
982 }
983 
984 void
985 pseudo_ioconf(fp)
986 	register FILE *fp;
987 {
988 	register struct device *dp;
989 
990 	(void)fprintf(fp, "\n#include <sys/device.h>\n\n");
991 	for (dp = dtab; dp != NULL; dp = dp->d_next)
992 		if (dp->d_type == PSEUDO_DEVICE)
993 			(void)fprintf(fp, "extern void %sattach __P((int));\n",
994 			    dp->d_name);
995 	/*
996 	 * XXX concatonated disks are pseudo-devices but appear as DEVICEs
997 	 * since they don't adhere to normal pseudo-device conventions
998 	 * (i.e. one entry with total count in d_slave).
999 	 */
1000 	if (seen_cd)
1001 		(void)fprintf(fp, "extern void cdattach __P((int));\n");
1002 	/* XXX temporary for HP300, others */
1003 	(void)fprintf(fp, "\n#include <sys/systm.h> /* XXX */\n");
1004 	(void)fprintf(fp, "#define etherattach (void (*)__P((int)))nullop\n");
1005 	(void)fprintf(fp, "#define iteattach (void (*) __P((int)))nullop\n");
1006 	(void)fprintf(fp, "\nstruct pdevinit pdevinit[] = {\n");
1007 	for (dp = dtab; dp != NULL; dp = dp->d_next)
1008 		if (dp->d_type == PSEUDO_DEVICE)
1009 			(void)fprintf(fp, "\t{ %sattach, %d },\n", dp->d_name,
1010 			    dp->d_slave > 0 ? dp->d_slave : 1);
1011 	/*
1012 	 * XXX count up cds and put out an entry
1013 	 */
1014 	if (seen_cd) {
1015 		struct file_list *fl;
1016 		int cdmax = -1;
1017 
1018 		for (fl = comp_list; fl != NULL; fl = fl->f_next)
1019 			if (fl->f_type == COMPDEVICE && fl->f_compinfo > cdmax)
1020 				cdmax = fl->f_compinfo;
1021 		(void)fprintf(fp, "\t{ cdattach, %d },\n", cdmax+1);
1022 	}
1023 	(void)fprintf(fp, "\t{ 0, 0 }\n};\n");
1024 	if (seen_cd)
1025 		comp_config(fp);
1026 }
1027 
1028 comp_config(fp)
1029 	FILE *fp;
1030 {
1031 	register struct file_list *fl;
1032 	register struct device *dp;
1033 
1034 	fprintf(fp, "\n#include \"dev/cdvar.h\"\n");
1035 	fprintf(fp, "\nstruct cddevice cddevice[] = {\n");
1036 	fprintf(fp, "/*\tunit\tileave\tflags\tdk\tdevs\t\t\t\t*/\n");
1037 
1038 	fl = comp_list;
1039 	while (fl) {
1040 		if (fl->f_type != COMPDEVICE) {
1041 			fl = fl->f_next;
1042 			continue;
1043 		}
1044 		for (dp = dtab; dp != 0; dp = dp->d_next)
1045 			if (dp->d_type == DEVICE &&
1046 			    eq(dp->d_name, fl->f_fn) &&
1047 			    dp->d_unit == fl->f_compinfo)
1048 				break;
1049 		if (dp == 0)
1050 			continue;
1051 		fprintf(fp, "\t%d,\t%d,\t%d,\t%d,\t{",
1052 			dp->d_unit, dp->d_pri < 0 ? 0 : dp->d_pri,
1053 			dp->d_flags, 1);
1054 		for (fl = fl->f_next; fl->f_type == COMPSPEC; fl = fl->f_next)
1055 			fprintf(fp, " 0x%x,", fl->f_compdev);
1056 		fprintf(fp, " NODEV },\n");
1057 	}
1058 	fprintf(fp, "\t-1,\t0,\t0,\t0,\t{ 0 },\n};\n");
1059 }
1060