1 /* $NetBSD: mkioconf.c,v 1.13 2009/01/20 18:20:48 drochner Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratories.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * from: @(#)mkioconf.c 8.1 (Berkeley) 6/6/93
43 #if HAVE_NBTOOL_CONFIG_H
44 #include "nbtool_config.h"
47 #include <sys/param.h>
58 static int cf_locators_print(const char *, void *, void *);
59 static int cforder(const void *, const void *);
60 static void emitcfdata(FILE *);
61 static void emitcfdrivers(FILE *);
62 static void emitexterns(FILE *);
63 static void emitcfattachinit(FILE *);
64 static void emithdr(FILE *);
65 static void emitloc(FILE *);
66 static void emitpseudo(FILE *);
67 static void emitparents(FILE *);
68 static void emitroots(FILE *);
69 static void emitname2blk(FILE *);
71 #define SEP(pos, max) (((u_int)(pos) % (max)) == 0 ? "\n\t" : " ")
73 #define ARRNAME(n, l) (strchr((n), ARRCHR) && strncmp((n), (l), strlen((l))) == 0)
76 * NEWLINE can only be used in the emitXXX functions.
77 * In most cases it can be subsumed into an fprintf.
79 #define NEWLINE putc('\n', fp)
86 qsort(packed
, npacked
, sizeof *packed
, cforder
);
87 if ((fp
= fopen("ioconf.c.tmp", "w")) == NULL
) {
88 warn("cannot write ioconf.c");
106 warn("error writing ioconf.c");
109 (void)unlink("ioconf.c.tmp");
115 if (moveifchanged("ioconf.c.tmp", "ioconf.c") != 0) {
116 warn("error renaming ioconf.c");
123 cforder(const void *a
, const void *b
)
127 n1
= (*(const struct devi
* const *)a
)->i_cfindex
;
128 n2
= (*(const struct devi
* const *)b
)->i_cfindex
;
137 char ifnbuf
[200], buf
[BUFSIZ
];
140 autogen_comment(ofp
, "ioconf.c");
142 (void)snprintf(ifnbuf
, sizeof(ifnbuf
), "arch/%s/conf/ioconf.incl.%s",
144 ifn
= sourcepath(ifnbuf
);
145 if ((ifp
= fopen(ifn
, "r")) != NULL
) {
146 while ((n
= fread(buf
, 1, sizeof(buf
), ifp
)) > 0)
147 (void)fwrite(buf
, 1, n
, ofp
);
149 err(EXIT_FAILURE
, "error reading %s", ifn
);
152 fputs("#include <sys/param.h>\n"
153 "#include <sys/conf.h>\n"
154 "#include <sys/device.h>\n"
155 "#include <sys/mount.h>\n", ofp
);
161 * Emit an initialized array of character strings describing this
162 * attribute's locators.
165 cf_locators_print(const char *name
, void *value
, void *arg
)
177 "static const struct cfiattrdata %scf_iattrdata = {\n",
179 fprintf(fp
, "\t\"%s\", %d,\n\t{\n", name
, a
->a_loclen
);
180 for (nv
= a
->a_locs
; nv
; nv
= nv
->nv_next
)
181 fprintf(fp
, "\t\t{ \"%s\", \"%s\", %s },\n",
183 (nv
->nv_str
? nv
->nv_str
: "NULL"),
184 (nv
->nv_str
? nv
->nv_str
: "0"));
185 fprintf(fp
, "\t}\n};\n");
188 "static const struct cfiattrdata %scf_iattrdata = {\n"
189 "\t\"%s\", 0, {\n\t\t{ NULL, NULL, 0 },\n\t}\n};\n",
197 emitcfdrivers(FILE *fp
)
205 ht_enumerate(attrtab
, cf_locators_print
, fp
);
208 TAILQ_FOREACH(d
, &allbases
, d_next
) {
209 if (!devbase_has_instances(d
, WILD
))
212 for (nv
= d
->d_attrs
; nv
!= NULL
; nv
= nv
->nv_next
) {
218 "static const struct cfiattrdata * const %s_attrs[] = { ",
221 fprintf(fp
, "&%scf_iattrdata, ", a
->a_name
);
224 fprintf(fp
, "NULL };\n");
225 fprintf(fp
, "CFDRIVER_DECL(%s, %s, ", d
->d_name
, /* ) */
226 d
->d_classattr
!= NULL
? d
->d_classattr
->a_devclass
229 fprintf(fp
, "%s_attrs", d
->d_name
);
232 fprintf(fp
, /* ( */ ");\n\n");
236 fprintf(fp
, "struct cfdriver * const cfdriver_list_initial[] = {\n");
237 TAILQ_FOREACH(d
, &allbases
, d_next
) {
238 if (!devbase_has_instances(d
, WILD
))
240 fprintf(fp
, "\t&%s_cd,\n", d
->d_name
);
242 fprintf(fp
, "\tNULL\n};\n");
246 emitexterns(FILE *fp
)
251 TAILQ_FOREACH(da
, &alldevas
, d_next
) {
252 if (!deva_has_instances(da
, WILD
))
254 fprintf(fp
, "extern struct cfattach %s_ca;\n",
260 emitcfattachinit(FILE *fp
)
266 TAILQ_FOREACH(d
, &allbases
, d_next
) {
267 if (!devbase_has_instances(d
, WILD
))
269 if (d
->d_ahead
== NULL
)
273 "static struct cfattach * const %s_cfattachinit[] = {\n\t",
275 for (da
= d
->d_ahead
; da
!= NULL
; da
= da
->d_bsame
) {
276 if (!deva_has_instances(da
, WILD
))
278 fprintf(fp
, "&%s_ca, ", da
->d_name
);
280 fprintf(fp
, "NULL\n};\n");
284 fprintf(fp
, "const struct cfattachinit cfattachinit[] = {\n");
286 TAILQ_FOREACH(d
, &allbases
, d_next
) {
287 if (!devbase_has_instances(d
, WILD
))
289 if (d
->d_ahead
== NULL
)
292 fprintf(fp
, "\t{ \"%s\", %s_cfattachinit },\n",
293 d
->d_name
, d
->d_name
);
296 fprintf(fp
, "\t{ NULL, NULL }\n};\n");
304 if (locators
.used
!= 0) {
305 fprintf(fp
, "\n/* locators */\n"
306 "static int loc[%d] = {", locators
.used
);
307 for (i
= 0; i
< locators
.used
; i
++)
308 fprintf(fp
, "%s%s,", SEP(i
, 8), locators
.vec
[i
]);
309 fprintf(fp
, "\n};\n");
310 } else if (*packed
!= NULL
) {
311 /* We need to have *something*. */
312 fprintf(fp
, "\n/* locators */\n"
313 "static int loc[1] = { -1 };\n");
318 * Emit static parent data.
321 emitparents(FILE *fp
)
326 TAILQ_FOREACH(p
, &allpspecs
, p_list
) {
327 if (p
->p_devs
== NULL
|| p
->p_active
!= DEVI_ACTIVE
)
330 "static const struct cfparent pspec%d = {\n", p
->p_inst
);
331 fprintf(fp
, "\t\"%s\", ", p
->p_iattr
->a_name
);
332 if (p
->p_atdev
!= NULL
) {
333 fprintf(fp
, "\"%s\", ", p
->p_atdev
->d_name
);
334 if (p
->p_atunit
== WILD
)
335 fprintf(fp
, "DVUNIT_ANY");
337 fprintf(fp
, "%d", p
->p_atunit
);
339 fprintf(fp
, "NULL, 0");
340 fprintf(fp
, "\n};\n");
345 * Emit the cfdata array.
353 const char *state
, *basename
, *attachment
;
358 const char *lastname
= "";
361 "#define NORM FSTATE_NOTFOUND\n"
362 "#define STAR FSTATE_STAR\n"
364 "struct cfdata cfdata[] = {\n"
365 " /* driver attachment unit state "
366 "loc flags pspec */\n");
367 for (p
= packed
; (i
= *p
) != NULL
; p
++) {
368 /* the description */
369 fprintf(fp
, "/*%3d: %s at ", i
->i_cfindex
, i
->i_name
);
370 if ((ps
= i
->i_pspec
) != NULL
) {
371 if (ps
->p_atdev
!= NULL
&&
372 ps
->p_atunit
!= WILD
) {
373 fprintf(fp
, "%s%d", ps
->p_atdev
->d_name
,
375 } else if (ps
->p_atdev
!= NULL
) {
376 fprintf(fp
, "%s?", ps
->p_atdev
->d_name
);
378 fprintf(fp
, "%s?", ps
->p_iattr
->a_name
);
382 for (nv
= a
->a_locs
, v
= 0; nv
!= NULL
;
383 nv
= nv
->nv_next
, v
++) {
384 if (ARRNAME(nv
->nv_name
, lastname
)) {
385 fprintf(fp
, " %s %s",
386 nv
->nv_name
, i
->i_locs
[v
]);
388 fprintf(fp
, " %s %s",
391 lastname
= nv
->nv_name
;
401 /* then the actual defining line */
402 basename
= i
->i_base
->d_name
;
403 attachment
= i
->i_atdeva
->d_name
;
404 if (i
->i_unit
== STAR
) {
405 unit
= i
->i_base
->d_umax
;
411 if (i
->i_locoff
>= 0) {
412 (void)snprintf(locbuf
, sizeof(locbuf
), "loc+%3d",
417 fprintf(fp
, " { \"%s\",%s\"%s\",%s%2d, %s, %7s, %#6x, ",
418 basename
, strlen(basename
) < 8 ? "\t\t"
420 attachment
, strlen(attachment
) < 5 ? "\t\t"
422 unit
, state
, loc
, i
->i_cfflags
);
424 fprintf(fp
, "&pspec%d },\n", ps
->p_inst
);
426 fputs("NULL },\n", fp
);
428 fprintf(fp
, " { %s,%s%s,%s%2d, %s, %7s, %#6x, %s }\n};\n",
429 "NULL", "\t\t", "NULL", "\t\t", 0, "0", "NULL", 0, "NULL");
433 * Emit the table of potential roots.
440 fputs("\nconst short cfroots[] = {\n", fp
);
441 for (p
= packed
; (i
= *p
) != NULL
; p
++) {
444 if (i
->i_unit
!= 0 &&
445 (i
->i_unit
!= STAR
|| i
->i_base
->d_umax
!= 0))
446 warnx("warning: `%s at root' is not unit 0", i
->i_name
);
447 fprintf(fp
, "\t%2d /* %s */,\n",
448 i
->i_cfindex
, i
->i_name
);
450 fputs("\t-1\n};\n", fp
);
454 * Emit pseudo-device initialization.
462 fputs("\n/* pseudo-devices */\n", fp
);
463 TAILQ_FOREACH(i
, &allpseudo
, i_next
) {
464 fprintf(fp
, "void %sattach(int);\n",
467 fputs("\nstruct pdevinit pdevinit[] = {\n", fp
);
468 TAILQ_FOREACH(i
, &allpseudo
, i_next
) {
470 fprintf(fp
, "\t{ %sattach, %d },\n",
471 d
->d_name
, d
->d_umax
);
473 fputs("\t{ 0, 0 }\n};\n", fp
);
477 * Emit name to major block number table.
480 emitname2blk(FILE *fp
)
484 fputs("\n/* device name to major block number */\n", fp
);
486 fprintf(fp
, "struct devnametobdevmaj dev_name2blk[] = {\n");
488 TAILQ_FOREACH(dev
, &allbases
, d_next
) {
489 if (dev
->d_major
== NODEVMAJOR
)
492 fprintf(fp
, "\t{ \"%s\", %d },\n",
493 dev
->d_name
, dev
->d_major
);
495 fprintf(fp
, "\t{ NULL, 0 }\n};\n");