Index: sys/dev/acpica/acpi.c =================================================================== --- sys/dev/acpica/acpi.c +++ sys/dev/acpica/acpi.c @@ -187,6 +187,8 @@ 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 @@ 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,22 @@ return (acpi_pnpinfo(dinfo->ad_handle, 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) { + if (dinfo->ad_handle != 0) { + sbuf_printf(sb, "%s", acpi_name(dinfo->ad_handle)); + } + return (0); + } + + /* For the rest, punt to the default handler */ + return (bus_generic_get_device_path(bus, child, locator, sb)); +} + /* * Handle device deletion. */ Index: sys/dev/acpica/acpi_pci.c =================================================================== --- sys/dev/acpica/acpi_pci.c +++ sys/dev/acpica/acpi_pci.c @@ -81,6 +81,8 @@ 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 @@ 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,22 @@ return (0); } +static int +acpi_pci_get_device_path(device_t bus, device_t child, const char *locator, struct sbuf *sb) +{ + struct acpi_pci_devinfo *dinfo = device_get_ivars(child); + + if (strcmp(locator, BUS_LOCATOR_ACPI) == 0) { + if (dinfo->ap_handle != 0) { + sbuf_printf(sb, "%s", acpi_name(dinfo->ap_handle)); + } + return (0); + } + + /* For the rest, punt to the default handler */ + return (bus_generic_get_device_path(bus, child, locator, sb)); +} + /* * PCI power manangement */ Index: sys/dev/iicbus/acpi_iicbus.c =================================================================== --- sys/dev/iicbus/acpi_iicbus.c +++ sys/dev/iicbus/acpi_iicbus.c @@ -747,6 +747,22 @@ return (error); } +static int +acpi_iicbus_get_device_path(device_t bus, device_t child, const char *locator, struct sbuf *sb) +{ + struct acpi_iicbus_ivars *devi = device_get_ivars(child); + + if (strcmp(locator, BUS_LOCATOR_ACPI) == 0) { + if (devi->handle != 0) { + sbuf_printf(sb, "%s", acpi_name(devi->handle)); + } + return (0); + } + + /* For the rest, punt to the default handler */ + return (bus_generic_get_device_path(bus, child, locator, sb)); +} + static device_method_t acpi_iicbus_methods[] = { /* Device interface */ DEVMETHOD(device_probe, acpi_iicbus_probe), @@ -763,7 +779,8 @@ DEVMETHOD(bus_read_ivar, acpi_iicbus_read_ivar), 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_child_pnpinfo, acpi_iicbus_child_pnpinfo), + DEVMETHOD(bus_get_device_path, acpi_iicbus_get_device_path), DEVMETHOD_END, }; Index: sys/dev/nvdimm/nvdimm_acpi.c =================================================================== --- sys/dev/nvdimm/nvdimm_acpi.c +++ sys/dev/nvdimm/nvdimm_acpi.c @@ -257,6 +257,23 @@ return (0); } +static int +nvdimm_root_get_device_path(device_t bus, device_t child, const char *locator, struct sbuf *sb) +{ + ACPI_HANDLE handle; + + if (strcmp(locator, BUS_LOCATOR_ACPI) == 0) { + handle = nvdimm_root_get_acpi_handle(child); + if (handle != 0) { + sbuf_printf(sb, "%s", acpi_name(handle)); + } + return (0); + } + + /* For the rest, punt to the default handler */ + return (bus_generic_get_device_path(bus, child, locator, sb)); +} + static device_method_t nvdimm_acpi_methods[] = { DEVMETHOD(device_probe, nvdimm_root_probe), DEVMETHOD(device_attach, nvdimm_root_attach), @@ -265,6 +282,7 @@ 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, nvdimm_root_get_device_path), DEVMETHOD_END }; Index: sys/dev/usb/usb_hub_acpi.c =================================================================== --- sys/dev/usb/usb_hub_acpi.c +++ sys/dev/usb/usb_hub_acpi.c @@ -553,11 +553,29 @@ return (0); } +static int +acpi_uhub_get_device_path(device_t bus, device_t child, const char *locator, struct sbuf *sb) +{ + ACPI_HANDLE ah; + + if (strcmp(locator, BUS_LOCATOR_ACPI) == 0) { + ah = acpi_get_handle(child); + if (ah != 0) { + sbuf_printf(sb, "%s", acpi_name(ah)); + } + return (0); + } + + /* 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 +587,7 @@ 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 }; Index: sys/kern/subr_bus.c =================================================================== --- sys/kern/subr_bus.c +++ sys/kern/subr_bus.c @@ -4603,9 +4603,19 @@ 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 are 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)); Index: sys/sys/bus.h =================================================================== --- sys/sys/bus.h +++ sys/sys/bus.h @@ -736,8 +736,9 @@ #define BUS_PASS_ORDER_LATE 7 #define BUS_PASS_ORDER_LAST 9 -#define BUS_LOCATOR_UEFI "UEFI" #define BUS_LOCATOR_FREEBSD "FreeBSD" +#define BUS_LOCATOR_UEFI "UEFI" +#define BUS_LOCATOR_ACPI "ACPI" extern int bus_current_pass;