diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2006-04-09 12:02:24 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2006-04-09 12:02:24 +0000 |
commit | 8687f73385de2fab544ff98f2f75958f8898c626 (patch) | |
tree | 103ec7b7fa31aef9145b32efba413ef0d8512c4d /sys/arch/sparc64 | |
parent | ec2fbd7461ac0e754d00506fa9a86c444a1e4b09 (diff) |
Rewrite bus_compatible() to allow one alias to expand to several drivers,
and in this case pick the one which matches the driver we are currently
attaching, if any; allows systems netbooted via gem interfaces to recognize
their boot device, and solves PR #5058.
Diffstat (limited to 'sys/arch/sparc64')
-rw-r--r-- | sys/arch/sparc64/sparc64/autoconf.c | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/sys/arch/sparc64/sparc64/autoconf.c b/sys/arch/sparc64/sparc64/autoconf.c index 663a1439055..256074e6a85 100644 --- a/sys/arch/sparc64/sparc64/autoconf.c +++ b/sys/arch/sparc64/sparc64/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.45 2006/03/15 20:20:41 miod Exp $ */ +/* $OpenBSD: autoconf.c,v 1.46 2006/04/09 12:02:23 miod Exp $ */ /* $NetBSD: autoconf.c,v 1.51 2001/07/24 19:32:11 eeh Exp $ */ /* @@ -1369,10 +1369,10 @@ static struct { }; /* - * A list of PROM device names that differ from our NetBSD + * A list of PROM device names that differ from our OpenBSD * device names. */ -static struct { +static const struct dev_compat_tab { char *bpname; int class; char *cfname; @@ -1390,6 +1390,8 @@ static struct { { "cmdk", BUSCLASS_NONE, "wd" }, { "pci108e,1101.1", BUSCLASS_NONE, "gem" }, { "dc", BUSCLASS_NONE, "dc" }, + /* ``network'' might be either gem or hme */ + { "network", BUSCLASS_NONE, "gem" }, { "network", BUSCLASS_NONE, "hme" }, { "ethernet", BUSCLASS_NONE, "dc" }, { "SUNW,fas", BUSCLASS_NONE, "esp" }, @@ -1399,6 +1401,7 @@ static struct { { "SUNW,glm", BUSCLASS_PCI, "siop" }, { "sd", BUSCLASS_NONE, "sd" }, { "ide-disk", BUSCLASS_NONE, "wd" }, + { NULL } }; char * @@ -1406,19 +1409,41 @@ bus_compatible(bp, dev) struct bootpath *bp; struct device *dev; { - int i, class = bus_class(dev); + const struct dev_compat_tab *lore, *sub; + int class = bus_class(dev); + const char *dvname = dev->dv_cfdata->cf_driver->cd_name; - for (i = sizeof(dev_compat_tab)/sizeof(dev_compat_tab[0]); i-- > 0;) { - if (strcmp(bp->compatible, dev_compat_tab[i].bpname) == 0 && - (dev_compat_tab[i].class == BUSCLASS_NONE || - dev_compat_tab[i].class == class)) - return (dev_compat_tab[i].cfname); + /* + * First try matching the ``compatible'' property. + * However, since more than one device can share the same + * ``compatible'' property, we have to take this into account + * and favor the entry matching our current device name, if + * there is one. + */ + for (lore = dev_compat_tab; lore->bpname != NULL; lore++) { + if (strcmp(bp->compatible, lore->bpname) != 0) + continue; + if (lore->class != BUSCLASS_NONE && + lore->class != class) + continue; + for (sub = lore + 1; sub->bpname != NULL; sub++) { + if (strcmp(lore->bpname, sub->bpname) != 0) + break; + if (strcmp(sub->cfname, dvname) == 0) + return (sub->cfname); + } + return (lore->cfname); } - for (i = sizeof(dev_compat_tab)/sizeof(dev_compat_tab[0]); i-- > 0;) { - if (strcmp(bp->name, dev_compat_tab[i].bpname) == 0 && - (dev_compat_tab[i].class == BUSCLASS_NONE || - dev_compat_tab[i].class == class)) - return (dev_compat_tab[i].cfname); + + /* + * If it has not been found, match on the ``name'' property; + * there can only be one instance in the table. + */ + for (lore = dev_compat_tab; lore->bpname != NULL; lore++) { + if (strcmp(bp->name, lore->bpname) == 0 && + (lore->class == BUSCLASS_NONE || + lore->class == class)) + return (lore->cfname); } return (bp->name); |