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