Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/acpica/acpi_ec.c
Show First 20 Lines • Show All 356 Lines • ▼ Show 20 Lines | acpi_ec_probe(device_t dev) | ||||
* access the namespace and make sure this is not a duplicate probe. | * access the namespace and make sure this is not a duplicate probe. | ||||
*/ | */ | ||||
ecdt = 1; | ecdt = 1; | ||||
params = acpi_get_private(dev); | params = acpi_get_private(dev); | ||||
if (params != NULL) | if (params != NULL) | ||||
ret = 0; | ret = 0; | ||||
goto out; | goto out; | ||||
} | } else | ||||
ecdt = 0; | |||||
ret = ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids, NULL); | ret = ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids, NULL); | ||||
if (ret > 0) | if (ret > 0) | ||||
return (ret); | return (ret); | ||||
params = malloc(sizeof(struct acpi_ec_params), M_TEMP, M_WAITOK | M_ZERO); | params = malloc(sizeof(struct acpi_ec_params), M_TEMP, M_WAITOK | M_ZERO); | ||||
buf.Pointer = NULL; | buf.Pointer = NULL; | ||||
buf.Length = ACPI_ALLOCATE_BUFFER; | buf.Length = ACPI_ALLOCATE_BUFFER; | ||||
h = acpi_get_handle(dev); | h = acpi_get_handle(dev); | ||||
/* | /* | ||||
* Read the unit ID to check for duplicate attach and the global lock value | * 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. | * to see if we should acquire it when accessing the EC. | ||||
*/ | */ | ||||
status = acpi_GetInteger(h, "_UID", ¶ms->uid); | status = acpi_GetInteger(h, "_UID", ¶ms->uid); | ||||
if (ACPI_FAILURE(status)) | if (ACPI_FAILURE(status)) | ||||
params->uid = 0; | params->uid = 0; | ||||
/* | |||||
* Check for a duplicate probe. This can happen when a probe via ECDT | |||||
* succeeded already. If this is a duplicate, disable this device. | |||||
* | |||||
* NB: It would seem device_disable would be sufficient to not get | |||||
* duplicated devices, and ENXIO isn't needed, however, device_probe() only | |||||
* checks DF_ENABLED at the start and so disabling it here is too late to | |||||
* prevent device_attach() from being called. | |||||
*/ | |||||
peer = devclass_get_device(acpi_ec_devclass, params->uid); | |||||
if (peer != NULL && device_is_alive(peer)) { | |||||
device_disable(dev); | |||||
ret = ENXIO; | |||||
goto out; | |||||
} | |||||
status = acpi_GetInteger(h, "_GLK", ¶ms->glk); | status = acpi_GetInteger(h, "_GLK", ¶ms->glk); | ||||
if (ACPI_FAILURE(status)) | if (ACPI_FAILURE(status)) | ||||
params->glk = 0; | params->glk = 0; | ||||
/* | /* | ||||
* Evaluate the _GPE method to find the GPE bit used by the EC to signal | * 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, | * status (SCI). If it's a package, it contains a reference and GPE bit, | ||||
* similar to _PRW. | * similar to _PRW. | ||||
Show All 23 Lines | acpi_ec_probe(device_t dev) | ||||
break; | break; | ||||
default: | default: | ||||
device_printf(dev, "_GPE has invalid type %d\n", obj->Type); | device_printf(dev, "_GPE has invalid type %d\n", obj->Type); | ||||
goto out; | goto out; | ||||
} | } | ||||
/* Store the values we got from the namespace for attach. */ | /* Store the values we got from the namespace for attach. */ | ||||
acpi_set_private(dev, params); | 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) | if (buf.Pointer) | ||||
AcpiOsFree(buf.Pointer); | AcpiOsFree(buf.Pointer); | ||||
out: | out: | ||||
if (ret <= 0) { | if (ret <= 0) { | ||||
snprintf(desc, sizeof(desc), "Embedded Controller: GPE %#x%s%s", | snprintf(desc, sizeof(desc), "Embedded Controller: GPE %#x%s%s", | ||||
params->gpe_bit, (params->glk) ? ", GLK" : "", | params->gpe_bit, (params->glk) ? ", GLK" : "", | ||||
ecdt ? ", ECDT" : ""); | ecdt ? ", ECDT" : ""); | ||||
▲ Show 20 Lines • Show All 590 Lines • Show Last 20 Lines |