Page MenuHomeFreeBSD

D32748.diff
No OneTemporary

D32748.diff

diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
--- a/sys/dev/acpica/acpi.c
+++ b/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,37 @@
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.
*/
diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c
--- a/sys/dev/acpica/acpi_pci.c
+++ b/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,17 @@
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
*/
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -495,6 +495,8 @@
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);
diff --git a/sys/dev/iicbus/acpi_iicbus.c b/sys/dev/iicbus/acpi_iicbus.c
--- a/sys/dev/iicbus/acpi_iicbus.c
+++ b/sys/dev/iicbus/acpi_iicbus.c
@@ -764,6 +764,7 @@
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,
};
diff --git a/sys/dev/nvdimm/nvdimm_acpi.c b/sys/dev/nvdimm/nvdimm_acpi.c
--- a/sys/dev/nvdimm/nvdimm_acpi.c
+++ b/sys/dev/nvdimm/nvdimm_acpi.c
@@ -265,6 +265,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, acpi_get_acpi_device_path),
DEVMETHOD_END
};
diff --git a/sys/dev/usb/usb_hub_acpi.c b/sys/dev/usb/usb_hub_acpi.c
--- a/sys/dev/usb/usb_hub_acpi.c
+++ b/sys/dev/usb/usb_hub_acpi.c
@@ -553,11 +553,22 @@
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 @@
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
};
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -4645,9 +4645,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 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));
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -737,6 +737,7 @@
#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;

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 30, 3:02 PM (17 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17859887
Default Alt Text
D32748.diff (6 KB)

Event Timeline