Index: usr.bin/config/defs.h =================================================================== RCS file: /cvsroot/src/usr.bin/config/defs.h,v retrieving revision 1.20 diff -d -p -u -u -r1.20 defs.h --- usr.bin/config/defs.h 13 Jan 2007 23:47:36 -0000 1.20 +++ usr.bin/config/defs.h 9 Jul 2007 20:52:31 -0000 @@ -258,9 +258,8 @@ struct devi { /* created during packing or ioconf.c generation */ short i_collapsed; /* set => this alias no longer needed */ short i_cfindex; /* our index in cfdata */ - short i_locoff; /* offset in locators.vec */ - }; + /* special units */ #define STAR (-1) /* unit number for, e.g., "sd*" */ #define WILD (-2) /* unit number for, e.g., "sd?" */ Index: usr.bin/config/mkheaders.c =================================================================== RCS file: /cvsroot/src/usr.bin/config/mkheaders.c,v retrieving revision 1.12 diff -d -p -u -u -r1.12 mkheaders.c --- usr.bin/config/mkheaders.c 12 May 2007 10:15:31 -0000 1.12 +++ usr.bin/config/mkheaders.c 9 Jul 2007 20:52:33 -0000 @@ -58,7 +58,6 @@ #include static int emitcnt(struct nvlist *); -static int emitlocs(void); static int emitopts(void); static int emitioconfh(void); static int emittime(void); @@ -95,7 +94,7 @@ mkheaders(void) return (1); } - if (emitopts() || emitlocs() || emitioconfh() || emittime()) + if (emitopts() || emitioconfh() || emittime()) return (1); return (0); @@ -337,34 +336,6 @@ locators_print(const char *name, void *v } /* - * Build the "locators.h" file with manifest constants for all potential - * locators in the configuration. Do this by enumerating the attribute - * hash table and emitting all the locators for each attribute. - */ -static int -emitlocs(void) -{ - char *tfname; - int rval; - FILE *tfp; - - tfname = "tmp_locators.h"; - if ((tfp = fopen(tfname, "w")) == NULL) - return (herr("open", tfname, NULL)); - - rval = ht_enumerate(attrtab, locators_print, tfp); - - fflush(tfp); - if (ferror(tfp)) - return (herr("writ", tfname, NULL)); - if (fclose(tfp) == EOF) - return (herr("clos", tfname, NULL)); - if (rval) - return (rval); - return (moveifchanged(tfname, "locators.h")); -} - -/* * Build the "ioconf.h" file with extern declarations for all configured * cfdrivers. */ Index: usr.bin/config/mkioconf.c =================================================================== RCS file: /cvsroot/src/usr.bin/config/mkioconf.c,v retrieving revision 1.9 diff -d -p -u -u -r1.9 mkioconf.c --- usr.bin/config/mkioconf.c 13 Jan 2007 23:47:36 -0000 1.9 +++ usr.bin/config/mkioconf.c 9 Jul 2007 20:52:33 -0000 @@ -62,16 +62,12 @@ static void emitcfdrivers(FILE *); static void emitexterns(FILE *); static void emitcfattachinit(FILE *); static void emithdr(FILE *); -static void emitloc(FILE *); +static void emitloc(struct devi *, FILE *); static void emitpseudo(FILE *); -static void emitparents(FILE *); -static void emitroots(FILE *); static void emitname2blk(FILE *); #define SEP(pos, max) (((u_int)(pos) % (max)) == 0 ? "\n\t" : " ") -#define ARRNAME(n, l) (strchr((n), ARRCHR) && strncmp((n), (l), strlen((l))) == 0) - /* * NEWLINE can only be used in the emitXXX functions. * In most cases it can be subsumed into an fprintf. @@ -93,10 +89,7 @@ mkioconf(void) emitcfdrivers(fp); emitexterns(fp); emitcfattachinit(fp); - emitloc(fp); - emitparents(fp); emitcfdata(fp); - emitroots(fp); emitpseudo(fp); if (!do_devsw) emitname2blk(fp); @@ -161,42 +154,6 @@ emithdr(FILE *ofp) free(ifn); } -/* - * Emit an initialized array of character strings describing this - * attribute's locators. - */ -static int -cf_locators_print(const char *name, void *value, void *arg) -{ - struct attr *a; - struct nvlist *nv; - FILE *fp = arg; - - a = value; - if (!a->a_iattr) - return (0); - - if (a->a_locs) { - fprintf(fp, - "static const struct cfiattrdata %scf_iattrdata = {\n", - name); - fprintf(fp, "\t\"%s\", %d,\n\t{\n", name, a->a_loclen); - for (nv = a->a_locs; nv; nv = nv->nv_next) - fprintf(fp, "\t\t{\"%s\", \"%s\", %s},\n", - nv->nv_name, - (nv->nv_str ? nv->nv_str : "NULL"), - (nv->nv_str ? nv->nv_str : "0")); - fprintf(fp, "\t}\n};\n"); - } else { - fprintf(fp, - "static const struct cfiattrdata %scf_iattrdata = {\n" - "\t\"%s\", 0, {\n\t\t{ NULL, NULL, 0 },\n\t}\n};\n", - name, name); - } - - return 0; -} - static void emitcfdrivers(FILE *fp) { @@ -206,9 +163,6 @@ emitcfdrivers(FILE *fp) int has_iattrs; NEWLINE; - ht_enumerate(attrtab, cf_locators_print, fp); - - NEWLINE; TAILQ_FOREACH(d, &allbases, d_next) { if (!devbase_has_instances(d, WILD)) continue; @@ -219,10 +173,10 @@ emitcfdrivers(FILE *fp) continue; if (has_iattrs == 0) fprintf(fp, - "static const struct cfiattrdata * const %s_attrs[] = { ", + "static const char * const %s_attrs[] = { ", d->d_name); has_iattrs = 1; - fprintf(fp, "&%scf_iattrdata, ", a->a_name); + fprintf(fp, "\"%s\", ", a->a_name); } if (has_iattrs) fprintf(fp, "NULL };\n"); @@ -300,160 +254,82 @@ emitcfattachinit(FILE *fp) fprintf(fp, "\t{ NULL, NULL }\n};\n"); } -static void -emitloc(FILE *fp) -{ - int i; - - if (locators.used != 0) { - fprintf(fp, "\n/* locators */\n" - "static int loc[%d] = {", locators.used); - for (i = 0; i < locators.used; i++) - fprintf(fp, "%s%s,", SEP(i, 8), locators.vec[i]); - fprintf(fp, "\n};\n"); - } else if (*packed != NULL) { - /* We need to have *something*. */ - fprintf(fp, "\n/* locators */\n" - "static int loc[1] = { -1 };\n"); - } -} - -/* - * Emit static parent data. - */ -static void -emitparents(FILE *fp) -{ - struct pspec *p; - - NEWLINE; - TAILQ_FOREACH(p, &allpspecs, p_list) { - if (p->p_devs == NULL || p->p_active != DEVI_ACTIVE) - continue; - fprintf(fp, - "static const struct cfparent pspec%d = {\n", p->p_inst); - fprintf(fp, "\t\"%s\", ", p->p_iattr->a_name); - if (p->p_atdev != NULL) { - fprintf(fp, "\"%s\", ", p->p_atdev->d_name); - if (p->p_atunit == WILD) - fprintf(fp, "DVUNIT_ANY"); - else - fprintf(fp, "%d", p->p_atunit); - } else - fprintf(fp, "NULL, 0"); - fprintf(fp, "\n};\n"); - } -} - /* * Emit the cfdata array. */ +#define Q "\\\"" + static void emitcfdata(FILE *fp) { struct devi **p, *i; struct pspec *ps; - int unit, v; - const char *state, *basename, *attachment; + int unit, v, clonable; + const char *basename, *attachment; struct nvlist *nv; struct attr *a; char *loc; char locbuf[20]; const char *lastname = ""; - fprintf(fp, "\n" - "#define NORM FSTATE_NOTFOUND\n" - "#define STAR FSTATE_STAR\n" - "\n" - "struct cfdata cfdata[] = {\n" - " /* driver attachment unit state " - "loc flags pspec */\n"); + /* + * XXX make this into a flat plist array in a separate file and + * XXX embed that into the kernel (and allow to edit it via bootprops + * XXX or userconf). + */ + fprintf(fp, "\n" "const char *resident_externalized_cfdata = \"[ \"\n"); for (p = packed; (i = *p) != NULL; p++) { - /* the description */ - fprintf(fp, "/*%3d: %s at ", i->i_cfindex, i->i_name); - if ((ps = i->i_pspec) != NULL) { - if (ps->p_atdev != NULL && - ps->p_atunit != WILD) { - fprintf(fp, "%s%d", ps->p_atdev->d_name, - ps->p_atunit); - } else if (ps->p_atdev != NULL) { - fprintf(fp, "%s?", ps->p_atdev->d_name); - } else { - fprintf(fp, "%s?", ps->p_iattr->a_name); - } - - a = ps->p_iattr; - for (nv = a->a_locs, v = 0; nv != NULL; - nv = nv->nv_next, v++) { - if (ARRNAME(nv->nv_name, lastname)) { - fprintf(fp, " %s %s", - nv->nv_name, i->i_locs[v]); - } else { - fprintf(fp, " %s %s", - nv->nv_name, - i->i_locs[v]); - lastname = nv->nv_name; - } - } - } else { - a = NULL; - fputs("root", fp); - } - - fputs(" */\n", fp); - - /* then the actual defining line */ + ps = i->i_pspec; basename = i->i_base->d_name; attachment = i->i_atdeva->d_name; + if (i->i_unit == STAR) { unit = i->i_base->d_umax; - state = "STAR"; + clonable = 1; } else { unit = i->i_unit; - state = "NORM"; + clonable = 0; } - if (i->i_locoff >= 0) { - (void)snprintf(locbuf, sizeof(locbuf), "loc+%3d", - i->i_locoff); - loc = locbuf; - } else - loc = "loc"; - fprintf(fp, " {\"%s\",%s\"%s\",%s%2d, %s, %7s, %#6x, ", - basename, strlen(basename) < 8 ? "\t\t" - : "\t", - attachment, strlen(attachment) < 5 ? "\t\t" - : "\t", - unit, state, loc, i->i_cfflags); - if (ps != NULL) - fprintf(fp, "&pspec%d},\n", ps->p_inst); - else - fputs("NULL},\n", fp); - } - fprintf(fp, " {%s,%s%s,%s%2d, %s, %7s, %#6x, %s}\n};\n", - "NULL", "\t\t", "NULL", "\t\t", 0, "0", "NULL", 0, "NULL"); -} -/* - * Emit the table of potential roots. - */ -static void -emitroots(FILE *fp) -{ - struct devi **p, *i; + fprintf(fp, "/*%3d*/\t\"{ ", i->i_cfindex); + fprintf(fp, "driver %s%s%s ", Q, basename, Q); + fprintf(fp, "attachment %s%s%s ", Q, attachment, Q); + fprintf(fp, "unit #%x ", unit); + fprintf(fp, "clonable %s ", (clonable ? "Yes" : "No")); - fputs("\nconst short cfroots[] = {\n", fp); - for (p = packed; (i = *p) != NULL; p++) { - if (i->i_at != NULL) - continue; - if (i->i_unit != 0 && - (i->i_unit != STAR || i->i_base->d_umax != 0)) - warnx("warning: `%s at root' is not unit 0", i->i_name); - fprintf(fp, "\t%2d /* %s */,\n", - i->i_cfindex, i->i_name); + fprintf(fp, "\"\n\t\" "); + + fprintf(fp, "flags #%x ", i->i_cfflags); + if (ps) { + /* + * Note that if 'attribute' is missing, the instance + * is possible root node. Autoconf(9) relies on this + * behaviour. + */ + fprintf(fp, "attribute %s%s%s ", + Q, ps->p_iattr->a_name, Q); + + if (ps->p_atdev) + fprintf(fp, "parent-driver %s%s%s ", + Q, ps->p_atdev->d_name, Q); + + if (ps->p_atunit != WILD) + fprintf(fp, "parent-unit #%x ", ps->p_atunit); + + emitloc(i, fp); + } + + fputs("\"\n\t\"} \"", fp); + if (ps == NULL) + fputs("\t /* Possible root device */", fp); + + NEWLINE; } - fputs("\t-1\n};\n", fp); + fputs("\"]\";\n", fp); } +#undef Q + /* * Emit pseudo-device initialization. */ @@ -498,3 +374,38 @@ emitname2blk(FILE *fp) } fprintf(fp, "\t{ NULL, 0 }\n};\n"); } + +/* + * Emit locators into instance's cfdata entry. + */ +static void +emitloc(struct devi *i, FILE *fp) +{ + struct nvlist *nv; + struct attr *a; + const char *s; + int v; + + /* + * XXX we're hardcoding SCN format and we do silly dance + * XXX about hexa integers... + */ + a = i->i_pspec->p_iattr; + fputs("\"\n\t\" locators { ", fp); + + for (nv = a->a_locs, v = 0; nv != NULL; nv = nv->nv_next, v++) { + if (strcmp(nv->nv_str, i->i_locs[v]) == 0) + continue; + + fputs(nv->nv_name, fp); /* locator name */ + fputs(" ", fp); + + s = i->i_locs[v]; + if (*s++ == '0' && *s++ == 'x') + fprintf(fp, "#%s ", s); + else + fprintf(fp, "%s ", i->i_locs[v]); + } + + fputs("} ", fp); +} Index: usr.bin/config/pack.c =================================================================== RCS file: /cvsroot/src/usr.bin/config/pack.c,v retrieving revision 1.5 diff -d -p -u -u -r1.5 pack.c --- usr.bin/config/pack.c 13 Jan 2007 23:47:36 -0000 1.5 +++ usr.bin/config/pack.c 9 Jul 2007 20:52:33 -0000 @@ -50,90 +50,13 @@ #include #include "defs.h" -/* - * Packing. We have three separate kinds of packing here. - * - * First, we pack device instances which have identical parent specs. - * - * Second, we pack locators. Given something like - * - * hp0 at mba0 drive 0 - * hp* at mba* drive ? - * ht0 at mba0 drive 0 - * tu0 at ht0 slave 0 - * ht* at mba* drive ? - * tu* at ht* slave ? - * - * (where the default drive and slave numbers are -1), we have three - * locators whose value is 0 and three whose value is -1. Rather than - * emitting six integers, we emit just two. - * - * When packing locators, we would like to find sequences such as - * {1 2 3} {2 3 4} {3} {4 5} - * and turn this into the flat sequence {1 2 3 4 5}, with each subsequence - * given by the appropriate offset (here 0, 1, 2, and 3 respectively). - * Non-overlapping packing is much easier, and so we use that here - * and miss out on the chance to squeeze the locator sequence optimally. - * (So it goes.) - */ - -typedef int (*vec_cmp_func)(const void *, int, int); - -#define TAILHSIZE 128 -#define PVHASH(i) ((i) & (TAILHSIZE - 1)) -#define LOCHASH(l) (((long)(l) >> 2) & (TAILHSIZE - 1)) -struct tails { - struct tails *t_next; - int t_ends_at; -}; - -static struct tails *tails[TAILHSIZE]; -static int locspace; - -static void packdevi(void); -static void packlocs(void); - static int sameas(struct devi *, struct devi *); -static int findvec(const void *, int, int, vec_cmp_func, int); -static int samelocs(const void *, int, int); -static int addlocs(const char **, int); -static int loclencmp(const void *, const void *); -static void resettails(void); - -void -pack(void) -{ - struct pspec *p; - struct devi *i; - - /* Pack instances and make parent vectors. */ - packdevi(); - - /* - * Now that we know what we have, find upper limits on space - * needed for the loc[] table. The loc table size is bounded by - * what we would get if no packing occurred. - */ - locspace = 0; - TAILQ_FOREACH(i, &alldevi, i_next) { - if (!i->i_active == DEVI_ACTIVE || i->i_collapsed) - continue; - if ((p = i->i_pspec) == NULL) - continue; - locspace += p->p_iattr->a_loclen; - } - - /* Allocate and pack loc[]. */ - locators.vec = ecalloc((size_t)locspace, sizeof(*locators.vec)); - locators.used = 0; - packlocs(); -} /* * Pack device instances together wherever possible. */ void -packdevi(void) +pack(void) { struct devi *firststar, *i, **ip, *l, *p; struct devbase *d; @@ -189,7 +112,6 @@ packdevi(void) for (l = i; l != NULL; l = l->i_alias) { if (l->i_active != DEVI_ACTIVE) continue; - l->i_locoff = -1; /* try to find an equivalent for l */ for (j = m; j < n; j++) { p = packed[j]; @@ -230,119 +152,3 @@ sameas(struct devi *i1, struct devi *i2) return (1); return (0); } - -static void -packlocs(void) -{ - struct pspec *ps; - struct devi **p, *i; - int l,o; - extern int Pflag; - - qsort(packed, npacked, sizeof *packed, loclencmp); - for (p = packed; (i = *p) != NULL; p++) { - if ((ps = i->i_pspec) != NULL && - (l = ps->p_iattr->a_loclen) > 0) { - if (Pflag) { - o = findvec(i->i_locs, - LOCHASH(i->i_locs[l - 1]), l, - samelocs, locators.used); - i->i_locoff = o < 0 ? - addlocs(i->i_locs, l) : o; - } else - i->i_locoff = addlocs(i->i_locs, l); - } else - i->i_locoff = -1; - } - resettails(); -} - -/* - * Return the index at which the given vector already exists, or -1 - * if it is not anywhere in the current set. If we return -1, we assume - * our caller will add it at the end of the current set, and we make - * sure that next time, we will find it there. - */ -static int -findvec(const void *ptr, int hash, int len, vec_cmp_func cmp, int nextplace) -{ - struct tails *t, **hp; - int off; - - hp = &tails[hash]; - for (t = *hp; t != NULL; t = t->t_next) { - off = t->t_ends_at - len; - if (off >= 0 && (*cmp)(ptr, off, len)) - return (off); - } - t = ecalloc(1, sizeof(*t)); - t->t_next = *hp; - *hp = t; - t->t_ends_at = nextplace + len; - return (-1); -} - -/* - * Comparison function for locators. - */ -static int -samelocs(const void *ptr, int off, int len) -{ - const char **p, **q; - - for (p = &locators.vec[off], q = (const char **)ptr; --len >= 0;) - if (*p++ != *q++) - return (0); /* different */ - return (1); /* same */ -} - -/* - * Add the given locators at the end of the global loc[] table. - */ -static int -addlocs(const char **locs, int len) -{ - const char **p; - int ret; - - ret = locators.used; - if ((locators.used = ret + len) > locspace) - panic("addlocs: overrun"); - for (p = &locators.vec[ret]; --len >= 0;) - *p++ = *locs++; - return (ret); -} - -/* - * Comparison function for qsort-by-locator-length, longest first. - * We rashly assume that subtraction of these lengths does not overflow. - */ -static int -loclencmp(const void *a, const void *b) -{ - const struct pspec *p1, *p2; - int l1, l2; - - p1 = (*(const struct devi **)a)->i_pspec; - l1 = p1 != NULL ? p1->p_iattr->a_loclen : 0; - - p2 = (*(const struct devi **)b)->i_pspec; - l2 = p2 != NULL ? p2->p_iattr->a_loclen : 0; - - return (l2 - l1); -} - -static void -resettails(void) -{ - struct tails **p, *t, *next; - int i; - - for (p = tails, i = TAILHSIZE; --i >= 0; p++) { - for (t = *p; t != NULL; t = next) { - next = t->t_next; - free(t); - } - *p = NULL; - } -}