GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/config/mkioconf.c Lines: 0 198 0.0 %
Date: 2017-11-07 Branches: 0 192 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: mkioconf.c,v 1.37 2017/09/27 15:14:51 deraadt Exp $	*/
2
/*	$NetBSD: mkioconf.c,v 1.41 1996/11/11 14:18:49 mycroft Exp $	*/
3
4
/*
5
 * Copyright (c) 1992, 1993
6
 *	The Regents of the University of California.  All rights reserved.
7
 *
8
 * This software was developed by the Computer Systems Engineering group
9
 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10
 * contributed to Berkeley.
11
 *
12
 * All advertising materials mentioning features or use of this software
13
 * must display the following acknowledgement:
14
 *	This product includes software developed by the University of
15
 *	California, Lawrence Berkeley Laboratories.
16
 *
17
 * Redistribution and use in source and binary forms, with or without
18
 * modification, are permitted provided that the following conditions
19
 * are met:
20
 * 1. Redistributions of source code must retain the above copyright
21
 *    notice, this list of conditions and the following disclaimer.
22
 * 2. Redistributions in binary form must reproduce the above copyright
23
 *    notice, this list of conditions and the following disclaimer in the
24
 *    documentation and/or other materials provided with the distribution.
25
 * 3. Neither the name of the University nor the names of its contributors
26
 *    may be used to endorse or promote products derived from this software
27
 *    without specific prior written permission.
28
 *
29
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39
 * SUCH DAMAGE.
40
 *
41
 *	from: @(#)mkioconf.c	8.1 (Berkeley) 6/6/93
42
 */
43
44
#include <err.h>
45
#include <errno.h>
46
#include <stdio.h>
47
#include <stdlib.h>
48
#include <string.h>
49
50
#include "config.h"
51
52
/*
53
 * Make ioconf.c.
54
 */
55
static int cforder(const void *, const void *);
56
static int emitcfdata(FILE *);
57
static int emitexterns(FILE *);
58
static int emithdr(FILE *);
59
static int emitloc(FILE *);
60
static int emitlocnames(FILE *);
61
static int emitpseudo(FILE *);
62
static int emitpv(FILE *);
63
static int emitroots(FILE *);
64
65
#define	SEP(pos, max)	(((u_int)(pos) % (max)) == 0 ? "\n\t" : " ")
66
67
/*
68
 * NEWLINE can only be used in the emitXXX functions.
69
 * In most cases it can be subsumed into an fprintf.
70
 */
71
#define	NEWLINE		if (putc('\n', fp) < 0) return (1)
72
73
int
74
mkioconf(void)
75
{
76
	FILE *fp;
77
	int v;
78
79
	qsort(packed, npacked, sizeof *packed, cforder);
80
	if ((fp = fopen("ioconf.c", "w")) == NULL) {
81
		warn("cannot write ioconf.c");
82
		return (1);
83
	}
84
	v = emithdr(fp);
85
	if (v != 0 || emitexterns(fp) || emitloc(fp) ||
86
	    emitlocnames(fp) || emitpv(fp) || emitcfdata(fp) ||
87
	    emitroots(fp) || emitpseudo(fp)) {
88
		if (v >= 0)
89
			warn("error writing ioconf.c");
90
		(void)fclose(fp);
91
		/* (void)unlink("ioconf.c"); */
92
		return (1);
93
	}
94
	(void)fclose(fp);
95
	return (0);
96
}
97
98
static int
99
cforder(const void *a, const void *b)
100
{
101
	int n1, n2;
102
103
	n1 = (*(struct devi **)a)->i_cfindex;
104
	n2 = (*(struct devi **)b)->i_cfindex;
105
	return (n1 - n2);
106
}
107
108
static int
109
emithdr(FILE *ofp)
110
{
111
	FILE *ifp;
112
	size_t n;
113
	char ifn[200], buf[BUFSIZ];
114
115
	if (fprintf(ofp, "\
116
/*\n\
117
 * MACHINE GENERATED: DO NOT EDIT\n\
118
 *\n\
119
 * ioconf.c, from \"%s\"\n\
120
 */\n\n", conffile) < 0)
121
		return (1);
122
	(void)snprintf(ifn, sizeof ifn, "ioconf.incl.%s", machine);
123
	if ((ifp = fopen(ifn, "r")) != NULL) {
124
		while ((n = fread(buf, 1, sizeof(buf), ifp)) > 0)
125
			if (fwrite(buf, 1, n, ofp) != n)
126
				return (1);
127
		if (ferror(ifp)) {
128
			warn("error reading %s", ifn);
129
			(void)fclose(ifp);
130
			return (-1);
131
		}
132
		(void)fclose(ifp);
133
	} else {
134
		if (fputs("\
135
#include <sys/param.h>\n\
136
#include <sys/device.h>\n", ofp) < 0)
137
			return (1);
138
	}
139
	return (0);
140
}
141
142
static int
143
emitexterns(FILE *fp)
144
{
145
	struct devbase *d;
146
	struct deva *da;
147
148
	NEWLINE;
149
	for (d = allbases; d != NULL; d = d->d_next) {
150
		if (!devbase_has_instances(d, WILD))
151
			continue;
152
		if (fprintf(fp, "extern struct cfdriver %s_cd;\n",
153
			    d->d_name) < 0)
154
			return (1);
155
	}
156
	NEWLINE;
157
	for (da = alldevas; da != NULL; da = da->d_next) {
158
		if (!deva_has_instances(da, WILD))
159
			continue;
160
		if (fprintf(fp, "extern struct cfattach %s_ca;\n",
161
			    da->d_name) < 0)
162
			return (1);
163
	}
164
	NEWLINE;
165
	return (0);
166
}
167
168
static int
169
emitloc(FILE *fp)
170
{
171
	int i;
172
173
	if (fprintf(fp, "\n/* locators */\n\
174
static long loc[%d] = {", locators.used) < 0)
175
		return (1);
176
	for (i = 0; i < locators.used; i++)
177
		if (fprintf(fp, "%s%s,", SEP(i, 8), locators.vec[i]) < 0)
178
			return (1);
179
	if (fprintf(fp, "\n};\n") < 0)
180
		return(1);
181
	return (fprintf(fp, "\n#ifndef MAXEXTRALOC\n\
182
#define MAXEXTRALOC 32\n\
183
#endif\n\
184
long extraloc[MAXEXTRALOC] = { -1 }; /* extra locator space */\n\
185
int rextraloc = MAXEXTRALOC; /* remaining extra locators */\n\
186
const int textraloc = MAXEXTRALOC; /* total extra relocators */\n") < 0);
187
}
188
189
static int nlocnames, maxlocnames = 8;
190
static char **locnames;
191
192
short
193
addlocname(const char *name)
194
{
195
	int i;
196
197
	if (locnames == NULL || nlocnames+1 > maxlocnames) {
198
		maxlocnames *= 4;
199
		locnames = ereallocarray(locnames, maxlocnames, sizeof(char *));
200
	}
201
	for (i = 0; i < nlocnames; i++)
202
		if (strcmp(name, locnames[i]) == 0)
203
			return (i);
204
	/*printf("adding %s at %d\n", name, nlocnames);*/
205
	locnames[nlocnames++] = (char *)name;
206
	return (nlocnames - 1);
207
}
208
209
static int nlocnami, maxlocnami = 8;
210
static short *locnami;
211
212
void
213
addlocnami(short index)
214
{
215
	if (locnami == NULL || nlocnami+1 > maxlocnami) {
216
		maxlocnami *= 4;
217
		locnami = ereallocarray(locnami, maxlocnami, sizeof(short));
218
	}
219
	locnami[nlocnami++] = index;
220
}
221
222
223
/*
224
 * Emit locator names
225
 * XXX the locnamp[] table is not compressed like it should be!
226
 */
227
static int
228
emitlocnames(FILE *fp)
229
{
230
	struct devi **p, *i;
231
	struct nvlist *nv;
232
	struct attr *a;
233
	int added, start;
234
	int v, j, x;
235
236
	addlocnami(-1);
237
	for (p = packed; (i = *p) != NULL; p++) {
238
		/*printf("child %s\n", i->i_name);*/
239
240
		/* initialize all uninitialized parents */
241
		for (x = 0; x < i->i_pvlen; x++) {
242
			if (i->i_parents[x]->i_plocnami)
243
				continue;
244
			start = nlocnami;
245
246
			/* add all the names */
247
			a = i->i_atattr;
248
			added = 0;
249
			for (nv = a->a_locs, v = 0; nv != NULL;
250
			    nv = nv->nv_next, v++) {
251
				addlocnami(addlocname(nv->nv_name));
252
				added = 1;
253
			}
254
			/* terminate list of names */
255
			if (added)
256
				addlocnami(-1);
257
			else
258
				start--;
259
260
			/*printf("bus %s starts at %d\n", i->i_parents[x]->i_name,
261
			    start);*/
262
			i->i_parents[x]->i_plocnami = start;
263
264
		}
265
	}
266
	for (p = packed; (i = *p) != NULL; p++)
267
		if (i->i_pvlen)
268
			i->i_locnami = i->i_parents[0]->i_plocnami;
269
	if (fprintf(fp, "\nchar *locnames[] = {\n") < 0)
270
		return (1);
271
	for (j = 0; j < nlocnames; j++)
272
		if (fprintf(fp, "\t\"%s\",\n", locnames[j]) < 0)
273
			return (1);
274
	if (fprintf(fp, "};\n\n") < 0)
275
		return (1);
276
277
	if (fprintf(fp,
278
	    "/* each entry is an index into locnames[]; -1 terminates */\n") < 0)
279
		return (1);
280
	if (fprintf(fp, "short locnamp[] = {") < 0)
281
		return (1);
282
	for (j = 0; j < nlocnami; j++)
283
		if (fprintf(fp, "%s%d,", SEP(j, 8), locnami[j]) < 0)
284
			return (1);
285
	return (fprintf(fp, "\n};\n") < 0);
286
}
287
288
289
/*
290
 * Emit global parents-vector.
291
 */
292
static int
293
emitpv(FILE *fp)
294
{
295
	int i;
296
297
	if (fprintf(fp, "\n/* size of parent vectors */\n\
298
int pv_size = %d;\n", parents.used) < 0)
299
		return (1);
300
	if (fprintf(fp, "\n/* parent vectors */\n\
301
short pv[%d] = {", parents.used) < 0)
302
		return (1);
303
	for (i = 0; i < parents.used; i++)
304
		if (fprintf(fp, "%s%d,", SEP(i, 16), parents.vec[i]) < 0)
305
			return (1);
306
	return (fprintf(fp, "\n};\n") < 0);
307
}
308
309
/*
310
 * Emit the cfdata array.
311
 */
312
static int
313
emitcfdata(FILE *fp)
314
{
315
	struct devi **p, *i;
316
	int unit, v;
317
	const char *state, *basename, *attachment;
318
	struct nvlist *nv;
319
	struct attr *a;
320
	char *loc;
321
	char locbuf[20];
322
323
	if (fprintf(fp, "\n\
324
#define NORM FSTATE_NOTFOUND\n\
325
#define STAR FSTATE_STAR\n\
326
#define DNRM FSTATE_DNOTFOUND\n\
327
#define DSTR FSTATE_DSTAR\n\
328
\n\
329
struct cfdata cfdata[] = {\n\
330
    /* attachment       driver        unit  state loc     flags parents nm starunit1 */\n") < 0)
331
		return (1);
332
	for (p = packed; (i = *p) != NULL; p++) {
333
		/* the description */
334
		if (fprintf(fp, "/*%3d: %s at ", i->i_cfindex, i->i_name) < 0)
335
			return (1);
336
		for (v = 0; v < i->i_pvlen; v++)
337
			if (fprintf(fp, "%s%s", v == 0 ? "" : "|",
338
			    i->i_parents[v]->i_name) < 0)
339
				return (1);
340
		if (v == 0 && fputs("root", fp) < 0)
341
			return (1);
342
		a = i->i_atattr;
343
		for (nv = a->a_locs, v = 0; nv != NULL; nv = nv->nv_next, v++)
344
			if (fprintf(fp, " %s %s",
345
			    nv->nv_name, i->i_locs[v]) < 0)
346
				return (1);
347
		if (fputs(" */\n", fp) < 0)
348
			return (-1);
349
350
		/* then the actual defining line */
351
		basename = i->i_base->d_name;
352
		attachment = i->i_atdeva->d_name;
353
		if (i->i_unit == STAR) {
354
			unit = i->i_base->d_umax;
355
			if (i->i_disable) {
356
				state = "DSTR";
357
			} else {
358
				state = "STAR";
359
			}
360
		} else {
361
			unit = i->i_unit;
362
			if (i->i_disable) {
363
				state = "DNRM";
364
			} else {
365
				state = "NORM";
366
			}
367
		}
368
		if (i->i_locoff >= 0) {
369
			(void)snprintf(locbuf, sizeof locbuf, "loc+%3d",
370
			    i->i_locoff);
371
			loc = locbuf;
372
		} else
373
			loc = "loc";
374
		if (fprintf(fp, "\
375
    {&%s_ca,%s&%s_cd,%s%2d, %s, %7s, %#4x, pv+%2d, %d, %4d},\n",
376
		    attachment, strlen(attachment) < 6 ? "\t\t" : "\t",
377
		    basename, strlen(basename) < 3 ? "\t\t" : "\t", unit,
378
		    state, loc, i->i_cfflags, i->i_pvoff, i->i_locnami,
379
		    unit) < 0)
380
			  return (1);
381
	}
382
	if (fprintf(fp, "    {0},\n    {0},\n    {0},\n    {0},\n") < 0)
383
		return (1);
384
	if (fprintf(fp, "    {0},\n    {0},\n    {0},\n    {0},\n") < 0)
385
		return (1);
386
	return (fputs("    {(struct cfattach *)-1}\n};\n", fp) < 0);
387
}
388
389
/*
390
 * Emit the table of potential roots.
391
 */
392
static int
393
emitroots(FILE *fp)
394
{
395
	struct devi **p, *i;
396
	int cnt = 0;
397
398
	if (fputs("\nshort cfroots[] = {\n", fp) < 0)
399
		return (1);
400
	for (p = packed; (i = *p) != NULL; p++) {
401
		if (i->i_at != NULL)
402
			continue;
403
		if (i->i_unit != 0 &&
404
		    (i->i_unit != STAR || i->i_base->d_umax != 0))
405
			warnx("warning: `%s at root' is not unit 0", i->i_name);
406
		if (fprintf(fp, "\t%2d /* %s */,\n",
407
		    i->i_cfindex, i->i_name) < 0)
408
			return (1);
409
		cnt++;
410
	}
411
	if (fputs("\t-1\n};\n", fp) < 0)
412
		return (1);
413
414
	return(fprintf(fp, "\nint cfroots_size = %d;\n", cnt+1) < 0);
415
}
416
417
/*
418
 * Emit pseudo-device initialization.
419
 */
420
static int
421
emitpseudo(FILE *fp)
422
{
423
	struct devi *i;
424
	struct devbase *d;
425
	int cnt = 0, umax;
426
427
	if (fputs("\n/* pseudo-devices */\n", fp) < 0)
428
		return (1);
429
	for (i = allpseudo; i != NULL; i = i->i_next)
430
		if (fprintf(fp, "extern void %sattach(int);\n",
431
		    i->i_base->d_name) < 0)
432
			return (1);
433
	if (fputs("\nchar *pdevnames[] = {\n", fp) < 0)
434
		return (1);
435
	for (i = allpseudo; i != NULL; i = i->i_next) {
436
		d = i->i_base;
437
		if (fprintf(fp, "\t\"%s\",\n", d->d_name) < 0)
438
			return (1);
439
		cnt++;
440
	}
441
	if (fputs("};\n", fp) < 0)
442
		return (1);
443
	if (fprintf(fp, "\nint pdevnames_size = %d;\n", cnt) < 0)
444
		return (1);
445
	if (fputs("\nstruct pdevinit pdevinit[] = {\n", fp) < 0)
446
		return (1);
447
	for (i = allpseudo; i != NULL; i = i->i_next) {
448
		d = i->i_base;
449
		umax = d->d_umax;
450
		if (i->i_disable)
451
		    umax*=-1;
452
		if (fprintf(fp, "\t{ %sattach, %d },\n",
453
		    d->d_name, umax) < 0)
454
			return (1);
455
	}
456
	return (fputs("\t{ NULL, 0 }\n};\n", fp) < 0);
457
}