Index: share/man/man9/BUS_GET_PROPERTY.9 =================================================================== --- share/man/man9/BUS_GET_PROPERTY.9 +++ share/man/man9/BUS_GET_PROPERTY.9 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 19, 2021 +.Dd December 14, 2021 .Dt BUS_GET_PROPERTY 9 .Os .Sh NAME @@ -36,7 +36,7 @@ .In sys/bus.h .Ft ssize_t .Fn BUS_GET_PROPERTY "device_t dev" "device_t child" "const char *propname" \ - "void *propvalue" "size_t size" + "void *propvalue" "size_t size" "device_property_type_t type" .Sh DESCRIPTION The .Fn BUS_GET_PROPERTY Index: share/man/man9/device_get_property.9 =================================================================== --- share/man/man9/device_get_property.9 +++ share/man/man9/device_get_property.9 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 19, 2021 +.Dd December 14, 2021 .Dt DEVICE_GET_PROPERTY 9 .Os .Sh NAME @@ -36,7 +36,8 @@ .In sys/param.h .In sys/bus.h .Ft ssize_t -.Fn device_get_property "device_t dev" "const char *prop" "void *val" "size_t sz" +.Fn device_get_property "device_t dev" "const char *prop" "void *val" "size_t sz" \ + "device_property_type_t type" .Ft bool .Fn device_has_property "device_t dev" "const char *prop" .Sh DESCRIPTION Index: sys/dev/acpica/acpi.c =================================================================== --- sys/dev/acpica/acpi.c +++ sys/dev/acpica/acpi.c @@ -144,8 +144,7 @@ int rid); static uint32_t acpi_isa_get_logicalid(device_t dev); static int acpi_isa_get_compatid(device_t dev, uint32_t *cids, int count); -static ssize_t acpi_bus_get_prop(device_t bus, device_t child, const char *propname, - void *propvalue, size_t size); +static bus_get_property_t acpi_bus_get_prop; static int acpi_device_id_probe(device_t bus, device_t dev, char **ids, char **match); static ACPI_STATUS acpi_device_eval_obj(device_t bus, device_t dev, ACPI_STRING pathname, ACPI_OBJECT_LIST *parameters, @@ -1822,7 +1821,7 @@ static ssize_t acpi_bus_get_prop(device_t bus, device_t child, const char *propname, - void *propvalue, size_t size) + void *propvalue, size_t size, device_property_type_t type) { ACPI_STATUS status; const ACPI_OBJECT *obj; @@ -1832,8 +1831,22 @@ if (ACPI_FAILURE(status)) return (-1); + switch (type) { + case DEVICE_PROP_ANY: + case DEVICE_PROP_UINT32: + case DEVICE_PROP_BUFFER: + break; + default: + return (-1); + } + switch (obj->Type) { case ACPI_TYPE_INTEGER: + if (type == DEVICE_PROP_UINT32) { + if (propvalue != NULL && size >= sizeof(uint32_t)) + *((uint32_t *)propvalue) = obj->Integer.Value; + return (sizeof(uint32_t)); + } if (propvalue != NULL && size >= sizeof(uint64_t)) *((uint64_t *) propvalue) = obj->Integer.Value; return (sizeof(uint64_t)); Index: sys/dev/fdt/simplebus.h =================================================================== --- sys/dev/fdt/simplebus.h +++ sys/dev/fdt/simplebus.h @@ -70,7 +70,6 @@ int simplebus_attach_impl(device_t dev); int simplebus_detach(device_t dev); -ssize_t simplebus_get_property(device_t bus, device_t child, - const char *propname, void *propvalue, size_t size); +bus_get_property_t simplebus_get_property; #endif /* _FDT_SIMPLEBUS_H */ Index: sys/dev/fdt/simplebus.c =================================================================== --- sys/dev/fdt/simplebus.c +++ sys/dev/fdt/simplebus.c @@ -354,14 +354,31 @@ ssize_t simplebus_get_property(device_t bus, device_t child, const char *propname, - void *propvalue, size_t size) + void *propvalue, size_t size, device_property_type_t type) { phandle_t node = ofw_bus_get_node(child); + switch (type) { + case DEVICE_PROP_ANY: + case DEVICE_PROP_UINT32: + case DEVICE_PROP_BUFFER: + break; + default: + return (-1); + } + if (propvalue == NULL || size == 0) return (OF_getproplen(node, propname)); - return (OF_getencprop(node, propname, propvalue, size)); + /* + * Integer values are stored in BE format. + * If caller declared that the underlying property type is uint32 + * we need to do the conversion to match host endianness. + */ + if (type == DEVICE_PROP_UINT32) + return (OF_getencprop(node, propname, propvalue, size)); + + return (OF_getprop(node, propname, propvalue, size)); } static struct resource * Index: sys/dev/mii/dp83867phy.c =================================================================== --- sys/dev/mii/dp83867phy.c +++ sys/dev/mii/dp83867phy.c @@ -144,7 +144,8 @@ sc = device_get_softc(dev); mii_sc = &sc->mii_sc; - size = device_get_property(dev, "max-speed", &maxspeed, sizeof(maxspeed)); + size = device_get_property(dev, "max-speed", &maxspeed, + sizeof(maxspeed), DEVICE_PROP_UINT32); if (size <= 0) maxspeed = 0; Index: sys/dev/mmc/mmc_helpers.c =================================================================== --- sys/dev/mmc/mmc_helpers.c +++ sys/dev/mmc/mmc_helpers.c @@ -89,10 +89,11 @@ int mmc_parse(device_t dev, struct mmc_helper *helper, struct mmc_host *host) { - uint64_t bus_width, max_freq; + uint32_t bus_width, max_freq; bus_width = 0; - if (device_get_property(dev, "bus-width", &bus_width, sizeof(uint64_t)) <= 0) + if (device_get_property(dev, "bus-width", &bus_width, + sizeof(bus_width), DEVICE_PROP_UINT32) <= 0) bus_width = 1; if (bus_width >= 4) @@ -106,7 +107,7 @@ * operates on */ if (device_get_property(dev, "max-frequency", &max_freq, - sizeof(uint64_t)) > 0) + sizeof(max_freq), DEVICE_PROP_UINT32) > 0) host->f_max = max_freq; if (device_has_property(dev, "broken-cd")) Index: sys/dev/sdhci/sdhci_xenon.c =================================================================== --- sys/dev/sdhci/sdhci_xenon.c +++ sys/dev/sdhci/sdhci_xenon.c @@ -471,20 +471,21 @@ sdhci_xenon_parse_prop(device_t dev) { struct sdhci_xenon_softc *sc; - uint64_t val; + uint32_t val; sc = device_get_softc(dev); val = 0; - if (device_get_property(dev, "quirks", &val, sizeof(val)) > 0) + if (device_get_property(dev, "quirks", + &val, sizeof(val), DEVICE_PROP_UINT32) > 0) sc->slot->quirks = val; sc->znr = XENON_ZNR_DEF_VALUE; if (device_get_property(dev, "marvell,xenon-phy-znr", - &val, sizeof(val)) > 0) + &val, sizeof(val), DEVICE_PROP_UINT32) > 0) sc->znr = val & XENON_ZNR_MASK; sc->zpr = XENON_ZPR_DEF_VALUE; if (device_get_property(dev, "marvell,xenon-phy-zpr", - &val, sizeof(val)) > 0) + &val, sizeof(val), DEVICE_PROP_UINT32) > 0) sc->zpr = val & XENON_ZPR_MASK; if (device_has_property(dev, "marvell,xenon-phy-slow-mode")) sc->slow_mode = true; Index: sys/kern/bus_if.m =================================================================== --- sys/kern/bus_if.m +++ sys/kern/bus_if.m @@ -79,7 +79,7 @@ static ssize_t null_get_property(device_t dev, device_t child, const char *propname, - void *propvalue, size_t size) + void *propvalue, size_t size, device_property_type_t type) { return (-1); } @@ -944,4 +944,5 @@ const char *_propname; void *_propvalue; size_t _size; + device_property_type_t type; } DEFAULT null_get_property; Index: sys/kern/subr_bus.c =================================================================== --- sys/kern/subr_bus.c +++ sys/kern/subr_bus.c @@ -2717,17 +2717,29 @@ } ssize_t -device_get_property(device_t dev, const char *prop, void *val, size_t sz) +device_get_property(device_t dev, const char *prop, void *val, size_t sz, + device_property_type_t type) { device_t bus = device_get_parent(dev); - return (BUS_GET_PROPERTY(bus, dev, prop, val, sz)); + switch (type) { + case DEVICE_PROP_UINT32: + if (sz % 4 != 0) + return (-1); + case DEVICE_PROP_ANY: + case DEVICE_PROP_BUFFER: + break; + default: + return (-1); + } + + return (BUS_GET_PROPERTY(bus, dev, prop, val, sz, type)); } bool device_has_property(device_t dev, const char *prop) { - return (device_get_property(dev, prop, NULL, 0) >= 0); + return (device_get_property(dev, prop, NULL, 0, DEVICE_PROP_ANY) >= 0); } /** Index: sys/sys/bus.h =================================================================== --- sys/sys/bus.h +++ sys/sys/bus.h @@ -60,6 +60,19 @@ DS_ATTACHED = 30, /**< @brief attach method called */ } device_state_t; +/** + * @brief Device proprty types. + * + * Those are used by bus logic to encode requested properties, + * e.g. in DT all properties are stored as BE and need to be converted + * to host endianness. + */ +typedef enum device_property_type { + DEVICE_PROP_ANY = 0, + DEVICE_PROP_BUFFER = 1, + DEVICE_PROP_UINT32 = 2, +} device_property_type_t; + /** * @brief Device information exported to userspace. * The strings are placed one after the other, separated by NUL characters. @@ -631,7 +644,8 @@ int device_shutdown(device_t dev); void device_unbusy(device_t dev); void device_verbose(device_t dev); -ssize_t device_get_property(device_t dev, const char *prop, void *val, size_t sz); +ssize_t device_get_property(device_t dev, const char *prop, void *val, size_t sz, + device_property_type_t type); bool device_has_property(device_t dev, const char *prop); /*