version 1.277, 2021/01/27 04:54:08 |
version 1.277.2.10, 2021/04/03 16:09:44 |
Line 107 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 107 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/devmon.h> |
#include <sys/devmon.h> |
#include <sys/cpu.h> |
#include <sys/cpu.h> |
#include <sys/sysctl.h> |
#include <sys/sysctl.h> |
|
#include <sys/stdarg.h> |
|
|
#include <sys/disk.h> |
#include <sys/disk.h> |
|
|
Line 167 struct alldevs_foray { |
|
Line 168 struct alldevs_foray { |
|
|
|
static char *number(char *, int); |
static char *number(char *, int); |
static void mapply(struct matchinfo *, cfdata_t); |
static void mapply(struct matchinfo *, cfdata_t); |
static device_t config_devalloc(const device_t, const cfdata_t, const int *); |
static device_t config_vattach(device_t, cfdata_t, void *, cfprint_t, cfarg_t, |
|
va_list); |
static void config_devdelete(device_t); |
static void config_devdelete(device_t); |
static void config_devunlink(device_t, struct devicelist *); |
static void config_devunlink(device_t, struct devicelist *); |
static void config_makeroom(int, struct cfdriver *); |
static void config_makeroom(int, struct cfdriver *); |
Line 808 cfdriver_get_iattr(const struct cfdriver |
|
Line 810 cfdriver_get_iattr(const struct cfdriver |
|
return 0; |
return 0; |
} |
} |
|
|
|
#if defined(DIAGNOSTIC) |
|
static int |
|
cfdriver_iattr_count(const struct cfdriver *cd) |
|
{ |
|
const struct cfiattrdata * const *cpp; |
|
int i; |
|
|
|
if (cd->cd_attrs == NULL) |
|
return 0; |
|
|
|
for (i = 0, cpp = cd->cd_attrs; *cpp; cpp++) { |
|
i++; |
|
} |
|
return i; |
|
} |
|
#endif /* DIAGNOSTIC */ |
|
|
/* |
/* |
* Lookup an interface attribute description by name. |
* Lookup an interface attribute description by name. |
* If the driver is given, consider only its supported attributes. |
* If the driver is given, consider only its supported attributes. |
Line 1001 config_match(device_t parent, cfdata_t c |
|
Line 1020 config_match(device_t parent, cfdata_t c |
|
return (*ca->ca_match)(parent, cf, aux); |
return (*ca->ca_match)(parent, cf, aux); |
} |
} |
|
|
|
static void |
|
config_get_cfargs(cfarg_t tag, |
|
cfsubmatch_t *fnp, /* output */ |
|
const char **ifattrp, /* output */ |
|
const int **locsp, /* output */ |
|
devhandle_t *handlep, /* output */ |
|
va_list ap) |
|
{ |
|
cfsubmatch_t fn = NULL; |
|
const char *ifattr = NULL; |
|
const int *locs = NULL; |
|
devhandle_t handle; |
|
|
|
devhandle_invalidate(&handle); |
|
|
|
while (tag != CFARG_EOL) { |
|
switch (tag) { |
|
case CFARG_SUBMATCH: |
|
fn = va_arg(ap, cfsubmatch_t); |
|
break; |
|
|
|
case CFARG_IATTR: |
|
ifattr = va_arg(ap, const char *); |
|
break; |
|
|
|
case CFARG_LOCATORS: |
|
locs = va_arg(ap, const int *); |
|
break; |
|
|
|
case CFARG_DEVHANDLE: |
|
handle = va_arg(ap, devhandle_t); |
|
break; |
|
|
|
default: |
|
/* XXX panic? */ |
|
/* XXX dump stack backtrace? */ |
|
aprint_error("%s: unknown cfarg tag: %d\n", |
|
__func__, tag); |
|
goto out; |
|
} |
|
tag = va_arg(ap, cfarg_t); |
|
} |
|
|
|
out: |
|
if (fnp != NULL) |
|
*fnp = fn; |
|
if (ifattrp != NULL) |
|
*ifattrp = ifattr; |
|
if (locsp != NULL) |
|
*locsp = locs; |
|
if (handlep != NULL) |
|
*handlep = handle; |
|
} |
|
|
/* |
/* |
* Iterate over all potential children of some device, calling the given |
* Iterate over all potential children of some device, calling the given |
* function (default being the child's match function) for each one. |
* function (default being the child's match function) for each one. |
Line 1012 config_match(device_t parent, cfdata_t c |
|
Line 1085 config_match(device_t parent, cfdata_t c |
|
* an arbitrary function to all potential children (its return value |
* an arbitrary function to all potential children (its return value |
* can be ignored). |
* can be ignored). |
*/ |
*/ |
cfdata_t |
static cfdata_t |
config_search_loc(cfsubmatch_t fn, device_t parent, |
config_vsearch(device_t parent, void *aux, cfarg_t tag, va_list ap) |
const char *ifattr, const int *locs, void *aux) |
|
{ |
{ |
|
cfsubmatch_t fn; |
|
const char *ifattr; |
|
const int *locs; |
struct cftable *ct; |
struct cftable *ct; |
cfdata_t cf; |
cfdata_t cf; |
struct matchinfo m; |
struct matchinfo m; |
|
|
|
config_get_cfargs(tag, &fn, &ifattr, &locs, NULL, ap); |
|
|
KASSERT(config_initialized); |
KASSERT(config_initialized); |
KASSERT(!ifattr || cfdriver_get_iattr(parent->dv_cfdriver, ifattr)); |
KASSERT(!ifattr || cfdriver_get_iattr(parent->dv_cfdriver, ifattr)); |
|
KASSERT(ifattr || cfdriver_iattr_count(parent->dv_cfdriver) < 2); |
|
|
m.fn = fn; |
m.fn = fn; |
m.parent = parent; |
m.parent = parent; |
Line 1064 config_search_loc(cfsubmatch_t fn, devic |
|
Line 1142 config_search_loc(cfsubmatch_t fn, devic |
|
} |
} |
|
|
cfdata_t |
cfdata_t |
config_search_ia(cfsubmatch_t fn, device_t parent, const char *ifattr, |
config_search(device_t parent, void *aux, cfarg_t tag, ...) |
void *aux) |
|
{ |
{ |
|
cfdata_t cf; |
|
va_list ap; |
|
|
|
va_start(ap, tag); |
|
cf = config_vsearch(parent, aux, tag, ap); |
|
va_end(ap); |
|
|
return config_search_loc(fn, parent, ifattr, NULL, aux); |
return cf; |
} |
} |
|
|
/* |
/* |
Line 1113 static const char * const msgs[3] = { "" |
|
Line 1196 static const char * const msgs[3] = { "" |
|
* functions) and attach it, and return its device_t. If the device was |
* functions) and attach it, and return its device_t. If the device was |
* not configured, call the given `print' function and return NULL. |
* not configured, call the given `print' function and return NULL. |
*/ |
*/ |
device_t |
static device_t |
config_found_sm_loc(device_t parent, |
config_vfound(device_t parent, void *aux, cfprint_t print, cfarg_t tag, |
const char *ifattr, const int *locs, void *aux, |
va_list ap) |
cfprint_t print, cfsubmatch_t submatch) |
|
{ |
{ |
cfdata_t cf; |
cfdata_t cf; |
|
va_list nap; |
|
|
|
va_copy(nap, ap); |
|
cf = config_vsearch(parent, aux, tag, nap); |
|
va_end(nap); |
|
|
|
if (cf != NULL) { |
|
return config_vattach(parent, cf, aux, print, tag, ap); |
|
} |
|
|
if ((cf = config_search_loc(submatch, parent, ifattr, locs, aux))) |
|
return(config_attach_loc(parent, cf, locs, aux, print)); |
|
if (print) { |
if (print) { |
if (config_do_twiddle && cold) |
if (config_do_twiddle && cold) |
twiddle(); |
twiddle(); |
Line 1140 config_found_sm_loc(device_t parent, |
|
Line 1229 config_found_sm_loc(device_t parent, |
|
} |
} |
|
|
device_t |
device_t |
config_found_ia(device_t parent, const char *ifattr, void *aux, |
config_found(device_t parent, void *aux, cfprint_t print, cfarg_t tag, ...) |
cfprint_t print) |
|
{ |
{ |
|
device_t dev; |
|
va_list ap; |
|
|
return config_found_sm_loc(parent, ifattr, NULL, aux, print, NULL); |
va_start(ap, tag); |
} |
dev = config_vfound(parent, aux, print, tag, ap); |
|
va_end(ap); |
device_t |
|
config_found(device_t parent, void *aux, cfprint_t print) |
|
{ |
|
|
|
return config_found_sm_loc(parent, NULL, NULL, aux, print, NULL); |
return dev; |
} |
} |
|
|
/* |
/* |
Line 1163 config_rootfound(const char *rootname, v |
|
Line 1250 config_rootfound(const char *rootname, v |
|
cfdata_t cf; |
cfdata_t cf; |
|
|
if ((cf = config_rootsearch(NULL, rootname, aux)) != NULL) |
if ((cf = config_rootsearch(NULL, rootname, aux)) != NULL) |
return config_attach(ROOT, cf, aux, NULL); |
return config_attach(ROOT, cf, aux, NULL, CFARG_EOL); |
aprint_error("root device %s not configured\n", rootname); |
aprint_error("root device %s not configured\n", rootname); |
return NULL; |
return NULL; |
} |
} |
Line 1379 config_unit_alloc(device_t dev, cfdriver |
|
Line 1466 config_unit_alloc(device_t dev, cfdriver |
|
} |
} |
|
|
static device_t |
static device_t |
config_devalloc(const device_t parent, const cfdata_t cf, const int *locs) |
config_vdevalloc(const device_t parent, const cfdata_t cf, cfarg_t tag, |
|
va_list ap) |
{ |
{ |
cfdriver_t cd; |
cfdriver_t cd; |
cfattach_t ca; |
cfattach_t ca; |
Line 1391 config_devalloc(const device_t parent, c |
|
Line 1479 config_devalloc(const device_t parent, c |
|
void *dev_private; |
void *dev_private; |
const struct cfiattrdata *ia; |
const struct cfiattrdata *ia; |
device_lock_t dvl; |
device_lock_t dvl; |
|
const int *locs; |
|
|
cd = config_cfdriver_lookup(cf->cf_name); |
cd = config_cfdriver_lookup(cf->cf_name); |
if (cd == NULL) |
if (cd == NULL) |
Line 1409 config_devalloc(const device_t parent, c |
|
Line 1498 config_devalloc(const device_t parent, c |
|
} |
} |
dev = kmem_zalloc(sizeof(*dev), KM_SLEEP); |
dev = kmem_zalloc(sizeof(*dev), KM_SLEEP); |
|
|
|
/* |
|
* If a handle was supplied to config_attach(), we'll get it |
|
* assigned automatically here. If not, then we'll get the |
|
* default invalid handle. |
|
*/ |
|
config_get_cfargs(tag, NULL, NULL, &locs, &dev->dv_handle, ap); |
|
|
dev->dv_class = cd->cd_class; |
dev->dv_class = cd->cd_class; |
dev->dv_cfdata = cf; |
dev->dv_cfdata = cf; |
dev->dv_cfdriver = cd; |
dev->dv_cfdriver = cd; |
Line 1429 config_devalloc(const device_t parent, c |
|
Line 1525 config_devalloc(const device_t parent, c |
|
xunit = number(&num[sizeof(num)], myunit); |
xunit = number(&num[sizeof(num)], myunit); |
lunit = &num[sizeof(num)] - xunit; |
lunit = &num[sizeof(num)] - xunit; |
if (lname + lunit > sizeof(dev->dv_xname)) |
if (lname + lunit > sizeof(dev->dv_xname)) |
panic("config_devalloc: device name too long"); |
panic("config_vdevalloc: device name too long"); |
|
|
dvl = device_getlock(dev); |
dvl = device_getlock(dev); |
|
|
Line 1470 config_devalloc(const device_t parent, c |
|
Line 1566 config_devalloc(const device_t parent, c |
|
return dev; |
return dev; |
} |
} |
|
|
|
static device_t |
|
config_devalloc(const device_t parent, const cfdata_t cf, cfarg_t tag, ...) |
|
{ |
|
device_t dev; |
|
va_list ap; |
|
|
|
va_start(ap, tag); |
|
dev = config_vdevalloc(parent, cf, tag, ap); |
|
va_end(ap); |
|
|
|
return dev; |
|
} |
|
|
/* |
/* |
* Create an array of device attach attributes and add it |
* Create an array of device attach attributes and add it |
* to the device's dv_properties dictionary. |
* to the device's dv_properties dictionary. |
Line 1552 config_add_attrib_dict(device_t dev) |
|
Line 1661 config_add_attrib_dict(device_t dev) |
|
/* |
/* |
* Attach a found device. |
* Attach a found device. |
*/ |
*/ |
device_t |
static device_t |
config_attach_loc(device_t parent, cfdata_t cf, |
config_vattach(device_t parent, cfdata_t cf, void *aux, cfprint_t print, |
const int *locs, void *aux, cfprint_t print) |
cfarg_t tag, va_list ap) |
{ |
{ |
device_t dev; |
device_t dev; |
struct cftable *ct; |
struct cftable *ct; |
const char *drvname; |
const char *drvname; |
|
|
dev = config_devalloc(parent, cf, locs); |
dev = config_vdevalloc(parent, cf, tag, ap); |
if (!dev) |
if (!dev) |
panic("config_attach: allocation of device softc failed"); |
panic("config_attach: allocation of device softc failed"); |
|
|
Line 1626 config_attach_loc(device_t parent, cfdat |
|
Line 1735 config_attach_loc(device_t parent, cfdat |
|
} |
} |
|
|
device_t |
device_t |
config_attach(device_t parent, cfdata_t cf, void *aux, cfprint_t print) |
config_attach(device_t parent, cfdata_t cf, void *aux, cfprint_t print, |
|
cfarg_t tag, ...) |
{ |
{ |
|
device_t dev; |
|
va_list ap; |
|
|
|
va_start(ap, tag); |
|
dev = config_vattach(parent, cf, aux, print, tag, ap); |
|
va_end(ap); |
|
|
return config_attach_loc(parent, cf, NULL, aux, print); |
return dev; |
} |
} |
|
|
/* |
/* |
Line 1646 config_attach_pseudo(cfdata_t cf) |
|
Line 1762 config_attach_pseudo(cfdata_t cf) |
|
{ |
{ |
device_t dev; |
device_t dev; |
|
|
dev = config_devalloc(ROOT, cf, NULL); |
dev = config_devalloc(ROOT, cf, CFARG_EOL); |
if (!dev) |
if (!dev) |
return NULL; |
return NULL; |
|
|