From owner-dev-commits-src-all@freebsd.org Mon Sep 20 15:18:18 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 5FA636A8310; Mon, 20 Sep 2021 15:18:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4HCp961z8hz3PTk; Mon, 20 Sep 2021 15:18:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 1FEF812BCF; Mon, 20 Sep 2021 15:18:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 18KFIHOw007404; Mon, 20 Sep 2021 15:18:17 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 18KFIHGd007403; Mon, 20 Sep 2021 15:18:17 GMT (envelope-from git) Date: Mon, 20 Sep 2021 15:18:17 GMT Message-Id: <202109201518.18KFIHGd007403@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Marcin Wojtas Subject: git: b91fc6c43a81 - main - acpica: add ACPI_GET_PROPERTY to access Device Specific Data (DSD) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mw X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: b91fc6c43a81d3b760fb570c8439a922e536d7e6 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Sep 2021 15:18:18 -0000 The branch main has been updated by mw: URL: https://cgit.FreeBSD.org/src/commit/?id=b91fc6c43a81d3b760fb570c8439a922e536d7e6 commit b91fc6c43a81d3b760fb570c8439a922e536d7e6 Author: Bartlomiej Grzesik AuthorDate: 2021-07-27 12:39:31 +0000 Commit: Marcin Wojtas CommitDate: 2021-09-20 14:31:08 +0000 acpica: add ACPI_GET_PROPERTY to access Device Specific Data (DSD) Add lazy acquiring of DSD package, which allows accessing Device Specific Data. Reviewed by: manu, mw Sponsored by: Semihalf Differential revision: https://reviews.freebsd.org/D31596 --- sys/dev/acpica/acpi.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ sys/dev/acpica/acpi_if.m | 21 ++++++++++ sys/dev/acpica/acpivar.h | 12 ++++++ 3 files changed, 132 insertions(+) diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 02358d407c66..40b928f9cdd6 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #if defined(__i386__) || defined(__amd64__) #include @@ -147,10 +148,13 @@ static int acpi_device_id_probe(device_t bus, device_t dev, char **ids, char **m static ACPI_STATUS acpi_device_eval_obj(device_t bus, device_t dev, ACPI_STRING pathname, ACPI_OBJECT_LIST *parameters, ACPI_BUFFER *ret); +static ACPI_STATUS acpi_device_get_prop(device_t bus, device_t dev, + ACPI_STRING propname, const ACPI_OBJECT **value); static ACPI_STATUS acpi_device_scan_cb(ACPI_HANDLE h, UINT32 level, void *context, void **retval); static ACPI_STATUS acpi_device_scan_children(device_t bus, device_t dev, int max_depth, acpi_scan_cb_t user_fn, void *arg); +static ACPI_STATUS acpi_find_dsd(device_t bus, device_t dev); static int acpi_isa_pnp_probe(device_t bus, device_t child, struct isa_pnp_id *ids); static void acpi_platform_osc(device_t dev); @@ -223,6 +227,7 @@ static device_method_t acpi_methods[] = { /* ACPI bus */ DEVMETHOD(acpi_id_probe, acpi_device_id_probe), DEVMETHOD(acpi_evaluate_object, acpi_device_eval_obj), + DEVMETHOD(acpi_get_property, acpi_device_get_prop), DEVMETHOD(acpi_pwr_for_sleep, acpi_device_pwr_for_sleep), DEVMETHOD(acpi_scan_children, acpi_device_scan_children), @@ -296,6 +301,15 @@ int acpi_susp_bounce; SYSCTL_INT(_debug_acpi, OID_AUTO, suspend_bounce, CTLFLAG_RW, &acpi_susp_bounce, 0, "Don't actually suspend, just test devices."); +/* + * ACPI standard UUID for Device Specific Data Package + * "Device Properties UUID for _DSD" Rev. 2.0 + */ +static const struct uuid acpi_dsd_uuid = { + 0xdaffd814, 0x6eba, 0x4d8c, 0x8a, 0x91, + { 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01 } +}; + /* * ACPI can only be loaded as a module by the loader; activating it after * system bootstrap time is not useful, and can be fatal to the system. @@ -1727,6 +1741,82 @@ acpi_device_eval_obj(device_t bus, device_t dev, ACPI_STRING pathname, return (AcpiEvaluateObject(h, pathname, parameters, ret)); } +static ACPI_STATUS +acpi_device_get_prop(device_t bus, device_t dev, ACPI_STRING propname, + const ACPI_OBJECT **value) +{ + const ACPI_OBJECT *pkg, *name, *val; + struct acpi_device *ad; + ACPI_STATUS status; + int i; + + ad = device_get_ivars(dev); + + if (ad == NULL || propname == NULL) + return (AE_BAD_PARAMETER); + if (ad->dsd_pkg == NULL) { + if (ad->dsd.Pointer == NULL) { + status = acpi_find_dsd(bus, dev); + if (ACPI_FAILURE(status)) + return (status); + } else { + return (AE_NOT_FOUND); + } + } + + for (i = 0; i < ad->dsd_pkg->Package.Count; i ++) { + pkg = &ad->dsd_pkg->Package.Elements[i]; + if (pkg->Type != ACPI_TYPE_PACKAGE || pkg->Package.Count != 2) + continue; + + name = &pkg->Package.Elements[0]; + val = &pkg->Package.Elements[1]; + if (name->Type != ACPI_TYPE_STRING) + continue; + if (strncmp(propname, name->String.Pointer, name->String.Length) == 0) { + if (value != NULL) + *value = val; + + return (AE_OK); + } + } + + return (AE_NOT_FOUND); +} + +static ACPI_STATUS +acpi_find_dsd(device_t bus, device_t dev) +{ + const ACPI_OBJECT *dsd, *guid, *pkg; + struct acpi_device *ad; + ACPI_STATUS status; + + ad = device_get_ivars(dev); + ad->dsd.Length = ACPI_ALLOCATE_BUFFER; + ad->dsd.Pointer = NULL; + ad->dsd_pkg = NULL; + + status = ACPI_EVALUATE_OBJECT(bus, dev, "_DSD", NULL, &ad->dsd); + if (ACPI_FAILURE(status)) + return (status); + + dsd = ad->dsd.Pointer; + guid = &dsd->Package.Elements[0]; + pkg = &dsd->Package.Elements[1]; + + if (guid->Type != ACPI_TYPE_BUFFER || pkg->Type != ACPI_TYPE_PACKAGE || + guid->Buffer.Length != sizeof(acpi_dsd_uuid)) + return (AE_NOT_FOUND); + if (memcmp(guid->Buffer.Pointer, &acpi_dsd_uuid, + sizeof(acpi_dsd_uuid)) == 0) { + + ad->dsd_pkg = pkg; + return (AE_OK); + } + + return (AE_NOT_FOUND); +} + int acpi_device_pwr_for_sleep(device_t bus, device_t dev, int *dstate) { @@ -2399,6 +2489,15 @@ acpi_GetHandleInScope(ACPI_HANDLE parent, char *path, ACPI_HANDLE *result) } } +ACPI_STATUS +acpi_GetProperty(device_t dev, ACPI_STRING propname, + const ACPI_OBJECT **value) +{ + device_t bus = device_get_parent(dev); + + return (ACPI_GET_PROPERTY(bus, dev, propname, value)); +} + /* * Allocate a buffer with a preset data size. */ diff --git a/sys/dev/acpica/acpi_if.m b/sys/dev/acpica/acpi_if.m index 6e36f398411e..e0ed4d72e899 100644 --- a/sys/dev/acpica/acpi_if.m +++ b/sys/dev/acpica/acpi_if.m @@ -121,6 +121,27 @@ METHOD ACPI_STATUS evaluate_object { ACPI_BUFFER *ret; }; +# +# Get property value from Device Specific Data +# +# device_t bus: parent bus for the device +# +# device_t dev: find property for this device's handle. +# +# const ACPI_STRING propname: name of the property +# +# const ACPI_OBJECT **value: property value output +# Specify NULL if ignored +# +# Returns: AE_OK or an error value +# +METHOD ACPI_STATUS get_property { + device_t bus; + device_t dev; + ACPI_STRING propname; + const ACPI_OBJECT **value; +}; + # # Get the highest power state (D0-D3) that is usable for a device when # suspending/resuming. If a bus calls this when suspending a device, it diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index 1f64b479d414..e276193aebc0 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -90,6 +90,9 @@ struct acpi_device { int ad_flags; int ad_cls_class; + ACPI_BUFFER dsd; /* Device Specific Data */ + const ACPI_OBJECT *dsd_pkg; + /* Resources */ struct resource_list ad_rl; }; @@ -350,6 +353,8 @@ BOOLEAN acpi_DeviceIsPresent(device_t dev); BOOLEAN acpi_BatteryIsPresent(device_t dev); ACPI_STATUS acpi_GetHandleInScope(ACPI_HANDLE parent, char *path, ACPI_HANDLE *result); +ACPI_STATUS acpi_GetProperty(device_t dev, ACPI_STRING propname, + const ACPI_OBJECT **value); ACPI_BUFFER *acpi_AllocBuffer(int size); ACPI_STATUS acpi_ConvertBufferToInteger(ACPI_BUFFER *bufp, UINT32 *number); @@ -396,6 +401,13 @@ int acpi_MatchHid(ACPI_HANDLE h, const char *hid); #define ACPI_MATCHHID_HID 1 #define ACPI_MATCHHID_CID 2 +static __inline bool +acpi_HasProperty(device_t dev, ACPI_STRING propname) +{ + + return ACPI_SUCCESS(acpi_GetProperty(dev, propname, NULL)); +} + struct acpi_parse_resource_set { void (*set_init)(device_t dev, void *arg, void **context); void (*set_done)(device_t dev, void *context);