Replace the "locnames", attached to cfdata, which was solely good for
userconf, by more complete information (including default values) about interface attributes, attached to the drivers which provide them.
This commit is contained in:
parent
f46880afbf
commit
6036af9fc4
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: kern_drvctl.c,v 1.1 2004/08/18 12:19:29 drochner Exp $ */
|
/* $NetBSD: kern_drvctl.c,v 1.2 2005/08/25 15:06:28 drochner Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2004
|
* Copyright (c) 2004
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: kern_drvctl.c,v 1.1 2004/08/18 12:19:29 drochner Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: kern_drvctl.c,v 1.2 2005/08/25 15:06:28 drochner Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -81,7 +81,7 @@ rescanbus(const char *busname, const char *ifattr,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct device *d;
|
struct device *d;
|
||||||
const char * const *ap;
|
const struct cfiattrdata * const *ap;
|
||||||
|
|
||||||
/* XXX there should be a way to get limits and defaults (per device)
|
/* XXX there should be a way to get limits and defaults (per device)
|
||||||
from config generated data */
|
from config generated data */
|
||||||
|
@ -106,11 +106,11 @@ rescanbus(const char *busname, const char *ifattr,
|
||||||
if (!ifattr) {
|
if (!ifattr) {
|
||||||
if (d->dv_cfdriver->cd_attrs[1])
|
if (d->dv_cfdriver->cd_attrs[1])
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
ifattr = d->dv_cfdriver->cd_attrs[0];
|
ifattr = d->dv_cfdriver->cd_attrs[0]->ci_name;
|
||||||
} else {
|
} else {
|
||||||
/* check for valid attribute passed */
|
/* check for valid attribute passed */
|
||||||
for (ap = d->dv_cfdriver->cd_attrs; *ap; ap++)
|
for (ap = d->dv_cfdriver->cd_attrs; *ap; ap++)
|
||||||
if (!strcmp(*ap, ifattr))
|
if (!strcmp((*ap)->ci_name, ifattr))
|
||||||
break;
|
break;
|
||||||
if (!*ap)
|
if (!*ap)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: subr_autoconf.c,v 1.95 2005/06/28 18:37:34 drochner Exp $ */
|
/* $NetBSD: subr_autoconf.c,v 1.96 2005/08/25 15:06:28 drochner Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 2000 Christopher G. Demetriou
|
* Copyright (c) 1996, 2000 Christopher G. Demetriou
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.95 2005/06/28 18:37:34 drochner Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.96 2005/08/25 15:06:28 drochner Exp $");
|
||||||
|
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
|
|
||||||
|
@ -459,25 +459,47 @@ mapply(struct matchinfo *m, struct cfdata *cf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper function: check whether the driver supports the interface attribute.
|
* Helper function: check whether the driver supports the interface attribute
|
||||||
|
* and return its descriptor structure.
|
||||||
*/
|
*/
|
||||||
static int
|
static const struct cfiattrdata *
|
||||||
cfdriver_has_iattr(const struct cfdriver *cd, const char *ia)
|
cfdriver_get_iattr(const struct cfdriver *cd, const char *ia)
|
||||||
{
|
{
|
||||||
const char * const *cpp;
|
const struct cfiattrdata * const *cpp;
|
||||||
|
|
||||||
if (cd->cd_attrs == NULL)
|
if (cd->cd_attrs == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
for (cpp = cd->cd_attrs; *cpp; cpp++) {
|
for (cpp = cd->cd_attrs; *cpp; cpp++) {
|
||||||
if (STREQ(*cpp, ia)) {
|
if (STREQ((*cpp)->ci_name, ia)) {
|
||||||
/* Match. */
|
/* Match. */
|
||||||
return (1);
|
return (*cpp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lookup an interface attribute description by name.
|
||||||
|
* If the driver is given, consider only its supported attributes.
|
||||||
|
*/
|
||||||
|
const struct cfiattrdata *
|
||||||
|
cfiattr_lookup(const char *name, const struct cfdriver *cd)
|
||||||
|
{
|
||||||
|
const struct cfdriver *d;
|
||||||
|
const struct cfiattrdata *ia;
|
||||||
|
|
||||||
|
if (cd)
|
||||||
|
return (cfdriver_get_iattr(cd, name));
|
||||||
|
|
||||||
|
LIST_FOREACH(d, &allcfdrivers, cd_list) {
|
||||||
|
ia = cfdriver_get_iattr(d, name);
|
||||||
|
if (ia)
|
||||||
|
return (ia);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine if `parent' is a potential parent for a device spec based
|
* Determine if `parent' is a potential parent for a device spec based
|
||||||
* on `cfp'.
|
* on `cfp'.
|
||||||
|
@ -498,7 +520,7 @@ cfparent_match(const struct device *parent, const struct cfparent *cfp)
|
||||||
* First, ensure this parent has the correct interface
|
* First, ensure this parent has the correct interface
|
||||||
* attribute.
|
* attribute.
|
||||||
*/
|
*/
|
||||||
if (!cfdriver_has_iattr(pcd, cfp->cfp_iattr))
|
if (!cfdriver_get_iattr(pcd, cfp->cfp_iattr))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -664,7 +686,7 @@ config_search_loc(cfsubmatch_t fn, struct device *parent,
|
||||||
struct matchinfo m;
|
struct matchinfo m;
|
||||||
|
|
||||||
KASSERT(config_initialized);
|
KASSERT(config_initialized);
|
||||||
KASSERT(!ifattr || cfdriver_has_iattr(parent->dv_cfdriver, ifattr));
|
KASSERT(!ifattr || cfdriver_get_iattr(parent->dv_cfdriver, ifattr));
|
||||||
|
|
||||||
m.fn_loc = fn;
|
m.fn_loc = fn;
|
||||||
m.parent = parent;
|
m.parent = parent;
|
||||||
|
@ -843,6 +865,7 @@ config_attach_loc(struct device *parent, struct cfdata *cf,
|
||||||
const char *xunit;
|
const char *xunit;
|
||||||
int myunit;
|
int myunit;
|
||||||
char num[10];
|
char num[10];
|
||||||
|
const struct cfiattrdata *ia;
|
||||||
|
|
||||||
cd = config_cfdriver_lookup(cf->cf_name);
|
cd = config_cfdriver_lookup(cf->cf_name);
|
||||||
KASSERT(cd != NULL);
|
KASSERT(cd != NULL);
|
||||||
|
@ -901,9 +924,14 @@ config_attach_loc(struct device *parent, struct cfdata *cf,
|
||||||
dev->dv_parent = parent;
|
dev->dv_parent = parent;
|
||||||
dev->dv_flags = DVF_ACTIVE; /* always initially active */
|
dev->dv_flags = DVF_ACTIVE; /* always initially active */
|
||||||
if (ldesc) {
|
if (ldesc) {
|
||||||
dev->dv_locators = malloc(ldesc->len * sizeof(int),
|
KASSERT(parent); /* no locators at root */
|
||||||
|
ia = cfiattr_lookup(cf->cf_pspec->cfp_iattr,
|
||||||
|
parent->dv_cfdriver);
|
||||||
|
KASSERT(ldesc->len == ia->ci_loclen); /* XXX will go away */
|
||||||
|
dev->dv_locators = malloc(ia->ci_loclen * sizeof(int),
|
||||||
M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
|
M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
|
||||||
memcpy(dev->dv_locators, ldesc->locs, ldesc->len * sizeof(int));
|
memcpy(dev->dv_locators, ldesc->locs,
|
||||||
|
ia->ci_loclen * sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_do_twiddle)
|
if (config_do_twiddle)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: subr_userconf.c,v 1.15 2005/06/23 18:44:44 thorpej Exp $ */
|
/* $NetBSD: subr_userconf.c,v 1.16 2005/08/25 15:06:28 drochner Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1996 Mats O Jansson <moj@stacken.kth.se>
|
* Copyright (c) 1996 Mats O Jansson <moj@stacken.kth.se>
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: subr_userconf.c,v 1.15 2005/06/23 18:44:44 thorpej Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: subr_userconf.c,v 1.16 2005/08/25 15:06:28 drochner Exp $");
|
||||||
|
|
||||||
#include "opt_userconf.h"
|
#include "opt_userconf.h"
|
||||||
|
|
||||||
|
@ -206,7 +206,9 @@ userconf_pdev(short devno)
|
||||||
struct cfdata *cd;
|
struct cfdata *cd;
|
||||||
const struct cfparent *cfp;
|
const struct cfparent *cfp;
|
||||||
int *l;
|
int *l;
|
||||||
const char * const *ln;
|
const struct cfiattrdata *ia;
|
||||||
|
const struct cflocdesc *ld;
|
||||||
|
int nld, i;
|
||||||
|
|
||||||
if (devno > userconf_maxdev) {
|
if (devno > userconf_maxdev) {
|
||||||
printf("Unknown devno (max is %d)\n", userconf_maxdev);
|
printf("Unknown devno (max is %d)\n", userconf_maxdev);
|
||||||
|
@ -239,11 +241,16 @@ userconf_pdev(short devno)
|
||||||
printf(" ???");
|
printf(" ???");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
l = cd->cf_loc;
|
if (cfp) {
|
||||||
ln = cd->cf_locnames;
|
l = cd->cf_loc;
|
||||||
while (ln && *ln) {
|
ia = cfiattr_lookup(cfp->cfp_iattr, 0);
|
||||||
printf(" %s ", *ln++);
|
KASSERT(ia);
|
||||||
userconf_pnum(*l++);
|
ld = ia->ci_locdesc;
|
||||||
|
nld = ia->ci_loclen;
|
||||||
|
for (i = 0; i < nld; i++) {
|
||||||
|
printf(" %s ", ld[i].cld_name);
|
||||||
|
userconf_pnum(*l++);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -363,7 +370,9 @@ userconf_change(int devno)
|
||||||
char c = '\0';
|
char c = '\0';
|
||||||
int *l;
|
int *l;
|
||||||
int ln;
|
int ln;
|
||||||
const char * const *locnames;
|
const struct cfiattrdata *ia;
|
||||||
|
const struct cflocdesc *ld;
|
||||||
|
int nld;
|
||||||
|
|
||||||
if (devno <= userconf_maxdev) {
|
if (devno <= userconf_maxdev) {
|
||||||
|
|
||||||
|
@ -383,17 +392,18 @@ userconf_change(int devno)
|
||||||
|
|
||||||
cd = &cfdata[devno];
|
cd = &cfdata[devno];
|
||||||
l = cd->cf_loc;
|
l = cd->cf_loc;
|
||||||
locnames = cd->cf_locnames;
|
ia = cfiattr_lookup(cd->cf_pspec->cfp_iattr, 0);
|
||||||
ln = 0;
|
KASSERT(ia);
|
||||||
|
ld = ia->ci_locdesc;
|
||||||
|
nld = ia->ci_loclen;
|
||||||
|
|
||||||
while (locnames[ln])
|
for (ln = 0; ln < nld; ln++)
|
||||||
{
|
{
|
||||||
userconf_modify(locnames[ln], l);
|
userconf_modify(ld[ln].cld_name, l);
|
||||||
|
|
||||||
/* XXX add *l */
|
/* XXX add *l */
|
||||||
userconf_hist_int(*l);
|
userconf_hist_int(*l);
|
||||||
|
|
||||||
ln++;
|
|
||||||
l++;
|
l++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: device.h,v 1.75 2005/06/28 18:37:34 drochner Exp $ */
|
/* $NetBSD: device.h,v 1.76 2005/08/25 15:06:28 drochner Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 2000 Christopher G. Demetriou
|
* Copyright (c) 1996, 2000 Christopher G. Demetriou
|
||||||
|
@ -171,6 +171,25 @@ TAILQ_HEAD(evcntlist, evcnt);
|
||||||
#define EVCNT_ATTACH_STATIC(ev) __link_set_add_data(evcnts, ev)
|
#define EVCNT_ATTACH_STATIC(ev) __link_set_add_data(evcnts, ev)
|
||||||
#define EVCNT_ATTACH_STATIC2(ev, n) __link_set_add_data2(evcnts, ev, n)
|
#define EVCNT_ATTACH_STATIC2(ev, n) __link_set_add_data2(evcnts, ev, n)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Description of a locator, as part of interface attribute definitions.
|
||||||
|
*/
|
||||||
|
struct cflocdesc {
|
||||||
|
const char *cld_name;
|
||||||
|
const char *cld_defaultstr; /* NULL if no default */
|
||||||
|
int cld_default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Description of an interface attribute, provided by potential
|
||||||
|
* parent device drivers, referred to by child device configuration data.
|
||||||
|
*/
|
||||||
|
struct cfiattrdata {
|
||||||
|
const char *ci_name;
|
||||||
|
int ci_loclen;
|
||||||
|
const struct cflocdesc ci_locdesc[];
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Description of a configuration parent. Each device attachment attaches
|
* Description of a configuration parent. Each device attachment attaches
|
||||||
* to an "interface attribute", which is given in this structure. The parent
|
* to an "interface attribute", which is given in this structure. The parent
|
||||||
|
@ -195,7 +214,6 @@ struct cfdata {
|
||||||
int *cf_loc; /* locators (machine dependent) */
|
int *cf_loc; /* locators (machine dependent) */
|
||||||
int cf_flags; /* flags from config */
|
int cf_flags; /* flags from config */
|
||||||
const struct cfparent *cf_pspec;/* parent specification */
|
const struct cfparent *cf_pspec;/* parent specification */
|
||||||
const char * const *cf_locnames;/* locator names (machine dependent) */
|
|
||||||
};
|
};
|
||||||
#define FSTATE_NOTFOUND 0 /* has not been found */
|
#define FSTATE_NOTFOUND 0 /* has not been found */
|
||||||
#define FSTATE_FOUND 1 /* has been found */
|
#define FSTATE_FOUND 1 /* has been found */
|
||||||
|
@ -215,7 +233,7 @@ TAILQ_HEAD(cftablelist, cftable);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX the "locdesc_t" is unnecessary; the len is known to "config" and
|
* XXX the "locdesc_t" is unnecessary; the len is known to "config" and
|
||||||
* should be made available through cfdata->cf_pspec->cfp_iattr.
|
* available through cfdata->cf_pspec->cfp_iattr.
|
||||||
* So just an "int *" should do it.
|
* So just an "int *" should do it.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -278,7 +296,7 @@ struct cfdriver {
|
||||||
const char *cd_name; /* device name */
|
const char *cd_name; /* device name */
|
||||||
enum devclass cd_class; /* device classification */
|
enum devclass cd_class; /* device classification */
|
||||||
int cd_ndevs; /* size of cd_devs array */
|
int cd_ndevs; /* size of cd_devs array */
|
||||||
const char * const *cd_attrs; /* attributes for this device */
|
const struct cfiattrdata * const *cd_attrs; /* attributes provided */
|
||||||
};
|
};
|
||||||
LIST_HEAD(cfdriverlist, cfdriver);
|
LIST_HEAD(cfdriverlist, cfdriver);
|
||||||
|
|
||||||
|
@ -354,6 +372,7 @@ int config_cfdata_detach(struct cfdata *);
|
||||||
|
|
||||||
struct cfdriver *config_cfdriver_lookup(const char *);
|
struct cfdriver *config_cfdriver_lookup(const char *);
|
||||||
struct cfattach *config_cfattach_lookup(const char *, const char *);
|
struct cfattach *config_cfattach_lookup(const char *, const char *);
|
||||||
|
const struct cfiattrdata *cfiattr_lookup(const char *, const struct cfdriver *);
|
||||||
|
|
||||||
struct cfdata *config_search_loc(cfsubmatch_t, struct device *,
|
struct cfdata *config_search_loc(cfsubmatch_t, struct device *,
|
||||||
const char *, const locdesc_t *, void *);
|
const char *, const locdesc_t *, void *);
|
||||||
|
|
Loading…
Reference in New Issue