mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
LinuxKPI: Add acpi_dev_present() function.
acpi_dev_present detects that a given ACPI device is present based on Hardware ID, Unique ID and Hardware Revision of the device. Sponsored by: Serenity Cyber Security, LLC Reviewed by: manu MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D42823 (cherry picked from commit 04952a9456e226460d1d95c42ea53861b1133b1a)
This commit is contained in:
parent
a87884e34e
commit
455fa56ad4
2 changed files with 83 additions and 0 deletions
|
|
@ -37,6 +37,8 @@ struct acpi_bus_event {
|
|||
uint32_t data;
|
||||
};
|
||||
|
||||
#define acpi_dev_present(...) lkpi_acpi_dev_present(__VA_ARGS__)
|
||||
|
||||
ACPI_HANDLE bsd_acpi_get_handle(device_t bsddev);
|
||||
bool acpi_check_dsm(ACPI_HANDLE handle, const char *uuid, int rev,
|
||||
uint64_t funcs);
|
||||
|
|
@ -46,5 +48,7 @@ ACPI_OBJECT * acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const char *uuid,
|
|||
int register_acpi_notifier(struct notifier_block *nb);
|
||||
int unregister_acpi_notifier(struct notifier_block *nb);
|
||||
uint32_t acpi_target_system_state(void);
|
||||
bool lkpi_acpi_dev_present(const char *hid, const char *uid,
|
||||
int64_t hrv);
|
||||
|
||||
#endif /* _LINUXKPI_ACPI_ACPI_BUS_H_ */
|
||||
|
|
|
|||
|
|
@ -174,6 +174,79 @@ acpi_target_system_state(void)
|
|||
return (linux_acpi_target_sleep_state);
|
||||
}
|
||||
|
||||
struct acpi_dev_present_ctx {
|
||||
const char *hid;
|
||||
const char *uid;
|
||||
int64_t hrv;
|
||||
};
|
||||
|
||||
static ACPI_STATUS
|
||||
acpi_dev_present_cb(ACPI_HANDLE handle, UINT32 level, void *context,
|
||||
void **result)
|
||||
{
|
||||
ACPI_DEVICE_INFO *devinfo;
|
||||
struct acpi_dev_present_ctx *match = context;
|
||||
bool present = false;
|
||||
UINT32 sta, hrv;
|
||||
int i;
|
||||
|
||||
if (handle == NULL)
|
||||
return (AE_OK);
|
||||
|
||||
if (!ACPI_FAILURE(acpi_GetInteger(handle, "_STA", &sta)) &&
|
||||
!ACPI_DEVICE_PRESENT(sta))
|
||||
return (AE_OK);
|
||||
|
||||
if (ACPI_FAILURE(AcpiGetObjectInfo(handle, &devinfo)))
|
||||
return (AE_OK);
|
||||
|
||||
if ((devinfo->Valid & ACPI_VALID_HID) != 0 &&
|
||||
strcmp(match->hid, devinfo->HardwareId.String) == 0) {
|
||||
present = true;
|
||||
} else if ((devinfo->Valid & ACPI_VALID_CID) != 0) {
|
||||
for (i = 0; i < devinfo->CompatibleIdList.Count; i++) {
|
||||
if (strcmp(match->hid,
|
||||
devinfo->CompatibleIdList.Ids[i].String) == 0) {
|
||||
present = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (present && match->uid != NULL &&
|
||||
((devinfo->Valid & ACPI_VALID_UID) == 0 ||
|
||||
strcmp(match->uid, devinfo->UniqueId.String) != 0))
|
||||
present = false;
|
||||
|
||||
AcpiOsFree(devinfo);
|
||||
if (!present)
|
||||
return (AE_OK);
|
||||
|
||||
if (match->hrv != -1) {
|
||||
if (ACPI_FAILURE(acpi_GetInteger(handle, "_HRV", &hrv)))
|
||||
return (AE_OK);
|
||||
if (hrv != match->hrv)
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
return (AE_ERROR);
|
||||
}
|
||||
|
||||
bool
|
||||
lkpi_acpi_dev_present(const char *hid, const char *uid, int64_t hrv)
|
||||
{
|
||||
struct acpi_dev_present_ctx match;
|
||||
int rv;
|
||||
|
||||
match.hid = hid;
|
||||
match.uid = uid;
|
||||
match.hrv = hrv;
|
||||
|
||||
rv = AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX, acpi_dev_present_cb, NULL, &match, NULL);
|
||||
|
||||
return (rv == AE_ERROR);
|
||||
}
|
||||
|
||||
static void
|
||||
linux_register_acpi_event_handlers(void *arg __unused)
|
||||
{
|
||||
|
|
@ -241,4 +314,10 @@ acpi_target_system_state(void)
|
|||
return (ACPI_STATE_S0);
|
||||
}
|
||||
|
||||
bool
|
||||
lkpi_acpi_dev_present(const char *hid, const char *uid, int64_t hrv)
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
|
||||
#endif /* !DEV_ACPI */
|
||||
|
|
|
|||
Loading…
Reference in a new issue