Index: sys/dev/acpica/acpi_ec.c =================================================================== --- sys/dev/acpica/acpi_ec.c +++ sys/dev/acpica/acpi_ec.c @@ -345,89 +345,94 @@ struct acpi_ec_params *params; static char *ec_ids[] = { "PNP0C09", NULL }; + ret = ENXIO; + /* Check that this is a device and that EC is not disabled. */ if (acpi_get_type(dev) != ACPI_TYPE_DEVICE || acpi_disabled("ec")) - return (ENXIO); + return (ret); + + if (device_is_devclass_fixed(dev)) { + /* + * If probed via ECDT, set description and continue. Otherwise, we can + * access the namespace and make sure this is not a duplicate probe. + */ + ecdt = 1; + params = acpi_get_private(dev); + if (params != NULL) + ret = 0; + + goto out; + } + + if (ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids) == NULL) + return (ret); + + params = malloc(sizeof(struct acpi_ec_params), M_TEMP, M_WAITOK | M_ZERO); - /* - * If probed via ECDT, set description and continue. Otherwise, - * we can access the namespace and make sure this is not a - * duplicate probe. - */ - ret = ENXIO; - ecdt = 0; buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; - params = acpi_get_private(dev); - if (params != NULL) { - ecdt = 1; - ret = 0; - } else if (ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids)) { - params = malloc(sizeof(struct acpi_ec_params), M_TEMP, - M_WAITOK | M_ZERO); - h = acpi_get_handle(dev); + h = acpi_get_handle(dev); - /* - * Read the unit ID to check for duplicate attach and the - * global lock value to see if we should acquire it when - * accessing the EC. - */ - status = acpi_GetInteger(h, "_UID", ¶ms->uid); - if (ACPI_FAILURE(status)) - params->uid = 0; - status = acpi_GetInteger(h, "_GLK", ¶ms->glk); - if (ACPI_FAILURE(status)) - params->glk = 0; + /* + * Read the unit ID to check for duplicate attach and the global lock value + * to see if we should acquire it when accessing the EC. + */ + status = acpi_GetInteger(h, "_UID", ¶ms->uid); + if (ACPI_FAILURE(status)) + params->uid = 0; - /* - * Evaluate the _GPE method to find the GPE bit used by the EC to - * signal status (SCI). If it's a package, it contains a reference - * and GPE bit, similar to _PRW. - */ - status = AcpiEvaluateObject(h, "_GPE", NULL, &buf); - if (ACPI_FAILURE(status)) { - device_printf(dev, "can't evaluate _GPE - %s\n", - AcpiFormatException(status)); - goto out; - } - obj = (ACPI_OBJECT *)buf.Pointer; - if (obj == NULL) - goto out; + status = acpi_GetInteger(h, "_GLK", ¶ms->glk); + if (ACPI_FAILURE(status)) + params->glk = 0; - switch (obj->Type) { - case ACPI_TYPE_INTEGER: - params->gpe_handle = NULL; - params->gpe_bit = obj->Integer.Value; - break; - case ACPI_TYPE_PACKAGE: - if (!ACPI_PKG_VALID(obj, 2)) - goto out; - params->gpe_handle = - acpi_GetReference(NULL, &obj->Package.Elements[0]); - if (params->gpe_handle == NULL || - acpi_PkgInt32(obj, 1, ¶ms->gpe_bit) != 0) - goto out; - break; - default: - device_printf(dev, "_GPE has invalid type %d\n", obj->Type); - goto out; - } + /* + * Evaluate the _GPE method to find the GPE bit used by the EC to signal + * status (SCI). If it's a package, it contains a reference and GPE bit, + * similar to _PRW. + */ + status = AcpiEvaluateObject(h, "_GPE", NULL, &buf); + if (ACPI_FAILURE(status)) { + device_printf(dev, "can't evaluate _GPE - %s\n", AcpiFormatException(status)); + goto out; + } - /* Store the values we got from the namespace for attach. */ - acpi_set_private(dev, params); + obj = (ACPI_OBJECT *)buf.Pointer; + if (obj == NULL) + goto out; - /* - * Check for a duplicate probe. This can happen when a probe - * via ECDT succeeded already. If this is a duplicate, disable - * this device. - */ - peer = devclass_get_device(acpi_ec_devclass, params->uid); - if (peer == NULL || !device_is_alive(peer)) - ret = 0; - else - device_disable(dev); + switch (obj->Type) { + case ACPI_TYPE_INTEGER: + params->gpe_handle = NULL; + params->gpe_bit = obj->Integer.Value; + break; + case ACPI_TYPE_PACKAGE: + if (!ACPI_PKG_VALID(obj, 2)) + goto out; + params->gpe_handle = acpi_GetReference(NULL, &obj->Package.Elements[0]); + if (params->gpe_handle == NULL || + acpi_PkgInt32(obj, 1, ¶ms->gpe_bit) != 0) + goto out; + break; + default: + device_printf(dev, "_GPE has invalid type %d\n", obj->Type); + goto out; } + /* Store the values we got from the namespace for attach. */ + acpi_set_private(dev, params); + + /* + * Check for a duplicate probe. This can happen when a probe via ECDT + * succeeded already. If this is a duplicate, disable this device. + */ + peer = devclass_get_device(acpi_ec_devclass, params->uid); + if (peer == NULL || !device_is_alive(peer)) + ret = 0; + else + device_disable(dev); + + if (buf.Pointer) + AcpiOsFree(buf.Pointer); out: if (ret == 0) { snprintf(desc, sizeof(desc), "Embedded Controller: GPE %#x%s%s", @@ -436,8 +441,7 @@ device_set_desc_copy(dev, desc); } else free(params, M_TEMP); - if (buf.Pointer) - AcpiOsFree(buf.Pointer); + return (ret); } Index: sys/kern/subr_bus.c =================================================================== --- sys/kern/subr_bus.c +++ sys/kern/subr_bus.c @@ -2779,6 +2779,16 @@ return (0); } +/** + * @brief Query the device to determine if it's of a fixed devclass + * @see device_set_devclass_fixed() + */ +bool +device_is_devclass_fixed(device_t dev) +{ + return !!(dev->flags & DF_FIXEDCLASS); +} + /** * @brief Set the driver of a device * Index: sys/sys/bus.h =================================================================== --- sys/sys/bus.h +++ sys/sys/bus.h @@ -612,6 +612,7 @@ void device_set_desc_copy(device_t dev, const char* desc); int device_set_devclass(device_t dev, const char *classname); int device_set_devclass_fixed(device_t dev, const char *classname); +bool device_is_devclass_fixed(device_t dev); int device_set_driver(device_t dev, driver_t *driver); void device_set_flags(device_t dev, u_int32_t flags); void device_set_softc(device_t dev, void *softc);