mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-11 09:50:12 +00:00
device: add device_get_property and device_has_property
Generialize bus specific property accessors. Those functions allow driver code to access device specific information. Currently there is only support for FDT and ACPI buses. Reviewed by: manu, mw Sponsored by: Semihalf Differential revision: https://reviews.freebsd.org/D31597
This commit is contained in:
parent
b91fc6c43a
commit
3f9a00e3b5
65
share/man/man9/BUS_GET_PROPERTY.9
Normal file
65
share/man/man9/BUS_GET_PROPERTY.9
Normal file
@ -0,0 +1,65 @@
|
||||
.\" -
|
||||
.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
.\"
|
||||
.\" Copyright (c) 2021 Semihalf
|
||||
.\"
|
||||
.\" 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 DEVELOPERS ``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 DEVELOPERS 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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 19, 2021
|
||||
.Dt BUS_GET_PROPERTY 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm BUS_GET_PROPERTY
|
||||
.Nd get child's specific property
|
||||
.Sh SYNOPSIS
|
||||
.In sys/param.h
|
||||
.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"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn BUS_GET_PROPERTY
|
||||
method
|
||||
is called from driver code which wants to access child's specific data stored
|
||||
on the bus.
|
||||
Property consits of its name and value.
|
||||
Implementation shall copy to
|
||||
.Fa propvalue
|
||||
at most
|
||||
.Fa size
|
||||
bytes.
|
||||
.Sh NOTES
|
||||
If
|
||||
.Fa propvalue
|
||||
is NULL or
|
||||
.Fa size
|
||||
is zero, then implementation shall only return size of the property.
|
||||
.Sh RETURN VALUES
|
||||
Property's size if successful, otherwise -1.
|
||||
.Sh SEE ALSO
|
||||
.Xr device 9 ,
|
||||
.Xr device_get_property 9
|
||||
.Sh AUTHORS
|
||||
This manual page was written by
|
||||
.An Bartlomiej Grzesik .
|
@ -47,6 +47,7 @@ MAN= accept_filter.9 \
|
||||
bus_generic_read_ivar.9 \
|
||||
bus_generic_shutdown.9 \
|
||||
BUS_GET_CPUS.9 \
|
||||
BUS_GET_PROPERTY.9 \
|
||||
bus_get_resource.9 \
|
||||
bus_map_resource.9 \
|
||||
BUS_NEW_PASS.9 \
|
||||
@ -108,6 +109,7 @@ MAN= accept_filter.9 \
|
||||
device_get_ivars.9 \
|
||||
device_get_name.9 \
|
||||
device_get_parent.9 \
|
||||
device_get_property.9 \
|
||||
device_get_softc.9 \
|
||||
device_get_state.9 \
|
||||
device_get_sysctl.9 \
|
||||
|
67
share/man/man9/device_get_property.9
Normal file
67
share/man/man9/device_get_property.9
Normal file
@ -0,0 +1,67 @@
|
||||
.\" -
|
||||
.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
.\"
|
||||
.\" Copyright (c) 2021 Semihalf
|
||||
.\"
|
||||
.\" 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 DEVELOPERS ``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 DEVELOPERS 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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 19, 2021
|
||||
.Dt DEVICE_GET_PROPERTY 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm device_get_property ,
|
||||
.Nm device_has_property
|
||||
.Nd access device specific data
|
||||
.Sh SYNOPSIS
|
||||
.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"
|
||||
.Ft bool
|
||||
.Fn device_has_property "device_t dev" "const char *prop"
|
||||
.Sh DESCRIPTION
|
||||
Access device specific data provided by the parent bus.
|
||||
Drivers can use these properties to obtain device capabilities and set
|
||||
necessary quirks.
|
||||
.Sh NOTES
|
||||
You can pass NULL as pointer to property's value when calling
|
||||
.Fn device_get_property
|
||||
to obtain its size.
|
||||
.Pp
|
||||
Currently this interface is implemented by
|
||||
.Xr simplebus 4
|
||||
and
|
||||
.Xr acpi 4 .
|
||||
.Sh RETURN VALUES
|
||||
.Fn device_get_property
|
||||
if successful returns property's size, otherwise returns -1.
|
||||
.Pp
|
||||
.Fn device_has_property
|
||||
returns true if given property was found.
|
||||
.Sh SEE ALSO
|
||||
.Xr acpi 4 ,
|
||||
.Xr simplebus 4 ,
|
||||
.Xr device 9
|
||||
.Sh AUTHORS
|
||||
This manual page was written by
|
||||
.An Bartlomiej Grzesik .
|
@ -144,6 +144,8 @@ static void acpi_delete_resource(device_t bus, device_t child, int type,
|
||||
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 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,
|
||||
@ -223,6 +225,7 @@ static device_method_t acpi_methods[] = {
|
||||
DEVMETHOD(bus_hint_device_unit, acpi_hint_device_unit),
|
||||
DEVMETHOD(bus_get_cpus, acpi_get_cpus),
|
||||
DEVMETHOD(bus_get_domain, acpi_get_domain),
|
||||
DEVMETHOD(bus_get_property, acpi_bus_get_prop),
|
||||
|
||||
/* ACPI bus */
|
||||
DEVMETHOD(acpi_id_probe, acpi_device_id_probe),
|
||||
@ -1817,6 +1820,40 @@ acpi_find_dsd(device_t bus, device_t dev)
|
||||
return (AE_NOT_FOUND);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
acpi_bus_get_prop(device_t bus, device_t child, const char *propname,
|
||||
void *propvalue, size_t size)
|
||||
{
|
||||
ACPI_STATUS status;
|
||||
const ACPI_OBJECT *obj;
|
||||
|
||||
status = acpi_device_get_prop(bus, child, __DECONST(char *, propname),
|
||||
&obj);
|
||||
if (ACPI_FAILURE(status))
|
||||
return (-1);
|
||||
|
||||
switch (obj->Type) {
|
||||
case ACPI_TYPE_INTEGER:
|
||||
if (propvalue != NULL && size >= sizeof(uint64_t))
|
||||
*((uint64_t *) propvalue) = obj->Integer.Value;
|
||||
return (sizeof(uint64_t));
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
if (propvalue != NULL && size > 0)
|
||||
memcpy(propvalue, obj->String.Pointer,
|
||||
MIN(size, obj->String.Length));
|
||||
return (obj->String.Length);
|
||||
|
||||
case ACPI_TYPE_BUFFER:
|
||||
if (propvalue != NULL && size > 0)
|
||||
memcpy(propvalue, obj->Buffer.Pointer,
|
||||
MIN(size, obj->Buffer.Length));
|
||||
return (obj->Buffer.Length);
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
acpi_device_pwr_for_sleep(device_t bus, device_t dev, int *dstate)
|
||||
{
|
||||
|
@ -54,6 +54,9 @@ static device_t simplebus_add_child(device_t dev, u_int order,
|
||||
const char *name, int unit);
|
||||
static struct resource_list *simplebus_get_resource_list(device_t bus,
|
||||
device_t child);
|
||||
|
||||
static ssize_t simplebus_get_property(device_t bus, device_t child,
|
||||
const char *propname, void *propvalue, size_t size);
|
||||
/*
|
||||
* ofw_bus interface
|
||||
*/
|
||||
@ -89,6 +92,7 @@ static device_method_t simplebus_methods[] = {
|
||||
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
|
||||
DEVMETHOD(bus_child_pnpinfo, ofw_bus_gen_child_pnpinfo),
|
||||
DEVMETHOD(bus_get_resource_list, simplebus_get_resource_list),
|
||||
DEVMETHOD(bus_get_property, simplebus_get_property),
|
||||
|
||||
/* ofw_bus interface */
|
||||
DEVMETHOD(ofw_bus_get_devinfo, simplebus_get_devinfo),
|
||||
@ -350,6 +354,18 @@ simplebus_get_resource_list(device_t bus __unused, device_t child)
|
||||
return (&ndi->rl);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
simplebus_get_property(device_t bus, device_t child, const char *propname,
|
||||
void *propvalue, size_t size)
|
||||
{
|
||||
phandle_t node = ofw_bus_get_node(child);
|
||||
|
||||
if (propvalue == NULL || size == 0)
|
||||
return (OF_getproplen(node, propname));
|
||||
|
||||
return (OF_getencprop(node, propname, propvalue, size));
|
||||
}
|
||||
|
||||
static struct resource *
|
||||
simplebus_alloc_resource(device_t bus, device_t child, int type, int *rid,
|
||||
rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
|
||||
|
@ -88,6 +88,13 @@ CODE {
|
||||
*newstart = start;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
null_get_property(device_t dev, device_t child, const char *propname,
|
||||
void *propvalue, size_t size)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -924,3 +931,27 @@ METHOD int reset_child {
|
||||
device_t _child;
|
||||
int _flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Gets child's specific property
|
||||
*
|
||||
* The bus_get_property can be used to access device
|
||||
* specific properties stored on the bus. If _propvalue
|
||||
* is NULL or _size is 0, then method only returns size
|
||||
* of the property.
|
||||
*
|
||||
* @param _dev the bus device
|
||||
* @param _child the child device
|
||||
* @param _propname property name
|
||||
* @param _propvalue property value destination
|
||||
* @param _size property value size
|
||||
*
|
||||
* @returns size of property if successful otherwise -1
|
||||
*/
|
||||
METHOD ssize_t get_property {
|
||||
device_t _dev;
|
||||
device_t _child;
|
||||
const char *_propname;
|
||||
void *_propvalue;
|
||||
size_t _size;
|
||||
} DEFAULT null_get_property;
|
||||
|
@ -2708,6 +2708,20 @@ device_verbose(device_t dev)
|
||||
dev->flags &= ~DF_QUIET;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
device_get_property(device_t dev, const char *prop, void *val, size_t sz)
|
||||
{
|
||||
device_t bus = device_get_parent(dev);
|
||||
|
||||
return (BUS_GET_PROPERTY(bus, dev, prop, val, sz));
|
||||
}
|
||||
|
||||
bool
|
||||
device_has_property(device_t dev, const char *prop)
|
||||
{
|
||||
return (device_get_property(dev, prop, NULL, 0) >= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return non-zero if the DF_QUIET_CHIDLREN flag is set on the device
|
||||
*/
|
||||
|
@ -631,6 +631,8 @@ int device_set_unit(device_t dev, int unit); /* XXX DONT USE XXX */
|
||||
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);
|
||||
bool device_has_property(device_t dev, const char *prop);
|
||||
|
||||
/*
|
||||
* Access functions for devclass.
|
||||
|
Loading…
Reference in New Issue
Block a user