157491Storek /* 257491Storek * Copyright (c) 1992 The Regents of the University of California. 357491Storek * 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*59881Storek * @(#)mkioconf.c 5.5 (Berkeley) 05/10/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 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 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 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 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 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 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 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 } 250*59881Storek return (fputs("\t{0}\n};\n", fp) < 0); 25157491Storek } 25257491Storek 25357491Storek /* 25457491Storek * Emit the table of potential roots. 25557491Storek */ 25657491Storek static int 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 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 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 * 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