? config.diff ? o Index: defs.h =================================================================== RCS file: /cvsroot/src/usr.bin/config/defs.h,v retrieving revision 1.100 diff -u -u -r1.100 defs.h --- defs.h 16 Nov 2017 17:08:07 -0000 1.100 +++ defs.h 17 Nov 2017 23:47:56 -0000 @@ -234,6 +234,7 @@ struct devbase *p_atdev; /* optional parent device base */ int p_atunit; /* optional parent device unit */ struct nvlist *p_devs; /* children using it */ + struct deva *p_deva; /* attribute */ int p_inst; /* parent spec instance */ int p_active; /* parent spec is actively used */ }; Index: sem.c =================================================================== RCS file: /cvsroot/src/usr.bin/config/sem.c,v retrieving revision 1.77 diff -u -u -r1.77 sem.c --- sem.c 13 Sep 2016 16:06:59 -0000 1.77 +++ sem.c 17 Nov 2017 23:47:56 -0000 @@ -79,7 +79,8 @@ static struct nvlist *addtoattr(struct nvlist *, struct devbase *); static int resolve(struct nvlist **, const char *, const char *, struct nvlist *, int); -static struct pspec *getpspec(struct attr *, struct devbase *, int); +static struct pspec *getpspec(struct attr *, struct devbase *, int, + struct deva *); static struct devi *newdevi(const char *, int, struct devbase *d); static struct devi *getdevi(const char *); static void remove_devi(struct devi *); @@ -641,7 +642,6 @@ struct nvlist *nv; struct attrlist *al; struct attr *a; - struct deva *da; if (dev == &errdev) goto bad; @@ -699,14 +699,16 @@ if (a == &errattr) continue; /* already complained */ +#if 0 /* * Make sure that an attachment spec doesn't * already say how to attach to this attribute. */ - for (da = dev->d_ahead; da != NULL; da = da->d_bsame) + for (struct deva *da = dev->d_ahead; da; da = da->d_bsame) if (onlist(da->d_atlist, a)) cfgerror("attach at `%s' already done by `%s'", a ? a->a_name : "root", da->d_name); +#endif if (a == NULL) { ht_insert(devroottab, dev->d_name, dev); @@ -1172,45 +1174,27 @@ struct devbase *ab; /* not NULL => at another dev */ struct attrlist *al; struct deva *iba; /* devbase attachment used */ + struct deva *lastiba; const char *cp; - int atunit; + int atunit, hit; char atbuf[NAMESIZE]; - int hit; + hit = 0; + lastiba = NULL; + if ((i = getdevi(name)) == NULL) + goto bad; + ib = i->i_base; +again: ab = NULL; iba = NULL; - if (at == NULL) { - /* "at root" */ - p = NULL; - if ((i = getdevi(name)) == NULL) - goto bad; - /* - * Must warn about i_unit > 0 later, after taking care of - * the STAR cases (we could do non-star's here but why - * bother?). Make sure this device can be at root. - */ - ib = i->i_base; - hit = 0; - for (iba = ib->d_ahead; iba != NULL; iba = iba->d_bsame) - if (onlist(iba->d_atlist, NULL)) { - hit = 1; - break; - } - if (!hit) { - cfgerror("`%s' cannot attach to the root", ib->d_name); - i->i_active = DEVI_BROKEN; - goto bad; - } - attr = &errattr; /* a convenient "empty" attr */ - } else { + attr = &errattr; /* a convenient "empty" attr */ + p = NULL; + if (at != NULL) { if (split(at, strlen(at), atbuf, sizeof atbuf, &atunit)) { cfgerror("invalid attachment name `%s'", at); /* (void)getdevi(name); -- ??? */ goto bad; } - if ((i = getdevi(name)) == NULL) - goto bad; - ib = i->i_base; /* * Devices can attach to two types of things: Attributes, @@ -1271,24 +1255,50 @@ i->i_active = DEVI_BROKEN; goto bad; - findattachment: + } + +findattachment: + /* find out which attachment it uses */ + if (lastiba == NULL) { + lastiba = ib->d_ahead; + } else { + for (iba = ib->d_ahead; iba != NULL; iba = iba->d_bsame) { + if (iba == lastiba) { + lastiba = iba->d_bsame; + break; + } + } + if (iba == NULL) + abort(); + } + for (iba = lastiba; iba != NULL; iba = iba->d_bsame) + if (onlist(iba->d_atlist, attr == &errattr ? NULL : attr)) + break; + + if (iba == NULL) { + if (hit) + goto bad; + if (attr != &errattr) { + panic("adddev: can't figure out attachment"); + } else { + cfgerror("`%s' cannot attach to the root", ib->d_name); + i->i_active = DEVI_BROKEN; + } + } + lastiba = iba; + + if (attr != &errattr) { /* * Find the parent spec. If a matching one has not yet been * created, create one. */ - p = getpspec(attr, ab, atunit); + p = getpspec(attr, ab, atunit, iba); p->p_devs = newnv(NULL, NULL, i, 0, p->p_devs); - - /* find out which attachment it uses */ - hit = 0; - for (iba = ib->d_ahead; iba != NULL; iba = iba->d_bsame) - if (onlist(iba->d_atlist, attr)) { - hit = 1; - break; - } - if (!hit) - panic("adddev: can't figure out attachment"); } + + if (hit && (i = getdevi(name)) == NULL) + goto bad; + if ((i->i_locs = fixloc(name, attr, loclist)) == NULL) { i->i_active = DEVI_BROKEN; goto bad; @@ -1297,10 +1307,12 @@ i->i_pspec = p; i->i_atdeva = iba; i->i_cfflags = flags; - CFGDBG(3, "devi `%s' added", i->i_name); + CFGDBG(3, "devi `%s' at '%s' added", i->i_name, iba->d_name); *iba->d_ipp = i; iba->d_ipp = &i->i_asame; + hit++; + goto again; /* all done, fall into ... */ bad: @@ -1846,6 +1858,7 @@ fixdevis(void) { struct devi *i; + struct pspec *p; int error = 0; TAILQ_FOREACH(i, &alldevi, i_next) { @@ -1858,9 +1871,11 @@ * i_at or i_pspec are NULL. */ ++error; + p = i->i_pspec; cfgxerror(i->i_srcfile, i->i_lineno, "`%s at %s' is orphaned (%s `%s' found)", - i->i_name, i->i_at, i->i_pspec->p_atunit == WILD ? + i->i_name, i->i_at, + p == NULL || p->p_atunit == WILD ? "nothing matching" : "no", i->i_at); } else if (vflag && i->i_active == DEVI_IGNORED) cfgxwarn(i->i_srcfile, i->i_lineno, "ignoring " @@ -1881,14 +1896,15 @@ * Look up a parent spec, creating a new one if it does not exist. */ static struct pspec * -getpspec(struct attr *attr, struct devbase *ab, int atunit) +getpspec(struct attr *attr, struct devbase *ab, int atunit, struct deva *da) { struct pspec *p; TAILQ_FOREACH(p, &allpspecs, p_list) { if (p->p_iattr == attr && p->p_atdev == ab && - p->p_atunit == atunit) + p->p_atunit == atunit && + p->p_deva == da) return (p); } @@ -1898,6 +1914,7 @@ p->p_atdev = ab; p->p_atunit = atunit; p->p_inst = npspecs++; + p->p_deva = da; p->p_active = 0; TAILQ_INSERT_TAIL(&allpspecs, p, p_list);