1 /* 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This software was developed by the Computer Systems Engineering group 6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7 * contributed to Berkeley. 8 * 9 * All advertising materials mentioning features or use of this software 10 * must display the following acknowledgement: 11 * This product includes software developed by the University of 12 * California, Lawrence Berkeley Laboratories. 13 * 14 * %sccs.include.redist.c% 15 * 16 * @(#)mkioconf.c 5.5 (Berkeley) 05/10/93 17 */ 18 19 #include <sys/param.h> 20 #include <errno.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include "config.h" 25 26 /* 27 * Make ioconf.c. 28 */ 29 static int cforder __P((const void *, const void *)); 30 static int emitcfdata __P((FILE *)); 31 static int emitexterns __P((FILE *)); 32 static int emithdr __P((FILE *)); 33 static int emitloc __P((FILE *)); 34 static int emitpseudo __P((FILE *)); 35 static int emitpv __P((FILE *)); 36 static int emitroots __P((FILE *)); 37 static int emitvec __P((FILE *)); 38 static char *vecname __P((char *, const char *, int)); 39 40 static const char *s_i386; 41 42 #define SEP(pos, max) (((u_int)(pos) % (max)) == 0 ? "\n\t" : " ") 43 44 /* 45 * NEWLINE can only be used in the emitXXX functions. 46 * In most cases it can be subsumed into an fprintf. 47 */ 48 #define NEWLINE if (putc('\n', fp) < 0) return (1) 49 50 int 51 mkioconf() 52 { 53 register FILE *fp; 54 register char *fname; 55 int v; 56 57 s_i386 = intern("i386"); 58 59 fname = path("ioconf.c"); 60 qsort(packed, npacked, sizeof *packed, cforder); 61 if ((fp = fopen(fname, "w")) == NULL) { 62 (void)fprintf(stderr, "config: cannot write %s: %s\n", 63 fname, strerror(errno)); 64 return (1); 65 } 66 v = emithdr(fp); 67 if (v != 0 || emitvec(fp) || emitexterns(fp) || emitloc(fp) || 68 emitpv(fp) || emitcfdata(fp) || emitroots(fp) || emitpseudo(fp)) { 69 if (v >= 0) 70 (void)fprintf(stderr, 71 "config: error writing %s: %s\n", 72 fname, strerror(errno)); 73 (void)fclose(fp); 74 /* (void)unlink(fname); */ 75 free(fname); 76 return (1); 77 } 78 (void)fclose(fp); 79 free(fname); 80 return (0); 81 } 82 83 static int 84 cforder(a, b) 85 const void *a, *b; 86 { 87 register int n1, n2; 88 89 n1 = (*(struct devi **)a)->i_cfindex; 90 n2 = (*(struct devi **)b)->i_cfindex; 91 return (n1 - n2); 92 } 93 94 static int 95 emithdr(ofp) 96 register FILE *ofp; 97 { 98 register FILE *ifp; 99 register int n; 100 char ifn[200], buf[BUFSIZ]; 101 102 if (fprintf(ofp, "\ 103 /*\n\ 104 * MACHINE GENERATED: DO NOT EDIT\n\ 105 *\n\ 106 * ioconf.c, from \"%s\"\n\ 107 */\n\n", conffile) < 0) 108 return (1); 109 (void)sprintf(ifn, "ioconf.incl.%s", machine); 110 if ((ifp = fopen(ifn, "r")) != NULL) { 111 while ((n = fread(buf, 1, sizeof(buf), ifp)) > 0) 112 if (fwrite(buf, 1, n, ofp) != n) 113 return (1); 114 if (ferror(ifp)) { 115 (void)fprintf(stderr, "config: error reading %s: %s\n", 116 ifn, strerror(errno)); 117 (void)fclose(ifp); 118 return (-1); 119 } 120 (void)fclose(ifp); 121 } else { 122 if (fputs("\ 123 #include <sys/param.h>\n\ 124 #include <sys/device.h>\n", ofp) < 0) 125 return (1); 126 } 127 return (0); 128 } 129 130 static int 131 emitexterns(fp) 132 register FILE *fp; 133 { 134 register struct devbase *d; 135 136 NEWLINE; 137 for (d = allbases; d != NULL; d = d->d_next) { 138 if (d->d_ihead == NULL) 139 continue; 140 if (fprintf(fp, "extern struct cfdriver %scd;\n", 141 d->d_name) < 0) 142 return (1); 143 } 144 NEWLINE; 145 return (0); 146 } 147 148 static int 149 emitloc(fp) 150 register FILE *fp; 151 { 152 register int i; 153 154 if (fprintf(fp, "\n/* locators */\n\ 155 static int loc[%d] = {", locators.used) < 0) 156 return (1); 157 for (i = 0; i < locators.used; i++) 158 if (fprintf(fp, "%s%s,", SEP(i, 8), locators.vec[i]) < 0) 159 return (1); 160 return (fprintf(fp, "\n};\n") < 0); 161 } 162 163 /* 164 * Emit global parents-vector. 165 */ 166 static int 167 emitpv(fp) 168 register FILE *fp; 169 { 170 register int i; 171 172 if (fprintf(fp, "\n/* parent vectors */\n\ 173 static short pv[%d] = {", parents.used) < 0) 174 return (1); 175 for (i = 0; i < parents.used; i++) 176 if (fprintf(fp, "%s%d,", SEP(i, 16), parents.vec[i]) < 0) 177 return (1); 178 return (fprintf(fp, "\n};\n") < 0); 179 } 180 181 /* 182 * Emit the cfdata array. 183 */ 184 static int 185 emitcfdata(fp) 186 register FILE *fp; 187 { 188 register struct devi **p, *i, **par; 189 register int unit, v; 190 register const char *vs, *state, *basename; 191 register struct nvlist *nv; 192 register struct attr *a; 193 char *loc; 194 char locbuf[20]; 195 196 if (fprintf(fp, "\n\ 197 #define NORM FSTATE_NOTFOUND\n\ 198 #define STAR FSTATE_STAR\n\ 199 \n\ 200 struct cfdata cfdata[] = {\n\ 201 \t/* driver unit state loc flags parents ivstubs */\n") < 0) 202 return (1); 203 for (p = packed; (i = *p) != NULL; p++) { 204 /* the description */ 205 if (fprintf(fp, "/*%3d: %s at ", i->i_cfindex, i->i_name) < 0) 206 return (1); 207 par = i->i_parents; 208 for (v = 0; v < i->i_pvlen; v++) 209 if (fprintf(fp, "%s%s", v == 0 ? "" : "|", 210 i->i_parents[v]->i_name) < 0) 211 return (1); 212 if (v == 0 && fputs("root", fp) < 0) 213 return (1); 214 a = i->i_atattr; 215 nv = a->a_locs; 216 for (nv = a->a_locs, v = 0; nv != NULL; nv = nv->nv_next, v++) 217 if (fprintf(fp, " %s %s", 218 nv->nv_name, i->i_locs[v]) < 0) 219 return (1); 220 if (fputs(" */\n", fp) < 0) 221 return (-1); 222 223 /* then the actual defining line */ 224 basename = i->i_base->d_name; 225 if (i->i_unit == STAR) { 226 unit = i->i_base->d_umax; 227 state = "STAR"; 228 } else { 229 unit = i->i_unit; 230 state = "NORM"; 231 } 232 if (i->i_ivoff < 0) { 233 vs = ""; 234 v = 0; 235 } else { 236 vs = "vec+"; 237 v = i->i_ivoff; 238 } 239 if (i->i_locoff >= 0) { 240 (void)sprintf(locbuf, "loc+%3d", i->i_locoff); 241 loc = locbuf; 242 } else 243 loc = "loc"; 244 if (fprintf(fp, "\ 245 \t{&%scd,%s%2d, %s, %7s, %#6x, pv+%2d, %s%d},\n", 246 basename, strlen(basename) < 3 ? "\t\t" : "\t", unit, 247 state, loc, i->i_cfflags, i->i_pvoff, vs, v) < 0) 248 return (1); 249 } 250 return (fputs("\t{0}\n};\n", fp) < 0); 251 } 252 253 /* 254 * Emit the table of potential roots. 255 */ 256 static int 257 emitroots(fp) 258 register FILE *fp; 259 { 260 register struct devi **p, *i; 261 262 if (fputs("\nshort cfroots[] = {\n", fp) < 0) 263 return (1); 264 for (p = packed; (i = *p) != NULL; p++) { 265 if (i->i_at != NULL) 266 continue; 267 if (i->i_unit != 0 && 268 (i->i_unit != STAR || i->i_base->d_umax != 0)) 269 (void)fprintf(stderr, 270 "config: warning: `%s at root' is not unit 0\n", 271 i->i_name); 272 if (fprintf(fp, "\t%2d /* %s */,\n", 273 i->i_cfindex, i->i_name) < 0) 274 return (1); 275 } 276 return (fputs("\t-1\n};\n", fp) < 0); 277 } 278 279 /* 280 * Emit pseudo-device initialization. 281 */ 282 static int 283 emitpseudo(fp) 284 register FILE *fp; 285 { 286 register struct devi *i; 287 register struct devbase *d; 288 289 if (fputs("\n/* pseudo-devices */\n", fp) < 0) 290 return (1); 291 for (i = allpseudo; i != NULL; i = i->i_next) 292 if (fprintf(fp, "extern void %sattach __P((int));\n", 293 i->i_base->d_name) < 0) 294 return (1); 295 if (fputs("\nstruct pdevinit pdevinit[] = {\n", fp) < 0) 296 return (1); 297 for (i = allpseudo; i != NULL; i = i->i_next) { 298 d = i->i_base; 299 if (fprintf(fp, "\t{ %sattach, %d },\n", 300 d->d_name, d->d_umax) < 0) 301 return (1); 302 } 303 return (fputs("\t{ 0, 0 }\n};\n", fp) < 0); 304 } 305 306 /* 307 * Emit interrupt vector declarations, and calculate offsets. 308 */ 309 static int 310 emitvec(fp) 311 register FILE *fp; 312 { 313 register struct nvlist *head, *nv; 314 register struct devi **p, *i; 315 register int j, nvec, unit; 316 char buf[200]; 317 318 nvec = 0; 319 for (p = packed; (i = *p) != NULL; p++) { 320 if ((head = i->i_base->d_vectors) == NULL) 321 continue; 322 if ((unit = i->i_unit) == STAR) 323 panic("emitvec unit==STAR"); 324 if (nvec == 0) 325 NEWLINE; 326 for (j = 0, nv = head; nv != NULL; j++, nv = nv->nv_next) 327 if (fprintf(fp, 328 "/* IVEC %s %d */ extern void %s();\n", 329 nv->nv_name, unit, 330 vecname(buf, nv->nv_name, unit)) < 0) 331 return (1); 332 nvec += j + 1; 333 } 334 if (nvec == 0) 335 return (0); 336 if (fprintf(fp, "\nstatic void (*vec[%d]) __P((void)) = {", nvec) < 0) 337 return (1); 338 nvec = 0; 339 for (p = packed; (i = *p) != NULL; p++) { 340 if ((head = i->i_base->d_vectors) == NULL) 341 continue; 342 i->i_ivoff = nvec; 343 unit = i->i_unit; 344 for (nv = head; nv != NULL; nv = nv->nv_next) 345 if (fprintf(fp, "%s%s,", 346 SEP(nvec++, 4), 347 vecname(buf, nv->nv_name, unit)) < 0) 348 return (1); 349 if (fprintf(fp, "%s0,", SEP(nvec++, 4)) < 0) 350 return (1); 351 } 352 return (fputs("\n};\n", fp) < 0); 353 } 354 355 static char * 356 vecname(buf, name, unit) 357 char *buf; 358 const char *name; 359 int unit; 360 { 361 362 /* @#%* 386 uses a different name format */ 363 if (machine == s_i386) { 364 (void)sprintf(buf, "V%s%d", name, unit); 365 return (buf); 366 } 367 (void)sprintf(buf, "X%s%d", name, unit); 368 return (buf); 369 } 370