diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-08-21 13:47:02 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-21 10:29:41 +0200 |
commit | bcdce02d9bc8150e1d191ed5ca9da45b7604964a (patch) | |
tree | 3b2faf509db7672ee1fc98857736470be97e7ed8 /freebsd/sys/dev/ofw | |
parent | Update to FreeBSD head 2018-04-01 (diff) | |
download | rtems-libbsd-bcdce02d9bc8150e1d191ed5ca9da45b7604964a.tar.bz2 |
Update to FreeBSD head 2018-06-01
Git mirror commit fb63610a69b0eb7f69a201ba05c4c1a7a2739cf9.
Update #3472.
Diffstat (limited to 'freebsd/sys/dev/ofw')
-rw-r--r-- | freebsd/sys/dev/ofw/ofw_bus_subr.c | 61 | ||||
-rw-r--r-- | freebsd/sys/dev/ofw/ofw_bus_subr.h | 2 | ||||
-rw-r--r-- | freebsd/sys/dev/ofw/ofw_fdt.c | 2 | ||||
-rw-r--r-- | freebsd/sys/dev/ofw/openfirm.c | 63 | ||||
-rw-r--r-- | freebsd/sys/dev/ofw/openfirm.h | 6 |
5 files changed, 97 insertions, 37 deletions
diff --git a/freebsd/sys/dev/ofw/ofw_bus_subr.c b/freebsd/sys/dev/ofw/ofw_bus_subr.c index 8406988f..5038bb03 100644 --- a/freebsd/sys/dev/ofw/ofw_bus_subr.c +++ b/freebsd/sys/dev/ofw/ofw_bus_subr.c @@ -59,12 +59,12 @@ ofw_bus_gen_setup_devinfo(struct ofw_bus_devinfo *obd, phandle_t node) if (obd == NULL) return (ENOMEM); /* The 'name' property is considered mandatory. */ - if ((OF_getprop_alloc(node, "name", 1, (void **)&obd->obd_name)) == -1) + if ((OF_getprop_alloc(node, "name", (void **)&obd->obd_name)) == -1) return (EINVAL); - OF_getprop_alloc(node, "compatible", 1, (void **)&obd->obd_compat); - OF_getprop_alloc(node, "device_type", 1, (void **)&obd->obd_type); - OF_getprop_alloc(node, "model", 1, (void **)&obd->obd_model); - OF_getprop_alloc(node, "status", 1, (void **)&obd->obd_status); + OF_getprop_alloc(node, "compatible", (void **)&obd->obd_compat); + OF_getprop_alloc(node, "device_type", (void **)&obd->obd_type); + OF_getprop_alloc(node, "model", (void **)&obd->obd_model); + OF_getprop_alloc(node, "status", (void **)&obd->obd_status); obd->obd_node = node; return (0); } @@ -321,10 +321,10 @@ ofw_bus_setup_iinfo(phandle_t node, struct ofw_bus_iinfo *ii, int intrsz) addrc = 2; ii->opi_addrc = addrc * sizeof(pcell_t); - ii->opi_imapsz = OF_getencprop_alloc(node, "interrupt-map", 1, + ii->opi_imapsz = OF_getencprop_alloc(node, "interrupt-map", (void **)&ii->opi_imap); if (ii->opi_imapsz > 0) { - msksz = OF_getencprop_alloc(node, "interrupt-map-mask", 1, + msksz = OF_getencprop_alloc(node, "interrupt-map-mask", (void **)&ii->opi_imapmsk); /* * Failure to get the mask is ignored; a full mask is used @@ -451,7 +451,8 @@ ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent, int err, i; /* TODO: This should be OF_searchprop_alloc if we had it */ - len = OF_getencprop_alloc(node, "msi-map", sizeof(*map), (void **)&map); + len = OF_getencprop_alloc_multi(node, "msi-map", sizeof(*map), + (void **)&map); if (len < 0) { if (msi_parent != NULL) { *msi_parent = 0; @@ -491,9 +492,9 @@ ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent, return (err); } -int -ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells, - struct resource_list *rl) +static int +ofw_bus_reg_to_rl_helper(device_t dev, phandle_t node, pcell_t acells, pcell_t scells, + struct resource_list *rl, const char *reg_source) { uint64_t phys, size; ssize_t i, j, rid, nreg, ret; @@ -504,11 +505,12 @@ ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells, * This may be just redundant when having ofw_bus_devinfo * but makes this routine independent of it. */ - ret = OF_getprop_alloc(node, "name", sizeof(*name), (void **)&name); + ret = OF_getprop_alloc(node, "name", (void **)&name); if (ret == -1) name = NULL; - ret = OF_getencprop_alloc(node, "reg", sizeof(*reg), (void **)®); + ret = OF_getencprop_alloc_multi(node, reg_source, sizeof(*reg), + (void **)®); nreg = (ret == -1) ? 0 : ret; if (nreg % (acells + scells) != 0) { @@ -539,6 +541,23 @@ ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells, return (0); } +int +ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells, + struct resource_list *rl) +{ + + return (ofw_bus_reg_to_rl_helper(dev, node, acells, scells, rl, "reg")); +} + +int +ofw_bus_assigned_addresses_to_rl(device_t dev, phandle_t node, pcell_t acells, + pcell_t scells, struct resource_list *rl) +{ + + return (ofw_bus_reg_to_rl_helper(dev, node, acells, scells, + rl, "assigned-addresses")); +} + /* * Get interrupt parent for given node. * Returns 0 if interrupt parent doesn't exist. @@ -569,7 +588,7 @@ ofw_bus_intr_to_rl(device_t dev, phandle_t node, int err, i, irqnum, nintr, rid; boolean_t extended; - nintr = OF_getencprop_alloc(node, "interrupts", sizeof(*intr), + nintr = OF_getencprop_alloc_multi(node, "interrupts", sizeof(*intr), (void **)&intr); if (nintr > 0) { iparent = ofw_bus_find_iparent(node); @@ -592,7 +611,7 @@ ofw_bus_intr_to_rl(device_t dev, phandle_t node, } extended = false; } else { - nintr = OF_getencprop_alloc(node, "interrupts-extended", + nintr = OF_getencprop_alloc_multi(node, "interrupts-extended", sizeof(*intr), (void **)&intr); if (nintr <= 0) return (0); @@ -635,7 +654,7 @@ ofw_bus_intr_by_rid(device_t dev, phandle_t node, int wanted_rid, int err, i, nintr, rid; boolean_t extended; - nintr = OF_getencprop_alloc(node, "interrupts", sizeof(*intr), + nintr = OF_getencprop_alloc_multi(node, "interrupts", sizeof(*intr), (void **)&intr); if (nintr > 0) { iparent = ofw_bus_find_iparent(node); @@ -658,7 +677,7 @@ ofw_bus_intr_by_rid(device_t dev, phandle_t node, int wanted_rid, } extended = false; } else { - nintr = OF_getencprop_alloc(node, "interrupts-extended", + nintr = OF_getencprop_alloc_multi(node, "interrupts-extended", sizeof(*intr), (void **)&intr); if (nintr <= 0) return (ESRCH); @@ -705,7 +724,7 @@ ofw_bus_find_child(phandle_t start, const char *child_name) phandle_t child; for (child = OF_child(start); child != 0; child = OF_peer(child)) { - ret = OF_getprop_alloc(child, "name", sizeof(*name), (void **)&name); + ret = OF_getprop_alloc(child, "name", (void **)&name); if (ret == -1) continue; if (strcmp(name, child_name) == 0) { @@ -806,7 +825,7 @@ ofw_bus_parse_xref_list_internal(phandle_t node, const char *list_name, int rv, i, j, nelems, cnt; elems = NULL; - nelems = OF_getencprop_alloc(node, list_name, sizeof(*elems), + nelems = OF_getencprop_alloc_multi(node, list_name, sizeof(*elems), (void **)&elems); if (nelems <= 0) return (ENOENT); @@ -901,7 +920,7 @@ ofw_bus_find_string_index(phandle_t node, const char *list_name, int rv, i, cnt, nelems; elems = NULL; - nelems = OF_getprop_alloc(node, list_name, 1, (void **)&elems); + nelems = OF_getprop_alloc(node, list_name, (void **)&elems); if (nelems <= 0) return (ENOENT); @@ -932,7 +951,7 @@ ofw_bus_string_list_to_array(phandle_t node, const char *list_name, int i, cnt, nelems, len; elems = NULL; - nelems = OF_getprop_alloc(node, list_name, 1, (void **)&elems); + nelems = OF_getprop_alloc(node, list_name, (void **)&elems); if (nelems <= 0) return (nelems); diff --git a/freebsd/sys/dev/ofw/ofw_bus_subr.h b/freebsd/sys/dev/ofw/ofw_bus_subr.h index 04f5a75b..7bf66a10 100644 --- a/freebsd/sys/dev/ofw/ofw_bus_subr.h +++ b/freebsd/sys/dev/ofw/ofw_bus_subr.h @@ -95,6 +95,8 @@ int ofw_bus_msimap(phandle_t, uint16_t, phandle_t *, uint32_t *); /* Routines for parsing device-tree data into resource lists. */ int ofw_bus_reg_to_rl(device_t, phandle_t, pcell_t, pcell_t, struct resource_list *); +int ofw_bus_assigned_addresses_to_rl(device_t, phandle_t, pcell_t, pcell_t, + struct resource_list *); int ofw_bus_intr_to_rl(device_t, phandle_t, struct resource_list *, int *); int ofw_bus_intr_by_rid(device_t, phandle_t, int, phandle_t *, int *, pcell_t **); diff --git a/freebsd/sys/dev/ofw/ofw_fdt.c b/freebsd/sys/dev/ofw/ofw_fdt.c index 8878b5c9..b1bbadee 100644 --- a/freebsd/sys/dev/ofw/ofw_fdt.c +++ b/freebsd/sys/dev/ofw/ofw_fdt.c @@ -134,7 +134,7 @@ sysctl_register_fdt_oid(void *arg) CTLTYPE_OPAQUE | CTLFLAG_RD, NULL, 0, sysctl_handle_dtb, "", "Device Tree Blob"); } -SYSINIT(dtb_oid, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_fdt_oid, 0); +SYSINIT(dtb_oid, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_fdt_oid, NULL); static int ofw_fdt_init(ofw_t ofw, void *data) diff --git a/freebsd/sys/dev/ofw/openfirm.c b/freebsd/sys/dev/ofw/openfirm.c index 406e8dd6..9cc7dbdc 100644 --- a/freebsd/sys/dev/ofw/openfirm.c +++ b/freebsd/sys/dev/ofw/openfirm.c @@ -442,7 +442,7 @@ OF_searchprop(phandle_t node, const char *propname, void *buf, size_t len) } ssize_t -OF_searchencprop(phandle_t node, const char *propname, void *buf, size_t len) +OF_searchencprop(phandle_t node, const char *propname, pcell_t *buf, size_t len) { ssize_t rv; @@ -454,11 +454,35 @@ OF_searchencprop(phandle_t node, const char *propname, void *buf, size_t len) /* * Store the value of a property of a package into newly allocated memory + * (using the M_OFWPROP malloc pool and M_WAITOK). + */ +ssize_t +OF_getprop_alloc(phandle_t package, const char *propname, void **buf) +{ + int len; + + *buf = NULL; + if ((len = OF_getproplen(package, propname)) == -1) + return (-1); + + if (len > 0) { + *buf = malloc(len, M_OFWPROP, M_WAITOK); + if (OF_getprop(package, propname, *buf, len) == -1) { + free(*buf, M_OFWPROP); + *buf = NULL; + return (-1); + } + } + return (len); +} + +/* + * Store the value of a property of a package into newly allocated memory * (using the M_OFWPROP malloc pool and M_WAITOK). elsz is the size of a * single element, the number of elements is return in number. */ ssize_t -OF_getprop_alloc(phandle_t package, const char *propname, int elsz, void **buf) +OF_getprop_alloc_multi(phandle_t package, const char *propname, int elsz, void **buf) { int len; @@ -467,30 +491,41 @@ OF_getprop_alloc(phandle_t package, const char *propname, int elsz, void **buf) len % elsz != 0) return (-1); - *buf = malloc(len, M_OFWPROP, M_WAITOK); - if (OF_getprop(package, propname, *buf, len) == -1) { - free(*buf, M_OFWPROP); - *buf = NULL; - return (-1); + if (len > 0) { + *buf = malloc(len, M_OFWPROP, M_WAITOK); + if (OF_getprop(package, propname, *buf, len) == -1) { + free(*buf, M_OFWPROP); + *buf = NULL; + return (-1); + } } return (len / elsz); } ssize_t -OF_getencprop_alloc(phandle_t package, const char *name, int elsz, void **buf) +OF_getencprop_alloc(phandle_t package, const char *name, void **buf) +{ + ssize_t ret; + + ret = OF_getencprop_alloc_multi(package, name, sizeof(pcell_t), + buf); + if (ret < 0) + return (ret); + else + return (ret * sizeof(pcell_t)); +} + +ssize_t +OF_getencprop_alloc_multi(phandle_t package, const char *name, int elsz, + void **buf) { ssize_t retval; pcell_t *cell; int i; - retval = OF_getprop_alloc(package, name, elsz, buf); + retval = OF_getprop_alloc_multi(package, name, elsz, buf); if (retval == -1) return (-1); - if (retval * elsz % 4 != 0) { - free(*buf, M_OFWPROP); - *buf = NULL; - return (-1); - } cell = *buf; for (i = 0; i < retval * elsz / 4; i++) diff --git a/freebsd/sys/dev/ofw/openfirm.h b/freebsd/sys/dev/ofw/openfirm.h index e1701164..f043197a 100644 --- a/freebsd/sys/dev/ofw/openfirm.h +++ b/freebsd/sys/dev/ofw/openfirm.h @@ -114,10 +114,14 @@ int OF_hasprop(phandle_t node, const char *propname); ssize_t OF_searchprop(phandle_t node, const char *propname, void *buf, size_t len); ssize_t OF_searchencprop(phandle_t node, const char *propname, - void *buf, size_t len); + pcell_t *buf, size_t len); ssize_t OF_getprop_alloc(phandle_t node, const char *propname, + void **buf); +ssize_t OF_getprop_alloc_multi(phandle_t node, const char *propname, int elsz, void **buf); ssize_t OF_getencprop_alloc(phandle_t node, const char *propname, + void **buf); +ssize_t OF_getencprop_alloc_multi(phandle_t node, const char *propname, int elsz, void **buf); void OF_prop_free(void *buf); int OF_nextprop(phandle_t node, const char *propname, char *buf, |