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 */
59char	*intv(struct device *dev);
60char	*intv2(struct device *dev);
61void	i386_pseudo_inits(FILE *fp);	/* XXX function in wrong block */
62void	check_vector(struct idlst *vec);
63void	nrw_ioconf(void);
64void	m88k_pseudo_inits(FILE *fp);
65void	m98k_pseudo_inits(FILE *fp);
66char	*m88k_dn(char *name);
67char	*m98k_dn(char *name);
68char	*concat3(char *buf, const char *p1, const char *p2, const char *p3);
69
70#if MACHINE_VAX
71
72void
73vax_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
328void pseudo_inits(FILE *fp);
329
330void
331check_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
342void
343sun_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
545void
546pseudo_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
576void
577romp_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
737void
738mmax_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
897struct 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
905struct 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
916static	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
932static	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
954static	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
962static	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
974static struct proto *
975find_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
987void
988dev_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
1018void
1019sqt_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
1212void
1213i386_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
1235void declare(const char *cp);
1236int is_declared(const char *cp);
1237
1238void
1239mips_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
1280checkvme:
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");
1461closefile:
1462	(void) fclose(fp);
1463}
1464
1465char *
1466intv2(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
1478char *
1479concat3(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
1487char decl_devices[MAXDEVS][DEVLEN];
1488
1489void
1490declare(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
1503int
1504is_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
1519char	*m68k_dn(const char *name);
1520void	m68k_pseudo_inits(FILE *fp);
1521
1522void
1523m68k_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
1659void
1660m68k_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
1683void
1684i386_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
1707char *
1708m68k_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
1715char	*nrw_dn(char *name);
1716void	nrw_pseudo_inits(FILE *fp);
1717
1718void
1719nrw_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
1735void
1736nrw_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
1759char *
1760nrw_dn(char *name)
1761{
1762	sprintf(errbuf, "&%sdriver,", name);
1763	return(errbuf);
1764}
1765
1766void
1767m88k_ioconf(void)
1768{
1769	nrw_ioconf();
1770}
1771
1772void
1773m98k_ioconf(void)
1774{
1775	nrw_ioconf();
1776}
1777
1778void
1779m88k_pseudo_inits(FILE *fp)
1780{
1781	nrw_pseudo_inits(fp);
1782}
1783
1784void
1785m98k_pseudo_inits(FILE *fp)
1786{
1787	nrw_pseudo_inits(fp);
1788}
1789
1790char *
1791m88k_dn(char *name)
1792{
1793	return(nrw_dn(name));
1794}
1795
1796char *
1797m98k_dn(char *name)
1798{
1799	return(nrw_dn(name));
1800}
1801
1802
1803#endif	/* MACHINE_M88K || MACHINE_M98K */
1804
1805#ifdef MACHINE_HPPA
1806char	*hppa_dn(char *name);
1807void	hppa_pseudo_inits(FILE *fp);
1808
1809void
1810hppa_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
1826void
1827hppa_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
1850char *
1851hppa_dn(char *name)
1852{
1853	sprintf(errbuf, "&%sdriver,", name);
1854
1855	return (errbuf);
1856}
1857
1858#endif /* MACHINE_HPPA */
1859
1860#ifdef MACHINE_SPARC
1861char	*sparc_dn(char *name);
1862void	sparc_pseudo_inits(FILE *fp);
1863
1864void
1865sparc_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
1881void
1882sparc_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
1905char *
1906sparc_dn(char *name)
1907{
1908	sprintf(errbuf, "&%sdriver,", name);
1909	return (errbuf);
1910}
1911
1912#endif /* MACHINE_SPARC */
1913
1914#ifdef MACHINE_PPC
1915char	*ppc_dn(char *name);
1916void	ppc_pseudo_inits(FILE *fp);
1917
1918void
1919ppc_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
1935void
1936ppc_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
1959char *
1960ppc_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
1970void	arm_pseudo_inits(FILE *fp);
1971
1972void
1973arm_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
1989void
1990arm_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
2016void	x86_64_pseudo_inits(FILE *fp);
2017
2018void
2019x86_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
2035void
2036x86_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
2061char *
2062intv(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
2074char *
2075qu(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}
2087