summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJennifer Averett <jennifer.averett@oarcorp.com>2012-04-16 13:22:45 -0500
committerJennifer Averett <jennifer.averett@oarcorp.com>2012-04-16 13:22:45 -0500
commite4b9989d16bb47f5f8b54d586cffd8b0610e7e14 (patch)
tree4d4b9fa46cd70f635566ea98f18c47b66066a9b9
parentAdded get_cyclecount() method. (diff)
downloadrtems-libbsd-e4b9989d16bb47f5f8b54d586cffd8b0610e7e14.tar.bz2
Addded resource_XXX methods to resolve linker issues.
-rw-r--r--Makefile1
-rwxr-xr-xfreebsd-to-rtems.py1
-rw-r--r--freebsd/kern/subr_hints.c389
3 files changed, 391 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 5632da70..13f8b19e 100644
--- a/Makefile
+++ b/Makefile
@@ -312,6 +312,7 @@ C_FILES = \
freebsd/cam/cam.c \
freebsd/cam/scsi/scsi_all.c \
freebsd/dev/usb/storage/umass.c \
+ freebsd/kern/subr_hints.c \
freebsd/dev/random/harvest.c \
freebsd/libkern/random.c \
freebsd/libkern/arc4random.c \
diff --git a/freebsd-to-rtems.py b/freebsd-to-rtems.py
index a3be1c11..fdd679b6 100755
--- a/freebsd-to-rtems.py
+++ b/freebsd-to-rtems.py
@@ -1128,6 +1128,7 @@ devNic.addHeaderFiles(
devNic.addSourceFiles(
[
# 'kern/subr_taskqueue.c',
+ 'kern/subr_hints.c',
'dev/random/harvest.c',
'libkern/random.c',
'libkern/arc4random.c',
diff --git a/freebsd/kern/subr_hints.c b/freebsd/kern/subr_hints.c
new file mode 100644
index 00000000..398b0aaa
--- /dev/null
+++ b/freebsd/kern/subr_hints.c
@@ -0,0 +1,389 @@
+#include <freebsd/machine/rtems-bsd-config.h>
+
+/*-
+ * Copyright (c) 2000,2001 Peter Wemm <peter@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <freebsd/sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <freebsd/sys/param.h>
+#include <freebsd/sys/lock.h>
+#include <freebsd/sys/mutex.h>
+#include <freebsd/sys/systm.h>
+#include <freebsd/sys/bus.h>
+
+/*
+ * Access functions for device resources.
+ */
+
+static int checkmethod = 1;
+static int use_kenv;
+static char *hintp;
+
+/*
+ * Evil wildcarding resource string lookup.
+ * This walks the supplied env string table and returns a match.
+ * The start point can be remembered for incremental searches.
+ */
+static int
+res_find(int *line, int *startln,
+ const char *name, int *unit, const char *resname, const char *value,
+ const char **ret_name, int *ret_namelen, int *ret_unit,
+ const char **ret_resname, int *ret_resnamelen, const char **ret_value)
+{
+ int n = 0, hit, i = 0;
+ char r_name[32];
+ int r_unit;
+ char r_resname[32];
+ char r_value[128];
+ const char *s, *cp;
+ char *p;
+
+ if (checkmethod) {
+ hintp = NULL;
+
+ switch (hintmode) {
+ case 0: /* loader hints in environment only */
+ break;
+ case 1: /* static hints only */
+ hintp = static_hints;
+ checkmethod = 0;
+ break;
+ case 2: /* fallback mode */
+ if (dynamic_kenv) {
+ mtx_lock(&kenv_lock);
+ cp = kenvp[0];
+ for (i = 0; cp != NULL; cp = kenvp[++i]) {
+ if (!strncmp(cp, "hint.", 5)) {
+ use_kenv = 1;
+ checkmethod = 0;
+ break;
+ }
+ }
+ mtx_unlock(&kenv_lock);
+ } else {
+ cp = kern_envp;
+ while (cp) {
+ if (strncmp(cp, "hint.", 5) == 0) {
+ cp = NULL;
+ hintp = kern_envp;
+ break;
+ }
+ while (*cp != '\0')
+ cp++;
+ cp++;
+ if (*cp == '\0') {
+ cp = NULL;
+ hintp = static_hints;
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if (hintp == NULL) {
+ if (dynamic_kenv) {
+ use_kenv = 1;
+ checkmethod = 0;
+ } else
+ hintp = kern_envp;
+ }
+ }
+
+ if (use_kenv) {
+ mtx_lock(&kenv_lock);
+ i = 0;
+ cp = kenvp[0];
+ if (cp == NULL) {
+ mtx_unlock(&kenv_lock);
+ return (ENOENT);
+ }
+ } else
+ cp = hintp;
+ while (cp) {
+ hit = 1;
+ (*line)++;
+ if (strncmp(cp, "hint.", 5) != 0)
+ hit = 0;
+ else
+ n = sscanf(cp, "hint.%32[^.].%d.%32[^=]=%128s",
+ r_name, &r_unit, r_resname, r_value);
+ if (hit && n != 4) {
+ printf("CONFIG: invalid hint '%s'\n", cp);
+ /* XXX: abuse bogus index() declaration */
+ p = index(cp, 'h');
+ *p = 'H';
+ hit = 0;
+ }
+ if (hit && startln && *startln >= 0 && *line < *startln)
+ hit = 0;
+ if (hit && name && strcmp(name, r_name) != 0)
+ hit = 0;
+ if (hit && unit && *unit != r_unit)
+ hit = 0;
+ if (hit && resname && strcmp(resname, r_resname) != 0)
+ hit = 0;
+ if (hit && value && strcmp(value, r_value) != 0)
+ hit = 0;
+ if (hit)
+ break;
+ if (use_kenv) {
+ cp = kenvp[++i];
+ if (cp == NULL)
+ break;
+ } else {
+ while (*cp != '\0')
+ cp++;
+ cp++;
+ if (*cp == '\0') {
+ cp = NULL;
+ break;
+ }
+ }
+ }
+ if (use_kenv)
+ mtx_unlock(&kenv_lock);
+ if (cp == NULL)
+ return ENOENT;
+
+ s = cp;
+ /* This is a bit of a hack, but at least is reentrant */
+ /* Note that it returns some !unterminated! strings. */
+ s = index(s, '.') + 1; /* start of device */
+ if (ret_name)
+ *ret_name = s;
+ s = index(s, '.') + 1; /* start of unit */
+ if (ret_namelen && ret_name)
+ *ret_namelen = s - *ret_name - 1; /* device length */
+ if (ret_unit)
+ *ret_unit = r_unit;
+ s = index(s, '.') + 1; /* start of resname */
+ if (ret_resname)
+ *ret_resname = s;
+ s = index(s, '=') + 1; /* start of value */
+ if (ret_resnamelen && ret_resname)
+ *ret_resnamelen = s - *ret_resname - 1; /* value len */
+ if (ret_value)
+ *ret_value = s;
+ if (startln) /* line number for anchor */
+ *startln = *line + 1;
+ return 0;
+}
+
+/*
+ * Search all the data sources for matches to our query. We look for
+ * dynamic hints first as overrides for static or fallback hints.
+ */
+static int
+resource_find(int *line, int *startln,
+ const char *name, int *unit, const char *resname, const char *value,
+ const char **ret_name, int *ret_namelen, int *ret_unit,
+ const char **ret_resname, int *ret_resnamelen, const char **ret_value)
+{
+ int i;
+ int un;
+
+ *line = 0;
+
+ /* Search for exact unit matches first */
+ i = res_find(line, startln, name, unit, resname, value,
+ ret_name, ret_namelen, ret_unit, ret_resname, ret_resnamelen,
+ ret_value);
+ if (i == 0)
+ return 0;
+ if (unit == NULL)
+ return ENOENT;
+ /* If we are still here, search for wildcard matches */
+ un = -1;
+ i = res_find(line, startln, name, &un, resname, value,
+ ret_name, ret_namelen, ret_unit, ret_resname, ret_resnamelen,
+ ret_value);
+ if (i == 0)
+ return 0;
+ return ENOENT;
+}
+
+int
+resource_int_value(const char *name, int unit, const char *resname, int *result)
+{
+ int error;
+ const char *str;
+ char *op;
+ unsigned long val;
+ int line;
+
+ line = 0;
+ error = resource_find(&line, NULL, name, &unit, resname, NULL,
+ NULL, NULL, NULL, NULL, NULL, &str);
+ if (error)
+ return error;
+ if (*str == '\0')
+ return EFTYPE;
+ val = strtoul(str, &op, 0);
+ if (*op != '\0')
+ return EFTYPE;
+ *result = val;
+ return 0;
+}
+
+#ifndef __rtems__
+int
+resource_long_value(const char *name, int unit, const char *resname,
+ long *result)
+{
+ int error;
+ const char *str;
+ char *op;
+ unsigned long val;
+ int line;
+
+ line = 0;
+ error = resource_find(&line, NULL, name, &unit, resname, NULL,
+ NULL, NULL, NULL, NULL, NULL, &str);
+ if (error)
+ return error;
+ if (*str == '\0')
+ return EFTYPE;
+ val = strtoul(str, &op, 0);
+ if (*op != '\0')
+ return EFTYPE;
+ *result = val;
+ return 0;
+}
+#endif /* __rtems__ */
+
+int
+resource_string_value(const char *name, int unit, const char *resname,
+ const char **result)
+{
+ int error;
+ const char *str;
+ int line;
+
+ line = 0;
+ error = resource_find(&line, NULL, name, &unit, resname, NULL,
+ NULL, NULL, NULL, NULL, NULL, &str);
+ if (error)
+ return error;
+ *result = str;
+ return 0;
+}
+
+/*
+ * This is a bit nasty, but allows us to not modify the env strings.
+ */
+static const char *
+resource_string_copy(const char *s, int len)
+{
+ static char stringbuf[256];
+ static int offset = 0;
+ const char *ret;
+
+ if (len == 0)
+ len = strlen(s);
+ if (len > 255)
+ return NULL;
+ if ((offset + len + 1) > 255)
+ offset = 0;
+ bcopy(s, &stringbuf[offset], len);
+ stringbuf[offset + len] = '\0';
+ ret = &stringbuf[offset];
+ offset += len + 1;
+ return ret;
+}
+
+/*
+ * err = resource_find_match(&anchor, &name, &unit, resname, value)
+ * Iteratively fetch a list of devices wired "at" something
+ * res and value are restrictions. eg: "at", "scbus0".
+ * For practical purposes, res = required, value = optional.
+ * *name and *unit are set.
+ * set *anchor to zero before starting.
+ */
+int
+resource_find_match(int *anchor, const char **name, int *unit,
+ const char *resname, const char *value)
+{
+ const char *found_name;
+ int found_namelen;
+ int found_unit;
+ int ret;
+ int newln;
+
+ newln = *anchor;
+ ret = resource_find(anchor, &newln, NULL, NULL, resname, value,
+ &found_name, &found_namelen, &found_unit, NULL, NULL, NULL);
+ if (ret == 0) {
+ *name = resource_string_copy(found_name, found_namelen);
+ *unit = found_unit;
+ }
+ *anchor = newln;
+ return ret;
+}
+
+#ifndef __rtems__
+
+/*
+ * err = resource_find_dev(&anchor, name, &unit, res, value);
+ * Iterate through a list of devices, returning their unit numbers.
+ * res and value are optional restrictions. eg: "at", "scbus0".
+ * *unit is set to the value.
+ * set *anchor to zero before starting.
+ */
+int
+resource_find_dev(int *anchor, const char *name, int *unit,
+ const char *resname, const char *value)
+{
+ int found_unit;
+ int newln;
+ int ret;
+
+ newln = *anchor;
+ ret = resource_find(anchor, &newln, name, NULL, resname, value,
+ NULL, NULL, &found_unit, NULL, NULL, NULL);
+ if (ret == 0) {
+ *unit = found_unit;
+ }
+ *anchor = newln;
+ return ret;
+}
+
+/*
+ * Check to see if a device is disabled via a disabled hint.
+ */
+int
+resource_disabled(const char *name, int unit)
+{
+ int error, value;
+
+ error = resource_int_value(name, unit, "disabled", &value);
+ if (error)
+ return (0);
+ return (value);
+}
+#endif /* __rtems__ */