From 8232e57ef030a255ea897c975899b89dd23e5b19 Mon Sep 17 00:00:00 2001 From: njl Date: Tue, 9 Oct 2007 07:48:07 +0000 Subject: [PATCH] Fix the HPET table probe routine to run from device_identify() instead of directly from acpi0. Before it would attach prior to the sysresource devices, causing the later allocation of its memory range to fail and print a warning like "acpi0: reservation of fed00000, 1000 (3) failed". Use an explicit define for our probe order base value of 10. Help from: jhb Tested by: Abdullah Ibn Hamad Al-Marri MFC after: 3 days Approved by: re --- sys/dev/acpica/acpi.c | 8 ++++---- sys/dev/acpica/acpi_hpet.c | 13 ++++++++----- sys/dev/acpica/acpivar.h | 10 ++++++++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 5e2105b38183..cc35e2c59dab 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -509,7 +509,6 @@ acpi_attach(device_t dev) * a problem but should be addressed eventually. */ acpi_ec_ecdt_probe(dev); - acpi_hpet_table_probe(dev); /* Bring device objects and regions online. */ if (ACPI_FAILURE(status = AcpiInitializeObjects(flags))) { @@ -1594,11 +1593,12 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status) /* * Create a placeholder device for this node. Sort the placeholder * so that the probe/attach passes will run breadth-first. Orders - * less than 10 are reserved for special objects (i.e., system - * resources). Larger values are used for all other devices. + * less than ACPI_DEV_BASE_ORDER are reserved for special objects + * (i.e., system resources). Larger values are used for all other + * devices. */ ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "scanning '%s'\n", handle_str)); - order = (level + 1) * 10; + order = (level + 1) * ACPI_DEV_BASE_ORDER; acpi_probe_order(handle, &order); child = BUS_ADD_CHILD(bus, order, NULL, -1); if (child == NULL) diff --git a/sys/dev/acpica/acpi_hpet.c b/sys/dev/acpica/acpi_hpet.c index 56a9c9c91f84..ab64c11aa052 100644 --- a/sys/dev/acpica/acpi_hpet.c +++ b/sys/dev/acpica/acpi_hpet.c @@ -83,14 +83,18 @@ hpet_get_timecount(struct timecounter *tc) } /* Discover the HPET via the ACPI table of the same name. */ -void -acpi_hpet_table_probe(device_t parent) +static void +acpi_hpet_identify(driver_t *driver, device_t parent) { ACPI_TABLE_HPET *hpet; ACPI_TABLE_HEADER *hdr; ACPI_STATUS status; device_t child; + /* Only one HPET device can be added. */ + if (devclass_get_device(acpi_hpet_devclass, 0)) + return; + /* Currently, ID and minimum clock tick info is unused. */ status = AcpiGetTable(ACPI_SIG_HPET, 1, (ACPI_TABLE_HEADER **)&hdr); @@ -105,7 +109,7 @@ acpi_hpet_table_probe(device_t parent) if (hpet->Sequence != 0) printf("ACPI HPET table warning: Sequence is non-zero (%d)\n", hpet->Sequence); - child = BUS_ADD_CHILD(parent, 0, "acpi_hpet", 0); + child = BUS_ADD_CHILD(parent, ACPI_DEV_BASE_ORDER, "acpi_hpet", 0); if (child == NULL) { printf("%s: can't add child\n", __func__); return; @@ -115,8 +119,6 @@ acpi_hpet_table_probe(device_t parent) acpi_set_magic(child, (uintptr_t)&acpi_hpet_devclass); bus_set_resource(child, SYS_RES_MEMORY, 0, hpet->Address.Address, HPET_MEM_WIDTH); - if (device_probe_and_attach(child) != 0) - device_delete_child(parent, child); } static int @@ -254,6 +256,7 @@ acpi_hpet_test(struct acpi_hpet_softc *sc) static device_method_t acpi_hpet_methods[] = { /* Device interface */ + DEVMETHOD(device_identify, acpi_hpet_identify), DEVMETHOD(device_probe, acpi_hpet_probe), DEVMETHOD(device_attach, acpi_hpet_attach), DEVMETHOD(device_detach, acpi_hpet_detach), diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index 103427333a12..35bd66dc0926 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -432,8 +432,6 @@ int acpi_battery_get_battinfo(device_t dev, /* Embedded controller. */ void acpi_ec_ecdt_probe(device_t); -/* HPET table probe*/ -void acpi_hpet_table_probe(device_t); /* AC adapter interface. */ int acpi_acad_get_acline(int *); @@ -449,6 +447,14 @@ int acpi_PkgGas(device_t dev, ACPI_OBJECT *res, int idx, int *type, int *rid, struct resource **dst, u_int flags); ACPI_HANDLE acpi_GetReference(ACPI_HANDLE scope, ACPI_OBJECT *obj); +/* + * Base level for BUS_ADD_CHILD. Special devices are added at orders less + * than this, and normal devices at or above this level. This keeps the + * probe order sorted so that things like sysresource are available before + * their children need them. + */ +#define ACPI_DEV_BASE_ORDER 10 + /* Default number of task queue threads to start. */ #ifndef ACPI_MAX_THREADS #define ACPI_MAX_THREADS 3