- Make sure to try aliases of removed device instances when walking

deaddevitab.
- Record the position in the config file of device instances so it is
  possible to tell if a device instance was declared before or after its
  parent's removal.

  E.g.:

     child* at parent?
     no parent

   will have the child instance ignored as an explicit orphan, while

     no parent
     child* at parent?

   will error out because now the child instance is a real orphan.

  That let the POSTPONED_ORPHAN regression test pass.
This commit is contained in:
cube 2005-10-04 20:13:39 +00:00
parent f531688ba9
commit a31ff6b408
3 changed files with 43 additions and 25 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: defs.h,v 1.6 2005/10/04 13:06:45 cube Exp $ */
/* $NetBSD: defs.h,v 1.7 2005/10/04 20:13:39 cube Exp $ */
/*
* Copyright (c) 1992, 1993
@ -244,6 +244,7 @@ struct devi {
int i_cfflags; /* flags from config line */
int i_lineno; /* line # in config, for later errors */
const char *i_srcfile; /* file it appears in */
int i_level; /* position between negated instances */
int i_active;
#define DEVI_ORPHAN 0 /* instance has no active parent */
#define DEVI_ACTIVE 1 /* instance has an active parent */
@ -399,6 +400,7 @@ int maxbdevm; /* max number of block major */
int maxcdevm; /* max number of character major */
int do_devsw; /* 0 if pre-devsw config */
int oktopackage; /* 0 before setmachine() */
int devilevel; /* used for devi->i_level */
TAILQ_HEAD(, files) allfiles; /* list of all kernel source files */
TAILQ_HEAD(, objects) allobjects; /* list of all kernel object and

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.4 2005/10/02 21:22:56 cube Exp $ */
/* $NetBSD: main.c,v 1.5 2005/10/04 20:13:39 cube Exp $ */
/*
* Copyright (c) 1992, 1993
@ -105,7 +105,7 @@ static int badstar(void);
static int mksymlinks(void);
static int mkident(void);
static int devbase_has_dead_instances(const char *, void *, void *);
static int devbase_has_any_instance(struct devbase *, int, int);
static int devbase_has_any_instance(struct devbase *, int, int, int);
static int check_dead_devi(const char *, void *, void *);
static void kill_orphans(void);
static void do_kill_orphans(struct devbase *, struct attr *,
@ -1486,17 +1486,20 @@ extract_config(const char *kname, const char *cname, int cfd)
struct dhdi_params {
struct devbase *d;
int unit;
int level;
};
static int
devbase_has_dead_instances(const char *key, void *value, void *aux)
{
struct devi *i = value;
struct devi *i;
struct dhdi_params *dhdi = aux;
for (i = value; i != NULL; i = i->i_alias)
if (i->i_base == dhdi->d &&
(dhdi->unit == WILD || dhdi->unit == i->i_unit ||
i->i_unit == STAR))
i->i_unit == STAR) &&
i->i_level >= dhdi->level)
return 1;
return 0;
}
@ -1507,7 +1510,7 @@ devbase_has_dead_instances(const char *key, void *value, void *aux)
*/
static int
devbase_has_any_instance(struct devbase *dev, int unit, int state)
devbase_has_any_instance(struct devbase *dev, int unit, int state, int level)
{
struct deva *da;
struct devi *i;
@ -1515,10 +1518,11 @@ devbase_has_any_instance(struct devbase *dev, int unit, int state)
if (dev->d_ispseudo) {
if (dev->d_ihead != NULL)
return 1;
else if (state == DEVI_IGNORED)
return (ht_lookup(deaddevitab, dev->d_name) != NULL);
else
else if (state != DEVI_IGNORED)
return 0;
if ((i = ht_lookup(deaddevitab, dev->d_name)) == NULL)
return 0;
return (i->i_level >= level);
}
for (da = dev->d_ahead; da != NULL; da = da->d_bsame)
@ -1530,7 +1534,7 @@ devbase_has_any_instance(struct devbase *dev, int unit, int state)
return 1;
if (state == DEVI_IGNORED) {
struct dhdi_params dhdi = { dev, unit };
struct dhdi_params dhdi = { dev, unit, level };
/* also check dead devices */
return ht_enumerate(deaddevitab, devbase_has_dead_instances,
&dhdi);
@ -1559,21 +1563,24 @@ check_dead_devi(const char *key, void *value, void *aux)
{
struct cdd_params *cdd = aux;
struct devi *i = value;
struct pspec *p = i->i_pspec;
struct pspec *p;
if (i->i_base != cdd->d)
return 0;
for (; i != NULL; i = i->i_alias) {
p = i->i_pspec;
if ((p == NULL && cdd->at == NULL) ||
(p != NULL && p->p_iattr == cdd->at &&
(p->p_atdev == NULL || p->p_atdev == cdd->parent))) {
if (p != NULL &&
!devbase_has_any_instance(cdd->parent, p->p_atunit,
DEVI_IGNORED))
DEVI_IGNORED, i->i_level))
return 0;
else
return 1;
}
}
return 0;
}
@ -1615,7 +1622,7 @@ do_kill_orphans(struct devbase *d, struct attr *at, struct devbase *parent,
p->p_atdev == parent))) {
if (p != NULL &&
!devbase_has_any_instance(parent,
p->p_atunit, state))
p->p_atunit, state, j->i_level))
continue;
/*
* There are Fry-like devices which can

View File

@ -1,4 +1,4 @@
/* $NetBSD: sem.c,v 1.12 2005/10/04 13:33:20 cube Exp $ */
/* $NetBSD: sem.c,v 1.13 2005/10/04 20:13:39 cube Exp $ */
/*
* Copyright (c) 1992, 1993
@ -882,6 +882,7 @@ newdevi(const char *name, int unit, struct devbase *d)
i->i_lineno = currentline();
i->i_srcfile = yyfile;
i->i_active = DEVI_ORPHAN; /* Proper analysis comes later */
i->i_level = devilevel;
if (unit >= d->d_umax)
d->d_umax = unit + 1;
return (i);
@ -1192,7 +1193,15 @@ remove_devi(struct devi *i)
ndevi--;
/*
* Put it in deaddevitab
*
* Each time a devi is removed, devilevel is increased so that later on
* it is possible to tell if an instance was added before or after the
* removal of its parent.
*
* For active instances, i_level contains the number of devi removed so
* far, and for dead devis, it contains its index.
*/
i->i_level = devilevel++;
i->i_alias = NULL;
f = ht_lookup(deaddevitab, i->i_name);
if (f == NULL) {