git: 04952a9456e2 - main - LinuxKPI: Add acpi_dev_present() function.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 24 Dec 2023 08:23:23 UTC
The branch main has been updated by wulf:
URL: https://cgit.FreeBSD.org/src/commit/?id=04952a9456e226460d1d95c42ea53861b1133b1a
commit 04952a9456e226460d1d95c42ea53861b1133b1a
Author: Vladimir Kondratyev <wulf@FreeBSD.org>
AuthorDate: 2023-12-24 08:20:00 +0000
Commit: Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2023-12-24 08:20:00 +0000
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
---
sys/compat/linuxkpi/common/include/acpi/acpi_bus.h | 4 ++
sys/compat/linuxkpi/common/src/linux_acpi.c | 79 ++++++++++++++++++++++
2 files changed, 83 insertions(+)
diff --git a/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h b/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h
index 3db8e7df58f4..f107902a26ad 100644
--- a/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h
+++ b/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h
@@ -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_ */
diff --git a/sys/compat/linuxkpi/common/src/linux_acpi.c b/sys/compat/linuxkpi/common/src/linux_acpi.c
index 6e342c8e2caa..e7b6854ecf13 100644
--- a/sys/compat/linuxkpi/common/src/linux_acpi.c
+++ b/sys/compat/linuxkpi/common/src/linux_acpi.c
@@ -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 */