157491Storek /*
2*61818Sbostic * Copyright (c) 1992, 1993
3*61818Sbostic * The Regents of the University of California. All rights reserved.
457491Storek *
557491Storek * This software was developed by the Computer Systems Engineering group
657491Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
757491Storek * contributed to Berkeley.
857491Storek *
957491Storek * All advertising materials mentioning features or use of this software
1057491Storek * must display the following acknowledgement:
1157491Storek * This product includes software developed by the University of
1257491Storek * California, Lawrence Berkeley Laboratories.
1357491Storek *
1457491Storek * %sccs.include.redist.c%
1557491Storek *
16*61818Sbostic * @(#)mkioconf.c 8.1 (Berkeley) 06/06/93
1757491Storek */
1857491Storek
1957491Storek #include <sys/param.h>
2057491Storek #include <errno.h>
2157491Storek #include <stdio.h>
2257491Storek #include <stdlib.h>
2357491Storek #include <string.h>
2457491Storek #include "config.h"
2557491Storek
2657491Storek /*
2757491Storek * Make ioconf.c.
2857491Storek */
2957491Storek static int cforder __P((const void *, const void *));
3057491Storek static int emitcfdata __P((FILE *));
3157491Storek static int emitexterns __P((FILE *));
3257491Storek static int emithdr __P((FILE *));
3357491Storek static int emitloc __P((FILE *));
3457491Storek static int emitpseudo __P((FILE *));
3557491Storek static int emitpv __P((FILE *));
3657491Storek static int emitroots __P((FILE *));
3757491Storek static int emitvec __P((FILE *));
3857491Storek static char *vecname __P((char *, const char *, int));
3957491Storek
4057491Storek static const char *s_i386;
4157491Storek
4257491Storek #define SEP(pos, max) (((u_int)(pos) % (max)) == 0 ? "\n\t" : " ")
4357491Storek
4457491Storek /*
4557491Storek * NEWLINE can only be used in the emitXXX functions.
4657491Storek * In most cases it can be subsumed into an fprintf.
4757491Storek */
4857491Storek #define NEWLINE if (putc('\n', fp) < 0) return (1)
4957491Storek
5057491Storek int
mkioconf()5157491Storek mkioconf()
5257491Storek {
5357491Storek register FILE *fp;
5457491Storek register char *fname;
5557491Storek int v;
5657491Storek
5757491Storek s_i386 = intern("i386");
5857491Storek
5957491Storek fname = path("ioconf.c");
6057491Storek qsort(packed, npacked, sizeof *packed, cforder);
6157491Storek if ((fp = fopen(fname, "w")) == NULL) {
6257491Storek (void)fprintf(stderr, "config: cannot write %s: %s\n",
6357491Storek fname, strerror(errno));
6457491Storek return (1);
6557491Storek }
6657491Storek v = emithdr(fp);
6757491Storek if (v != 0 || emitvec(fp) || emitexterns(fp) || emitloc(fp) ||
6857491Storek emitpv(fp) || emitcfdata(fp) || emitroots(fp) || emitpseudo(fp)) {
6957491Storek if (v >= 0)
7057491Storek (void)fprintf(stderr,
7157491Storek "config: error writing %s: %s\n",
7257491Storek fname, strerror(errno));
7357491Storek (void)fclose(fp);
7457491Storek /* (void)unlink(fname); */
7557491Storek free(fname);
7657491Storek return (1);
7757491Storek }
7857491Storek (void)fclose(fp);
7957491Storek free(fname);
8057491Storek return (0);
8157491Storek }
8257491Storek
8357491Storek static int
cforder(a,b)8457491Storek cforder(a, b)
8557491Storek const void *a, *b;
8657491Storek {
8757491Storek register int n1, n2;
8857491Storek
8957491Storek n1 = (*(struct devi **)a)->i_cfindex;
9057491Storek n2 = (*(struct devi **)b)->i_cfindex;
9157491Storek return (n1 - n2);
9257491Storek }
9357491Storek
9457491Storek static int
emithdr(ofp)9557491Storek emithdr(ofp)
9657491Storek register FILE *ofp;
9757491Storek {
9857491Storek register FILE *ifp;
9957491Storek register int n;
10057491Storek char ifn[200], buf[BUFSIZ];
10157491Storek
10257491Storek if (fprintf(ofp, "\
10357491Storek /*\n\
10457491Storek * MACHINE GENERATED: DO NOT EDIT\n\
10557491Storek *\n\
10657491Storek * ioconf.c, from \"%s\"\n\
10757491Storek */\n\n", conffile) < 0)
10857491Storek return (1);
10957491Storek (void)sprintf(ifn, "ioconf.incl.%s", machine);
11057491Storek if ((ifp = fopen(ifn, "r")) != NULL) {
11157491Storek while ((n = fread(buf, 1, sizeof(buf), ifp)) > 0)
11257491Storek if (fwrite(buf, 1, n, ofp) != n)
11357491Storek return (1);
11457491Storek if (ferror(ifp)) {
11557491Storek (void)fprintf(stderr, "config: error reading %s: %s\n",
11657491Storek ifn, strerror(errno));
11757491Storek (void)fclose(ifp);
11857491Storek return (-1);
11957491Storek }
12057491Storek (void)fclose(ifp);
12157491Storek } else {
12257491Storek if (fputs("\
12357491Storek #include <sys/param.h>\n\
12457491Storek #include <sys/device.h>\n", ofp) < 0)
12557491Storek return (1);
12657491Storek }
12757491Storek return (0);
12857491Storek }
12957491Storek
13057491Storek static int
emitexterns(fp)13157491Storek emitexterns(fp)
13257491Storek register FILE *fp;
13357491Storek {
13457491Storek register struct devbase *d;
13557491Storek
13657491Storek NEWLINE;
13757491Storek for (d = allbases; d != NULL; d = d->d_next) {
13857491Storek if (d->d_ihead == NULL)
13957491Storek continue;
14057491Storek if (fprintf(fp, "extern struct cfdriver %scd;\n",
14157491Storek d->d_name) < 0)
14257491Storek return (1);
14357491Storek }
14457491Storek NEWLINE;
14557491Storek return (0);
14657491Storek }
14757491Storek
14857491Storek static int
emitloc(fp)14957491Storek emitloc(fp)
15057491Storek register FILE *fp;
15157491Storek {
15257491Storek register int i;
15357491Storek
15457491Storek if (fprintf(fp, "\n/* locators */\n\
15557491Storek static int loc[%d] = {", locators.used) < 0)
15657491Storek return (1);
15757491Storek for (i = 0; i < locators.used; i++)
15857491Storek if (fprintf(fp, "%s%s,", SEP(i, 8), locators.vec[i]) < 0)
15957491Storek return (1);
16057491Storek return (fprintf(fp, "\n};\n") < 0);
16157491Storek }
16257491Storek
16357491Storek /*
16457491Storek * Emit global parents-vector.
16557491Storek */
16657491Storek static int
emitpv(fp)16757491Storek emitpv(fp)
16857491Storek register FILE *fp;
16957491Storek {
17057491Storek register int i;
17157491Storek
17257491Storek if (fprintf(fp, "\n/* parent vectors */\n\
17357491Storek static short pv[%d] = {", parents.used) < 0)
17457491Storek return (1);
17557491Storek for (i = 0; i < parents.used; i++)
17657491Storek if (fprintf(fp, "%s%d,", SEP(i, 16), parents.vec[i]) < 0)
17757491Storek return (1);
17857491Storek return (fprintf(fp, "\n};\n") < 0);
17957491Storek }
18057491Storek
18157491Storek /*
18257491Storek * Emit the cfdata array.
18357491Storek */
18457491Storek static int
emitcfdata(fp)18557491Storek emitcfdata(fp)
18657491Storek register FILE *fp;
18757491Storek {
18857491Storek register struct devi **p, *i, **par;
18957491Storek register int unit, v;
19057491Storek register const char *vs, *state, *basename;
19157491Storek register struct nvlist *nv;
19257491Storek register struct attr *a;
19357491Storek char *loc;
19457491Storek char locbuf[20];
19557491Storek
19657491Storek if (fprintf(fp, "\n\
19757491Storek #define NORM FSTATE_NOTFOUND\n\
19857491Storek #define STAR FSTATE_STAR\n\
19957491Storek \n\
20057491Storek struct cfdata cfdata[] = {\n\
20157491Storek \t/* driver unit state loc flags parents ivstubs */\n") < 0)
20257491Storek return (1);
20357491Storek for (p = packed; (i = *p) != NULL; p++) {
20457491Storek /* the description */
20557491Storek if (fprintf(fp, "/*%3d: %s at ", i->i_cfindex, i->i_name) < 0)
20657491Storek return (1);
20757491Storek par = i->i_parents;
20857491Storek for (v = 0; v < i->i_pvlen; v++)
20957491Storek if (fprintf(fp, "%s%s", v == 0 ? "" : "|",
21057491Storek i->i_parents[v]->i_name) < 0)
21157491Storek return (1);
21257491Storek if (v == 0 && fputs("root", fp) < 0)
21357491Storek return (1);
21457491Storek a = i->i_atattr;
21557491Storek nv = a->a_locs;
21657491Storek for (nv = a->a_locs, v = 0; nv != NULL; nv = nv->nv_next, v++)
21757491Storek if (fprintf(fp, " %s %s",
21857491Storek nv->nv_name, i->i_locs[v]) < 0)
21957491Storek return (1);
22057491Storek if (fputs(" */\n", fp) < 0)
22157491Storek return (-1);
22257491Storek
22357491Storek /* then the actual defining line */
22457491Storek basename = i->i_base->d_name;
22557491Storek if (i->i_unit == STAR) {
22657491Storek unit = i->i_base->d_umax;
22757491Storek state = "STAR";
22857491Storek } else {
22957491Storek unit = i->i_unit;
23057491Storek state = "NORM";
23157491Storek }
23257491Storek if (i->i_ivoff < 0) {
23357491Storek vs = "";
23457491Storek v = 0;
23557491Storek } else {
23657491Storek vs = "vec+";
23757491Storek v = i->i_ivoff;
23857491Storek }
23957491Storek if (i->i_locoff >= 0) {
24057491Storek (void)sprintf(locbuf, "loc+%3d", i->i_locoff);
24157491Storek loc = locbuf;
24257491Storek } else
24357491Storek loc = "loc";
24457491Storek if (fprintf(fp, "\
24557491Storek \t{&%scd,%s%2d, %s, %7s, %#6x, pv+%2d, %s%d},\n",
24657491Storek basename, strlen(basename) < 3 ? "\t\t" : "\t", unit,
24757491Storek state, loc, i->i_cfflags, i->i_pvoff, vs, v) < 0)
24857491Storek return (1);
24957491Storek }
25059881Storek return (fputs("\t{0}\n};\n", fp) < 0);
25157491Storek }
25257491Storek
25357491Storek /*
25457491Storek * Emit the table of potential roots.
25557491Storek */
25657491Storek static int
emitroots(fp)25757491Storek emitroots(fp)
25857491Storek register FILE *fp;
25957491Storek {
26057491Storek register struct devi **p, *i;
26157491Storek
26257491Storek if (fputs("\nshort cfroots[] = {\n", fp) < 0)
26357491Storek return (1);
26457491Storek for (p = packed; (i = *p) != NULL; p++) {
26557491Storek if (i->i_at != NULL)
26657491Storek continue;
26757491Storek if (i->i_unit != 0 &&
26857491Storek (i->i_unit != STAR || i->i_base->d_umax != 0))
26957491Storek (void)fprintf(stderr,
27057491Storek "config: warning: `%s at root' is not unit 0\n",
27157491Storek i->i_name);
27257491Storek if (fprintf(fp, "\t%2d /* %s */,\n",
27357491Storek i->i_cfindex, i->i_name) < 0)
27457491Storek return (1);
27557491Storek }
27657491Storek return (fputs("\t-1\n};\n", fp) < 0);
27757491Storek }
27857491Storek
27957491Storek /*
28057491Storek * Emit pseudo-device initialization.
28157491Storek */
28257491Storek static int
emitpseudo(fp)28357491Storek emitpseudo(fp)
28457491Storek register FILE *fp;
28557491Storek {
28657491Storek register struct devi *i;
28757491Storek register struct devbase *d;
28857491Storek
28959148Storek if (fputs("\n/* pseudo-devices */\n", fp) < 0)
29057491Storek return (1);
29157491Storek for (i = allpseudo; i != NULL; i = i->i_next)
29257491Storek if (fprintf(fp, "extern void %sattach __P((int));\n",
29357491Storek i->i_base->d_name) < 0)
29457491Storek return (1);
29557491Storek if (fputs("\nstruct pdevinit pdevinit[] = {\n", fp) < 0)
29657491Storek return (1);
29757491Storek for (i = allpseudo; i != NULL; i = i->i_next) {
29857491Storek d = i->i_base;
29957563Storek if (fprintf(fp, "\t{ %sattach, %d },\n",
30057491Storek d->d_name, d->d_umax) < 0)
30157491Storek return (1);
30257491Storek }
30359148Storek return (fputs("\t{ 0, 0 }\n};\n", fp) < 0);
30457491Storek }
30557491Storek
30657491Storek /*
30757491Storek * Emit interrupt vector declarations, and calculate offsets.
30857491Storek */
30957491Storek static int
emitvec(fp)31057491Storek emitvec(fp)
31157491Storek register FILE *fp;
31257491Storek {
31357491Storek register struct nvlist *head, *nv;
31457491Storek register struct devi **p, *i;
31557491Storek register int j, nvec, unit;
31657491Storek char buf[200];
31757491Storek
31857491Storek nvec = 0;
31957491Storek for (p = packed; (i = *p) != NULL; p++) {
32057491Storek if ((head = i->i_base->d_vectors) == NULL)
32157491Storek continue;
32257491Storek if ((unit = i->i_unit) == STAR)
32357491Storek panic("emitvec unit==STAR");
32457491Storek if (nvec == 0)
32557491Storek NEWLINE;
32657491Storek for (j = 0, nv = head; nv != NULL; j++, nv = nv->nv_next)
32757491Storek if (fprintf(fp,
32857491Storek "/* IVEC %s %d */ extern void %s();\n",
32957491Storek nv->nv_name, unit,
33057491Storek vecname(buf, nv->nv_name, unit)) < 0)
33157491Storek return (1);
33257491Storek nvec += j + 1;
33357491Storek }
33457491Storek if (nvec == 0)
33557491Storek return (0);
33657491Storek if (fprintf(fp, "\nstatic void (*vec[%d]) __P((void)) = {", nvec) < 0)
33757491Storek return (1);
33857491Storek nvec = 0;
33957491Storek for (p = packed; (i = *p) != NULL; p++) {
34057491Storek if ((head = i->i_base->d_vectors) == NULL)
34157491Storek continue;
34257491Storek i->i_ivoff = nvec;
34357491Storek unit = i->i_unit;
34457491Storek for (nv = head; nv != NULL; nv = nv->nv_next)
34557491Storek if (fprintf(fp, "%s%s,",
34657491Storek SEP(nvec++, 4),
34757491Storek vecname(buf, nv->nv_name, unit)) < 0)
34857491Storek return (1);
34957491Storek if (fprintf(fp, "%s0,", SEP(nvec++, 4)) < 0)
35057491Storek return (1);
35157491Storek }
35257491Storek return (fputs("\n};\n", fp) < 0);
35357491Storek }
35457491Storek
35557491Storek static char *
vecname(buf,name,unit)35657491Storek vecname(buf, name, unit)
35757491Storek char *buf;
35857491Storek const char *name;
35957491Storek int unit;
36057491Storek {
36157491Storek
36257491Storek /* @#%* 386 uses a different name format */
36357491Storek if (machine == s_i386) {
36457491Storek (void)sprintf(buf, "V%s%d", name, unit);
36557491Storek return (buf);
36657491Storek }
36757491Storek (void)sprintf(buf, "X%s%d", name, unit);
36857491Storek return (buf);
36957491Storek }
370