xref: /original-bsd/usr.sbin/config/mkioconf.c (revision 00534a39)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)mkioconf.c	5.28 (Berkeley) 04/17/93";
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 \"pmax/dev/device.h\"\n\n");
725 	fprintf(fp, "#define C (char *)\n\n");
726 
727 	/* print controller initialization structures */
728 	for (dp = dtab; dp != 0; dp = dp->d_next) {
729 		if (dp->d_type == PSEUDO_DEVICE)
730 			continue;
731 		fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name);
732 	}
733 	fprintf(fp, "\nstruct pmax_ctlr pmax_cinit[] = {\n");
734 	fprintf(fp, "/*\tdriver,\t\tunit,\taddr,\t\tpri,\tflags */\n");
735 	for (dp = dtab; dp != 0; dp = dp->d_next) {
736 		if (dp->d_type != CONTROLLER && dp->d_type != MASTER)
737 			continue;
738 		if (dp->d_conn != TO_NEXUS) {
739 			printf("%s%s must be attached to a nexus (internal bus)\n",
740 				dp->d_name, wnum(dp->d_unit));
741 			continue;
742 		}
743 		if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
744 			printf("can't specify drive/slave for %s%s\n",
745 				dp->d_name, wnum(dp->d_unit));
746 			continue;
747 		}
748 		if (dp->d_unit == UNKNOWN || dp->d_unit == QUES)
749 			dp->d_unit = 0;
750 		fprintf(fp,
751 			"\t{ &%sdriver,\t%d,\tC 0x%x,\t%d,\t0x%x },\n",
752 			dp->d_name, dp->d_unit, dp->d_addr, dp->d_pri,
753 			dp->d_flags);
754 	}
755 	fprintf(fp, "\t0\n};\n");
756 
757 	/* print devices connected to other controllers */
758 	fprintf(fp, "\nstruct scsi_device scsi_dinit[] = {\n");
759 	fprintf(fp,
760 	   "/*driver,\tcdriver,\tunit,\tctlr,\tdrive,\tslave,\tdk,\tflags*/\n");
761 	for (dp = dtab; dp != 0; dp = dp->d_next) {
762 		if (dp->d_type == CONTROLLER || dp->d_type == MASTER ||
763 		    dp->d_type == PSEUDO_DEVICE)
764 			continue;
765 		mp = dp->d_conn;
766 		if (mp == 0 ||
767 		    !eq(mp->d_name, "asc") && !eq(mp->d_name, "sii")) {
768 			printf("%s%s: devices must be attached to a SCSI (asc or sii) controller\n",
769 				dp->d_name, wnum(dp->d_unit));
770 			continue;
771 		}
772 		if ((unsigned)dp->d_drive > 6) {
773 			printf("%s%s: SCSI drive must be in the range 0..6\n",
774 				dp->d_name, wnum(dp->d_unit));
775 			continue;
776 		}
777 		/* may want to allow QUES later */
778 		if ((unsigned)dp->d_slave > 7) {
779 			printf("%s%s: SCSI slave (LUN) must be in the range 0..7\n",
780 				dp->d_name, wnum(dp->d_unit));
781 			continue;
782 		}
783 		fprintf(fp, "{ &%sdriver,\t&%sdriver,", dp->d_name, mp->d_name);
784 		fprintf(fp, "\t%d,\t%d,\t%d,\t%d,\t%d,\t0x%x },\n",
785 			dp->d_unit, mp->d_unit, dp->d_drive, dp->d_slave,
786 			dp->d_dk, dp->d_flags);
787 	}
788 	fprintf(fp, "0\n};\n");
789 	pseudo_ioconf(fp);
790 	(void) fclose(fp);
791 }
792 #endif
793 
794 #if MACHINE_NEWS3400
795 int have_iop = 0;
796 int have_hb = 0;
797 int have_vme = 0;
798 
799 news_ioconf()
800 {
801 	register struct device *dp, *mp;
802 	register int slave;
803 	FILE *fp;
804 
805 	fp = fopen(path("ioconf.c"), "w");
806 	if (fp == 0) {
807 		perror(path("ioconf.c"));
808 		exit(1);
809 	}
810 	fprintf(fp, "#include \"sys/param.h\"\n");
811 	fprintf(fp, "#include \"sys/buf.h\"\n");
812 	fprintf(fp, "#include \"sys/map.h\"\n");
813 	fprintf(fp, "#include \"vm/vm.h\"\n");
814 	fprintf(fp, "#include \"iop.h\"\n");
815 	fprintf(fp, "#include \"hb.h\"\n");
816 	fprintf(fp, "\n");
817 	fprintf(fp, "#if NIOP > 0\n");
818 	fprintf(fp, "#include \"news3400/iop/iopvar.h\"\n");
819 	fprintf(fp, "#endif\n");
820 	fprintf(fp, "#if NHB > 0\n");
821 	fprintf(fp, "#include \"news3400/hbdev/hbvar.h\"\n");
822 	fprintf(fp, "#endif\n");
823 	fprintf(fp, "\n");
824 	fprintf(fp, "#define C (caddr_t)\n\n");
825 	fprintf(fp, "\n");
826 
827 /* BEGIN HB */
828 	fprintf(fp, "#if NHB > 0\n");
829 	/*
830 	 * Now generate interrupt vectors for the HYPER-BUS
831 	 */
832 	for (dp = dtab; dp != 0; dp = dp->d_next) {
833 		if (dp->d_pri >= 0) {
834 			mp = dp->d_conn;
835 			if (mp == 0 || mp == TO_NEXUS ||
836 			    !eq(mp->d_name, "hb"))
837 				continue;
838 			fprintf(fp, "extern struct hb_driver %sdriver;\n",
839 			    dp->d_name);
840 			have_hb++;
841 		}
842 	}
843 	/*
844 	 * Now spew forth the hb_cinfo structure
845 	 */
846 	fprintf(fp, "\nstruct hb_ctlr hminit[] = {\n");
847 	fprintf(fp, "/*\t driver,\tctlr,\talive,\taddr,\tintpri */\n");
848 	for (dp = dtab; dp != 0; dp = dp->d_next) {
849 		mp = dp->d_conn;
850 		if ((dp->d_type != MASTER && dp->d_type != CONTROLLER)
851 		    || mp == TO_NEXUS || mp == 0 ||
852 		    !eq(mp->d_name, "hb"))
853 			continue;
854 		if (dp->d_pri < 0) {
855 			printf("must specify priority for %s%d\n",
856 			    dp->d_name, dp->d_unit);
857 			continue;
858 		}
859 		if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
860 			printf("drives need their own entries; ");
861 			printf("dont specify drive or slave for %s%d\n",
862 			    dp->d_name, dp->d_unit);
863 			continue;
864 		}
865 		if (dp->d_flags) {
866 			printf("controllers (e.g. %s%d) don't have flags, ");
867 			printf("only devices do\n",
868 			    dp->d_name, dp->d_unit);
869 			continue;
870 		}
871 		fprintf(fp, "\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t%d },\n",
872 		    dp->d_name, dp->d_unit, dp->d_addr, dp->d_pri);
873 	}
874 	fprintf(fp, "\t0\n};\n");
875 	/*
876 	 * Now we go for the hb_device stuff
877 	 */
878 	fprintf(fp, "\nstruct hb_device hdinit[] = {\n");
879 	fprintf(fp,
880 "\t/* driver,  unit, ctlr,  slave,   addr,    pri,    dk, flags*/\n");
881 	for (dp = dtab; dp != 0; dp = dp->d_next) {
882 		mp = dp->d_conn;
883 		if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 ||
884 		    mp == TO_NEXUS || /* mp->d_type == MASTER || */
885 		    eq(mp->d_name, "iop") || eq(mp->d_name, "vme"))
886 			continue;
887 		if (eq(mp->d_name, "hb")) {
888 			if (dp->d_pri < 0) {
889 				printf("must specify vector for device %s%d\n",
890 				    dp->d_name, dp->d_unit);
891 				continue;
892 			}
893 			if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
894 				printf("drives/slaves can be specified only ");
895 				printf("for controllers, not for device %s%d\n",
896 				    dp->d_name, dp->d_unit);
897 				continue;
898 			}
899 			slave = QUES;
900 		} else {
901 			if (mp->d_conn == 0) {
902 				printf("%s%d isn't connected to anything, ",
903 				    mp->d_name, mp->d_unit);
904 				printf("so %s%d is unattached\n",
905 				    dp->d_name, dp->d_unit);
906 				continue;
907 			}
908 			if (dp->d_drive == UNKNOWN) {
909 				printf("must specify ``drive number'' for %s%d\n",
910 				   dp->d_name, dp->d_unit);
911 				continue;
912 			}
913 			/* NOTE THAT ON THE IOP ``drive'' IS STORED IN */
914 			/* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */
915 			if (dp->d_slave != UNKNOWN) {
916 				printf("slave numbers should be given only ");
917 				printf("for massbus tapes, not for %s%d\n",
918 				    dp->d_name, dp->d_unit);
919 				continue;
920 			}
921 			if (dp->d_pri >= 0) {
922 				printf("interrupt priority should not be ");
923 				printf("given for drive %s%d\n",
924 				    dp->d_name, dp->d_unit);
925 				continue;
926 			}
927 			if (dp->d_addr != 0) {
928 				printf("csr addresses should be given only");
929 				printf("on controllers, not on %s%d\n",
930 				    dp->d_name, dp->d_unit);
931 				continue;
932 			}
933 			slave = dp->d_drive;
934 		}
935 		fprintf(fp,
936 "\t{ &%sdriver,  %2d,   %s,    %2d,   C 0x%x, %d,  %d,  0x%x },\n",
937 		    eq(mp->d_name, "hb") ? dp->d_name : mp->d_name, dp->d_unit,
938 		    eq(mp->d_name, "hb") ? " -1" : qu(mp->d_unit),
939 		    slave, dp->d_addr, dp->d_pri, dp->d_dk, dp->d_flags);
940 	}
941 	fprintf(fp, "\t0\n};\n\n");
942 	fprintf(fp, "#endif\n\n");
943 /* END HB */
944 	pseudo_ioconf(fp);
945 	(void) fclose(fp);
946 }
947 #endif
948 
949 char *
950 intv(dev)
951 	register struct device *dev;
952 {
953 	static char buf[20];
954 
955 	if (dev->d_vec == 0)
956 		return ("     0");
957 	(void) sprintf(buf, "%sint%d", dev->d_name, dev->d_unit);
958 	return (buf);
959 }
960 
961 char *
962 qu(num)
963 {
964 
965 	if (num == QUES)
966 		return ("'?'");
967 	if (num == UNKNOWN)
968 		return (" -1");
969 	(void) sprintf(errbuf, "%3d", num);
970 	return (errbuf);
971 }
972 
973 char *
974 wnum(num)
975 {
976 
977 	if (num == QUES || num == UNKNOWN)
978 		return ("?");
979 	(void) sprintf(errbuf, "%d", num);
980 	return (errbuf);
981 }
982 
983 void
984 pseudo_ioconf(fp)
985 	register FILE *fp;
986 {
987 	register struct device *dp;
988 
989 	(void)fprintf(fp, "\n#include <sys/device.h>\n\n");
990 	for (dp = dtab; dp != NULL; dp = dp->d_next)
991 		if (dp->d_type == PSEUDO_DEVICE)
992 			(void)fprintf(fp, "extern void %sattach __P((int));\n",
993 			    dp->d_name);
994 	/* XXX temporary for HP300, others */
995 	(void)fprintf(fp, "\n#include <sys/systm.h> /* XXX */\n");
996 	(void)fprintf(fp, "#define etherattach (void (*)__P((int)))nullop\n");
997 	(void)fprintf(fp, "#define iteattach (void (*) __P((int)))nullop\n");
998 	(void)fprintf(fp, "\nstruct pdevinit pdevinit[] = {\n");
999 	for (dp = dtab; dp != NULL; dp = dp->d_next)
1000 		if (dp->d_type == PSEUDO_DEVICE)
1001 			(void)fprintf(fp, "\t{ %sattach, %d },\n", dp->d_name,
1002 			    dp->d_slave > 0 ? dp->d_slave : 1);
1003 	(void)fprintf(fp, "\t{ 0, 0 }\n};\n");
1004 }
1005