git: b3e602d9ac5e - stable/13 - device_get_property: add a HANDLE case
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 18 Jan 2023 16:24:35 UTC
The branch stable/13 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=b3e602d9ac5e3157874dfe3986dc819971d2142c commit b3e602d9ac5e3157874dfe3986dc819971d2142c Author: Bjoern A. Zeeb <bz@FreeBSD.org> AuthorDate: 2022-09-29 12:41:58 +0000 Commit: Bjoern A. Zeeb <bz@FreeBSD.org> CommitDate: 2023-01-18 13:22:13 +0000 device_get_property: add a HANDLE case This will resolve a reference and return the appropriate handle, a node on the simplebus or an ACPI_HANDLE for ACPI. For now we do not try to further abstract the return type. Reviewed by: mw Differential Revision: https://reviews.freebsd.org/D36793 (cherry picked from commit 99e6980fcf5e12654c3e89b97b774de807d740a4) --- share/man/man9/device_get_property.9 | 5 +++- sys/dev/acpica/acpi.c | 47 ++++++++++++++++++++++++++++++++++++ sys/dev/fdt/simplebus.c | 19 +++++++++++++-- sys/kern/subr_bus.c | 1 + sys/sys/bus.h | 1 + 5 files changed, 70 insertions(+), 3 deletions(-) diff --git a/share/man/man9/device_get_property.9 b/share/man/man9/device_get_property.9 index d925f5f224db..93c01f199477 100644 --- a/share/man/man9/device_get_property.9 +++ b/share/man/man9/device_get_property.9 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 18, 2022 +.Dd September 29, 2022 .Dt DEVICE_GET_PROPERTY 9 .Os .Sh NAME @@ -54,6 +54,9 @@ Currently the following types are supported: The underlying property is a string of bytes. .It Dv DEVICE_PROP_ANY Wildcard property type. +.It Dv DEVICE_PROP_HANDLE +Following a reference the underlying property is a handle of the +respective bus. .It Dv DEVICE_PROP_UINT32 The underlying property is an array of unsigned 32 bit integers. The diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 9005448ddee9..8f4419a76c58 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -1824,6 +1824,35 @@ acpi_find_dsd(struct acpi_device *ad) return (AE_NOT_FOUND); } +static ssize_t +acpi_bus_get_prop_handle(const ACPI_OBJECT *hobj, void *propvalue, size_t size) +{ + ACPI_OBJECT *pobj; + ACPI_HANDLE h; + + if (hobj->Type != ACPI_TYPE_PACKAGE) + goto err; + if (hobj->Package.Count != 1) + goto err; + + pobj = &hobj->Package.Elements[0]; + if (pobj == NULL) + goto err; + if (pobj->Type != ACPI_TYPE_LOCAL_REFERENCE) + goto err; + + h = acpi_GetReference(NULL, pobj); + if (h == NULL) + goto err; + + if (propvalue != NULL && size >= sizeof(ACPI_HANDLE)) + *(ACPI_HANDLE *)propvalue = h; + return (sizeof(ACPI_HANDLE)); + +err: + return (-1); +} + static ssize_t acpi_bus_get_prop(device_t bus, device_t child, const char *propname, void *propvalue, size_t size, device_property_type_t type) @@ -1842,6 +1871,8 @@ acpi_bus_get_prop(device_t bus, device_t child, const char *propname, case DEVICE_PROP_UINT32: case DEVICE_PROP_UINT64: break; + case DEVICE_PROP_HANDLE: + return (acpi_bus_get_prop_handle(obj, propvalue, size)); default: return (-1); } @@ -1873,6 +1904,22 @@ acpi_bus_get_prop(device_t bus, device_t child, const char *propname, MIN(size, obj->Buffer.Length)); return (obj->Buffer.Length); + case ACPI_TYPE_PACKAGE: + if (propvalue != NULL && size >= sizeof(ACPI_OBJECT *)) { + *((ACPI_OBJECT **) propvalue) = + __DECONST(ACPI_OBJECT *, obj); + } + return (sizeof(ACPI_OBJECT *)); + + case ACPI_TYPE_LOCAL_REFERENCE: + if (propvalue != NULL && size >= sizeof(ACPI_HANDLE)) { + ACPI_HANDLE h; + + h = acpi_GetReference(NULL, + __DECONST(ACPI_OBJECT *, obj)); + memcpy(propvalue, h, sizeof(ACPI_HANDLE)); + } + return (sizeof(ACPI_HANDLE)); default: return (0); } diff --git a/sys/dev/fdt/simplebus.c b/sys/dev/fdt/simplebus.c index ab7868f245bf..a29b28f2a016 100644 --- a/sys/dev/fdt/simplebus.c +++ b/sys/dev/fdt/simplebus.c @@ -359,7 +359,7 @@ static ssize_t simplebus_get_property(device_t bus, device_t child, const char *propname, void *propvalue, size_t size, device_property_type_t type) { - phandle_t node = ofw_bus_get_node(child); + phandle_t node, xref; ssize_t ret, i; uint32_t *buffer; uint64_t val; @@ -369,11 +369,13 @@ simplebus_get_property(device_t bus, device_t child, const char *propname, case DEVICE_PROP_BUFFER: case DEVICE_PROP_UINT32: case DEVICE_PROP_UINT64: + case DEVICE_PROP_HANDLE: break; default: return (-1); } + node = ofw_bus_get_node(child); if (propvalue == NULL || size == 0) return (OF_getproplen(node, propname)); @@ -404,7 +406,20 @@ simplebus_get_property(device_t bus, device_t child, const char *propname, ((uint64_t *)buffer)[i / 2] = val; } return (ret); - } + } + + if (type == DEVICE_PROP_HANDLE) { + if (size < sizeof(node)) + return (-1); + ret = OF_getencprop(node, propname, &xref, sizeof(xref)); + if (ret <= 0) + return (ret); + + node = OF_node_from_xref(xref); + if (propvalue != NULL) + *(uint32_t *)propvalue = node; + return (ret); + } return (OF_getprop(node, propname, propvalue, size)); } diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index c70e0e7b5ec1..c1383add7e47 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -2683,6 +2683,7 @@ device_get_property(device_t dev, const char *prop, void *val, size_t sz, switch (type) { case DEVICE_PROP_ANY: case DEVICE_PROP_BUFFER: + case DEVICE_PROP_HANDLE: /* Size checks done in implementation. */ break; case DEVICE_PROP_UINT32: if (sz % 4 != 0) diff --git a/sys/sys/bus.h b/sys/sys/bus.h index c017f38dcf11..a308810f158f 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -73,6 +73,7 @@ typedef enum device_property_type { DEVICE_PROP_BUFFER = 1, DEVICE_PROP_UINT32 = 2, DEVICE_PROP_UINT64 = 3, + DEVICE_PROP_HANDLE = 4, } device_property_type_t; /**