1*57487Storek /* 2*57487Storek * Copyright (c) 1992 The Regents of the University of California. 3*57487Storek * All rights reserved. 4*57487Storek * 5*57487Storek * This software was developed by the Computer Systems Engineering group 6*57487Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7*57487Storek * contributed to Berkeley. 8*57487Storek * 9*57487Storek * All advertising materials mentioning features or use of this software 10*57487Storek * must display the following acknowledgement: 11*57487Storek * This product includes software developed by the University of 12*57487Storek * California, Lawrence Berkeley Laboratories. 13*57487Storek * 14*57487Storek * %sccs.include.redist.c% 15*57487Storek * 16*57487Storek * @(#)config.h 5.1 (Berkeley) 01/12/93 17*57487Storek * 18*57487Storek * from: $Header: config.h,v 1.4 93/01/12 03:54:25 torek Exp $ 19*57487Storek */ 20*57487Storek 21*57487Storek /* 22*57487Storek * Name/value lists. Values can be strings or pointers and/or can carry 23*57487Storek * integers. The names can be NULL, resulting in simple value lists. 24*57487Storek */ 25*57487Storek struct nvlist { 26*57487Storek struct nvlist *nv_next; 27*57487Storek const char *nv_name; 28*57487Storek union { 29*57487Storek const char *un_str; 30*57487Storek void *un_ptr; 31*57487Storek } nv_un; 32*57487Storek #define nv_str nv_un.un_str 33*57487Storek #define nv_ptr nv_un.un_ptr 34*57487Storek int nv_int; 35*57487Storek }; 36*57487Storek 37*57487Storek /* 38*57487Storek * Kernel configurations. 39*57487Storek */ 40*57487Storek struct config { 41*57487Storek struct config *cf_next; /* linked list */ 42*57487Storek const char *cf_name; /* "vmunix" */ 43*57487Storek int cf_lineno; /* source line */ 44*57487Storek struct nvlist *cf_root; /* "root on ra0a" */ 45*57487Storek struct nvlist *cf_swap; /* "swap on ra0b and ra1b" */ 46*57487Storek struct nvlist *cf_dump; /* "dumps on ra0b" */ 47*57487Storek }; 48*57487Storek 49*57487Storek /* 50*57487Storek * Attributes. These come in two flavors: "plain" and "interface". 51*57487Storek * Plain attributes (e.g., "ether") simply serve to pull in files. 52*57487Storek * Interface attributes (e.g., "scsi") carry three lists: locators, 53*57487Storek * child devices, and references. The locators are those things 54*57487Storek * that must be specified in order to configure a device instance 55*57487Storek * using this attribute (e.g., "tg0 at scsi0"). The a_devs field 56*57487Storek * lists child devices that can connect here (e.g., "tg"s), while 57*57487Storek * the a_refs are parents that carry the attribute (e.g., actual 58*57487Storek * SCSI host adapter drivers such as the SPARC "esp"). 59*57487Storek */ 60*57487Storek struct attr { 61*57487Storek const char *a_name; /* name of this attribute */ 62*57487Storek int a_iattr; /* true => allows children */ 63*57487Storek struct nvlist *a_locs; /* locators required */ 64*57487Storek int a_loclen; /* length of above list */ 65*57487Storek struct nvlist *a_devs; /* children */ 66*57487Storek struct nvlist *a_refs; /* parents */ 67*57487Storek }; 68*57487Storek 69*57487Storek /* 70*57487Storek * The "base" part of a device ("uba", "sd"; but not "uba2" or 71*57487Storek * "sd0"). It may be found "at" one or more attributes, including 72*57487Storek * "at root" (this is represented by a NULL attribute). 73*57487Storek * 74*57487Storek * Each device may also export attributes. If any provide an output 75*57487Storek * interface (e.g., "esp" provides "scsi"), other devices (e.g., 76*57487Storek * "tg"s) can be found at instances of this one (e.g., "esp"s). 77*57487Storek * Such a connection must provide locators as specified by that 78*57487Storek * interface attribute (e.g., "target"). 79*57487Storek * 80*57487Storek * Each base carries a list of instances (via d_ihead). Note that this 81*57487Storek * list "skips over" aliases; those must be found through the instances 82*57487Storek * themselves. 83*57487Storek */ 84*57487Storek struct devbase { 85*57487Storek const char *d_name; /* e.g., "sd" */ 86*57487Storek struct devbase *d_next; /* linked list */ 87*57487Storek int d_isdef; /* set once properly defined */ 88*57487Storek int d_ispseudo; /* is a pseudo-device */ 89*57487Storek int d_major; /* used for "root on sd0", e.g. */ 90*57487Storek struct nvlist *d_atlist; /* e.g., "at tg" (attr list) */ 91*57487Storek struct nvlist *d_vectors; /* interrupt vectors, if any */ 92*57487Storek struct nvlist *d_attrs; /* attributes, if any */ 93*57487Storek struct devi *d_ihead; /* first instance, if any */ 94*57487Storek struct devi **d_ipp; /* used for tacking on more instances */ 95*57487Storek int d_umax; /* highest unit number + 1 */ 96*57487Storek }; 97*57487Storek 98*57487Storek /* 99*57487Storek * An "instance" of a device. The same instance may be listed more 100*57487Storek * than once, e.g., "xx0 at isa? port FOO" + "xx0 at isa? port BAR". 101*57487Storek * 102*57487Storek * After everything has been read in and verified, the devi's are 103*57487Storek * "packed" to collect all the information needed to generate ioconf.c. 104*57487Storek * In particular, we try to collapse multiple aliases into a single entry. 105*57487Storek * We then assign each "primary" (non-collapsed) instance a cfdata index. 106*57487Storek * Note that there may still be aliases among these. 107*57487Storek */ 108*57487Storek struct devi { 109*57487Storek /* created while parsing config file */ 110*57487Storek const char *i_name; /* e.g., "sd0" */ 111*57487Storek int i_unit; /* unit from name, e.g., 0 */ 112*57487Storek struct devbase *i_base;/* e.g., pointer to "sd" base */ 113*57487Storek struct devi *i_next; /* list of all instances */ 114*57487Storek struct devi *i_bsame; /* list on same base */ 115*57487Storek struct devi *i_alias; /* other aliases of this instance */ 116*57487Storek const char *i_at; /* where this is "at" (NULL if at root) */ 117*57487Storek struct attr *i_atattr; /* attr that allowed attach */ 118*57487Storek struct devbase *i_atdev;/* dev if "at <devname><unit>", else NULL */ 119*57487Storek const char **i_locs; /* locators (as given by i_atattr) */ 120*57487Storek int i_atunit; /* unit from "at" */ 121*57487Storek int i_cfflags; /* flags from config line */ 122*57487Storek int i_lineno; /* line # in config, for later errors */ 123*57487Storek 124*57487Storek /* created during packing or ioconf.c generation */ 125*57487Storek /* i_loclen via i_atattr->a_loclen */ 126*57487Storek short i_collapsed; /* set => this alias no longer needed */ 127*57487Storek short i_cfindex; /* our index in cfdata */ 128*57487Storek short i_pvlen; /* number of parents */ 129*57487Storek short i_pvoff; /* offset in parents.vec */ 130*57487Storek short i_locoff; /* offset in locators.vec */ 131*57487Storek short i_ivoff; /* offset in interrupt vectors, if any */ 132*57487Storek struct devi **i_parents;/* the parents themselves */ 133*57487Storek 134*57487Storek }; 135*57487Storek /* special units */ 136*57487Storek #define STAR (-1) /* unit number for, e.g., "sd*" */ 137*57487Storek #define WILD (-2) /* unit number for, e.g., "sd?" */ 138*57487Storek 139*57487Storek /* 140*57487Storek * Files. Each file is either standard (always included) or optional, 141*57487Storek * depending on whether it has names on which to *be* optional. 142*57487Storek */ 143*57487Storek struct files { 144*57487Storek struct files *fi_next; /* linked list */ 145*57487Storek const char *fi_srcfile; /* the name of the "files" file that got us */ 146*57487Storek u_short fi_srcline; /* and the line number */ 147*57487Storek u_char fi_flags; /* as below */ 148*57487Storek char fi_lastc; /* last char from path */ 149*57487Storek const char *fi_path; /* full file path */ 150*57487Storek const char *fi_tail; /* name, i.e., rindex(fi_path, '/') + 1 */ 151*57487Storek const char *fi_base; /* tail minus ".c" (or whatever) */ 152*57487Storek struct nvlist *fi_opt; /* optional on ... */ 153*57487Storek const char *fi_mkrule; /* special make rule, if any */ 154*57487Storek }; 155*57487Storek 156*57487Storek /* flags */ 157*57487Storek #define FI_SEL 0x01 /* selected */ 158*57487Storek #define FI_CONFIGDEP 0x02 /* config-dependent */ 159*57487Storek #define FI_DRIVER 0x04 /* device-driver */ 160*57487Storek #define FI_NEEDSCOUNT 0x08 /* needs-count */ 161*57487Storek #define FI_NEEDSFLAG 0x10 /* needs-flag */ 162*57487Storek #define FI_HIDDEN 0x20 /* obscured by other(s), base names overlap */ 163*57487Storek 164*57487Storek /* 165*57487Storek * Hash tables look up name=value pairs. The pointer value of the name 166*57487Storek * is assumed to be constant forever; this can be arranged by interning 167*57487Storek * the name. (This is fairly convenient since our lexer does this for 168*57487Storek * all identifier-like strings---it has to save them anyway, lest yacc's 169*57487Storek * look-ahead wipe out the current one.) 170*57487Storek */ 171*57487Storek struct hashtab; 172*57487Storek 173*57487Storek const char *conffile; /* source file, e.g., "GENERIC.sparc" */ 174*57487Storek const char *confdirbase; /* basename of compile directory, usu. same */ 175*57487Storek const char *machine; /* machine type, e.g., "sparc" */ 176*57487Storek int errors; /* counts calls to error() */ 177*57487Storek int minmaxusers; /* minimum "maxusers" parameter */ 178*57487Storek int defmaxusers; /* default "maxusers" parameter */ 179*57487Storek int maxmaxusers; /* default "maxusers" parameter */ 180*57487Storek int maxusers; /* configuration's "maxusers" parameter */ 181*57487Storek struct nvlist *options; /* options */ 182*57487Storek struct nvlist *mkoptions; /* makeoptions */ 183*57487Storek struct hashtab *devbasetab; /* devbase lookup */ 184*57487Storek struct hashtab *selecttab; /* selects things that are "optional foo" */ 185*57487Storek struct hashtab *needcnttab; /* retains names marked "needs-count" */ 186*57487Storek 187*57487Storek struct devbase *allbases; /* list of all devbase structures */ 188*57487Storek struct config *allcf; /* list of configured kernels */ 189*57487Storek struct devi *alldevi; /* list of all instances */ 190*57487Storek struct devi *allpseudo; /* list of all pseudo-devices */ 191*57487Storek int ndevi; /* number of devi's (before packing) */ 192*57487Storek int npseudo; /* number of pseudo's */ 193*57487Storek 194*57487Storek struct files *allfiles; /* list of all kernel source files */ 195*57487Storek 196*57487Storek struct devi **packed; /* arrayified table for packed devi's */ 197*57487Storek int npacked; /* size of packed table, <= ndevi */ 198*57487Storek 199*57487Storek struct { /* pv[] table for config */ 200*57487Storek short *vec; 201*57487Storek int used; 202*57487Storek } parents; 203*57487Storek struct { /* loc[] table for config */ 204*57487Storek const char **vec; 205*57487Storek int used; 206*57487Storek } locators; 207*57487Storek 208*57487Storek /* files.c */ 209*57487Storek void initfiles __P((void)); 210*57487Storek void checkfiles __P((void)); 211*57487Storek int fixfiles __P((void)); /* finalize */ 212*57487Storek void addfile __P((const char *, struct nvlist *, int, const char *)); 213*57487Storek 214*57487Storek /* hash.c */ 215*57487Storek struct hashtab *ht_new __P((void)); 216*57487Storek int ht_insrep __P((struct hashtab *, const char *, void *, int)); 217*57487Storek #define ht_insert(ht, nam, val) ht_insrep(ht, nam, val, 0) 218*57487Storek #define ht_replace(ht, nam, val) ht_insrep(ht, nam, val, 1) 219*57487Storek void *ht_lookup __P((struct hashtab *, const char *)); 220*57487Storek void initintern __P((void)); 221*57487Storek const char *intern __P((const char *)); 222*57487Storek 223*57487Storek /* main.c */ 224*57487Storek void addoption __P((const char *name, const char *value)); 225*57487Storek void addmkoption __P((const char *name, const char *value)); 226*57487Storek 227*57487Storek /* mkheaders.c */ 228*57487Storek int mkheaders __P((void)); 229*57487Storek 230*57487Storek /* mkioconf.c */ 231*57487Storek int mkioconf __P((void)); 232*57487Storek 233*57487Storek /* mkmakefile.c */ 234*57487Storek int mkmakefile __P((void)); 235*57487Storek 236*57487Storek /* mkswap.c */ 237*57487Storek int mkswap __P((void)); 238*57487Storek 239*57487Storek /* pack.c */ 240*57487Storek void pack __P((void)); 241*57487Storek 242*57487Storek /* scan.l */ 243*57487Storek int currentline __P((void)); 244*57487Storek 245*57487Storek /* sem.c, other than for yacc actions */ 246*57487Storek void initsem __P((void)); 247*57487Storek 248*57487Storek /* util.c */ 249*57487Storek void *emalloc __P((size_t)); 250*57487Storek void *erealloc __P((void *, size_t)); 251*57487Storek char *path __P((const char *)); 252*57487Storek void error __P((const char *, ...)); /* immediate errs */ 253*57487Storek void xerror __P((const char *, int, const char *, ...)); /* delayed errs */ 254*57487Storek __dead void panic __P((const char *, ...)); 255*57487Storek struct nvlist *newnv __P((const char *, const char *, void *, int)); 256*57487Storek void nvfree __P((struct nvlist *)); 257*57487Storek void nvfreel __P((struct nvlist *)); 258