Add a new function config_scan(), which just calls a particular function

with each plausibly cfdata, ignoring the priority mechanism completely.
This commit is contained in:
mycroft 1994-11-04 06:40:11 +00:00
parent 2e8ae560f6
commit 1948fcb3fa
4 changed files with 114 additions and 89 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: isa.c,v 1.63 1994/11/04 03:57:32 mycroft Exp $ */
/* $NetBSD: isa.c,v 1.64 1994/11/04 06:40:14 mycroft Exp $ */
/*-
* Copyright (c) 1993, 1994 Charles Hannum. All rights reserved.
@ -39,6 +39,8 @@
#include <i386/isa/isareg.h>
#include <i386/isa/isavar.h>
#include <machine/limits.h>
/* sorry, has to be here, no place else really suitable */
#include <machine/pc/display.h>
u_short *Crtat = (u_short *)MONO_BUF;
@ -83,43 +85,38 @@ isaprint(aux, isa)
return (QUIET);
}
void
isascan(parent, match)
struct device *parent;
void *match;
{
struct device *dev = match;
struct cfdata *cf = dev->dv_cfdata;
struct isa_attach_args ia;
if (cf->cf_fstate == FSTATE_STAR)
panic("not bloody likely");
ia.ia_iobase = cf->cf_loc[0];
ia.ia_iosize = 0x666;
ia.ia_maddr = cf->cf_loc[2] - 0xa0000 + atdevbase;
ia.ia_msize = cf->cf_loc[3];
ia.ia_irq = (cf->cf_loc[4] == -1) ? IRQUNK : (1 << cf->cf_loc[4]);
ia.ia_drq = cf->cf_loc[5];
if ((*cf->cf_driver->cd_match)(parent, dev, &ia) > 0)
config_attach(parent, dev, &ia, isaprint);
else
free(dev, M_DEVBUF);
}
void
isaattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
register struct cfdata *cf;
register short *p;
struct matchinfo m;
struct isa_attach_args ia;
extern struct cfdata cfdata[];
printf("\n");
m.fn = NULL;
m.parent = self;
m.aux = &ia;
m.indirect = 1;
for (cf = cfdata; cf->cf_driver; cf++) {
if (cf->cf_fstate == FSTATE_FOUND)
continue;
for (p = cf->cf_parents; *p >= 0; p++) {
if (self->dv_cfdata != &cfdata[*p])
continue;
m.match = NULL;
m.pri = 0;
ia.ia_iobase = cf->cf_loc[0];
ia.ia_iosize = 0x666;
ia.ia_maddr = cf->cf_loc[2] - 0xa0000 + atdevbase;
ia.ia_msize = cf->cf_loc[3];
ia.ia_irq =
(cf->cf_loc[4] == -1) ? IRQUNK : (1 << cf->cf_loc[4]);
ia.ia_drq = cf->cf_loc[5];
config_mapply(&m, cf);
if (m.pri > 0) {
config_attach(self, m.match, &ia, isaprint);
break;
}
}
}
config_scan(isascan, self);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: isa.c,v 1.63 1994/11/04 03:57:32 mycroft Exp $ */
/* $NetBSD: isa.c,v 1.64 1994/11/04 06:40:14 mycroft Exp $ */
/*-
* Copyright (c) 1993, 1994 Charles Hannum. All rights reserved.
@ -39,6 +39,8 @@
#include <i386/isa/isareg.h>
#include <i386/isa/isavar.h>
#include <machine/limits.h>
/* sorry, has to be here, no place else really suitable */
#include <machine/pc/display.h>
u_short *Crtat = (u_short *)MONO_BUF;
@ -83,43 +85,38 @@ isaprint(aux, isa)
return (QUIET);
}
void
isascan(parent, match)
struct device *parent;
void *match;
{
struct device *dev = match;
struct cfdata *cf = dev->dv_cfdata;
struct isa_attach_args ia;
if (cf->cf_fstate == FSTATE_STAR)
panic("not bloody likely");
ia.ia_iobase = cf->cf_loc[0];
ia.ia_iosize = 0x666;
ia.ia_maddr = cf->cf_loc[2] - 0xa0000 + atdevbase;
ia.ia_msize = cf->cf_loc[3];
ia.ia_irq = (cf->cf_loc[4] == -1) ? IRQUNK : (1 << cf->cf_loc[4]);
ia.ia_drq = cf->cf_loc[5];
if ((*cf->cf_driver->cd_match)(parent, dev, &ia) > 0)
config_attach(parent, dev, &ia, isaprint);
else
free(dev, M_DEVBUF);
}
void
isaattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
register struct cfdata *cf;
register short *p;
struct matchinfo m;
struct isa_attach_args ia;
extern struct cfdata cfdata[];
printf("\n");
m.fn = NULL;
m.parent = self;
m.aux = &ia;
m.indirect = 1;
for (cf = cfdata; cf->cf_driver; cf++) {
if (cf->cf_fstate == FSTATE_FOUND)
continue;
for (p = cf->cf_parents; *p >= 0; p++) {
if (self->dv_cfdata != &cfdata[*p])
continue;
m.match = NULL;
m.pri = 0;
ia.ia_iobase = cf->cf_loc[0];
ia.ia_iosize = 0x666;
ia.ia_maddr = cf->cf_loc[2] - 0xa0000 + atdevbase;
ia.ia_msize = cf->cf_loc[3];
ia.ia_irq =
(cf->cf_loc[4] == -1) ? IRQUNK : (1 << cf->cf_loc[4]);
ia.ia_drq = cf->cf_loc[5];
config_mapply(&m, cf);
if (m.pri > 0) {
config_attach(self, m.match, &ia, isaprint);
break;
}
}
}
config_scan(isascan, self);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr_autoconf.c,v 1.15 1994/11/04 03:12:20 mycroft Exp $ */
/* $NetBSD: subr_autoconf.c,v 1.16 1994/11/04 06:40:11 mycroft Exp $ */
/*
* Copyright (c) 1992, 1993
@ -50,6 +50,7 @@
#include <sys/device.h>
#include <sys/malloc.h>
#include <lib/libkern/libkern.h>
#include <machine/limits.h>
/*
* Autoconfiguration subroutines.
@ -66,37 +67,40 @@ extern short cfroots[];
struct device *config_make_softc __P((struct device *, struct cfdata *));
struct matchinfo {
cfmatch_t fn;
struct device *parent;
void *match, *aux;
int indirect, pri;
};
/*
* Apply the matching function and choose the best. This is used
* a few times and we want to keep the code small.
*/
void
config_mapply(m, cf)
static void
mapply(m, cf)
register struct matchinfo *m;
register struct cfdata *cf;
{
register int pri;
void *match;
if (m->indirect) {
if (m->indirect)
match = config_make_softc(m->parent, cf);
cf->cf_driver->cd_devs[cf->cf_unit] = match;
} else
else
match = cf;
if (m->fn != NULL)
pri = (*m->fn)(m->parent, match, m->aux);
else {
if (cf->cf_driver->cd_match == NULL) {
panic("config_mapply: no match function for '%s' device\n",
panic("mapply: no match function for '%s' device\n",
cf->cf_driver->cd_name);
}
pri = (*cf->cf_driver->cd_match)(m->parent, match, m->aux);
}
if (m->indirect)
cf->cf_driver->cd_devs[cf->cf_unit] = NULL;
if (pri > m->pri) {
if (m->indirect && m->match)
free(m->match, M_DEVBUF);
@ -144,11 +148,48 @@ config_search(fn, parent, aux)
continue;
for (p = cf->cf_parents; *p >= 0; p++)
if (parent->dv_cfdata == &cfdata[*p])
config_mapply(&m, cf);
mapply(&m, cf);
}
return (m.match);
}
/*
* Iterate over all potential children of some device, calling the given
* function for each one.
*
* Note that this function is designed so that it can be used to apply
* an arbitrary function to all potential children (its return value
* can be ignored).
*/
void
config_scan(fn, parent)
cfscan_t fn;
register struct device *parent;
{
register struct cfdata *cf;
register short *p;
void *match;
int indirect;
indirect = parent && parent->dv_cfdata->cf_driver->cd_indirect;
for (cf = cfdata; cf->cf_driver; cf++) {
/*
* Skip cf if no longer eligible, otherwise scan through
* parents for one matching `parent', and try match function.
*/
if (cf->cf_fstate == FSTATE_FOUND)
continue;
for (p = cf->cf_parents; *p >= 0; p++)
if (parent->dv_cfdata == &cfdata[*p]) {
if (indirect)
match = config_make_softc(parent, cf);
else
match = cf;
(*fn)(parent, match);
}
}
}
/*
* Find the given root device.
* This is much like config_search, but there is no parent.
@ -177,7 +218,7 @@ config_rootsearch(fn, rootname, aux)
for (p = cfroots; *p >= 0; p++) {
cf = &cfdata[*p];
if (strcmp(cf->cf_driver->cd_name, rootname) == 0)
config_mapply(&m, cf);
mapply(&m, cf);
}
return (m.match);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: device.h,v 1.7 1994/11/04 03:12:23 mycroft Exp $ */
/* $NetBSD: device.h,v 1.8 1994/11/04 06:40:17 mycroft Exp $ */
/*
* Copyright (c) 1992, 1993
@ -94,6 +94,7 @@ struct cfdata {
#define FSTATE_STAR 2 /* duplicable */
typedef int (*cfmatch_t) __P((struct device *, void *, void *));
typedef void (*cfscan_t) __P((struct device *, void *));
/*
* `configuration' driver (what the machine-independent autoconf uses).
@ -114,18 +115,6 @@ struct cfdriver {
int cd_ndevs; /* size of cd_devs array */
};
/*
* Structure used to record the state of a config_found() or a
* config_rootfound() loop.
*/
struct matchinfo {
cfmatch_t fn;
struct device *parent;
void *match, *aux;
int indirect, pri;
};
void config_mapply __P((struct matchinfo *, struct cfdata *));
/*
* Configuration printing functions, and their return codes. The second
* argument is NULL if the device was configured; otherwise it is the name
@ -152,6 +141,7 @@ void *config_search __P((cfmatch_t, struct device *, void *));
void *config_rootsearch __P((cfmatch_t, char *, void *));
int config_found __P((struct device *, void *, cfprint_t));
int config_rootfound __P((char *, void *));
void config_scan __P((cfscan_t, struct device *));
void config_attach __P((struct device *, void *, void *, cfprint_t));
void evcnt_attach __P((struct device *, const char *, struct evcnt *));