bus: Add ACPI locator support
Add support for printing ACPI paths. This is a bit of a degenerate case for this interface since it's always just the device handle if the device has one. But it is illustrtive of how to do this for a few nodes in the tree. Sponsored by: Netflix Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D32748
This commit is contained in:
parent
f5366026ad
commit
cae7d9ec83
@ -187,6 +187,8 @@ static int acpi_child_location_method(device_t acdev, device_t child,
|
||||
struct sbuf *sb);
|
||||
static int acpi_child_pnpinfo_method(device_t acdev, device_t child,
|
||||
struct sbuf *sb);
|
||||
static int acpi_get_device_path(device_t bus, device_t child,
|
||||
const char *locator, struct sbuf *sb);
|
||||
static void acpi_enable_pcie(void);
|
||||
static void acpi_hint_device_unit(device_t acdev, device_t child,
|
||||
const char *name, int *unitp);
|
||||
@ -226,6 +228,7 @@ static device_method_t acpi_methods[] = {
|
||||
DEVMETHOD(bus_get_cpus, acpi_get_cpus),
|
||||
DEVMETHOD(bus_get_domain, acpi_get_domain),
|
||||
DEVMETHOD(bus_get_property, acpi_bus_get_prop),
|
||||
DEVMETHOD(bus_get_device_path, acpi_get_device_path),
|
||||
|
||||
/* ACPI bus */
|
||||
DEVMETHOD(acpi_id_probe, acpi_device_id_probe),
|
||||
@ -928,6 +931,37 @@ acpi_child_pnpinfo_method(device_t cbdev, device_t child, struct sbuf *sb)
|
||||
return (acpi_pnpinfo(dinfo->ad_handle, sb));
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: the check for ACPI locator may be reduntant. However, this routine is
|
||||
* suitable for both busses whose only locator is ACPI and as a building block
|
||||
* for busses that have multiple locators to cope with.
|
||||
*/
|
||||
int
|
||||
acpi_get_acpi_device_path(device_t bus, device_t child, const char *locator, struct sbuf *sb)
|
||||
{
|
||||
if (strcmp(locator, BUS_LOCATOR_ACPI) == 0) {
|
||||
ACPI_HANDLE *handle = acpi_get_handle(child);
|
||||
|
||||
if (handle != NULL)
|
||||
sbuf_printf(sb, "%s", acpi_name(handle));
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (bus_generic_get_device_path(bus, child, locator, sb));
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_get_device_path(device_t bus, device_t child, const char *locator, struct sbuf *sb)
|
||||
{
|
||||
struct acpi_device *dinfo = device_get_ivars(child);
|
||||
|
||||
if (strcmp(locator, BUS_LOCATOR_ACPI) == 0)
|
||||
return (acpi_get_acpi_device_path(bus, child, locator, sb));
|
||||
|
||||
/* For the rest, punt to the default handler */
|
||||
return (bus_generic_get_device_path(bus, child, locator, sb));
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle device deletion.
|
||||
*/
|
||||
|
@ -81,6 +81,8 @@ static int acpi_pci_attach(device_t dev);
|
||||
static void acpi_pci_child_deleted(device_t dev, device_t child);
|
||||
static int acpi_pci_child_location_method(device_t cbdev,
|
||||
device_t child, struct sbuf *sb);
|
||||
static int acpi_pci_get_device_path(device_t cbdev,
|
||||
device_t child, const char *locator, struct sbuf *sb);
|
||||
static int acpi_pci_detach(device_t dev);
|
||||
static int acpi_pci_probe(device_t dev);
|
||||
static int acpi_pci_read_ivar(device_t dev, device_t child, int which,
|
||||
@ -105,6 +107,7 @@ static device_method_t acpi_pci_methods[] = {
|
||||
DEVMETHOD(bus_write_ivar, acpi_pci_write_ivar),
|
||||
DEVMETHOD(bus_child_deleted, acpi_pci_child_deleted),
|
||||
DEVMETHOD(bus_child_location, acpi_pci_child_location_method),
|
||||
DEVMETHOD(bus_get_device_path, acpi_pci_get_device_path),
|
||||
DEVMETHOD(bus_get_cpus, acpi_get_cpus),
|
||||
DEVMETHOD(bus_get_dma_tag, acpi_pci_get_dma_tag),
|
||||
DEVMETHOD(bus_get_domain, acpi_get_domain),
|
||||
@ -196,6 +199,17 @@ acpi_pci_child_location_method(device_t cbdev, device_t child, struct sbuf *sb)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_pci_get_device_path(device_t bus, device_t child, const char *locator, struct sbuf *sb)
|
||||
{
|
||||
|
||||
if (strcmp(locator, BUS_LOCATOR_ACPI) == 0)
|
||||
return (acpi_get_acpi_device_path(bus, child, locator, sb));
|
||||
|
||||
/* For the rest, punt to the default handler */
|
||||
return (bus_generic_get_device_path(bus, child, locator, sb));
|
||||
}
|
||||
|
||||
/*
|
||||
* PCI power manangement
|
||||
*/
|
||||
|
@ -495,6 +495,8 @@ acpi_get_verbose(struct acpi_softc *sc)
|
||||
char *acpi_name(ACPI_HANDLE handle);
|
||||
int acpi_avoid(ACPI_HANDLE handle);
|
||||
int acpi_disabled(char *subsys);
|
||||
int acpi_get_acpi_device_path(device_t bus, device_t child,
|
||||
const char *locator, struct sbuf *sb);
|
||||
int acpi_machdep_init(device_t dev);
|
||||
void acpi_install_wakeup_handler(struct acpi_softc *sc);
|
||||
int acpi_sleep_machdep(struct acpi_softc *sc, int state);
|
||||
|
@ -764,6 +764,7 @@ static device_method_t acpi_iicbus_methods[] = {
|
||||
DEVMETHOD(bus_write_ivar, acpi_iicbus_write_ivar),
|
||||
DEVMETHOD(bus_child_location, acpi_iicbus_child_location),
|
||||
DEVMETHOD(bus_child_pnpinfo, acpi_iicbus_child_pnpinfo),
|
||||
DEVMETHOD(bus_get_device_path, acpi_get_acpi_device_path),
|
||||
|
||||
DEVMETHOD_END,
|
||||
};
|
||||
|
@ -265,6 +265,7 @@ static device_method_t nvdimm_acpi_methods[] = {
|
||||
DEVMETHOD(bus_read_ivar, nvdimm_root_read_ivar),
|
||||
DEVMETHOD(bus_write_ivar, nvdimm_root_write_ivar),
|
||||
DEVMETHOD(bus_child_location, nvdimm_root_child_location),
|
||||
DEVMETHOD(bus_get_device_path, acpi_get_acpi_device_path),
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
|
@ -553,11 +553,22 @@ acpi_uhub_child_location(device_t parent, device_t child, struct sbuf *sb)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_uhub_get_device_path(device_t bus, device_t child, const char *locator, struct sbuf *sb)
|
||||
{
|
||||
if (strcmp(locator, BUS_LOCATOR_ACPI) == 0)
|
||||
return (acpi_get_acpi_device_path(bus, child, locator, sb));
|
||||
|
||||
/* For the rest, punt to the default handler */
|
||||
return (bus_generic_get_device_path(bus, child, locator, sb));
|
||||
}
|
||||
|
||||
static device_method_t acpi_uhub_methods[] = {
|
||||
DEVMETHOD(device_probe, acpi_uhub_probe),
|
||||
DEVMETHOD(device_attach, acpi_uhub_attach),
|
||||
DEVMETHOD(device_detach, acpi_uhub_detach),
|
||||
DEVMETHOD(bus_child_location, acpi_uhub_child_location),
|
||||
DEVMETHOD(bus_get_device_path, acpi_uhub_get_device_path),
|
||||
DEVMETHOD(bus_read_ivar, acpi_uhub_read_ivar),
|
||||
DEVMETHOD_END
|
||||
|
||||
@ -569,6 +580,7 @@ static device_method_t acpi_uhub_root_methods[] = {
|
||||
DEVMETHOD(device_detach, acpi_uhub_detach),
|
||||
DEVMETHOD(bus_read_ivar, acpi_uhub_read_ivar),
|
||||
DEVMETHOD(bus_child_location, acpi_uhub_child_location),
|
||||
DEVMETHOD(bus_get_device_path, acpi_uhub_get_device_path),
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
|
@ -4645,9 +4645,19 @@ bus_generic_get_device_path(device_t bus, device_t child, const char *locator,
|
||||
int rv = 0;
|
||||
device_t parent;
|
||||
|
||||
/*
|
||||
* We don't recurse on ACPI since either we know the handle for the
|
||||
* device or we don't. And if we're in the generic routine, we don't
|
||||
* have a ACPI override. All other locators build up a path by having
|
||||
* their parents create a path and then adding the path element for this
|
||||
* node. That's why we recurse with parent, bus rather than the typical
|
||||
* parent, child: each spot in the tree is independent of what our child
|
||||
* will do with this path.
|
||||
*/
|
||||
parent = device_get_parent(bus);
|
||||
if (parent != NULL)
|
||||
if (parent != NULL && strcmp(locator, BUS_LOCATOR_ACPI) != 0) {
|
||||
rv = BUS_GET_DEVICE_PATH(parent, bus, locator, sb);
|
||||
}
|
||||
if (strcmp(locator, BUS_LOCATOR_FREEBSD) == 0) {
|
||||
if (rv == 0) {
|
||||
sbuf_printf(sb, "/%s", device_get_nameunit(child));
|
||||
|
@ -737,6 +737,7 @@ void bus_data_generation_update(void);
|
||||
#define BUS_PASS_ORDER_LATE 7
|
||||
#define BUS_PASS_ORDER_LAST 9
|
||||
|
||||
#define BUS_LOCATOR_ACPI "ACPI"
|
||||
#define BUS_LOCATOR_FREEBSD "FreeBSD"
|
||||
|
||||
extern int bus_current_pass;
|
||||
|
Loading…
Reference in New Issue
Block a user