4.4BSD snapshot (revision 8.1); add 1993 to copyright
[unix-history] / usr / src / usr.sbin / config.new / mkioconf.c
CommitLineData
6b5eacd2 1/*
62a2aae7
KB
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
6b5eacd2
CT
4 *
5 * This software was developed by the Computer Systems Engineering group
6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7 * contributed to Berkeley.
8 *
9 * All advertising materials mentioning features or use of this software
10 * must display the following acknowledgement:
11 * This product includes software developed by the University of
12 * California, Lawrence Berkeley Laboratories.
13 *
14 * %sccs.include.redist.c%
15 *
62a2aae7 16 * @(#)mkioconf.c 8.1 (Berkeley) %G%
6b5eacd2
CT
17 */
18
19#include <sys/param.h>
20#include <errno.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include "config.h"
25
26/*
27 * Make ioconf.c.
28 */
29static int cforder __P((const void *, const void *));
30static int emitcfdata __P((FILE *));
31static int emitexterns __P((FILE *));
32static int emithdr __P((FILE *));
33static int emitloc __P((FILE *));
34static int emitpseudo __P((FILE *));
35static int emitpv __P((FILE *));
36static int emitroots __P((FILE *));
37static int emitvec __P((FILE *));
38static char *vecname __P((char *, const char *, int));
39
40static const char *s_i386;
41
42#define SEP(pos, max) (((u_int)(pos) % (max)) == 0 ? "\n\t" : " ")
43
44/*
45 * NEWLINE can only be used in the emitXXX functions.
46 * In most cases it can be subsumed into an fprintf.
47 */
48#define NEWLINE if (putc('\n', fp) < 0) return (1)
49
50int
51mkioconf()
52{
53 register FILE *fp;
54 register char *fname;
55 int v;
56
57 s_i386 = intern("i386");
58
59 fname = path("ioconf.c");
60 qsort(packed, npacked, sizeof *packed, cforder);
61 if ((fp = fopen(fname, "w")) == NULL) {
62 (void)fprintf(stderr, "config: cannot write %s: %s\n",
63 fname, strerror(errno));
64 return (1);
65 }
66 v = emithdr(fp);
67 if (v != 0 || emitvec(fp) || emitexterns(fp) || emitloc(fp) ||
68 emitpv(fp) || emitcfdata(fp) || emitroots(fp) || emitpseudo(fp)) {
69 if (v >= 0)
70 (void)fprintf(stderr,
71 "config: error writing %s: %s\n",
72 fname, strerror(errno));
73 (void)fclose(fp);
74 /* (void)unlink(fname); */
75 free(fname);
76 return (1);
77 }
78 (void)fclose(fp);
79 free(fname);
80 return (0);
81}
82
83static int
84cforder(a, b)
85 const void *a, *b;
86{
87 register int n1, n2;
88
89 n1 = (*(struct devi **)a)->i_cfindex;
90 n2 = (*(struct devi **)b)->i_cfindex;
91 return (n1 - n2);
92}
93
94static int
95emithdr(ofp)
96 register FILE *ofp;
97{
98 register FILE *ifp;
99 register int n;
100 char ifn[200], buf[BUFSIZ];
101
102 if (fprintf(ofp, "\
103/*\n\
104 * MACHINE GENERATED: DO NOT EDIT\n\
105 *\n\
106 * ioconf.c, from \"%s\"\n\
107 */\n\n", conffile) < 0)
108 return (1);
109 (void)sprintf(ifn, "ioconf.incl.%s", machine);
110 if ((ifp = fopen(ifn, "r")) != NULL) {
111 while ((n = fread(buf, 1, sizeof(buf), ifp)) > 0)
112 if (fwrite(buf, 1, n, ofp) != n)
113 return (1);
114 if (ferror(ifp)) {
115 (void)fprintf(stderr, "config: error reading %s: %s\n",
116 ifn, strerror(errno));
117 (void)fclose(ifp);
118 return (-1);
119 }
120 (void)fclose(ifp);
121 } else {
122 if (fputs("\
123#include <sys/param.h>\n\
124#include <sys/device.h>\n", ofp) < 0)
125 return (1);
126 }
127 return (0);
128}
129
130static int
131emitexterns(fp)
132 register FILE *fp;
133{
134 register struct devbase *d;
135
136 NEWLINE;
137 for (d = allbases; d != NULL; d = d->d_next) {
138 if (d->d_ihead == NULL)
139 continue;
140 if (fprintf(fp, "extern struct cfdriver %scd;\n",
141 d->d_name) < 0)
142 return (1);
143 }
144 NEWLINE;
145 return (0);
146}
147
148static int
149emitloc(fp)
150 register FILE *fp;
151{
152 register int i;
153
154 if (fprintf(fp, "\n/* locators */\n\
155static int loc[%d] = {", locators.used) < 0)
156 return (1);
157 for (i = 0; i < locators.used; i++)
158 if (fprintf(fp, "%s%s,", SEP(i, 8), locators.vec[i]) < 0)
159 return (1);
160 return (fprintf(fp, "\n};\n") < 0);
161}
162
163/*
164 * Emit global parents-vector.
165 */
166static int
167emitpv(fp)
168 register FILE *fp;
169{
170 register int i;
171
172 if (fprintf(fp, "\n/* parent vectors */\n\
173static short pv[%d] = {", parents.used) < 0)
174 return (1);
175 for (i = 0; i < parents.used; i++)
176 if (fprintf(fp, "%s%d,", SEP(i, 16), parents.vec[i]) < 0)
177 return (1);
178 return (fprintf(fp, "\n};\n") < 0);
179}
180
181/*
182 * Emit the cfdata array.
183 */
184static int
185emitcfdata(fp)
186 register FILE *fp;
187{
188 register struct devi **p, *i, **par;
189 register int unit, v;
190 register const char *vs, *state, *basename;
191 register struct nvlist *nv;
192 register struct attr *a;
193 char *loc;
194 char locbuf[20];
195
196 if (fprintf(fp, "\n\
197#define NORM FSTATE_NOTFOUND\n\
198#define STAR FSTATE_STAR\n\
199\n\
200struct cfdata cfdata[] = {\n\
201\t/* driver unit state loc flags parents ivstubs */\n") < 0)
202 return (1);
203 for (p = packed; (i = *p) != NULL; p++) {
204 /* the description */
205 if (fprintf(fp, "/*%3d: %s at ", i->i_cfindex, i->i_name) < 0)
206 return (1);
207 par = i->i_parents;
208 for (v = 0; v < i->i_pvlen; v++)
209 if (fprintf(fp, "%s%s", v == 0 ? "" : "|",
210 i->i_parents[v]->i_name) < 0)
211 return (1);
212 if (v == 0 && fputs("root", fp) < 0)
213 return (1);
214 a = i->i_atattr;
215 nv = a->a_locs;
216 for (nv = a->a_locs, v = 0; nv != NULL; nv = nv->nv_next, v++)
217 if (fprintf(fp, " %s %s",
218 nv->nv_name, i->i_locs[v]) < 0)
219 return (1);
220 if (fputs(" */\n", fp) < 0)
221 return (-1);
222
223 /* then the actual defining line */
224 basename = i->i_base->d_name;
225 if (i->i_unit == STAR) {
226 unit = i->i_base->d_umax;
227 state = "STAR";
228 } else {
229 unit = i->i_unit;
230 state = "NORM";
231 }
232 if (i->i_ivoff < 0) {
233 vs = "";
234 v = 0;
235 } else {
236 vs = "vec+";
237 v = i->i_ivoff;
238 }
239 if (i->i_locoff >= 0) {
240 (void)sprintf(locbuf, "loc+%3d", i->i_locoff);
241 loc = locbuf;
242 } else
243 loc = "loc";
244 if (fprintf(fp, "\
245\t{&%scd,%s%2d, %s, %7s, %#6x, pv+%2d, %s%d},\n",
246 basename, strlen(basename) < 3 ? "\t\t" : "\t", unit,
247 state, loc, i->i_cfflags, i->i_pvoff, vs, v) < 0)
248 return (1);
249 }
9cf45c42 250 return (fputs("\t{0}\n};\n", fp) < 0);
6b5eacd2
CT
251}
252
253/*
254 * Emit the table of potential roots.
255 */
256static int
257emitroots(fp)
258 register FILE *fp;
259{
260 register struct devi **p, *i;
261
262 if (fputs("\nshort cfroots[] = {\n", fp) < 0)
263 return (1);
264 for (p = packed; (i = *p) != NULL; p++) {
265 if (i->i_at != NULL)
266 continue;
267 if (i->i_unit != 0 &&
268 (i->i_unit != STAR || i->i_base->d_umax != 0))
269 (void)fprintf(stderr,
270 "config: warning: `%s at root' is not unit 0\n",
271 i->i_name);
272 if (fprintf(fp, "\t%2d /* %s */,\n",
273 i->i_cfindex, i->i_name) < 0)
274 return (1);
275 }
276 return (fputs("\t-1\n};\n", fp) < 0);
277}
278
279/*
280 * Emit pseudo-device initialization.
281 */
282static int
283emitpseudo(fp)
284 register FILE *fp;
285{
286 register struct devi *i;
287 register struct devbase *d;
288
19e0980e 289 if (fputs("\n/* pseudo-devices */\n", fp) < 0)
6b5eacd2
CT
290 return (1);
291 for (i = allpseudo; i != NULL; i = i->i_next)
292 if (fprintf(fp, "extern void %sattach __P((int));\n",
293 i->i_base->d_name) < 0)
294 return (1);
295 if (fputs("\nstruct pdevinit pdevinit[] = {\n", fp) < 0)
296 return (1);
297 for (i = allpseudo; i != NULL; i = i->i_next) {
298 d = i->i_base;
a6ea7586 299 if (fprintf(fp, "\t{ %sattach, %d },\n",
6b5eacd2
CT
300 d->d_name, d->d_umax) < 0)
301 return (1);
302 }
19e0980e 303 return (fputs("\t{ 0, 0 }\n};\n", fp) < 0);
6b5eacd2
CT
304}
305
306/*
307 * Emit interrupt vector declarations, and calculate offsets.
308 */
309static int
310emitvec(fp)
311 register FILE *fp;
312{
313 register struct nvlist *head, *nv;
314 register struct devi **p, *i;
315 register int j, nvec, unit;
316 char buf[200];
317
318 nvec = 0;
319 for (p = packed; (i = *p) != NULL; p++) {
320 if ((head = i->i_base->d_vectors) == NULL)
321 continue;
322 if ((unit = i->i_unit) == STAR)
323 panic("emitvec unit==STAR");
324 if (nvec == 0)
325 NEWLINE;
326 for (j = 0, nv = head; nv != NULL; j++, nv = nv->nv_next)
327 if (fprintf(fp,
328 "/* IVEC %s %d */ extern void %s();\n",
329 nv->nv_name, unit,
330 vecname(buf, nv->nv_name, unit)) < 0)
331 return (1);
332 nvec += j + 1;
333 }
334 if (nvec == 0)
335 return (0);
336 if (fprintf(fp, "\nstatic void (*vec[%d]) __P((void)) = {", nvec) < 0)
337 return (1);
338 nvec = 0;
339 for (p = packed; (i = *p) != NULL; p++) {
340 if ((head = i->i_base->d_vectors) == NULL)
341 continue;
342 i->i_ivoff = nvec;
343 unit = i->i_unit;
344 for (nv = head; nv != NULL; nv = nv->nv_next)
345 if (fprintf(fp, "%s%s,",
346 SEP(nvec++, 4),
347 vecname(buf, nv->nv_name, unit)) < 0)
348 return (1);
349 if (fprintf(fp, "%s0,", SEP(nvec++, 4)) < 0)
350 return (1);
351 }
352 return (fputs("\n};\n", fp) < 0);
353}
354
355static char *
356vecname(buf, name, unit)
357 char *buf;
358 const char *name;
359 int unit;
360{
361
362 /* @#%* 386 uses a different name format */
363 if (machine == s_i386) {
364 (void)sprintf(buf, "V%s%d", name, unit);
365 return (buf);
366 }
367 (void)sprintf(buf, "X%s%d", name, unit);
368 return (buf);
369}