Implement the equivalent of OF_getprop() for device-tree-like
properties in ACPI land.  Needed for the upcomong Raspberry Pi4
network interface driver.

ok?


Index: dev/acpi/acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.381
diff -u -p -r1.381 acpi.c
--- dev/acpi/acpi.c     12 Apr 2020 09:21:19 -0000      1.381
+++ dev/acpi/acpi.c     12 Apr 2020 14:57:21 -0000
@@ -2961,6 +2961,57 @@ acpi_foundsony(struct aml_node *node, vo
 
 /* Support for _DSD Device Properties. */
 
+int
+acpi_getprop(struct aml_node *node, const char *prop, void *buf, int buflen)
+{
+       struct aml_value dsd;
+       int i;
+
+       /* daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
+       static uint8_t prop_guid[] = {
+               0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
+               0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01,
+       };
+
+       if (aml_evalname(acpi_softc, node, "_DSD", 0, NULL, &dsd))
+               return -1;
+
+       if (dsd.type != AML_OBJTYPE_PACKAGE || dsd.length != 2 ||
+           dsd.v_package[0]->type != AML_OBJTYPE_BUFFER ||
+           dsd.v_package[1]->type != AML_OBJTYPE_PACKAGE)
+               return -1;
+
+       /* Check UUID. */
+       if (dsd.v_package[0]->length != sizeof(prop_guid) ||
+           memcmp(dsd.v_package[0]->v_buffer, prop_guid,
+           sizeof(prop_guid)) != 0)
+               return -1;
+
+       /* Check properties. */
+       for (i = 0; i < dsd.v_package[1]->length; i++) {
+               struct aml_value *res = dsd.v_package[1]->v_package[i];
+               int len;
+
+               if (res->type != AML_OBJTYPE_PACKAGE || res->length != 2 ||
+                   res->v_package[0]->type != AML_OBJTYPE_STRING)
+                       continue;
+
+               len = res->v_package[1]->length;
+               switch (res->v_package[1]->type) {
+               case AML_OBJTYPE_BUFFER:
+                       memcpy(buf, res->v_package[1]->v_buffer,
+                           min(len, buflen));
+                       return len;
+               case AML_OBJTYPE_STRING:
+                       memcpy(buf, res->v_package[1]->v_string,
+                           min(len, buflen));
+                       return len;
+               }
+       }
+
+       return -1;
+}
+
 uint32_t
 acpi_getpropint(struct aml_node *node, const char *prop, uint32_t defval)
 {
@@ -2999,7 +3050,7 @@ acpi_getpropint(struct aml_node *node, c
                if (strcmp(res->v_package[0]->v_string, prop) == 0)
                        return res->v_package[1]->v_integer;
        }
-       
+
        return defval;
 }
 
Index: dev/acpi/acpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.106
diff -u -p -r1.106 acpivar.h
--- dev/acpi/acpivar.h  12 Apr 2020 09:21:19 -0000      1.106
+++ dev/acpi/acpivar.h  12 Apr 2020 14:57:21 -0000
@@ -372,6 +372,7 @@ int acpi_matchhids(struct acpi_attach_ar
 int    acpi_parsehid(struct aml_node *, void *, char *, char *, size_t);
 int64_t        acpi_getsta(struct acpi_softc *sc, struct aml_node *);
 
+int    acpi_getprop(struct aml_node *, const char *, void *, int);
 uint32_t acpi_getpropint(struct aml_node *, const char *, uint32_t);
 
 int    acpi_record_event(struct acpi_softc *, u_int);

Reply via email to