summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_bus.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2000-06-15 09:57:20 +0000
committerpeter <peter@FreeBSD.org>2000-06-15 09:57:20 +0000
commitf29679832cc93d2704e4eddf06408ba75d926ed4 (patch)
treedc3331a25d65385ece00b07e19d2329db1246420 /sys/kern/subr_bus.c
parentffbc430314ceb9933d963f6f5af5476352346820 (diff)
downloadFreeBSD-src-f29679832cc93d2704e4eddf06408ba75d926ed4.zip
FreeBSD-src-f29679832cc93d2704e4eddf06408ba75d926ed4.tar.gz
As a bit of a gross hack, allow earlier access to both the static and
dynamic hints. This allows the resource_XXX_value() calls to work before malloc() has started. This gets the serial console working as well as a few other things.
Diffstat (limited to 'sys/kern/subr_bus.c')
-rw-r--r--sys/kern/subr_bus.c62
1 files changed, 58 insertions, 4 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index c859cc7..7690444 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -98,6 +98,9 @@ static void device_register_oids(device_t dev);
static void device_unregister_oids(device_t dev);
#endif
+extern char static_hints[];
+static int hints_loaded;
+
kobj_method_t null_methods[] = {
{ 0, 0 }
};
@@ -1279,12 +1282,65 @@ resource_match_string(int i, const char *resname, const char *value)
}
static int
+resource_find_hard(const char *cp, const char *name, int unit,
+ const char *resname, struct config_resource **result)
+{
+ static char match[100];
+ int matchlen;
+ char *op;
+ long val;
+
+ snprintf(match, sizeof(match), "hint.%s.%d.%s=", name, unit, resname);
+ matchlen = strlen(match);
+ while (cp) {
+ if (strncmp(match, cp, matchlen) == 0)
+ break;
+ while (*cp != '\0')
+ cp++;
+ cp++;
+ if (*cp == '\0') {
+ cp = NULL;
+ break;
+ }
+ }
+ if (cp)
+ cp += matchlen; /* skip over name and '=' */
+ else
+ return ENOENT;
+ val = strtol(cp, &op, 0);
+ if (*cp != '\0' && *op == '\0') {
+ (*result)->type = RES_INT;
+ (*result)->u.intval = val;
+ } else {
+ (*result)->type = RES_STRING;
+ (*result)->u.stringval = cp;
+ }
+ return 0;
+}
+
+static int
resource_find(const char *name, int unit, const char *resname,
struct config_resource **result)
{
int i, j;
struct config_resource *res;
+ if (!hints_loaded) {
+ /* First specific, then generic. Dynamic over static. */
+ i = resource_find_hard(kern_envp, name, unit, resname, result);
+ if (i == 0)
+ return 0;
+ i = resource_find_hard(static_hints, name, unit, resname,
+ result);
+ if (i == 0)
+ return 0;
+ i = resource_find_hard(kern_envp, name, -1, resname, result);
+ if (i == 0)
+ return 0;
+ i = resource_find_hard(static_hints, name, -1, resname, result);
+ return i;
+ }
+
/*
* First check specific instances, then generic.
*/
@@ -1303,9 +1359,7 @@ resource_find(const char *name, int unit, const char *resname,
for (i = 0; i < devtab_count; i++) {
if (devtab[i].unit >= 0)
continue;
- /* XXX should this `&& devtab[i].unit == unit' be here? */
- /* XXX if so, then the generic match does nothing */
- if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {
+ if (!strcmp(devtab[i].name, name)) {
res = devtab[i].resources;
for (j = 0; j < devtab[i].resource_count; j++, res++)
if (!strcmp(res->name, resname)) {
@@ -1562,7 +1616,6 @@ hint_load(char *cp)
}
}
-extern char static_hints[];
static void
hints_load(void *dummy __unused)
@@ -1587,6 +1640,7 @@ hints_load(void *dummy __unused)
if (*cp == 0)
break;
}
+ hints_loaded++;
}
SYSINIT(cfghints, SI_SUB_KMEM, SI_ORDER_ANY + 60, hints_load, 0)
OpenPOWER on IntegriCloud