Blame SOURCES/0010-Improve-ACPI-device-path-formatting.patch

5e6fc3
From eb7db33c6cf4172551fe0f9f7cf4aa047dc16d88 Mon Sep 17 00:00:00 2001
5e6fc3
From: Peter Jones <pjones@redhat.com>
5e6fc3
Date: Wed, 20 Jun 2018 14:27:11 -0400
5e6fc3
Subject: [PATCH 10/39] Improve ACPI device path formatting
5e6fc3
5e6fc3
This factors a bunch of the duplication out to another function, which
5e6fc3
also does a better job of it.
5e6fc3
5e6fc3
Signed-off-by: Peter Jones <pjones@redhat.com>
5e6fc3
---
5e6fc3
 src/dp-acpi.c                  | 296 ++++++++++++++++++---------------
5e6fc3
 src/include/efivar/efivar-dp.h |   2 +-
5e6fc3
 2 files changed, 159 insertions(+), 139 deletions(-)
5e6fc3
5e6fc3
diff --git a/src/dp-acpi.c b/src/dp-acpi.c
5e6fc3
index 70162f320dc..a49ef38488c 100644
5e6fc3
--- a/src/dp-acpi.c
5e6fc3
+++ b/src/dp-acpi.c
5e6fc3
@@ -44,6 +44,59 @@ _format_acpi_adr(char *buf, size_t size,
5e6fc3
 #define format_acpi_adr(buf, size, off, dp)				\
5e6fc3
 	format_helper(_format_acpi_adr, buf, size, off, "AcpiAdr", dp)
5e6fc3
 
5e6fc3
+static ssize_t
5e6fc3
+_format_acpi_hid_ex(char *buf, size_t size, const char *dp_type UNUSED,
5e6fc3
+		    const_efidp dp,
5e6fc3
+		    const char *hidstr, const char *cidstr, const char *uidstr)
5e6fc3
+{
5e6fc3
+	ssize_t off = 0;
5e6fc3
+
5e6fc3
+	debug(DEBUG, "hid:0x%08x hidstr:\"%s\"", dp->acpi_hid_ex.hid, hidstr);
5e6fc3
+	debug(DEBUG, "cid:0x%08x cidstr:\"%s\"", dp->acpi_hid_ex.cid, cidstr);
5e6fc3
+	debug(DEBUG, "uid:0x%08x uidstr:\"%s\"", dp->acpi_hid_ex.uid, uidstr);
5e6fc3
+
5e6fc3
+	if (!hidstr && !cidstr && (uidstr || dp->acpi_hid_ex.uid)) {
5e6fc3
+		format(buf, size, off, "AcpiExp",
5e6fc3
+		       "AcpiExp(0x%"PRIx32",0x%"PRIx32",",
5e6fc3
+		       dp->acpi_hid_ex.hid, dp->acpi_hid_ex.cid);
5e6fc3
+		if (uidstr) {
5e6fc3
+			format(buf, size, off, "AcpiExp", "%s)", uidstr);
5e6fc3
+		} else {
5e6fc3
+			format(buf, size, off, "AcpiExp", "0x%"PRIx32")",
5e6fc3
+			       dp->acpi_hid_ex.uid);
5e6fc3
+		}
5e6fc3
+		return off;
5e6fc3
+	}
5e6fc3
+
5e6fc3
+	format(buf, size, off, "AcpiEx", "AcpiEx(");
5e6fc3
+	if (hidstr) {
5e6fc3
+		format(buf, size, off, "AcpiEx", "%s,", hidstr);
5e6fc3
+	} else {
5e6fc3
+		format(buf, size, off, "AcpiEx", "0x%"PRIx32",",
5e6fc3
+		       dp->acpi_hid_ex.hid);
5e6fc3
+	}
5e6fc3
+
5e6fc3
+	if (cidstr) {
5e6fc3
+		format(buf, size, off, "AcpiEx", "%s,", cidstr);
5e6fc3
+	} else {
5e6fc3
+		format(buf, size, off, "AcpiEx", "0x%"PRIx32",",
5e6fc3
+		       dp->acpi_hid_ex.cid);
5e6fc3
+	}
5e6fc3
+
5e6fc3
+	if (uidstr) {
5e6fc3
+		format(buf, size, off, "AcpiEx", "%s)", uidstr);
5e6fc3
+	} else {
5e6fc3
+		format(buf, size, off, "AcpiEx", "0x%"PRIx32")",
5e6fc3
+		       dp->acpi_hid_ex.uid);
5e6fc3
+	}
5e6fc3
+
5e6fc3
+	return off;
5e6fc3
+}
5e6fc3
+
5e6fc3
+#define format_acpi_hid_ex(buf, size, off, dp, hidstr, cidstr, uidstr)  \
5e6fc3
+	format_helper(_format_acpi_hid_ex, buf, size, off, "AcpiEx", dp,\
5e6fc3
+		      hidstr, cidstr, uidstr)
5e6fc3
+
5e6fc3
 ssize_t
5e6fc3
 _format_acpi_dn(char *buf, size_t size, const_efidp dp)
5e6fc3
 {
5e6fc3
@@ -53,13 +106,15 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
5e6fc3
 	const char *uidstr = NULL;
5e6fc3
 	size_t uidlen = 0;
5e6fc3
 	const char *cidstr = NULL;
5e6fc3
-	size_t cidlen = 0;
5e6fc3
+	// size_t cidlen = 0;
5e6fc3
 
5e6fc3
 	if (dp->subtype == EFIDP_ACPI_ADR) {
5e6fc3
+		debug(DEBUG, "formatting ACPI _ADR");
5e6fc3
 		format_acpi_adr(buf, size, off, dp);
5e6fc3
 		return off;
5e6fc3
 	} else if (dp->subtype != EFIDP_ACPI_HID_EX &&
5e6fc3
 		   dp->subtype != EFIDP_ACPI_HID) {
5e6fc3
+		debug(DEBUG, "DP subtype %d, formatting as ACPI Path", dp->subtype);
5e6fc3
 		format(buf, size, off, "AcpiPath", "AcpiPath(%d,", dp->subtype);
5e6fc3
 		format_hex(buf, size, off, "AcpiPath", (uint8_t *)dp+4,
5e6fc3
 			   (efidp_node_size(dp)-4) / 2);
5e6fc3
@@ -69,6 +124,7 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
5e6fc3
 		ssize_t limit = efidp_node_size(dp)
5e6fc3
 				- offsetof(efidp_acpi_hid_ex, hidstr);
5e6fc3
 
5e6fc3
+		debug(DEBUG, "formatting ACPI HID EX");
5e6fc3
 		hidstr = dp->acpi_hid_ex.hidstr;
5e6fc3
 		hidlen = strnlen(hidstr, limit);
5e6fc3
 		limit -= hidlen + 1;
5e6fc3
@@ -81,7 +137,7 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
5e6fc3
 
5e6fc3
 		if (limit) {
5e6fc3
 			cidstr = uidstr + uidlen + 1;
5e6fc3
-			cidlen = strnlen(cidstr, limit);
5e6fc3
+			// cidlen = strnlen(cidstr, limit);
5e6fc3
 			// limit -= cidlen + 1;
5e6fc3
 		}
5e6fc3
 
5e6fc3
@@ -96,143 +152,102 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
5e6fc3
 				       "PcieRoot(%s)", uidstr);
5e6fc3
 				return off;
5e6fc3
 			default:
5e6fc3
-				format(buf, size, off, "AcpiEx", "AcpiEx(");
5e6fc3
-				if (hidlen)
5e6fc3
-					format(buf, size, off, "AcpiEx", "%s",
5e6fc3
-							hidstr);
5e6fc3
-				else
5e6fc3
-					format(buf, size, off, "AcpiEx", "0x%"PRIx32,
5e6fc3
-							dp->acpi_hid_ex.hid);
5e6fc3
-				if (cidlen)
5e6fc3
-					format(buf, size, off, "AcpiEx", ",%s",
5e6fc3
-							cidstr);
5e6fc3
-				else
5e6fc3
-					format(buf, size, off, "AcpiEx", ",0x%"PRIx32,
5e6fc3
-							dp->acpi_hid_ex.cid);
5e6fc3
-				if (uidlen)
5e6fc3
-					format(buf, size, off, "AcpiEx", ",%s",
5e6fc3
-							uidstr);
5e6fc3
-				else
5e6fc3
-					format(buf, size, off, "AcpiEx", ",0x%"PRIx32,
5e6fc3
-							dp->acpi_hid_ex.uid);
5e6fc3
-				format(buf, size, off, "AcpiEx", ")");
5e6fc3
-				break;
5e6fc3
+				format_acpi_hid_ex(buf, size, off, dp,
5e6fc3
+						   hidstr, cidstr, uidstr);
5e6fc3
+				return off;
5e6fc3
 			}
5e6fc3
 		}
5e6fc3
-	}
5e6fc3
-
5e6fc3
-	switch (dp->acpi_hid.hid) {
5e6fc3
-	case EFIDP_ACPI_PCI_ROOT_HID:
5e6fc3
-		format(buf, size, off, "PciRoot", "PciRoot(0x%"PRIx32")",
5e6fc3
-		       dp->acpi_hid.uid);
5e6fc3
-		break;
5e6fc3
-	case EFIDP_ACPI_PCIE_ROOT_HID:
5e6fc3
-		format(buf, size, off, "PcieRoot", "PcieRoot(0x%"PRIx32")",
5e6fc3
-		       dp->acpi_hid.uid);
5e6fc3
-		break;
5e6fc3
-	case EFIDP_ACPI_FLOPPY_HID:
5e6fc3
-		format(buf, size, off, "Floppy", "Floppy(0x%"PRIx32")",
5e6fc3
-		       dp->acpi_hid.uid);
5e6fc3
-		break;
5e6fc3
-	case EFIDP_ACPI_KEYBOARD_HID:
5e6fc3
-		format(buf, size, off, "Keyboard", "Keyboard(0x%"PRIx32")",
5e6fc3
-		       dp->acpi_hid.uid);
5e6fc3
-		break;
5e6fc3
-	case EFIDP_ACPI_SERIAL_HID:
5e6fc3
-		format(buf, size, off, "Keyboard", "Serial(0x%"PRIx32")",
5e6fc3
-		       dp->acpi_hid.uid);
5e6fc3
-		break;
5e6fc3
-	case EFIDP_ACPI_NVDIMM_HID: {
5e6fc3
-		int rc;
5e6fc3
-		const_efidp next = NULL;
5e6fc3
-		efidp_acpi_adr *adrdp;
5e6fc3
-		int end;
5e6fc3
-
5e6fc3
-		format(buf, size, off, "NvRoot()", "NvRoot()");
5e6fc3
-
5e6fc3
-		rc = efidp_next_node(dp, &next;;
5e6fc3
-		if (rc < 0 || !next) {
5e6fc3
-			efi_error("could not format DP");
5e6fc3
-			return rc;
5e6fc3
-		}
5e6fc3
+	} else if (dp->subtype == EFIDP_ACPI_HID_EX) {
5e6fc3
+		switch (dp->acpi_hid.hid) {
5e6fc3
+		case EFIDP_ACPI_PCI_ROOT_HID:
5e6fc3
+			format(buf, size, off, "PciRoot",
5e6fc3
+			       "PciRoot(0x%"PRIx32")",
5e6fc3
+			       dp->acpi_hid.uid);
5e6fc3
+			break;
5e6fc3
+		case EFIDP_ACPI_PCIE_ROOT_HID:
5e6fc3
+			format(buf, size, off, "PcieRoot",
5e6fc3
+			       "PcieRoot(0x%"PRIx32")",
5e6fc3
+			       dp->acpi_hid.uid);
5e6fc3
+			break;
5e6fc3
+		case EFIDP_ACPI_FLOPPY_HID:
5e6fc3
+			format(buf, size, off, "Floppy",
5e6fc3
+			       "Floppy(0x%"PRIx32")",
5e6fc3
+			       dp->acpi_hid.uid);
5e6fc3
+			break;
5e6fc3
+		case EFIDP_ACPI_KEYBOARD_HID:
5e6fc3
+			format(buf, size, off, "Keyboard",
5e6fc3
+			       "Keyboard(0x%"PRIx32")",
5e6fc3
+			       dp->acpi_hid.uid);
5e6fc3
+			break;
5e6fc3
+		case EFIDP_ACPI_SERIAL_HID:
5e6fc3
+			format(buf, size, off, "Serial",
5e6fc3
+			       "Serial(0x%"PRIx32")",
5e6fc3
+			       dp->acpi_hid.uid);
5e6fc3
+			break;
5e6fc3
+		case EFIDP_ACPI_NVDIMM_HID: {
5e6fc3
+			int rc;
5e6fc3
+			const_efidp next = NULL;
5e6fc3
+			efidp_acpi_adr *adrdp;
5e6fc3
+			int end;
5e6fc3
 
5e6fc3
-		if (efidp_type(next) != EFIDP_ACPI_TYPE ||
5e6fc3
-		    efidp_subtype(next) != EFIDP_ACPI_ADR) {
5e6fc3
-			efi_error("Invalid child node type (0x%02x,0x%02x)",
5e6fc3
-				  efidp_type(next), efidp_subtype(next));
5e6fc3
-			return -EINVAL;
5e6fc3
-		}
5e6fc3
-		adrdp = (efidp_acpi_adr *)next;
5e6fc3
+			format(buf, size, off, "NvRoot()", "NvRoot()");
5e6fc3
 
5e6fc3
-		end = efidp_size_after(adrdp, header)
5e6fc3
-			/ sizeof(adrdp->adr[0]);
5e6fc3
+			rc = efidp_next_node(dp, &next;;
5e6fc3
+			if (rc < 0 || !next) {
5e6fc3
+				efi_error("could not format DP");
5e6fc3
+				return rc;
5e6fc3
+			}
5e6fc3
 
5e6fc3
-		for (int i = 0; i < end; i++) {
5e6fc3
-			uint32_t node_controller, socket, memory_controller;
5e6fc3
-			uint32_t memory_channel, dimm;
5e6fc3
-			uint32_t adr = adrdp->adr[i];
5e6fc3
+			if (efidp_type(next) != EFIDP_ACPI_TYPE ||
5e6fc3
+			    efidp_subtype(next) != EFIDP_ACPI_ADR) {
5e6fc3
+				efi_error("Invalid child node type (0x%02x,0x%02x)",
5e6fc3
+					  efidp_type(next), efidp_subtype(next));
5e6fc3
+				return -EINVAL;
5e6fc3
+			}
5e6fc3
+			adrdp = (efidp_acpi_adr *)next;
5e6fc3
 
5e6fc3
-			efidp_decode_acpi_nvdimm_adr(adr, &node_controller,
5e6fc3
-						     &socket,
5e6fc3
-						     &memory_controller,
5e6fc3
-						     &memory_channel, &dimm);
5e6fc3
+			end = efidp_size_after(adrdp, header)
5e6fc3
+				/ sizeof(adrdp->adr[0]);
5e6fc3
 
5e6fc3
-			if (i != 0)
5e6fc3
-				format(buf, size, off, "NvDimm", ",");
5e6fc3
+			for (int i = 0; i < end; i++) {
5e6fc3
+				uint32_t node_controller, socket, memory_controller;
5e6fc3
+				uint32_t memory_channel, dimm;
5e6fc3
+				uint32_t adr = adrdp->adr[i];
5e6fc3
 
5e6fc3
-			format(buf, size, off, "NvDimm",
5e6fc3
-			       "NvDimm(0x%03x,0x%01x,0x%01x,0x%01x,0x%01x)",
5e6fc3
-			       node_controller, socket, memory_controller,
5e6fc3
-			       memory_channel, dimm);
5e6fc3
-		}
5e6fc3
-		break;
5e6fc3
-				    }
5e6fc3
-	default:
5e6fc3
-		switch (dp->subtype) {
5e6fc3
-		case EFIDP_ACPI_HID_EX:
5e6fc3
-			if (!hidstr && !cidstr &&
5e6fc3
-					(uidstr || dp->acpi_hid_ex.uid)){
5e6fc3
-				format(buf, size, off, "AcpiExp",
5e6fc3
-				       "AcpiExp(0x%"PRIx32",0x%"PRIx32",",
5e6fc3
-				       dp->acpi_hid_ex.hid,
5e6fc3
-				       dp->acpi_hid_ex.cid);
5e6fc3
-				if (uidstr) {
5e6fc3
-					format(buf, size, off, "AcpiExp",
5e6fc3
-					       "%s)", uidstr);
5e6fc3
-				} else {
5e6fc3
-					format(buf, size, off, "AcpiExp",
5e6fc3
-					       "0x%"PRIx32")",
5e6fc3
-					       dp->acpi_hid.uid);
5e6fc3
-				}
5e6fc3
-				break;
5e6fc3
-			}
5e6fc3
-			format(buf, size, off, "AcpiEx", "AcpiEx(");
5e6fc3
-			if (hidstr) {
5e6fc3
-				format(buf, size, off, "AcpiEx", "%s,", hidstr);
5e6fc3
-			} else {
5e6fc3
-				format(buf, size, off, "AcpiEx", "0x%"PRIx32",",
5e6fc3
-					      dp->acpi_hid.hid);
5e6fc3
-			}
5e6fc3
+				efidp_decode_acpi_nvdimm_adr(adr,
5e6fc3
+					&node_controller, &socket,
5e6fc3
+					&memory_controller, &memory_channel,
5e6fc3
+					&dimm);
5e6fc3
 
5e6fc3
-			if (cidstr) {
5e6fc3
-				format(buf, size, off, "AcpiEx", "%s,", cidstr);
5e6fc3
-			} else {
5e6fc3
-				format(buf, size, off, "AcpiEx", "0x%"PRIx32",",
5e6fc3
-				       dp->acpi_hid_ex.cid);
5e6fc3
-			}
5e6fc3
+				if (i != 0)
5e6fc3
+					format(buf, size, off, "NvDimm", ",");
5e6fc3
 
5e6fc3
-			if (uidstr) {
5e6fc3
-				format(buf, size, off, "AcpiEx", "%s)", uidstr);
5e6fc3
-			} else {
5e6fc3
-				format(buf, size, off, "AcpiEx", "0x%"PRIx32")",
5e6fc3
-				       dp->acpi_hid.uid);
5e6fc3
+				format(buf, size, off, "NvDimm",
5e6fc3
+				       "NvDimm(0x%03x,0x%01x,0x%01x,0x%01x,0x%01x)",
5e6fc3
+				       node_controller, socket, memory_controller,
5e6fc3
+				       memory_channel, dimm);
5e6fc3
 			}
5e6fc3
 			break;
5e6fc3
-		case EFIDP_ACPI_HID:
5e6fc3
-			format(buf, size, off, "Acpi",
5e6fc3
-			       "Acpi(0x%"PRIx32",0x%"PRIx32")",
5e6fc3
-			       dp->acpi_hid.hid, dp->acpi_hid.uid);
5e6fc3
-			break;
5e6fc3
+					    }
5e6fc3
+		default:
5e6fc3
+			debug(DEBUG, "Decoding non-well-known HID");
5e6fc3
+			switch (dp->subtype) {
5e6fc3
+			case EFIDP_ACPI_HID_EX:
5e6fc3
+				format_acpi_hid_ex(buf, size, off, dp,
5e6fc3
+						   hidstr, cidstr, uidstr);
5e6fc3
+				break;
5e6fc3
+			case EFIDP_ACPI_HID:
5e6fc3
+				debug(DEBUG, "Decoding ACPI HID");
5e6fc3
+				format(buf, size, off, "Acpi",
5e6fc3
+				       "Acpi(0x%08x,0x%"PRIx32")",
5e6fc3
+				       dp->acpi_hid.hid, dp->acpi_hid.uid);
5e6fc3
+				break;
5e6fc3
+			default:
5e6fc3
+				debug(DEBUG, "ACPI subtype %d???",
5e6fc3
+				      dp->subtype);
5e6fc3
+				errno = EINVAL;
5e6fc3
+				return -1;
5e6fc3
+			}
5e6fc3
 		}
5e6fc3
 	}
5e6fc3
 
5e6fc3
@@ -259,7 +274,7 @@ efidp_make_acpi_hid(uint8_t *buf, ssize_t size, uint32_t hid, uint32_t uid)
5e6fc3
 	return sz;
5e6fc3
 }
5e6fc3
 
5e6fc3
-ssize_t PUBLIC NONNULL(6, 7, 8)
5e6fc3
+ssize_t PUBLIC
5e6fc3
 efidp_make_acpi_hid_ex(uint8_t *buf, ssize_t size,
5e6fc3
 		       uint32_t hid, uint32_t uid, uint32_t cid,
5e6fc3
 		       const char *hidstr, const char *uidstr,
5e6fc3
@@ -268,21 +283,26 @@ efidp_make_acpi_hid_ex(uint8_t *buf, ssize_t size,
5e6fc3
 	efidp_acpi_hid_ex *acpi_hid = (efidp_acpi_hid_ex *)buf;
5e6fc3
 	ssize_t req;
5e6fc3
 	ssize_t sz;
5e6fc3
+	size_t hidlen = hidstr ? strlen(hidstr) : 0;
5e6fc3
+	size_t uidlen = uidstr ? strlen(uidstr) : 0;
5e6fc3
+	size_t cidlen = cidstr ? strlen(cidstr) : 0;
5e6fc3
 
5e6fc3
-	req = sizeof (*acpi_hid) + 3 +
5e6fc3
-		strlen(hidstr) + strlen(uidstr) + strlen(cidstr);
5e6fc3
+	req = sizeof (*acpi_hid) + 3 + hidlen + uidlen + cidlen;
5e6fc3
 	sz = efidp_make_generic(buf, size, EFIDP_ACPI_TYPE, EFIDP_ACPI_HID_EX,
5e6fc3
 				req);
5e6fc3
 	if (size && sz == req) {
5e6fc3
-		acpi_hid->uid = uid;
5e6fc3
-		acpi_hid->hid = hid;
5e6fc3
-		acpi_hid->cid = cid;
5e6fc3
+		acpi_hid->hid = hidlen ? 0 : hid;
5e6fc3
+		acpi_hid->uid = uidlen ? 0 : uid;
5e6fc3
+		acpi_hid->cid = cidlen ? 0 : cid;
5e6fc3
 		char *next = (char *)buf+offsetof(efidp_acpi_hid_ex, hidstr);
5e6fc3
-		strcpy(next, hidstr);
5e6fc3
-		next += strlen(hidstr) + 1;
5e6fc3
-		strcpy(next, uidstr);
5e6fc3
-		next += strlen(uidstr) + 1;
5e6fc3
-		strcpy(next, cidstr);
5e6fc3
+		if (hidlen)
5e6fc3
+			strcpy(next, hidstr);
5e6fc3
+		next += hidlen + 1;
5e6fc3
+		if (uidlen)
5e6fc3
+			strcpy(next, uidstr);
5e6fc3
+		next += uidlen + 1;
5e6fc3
+		if (cidlen)
5e6fc3
+			strcpy(next, cidstr);
5e6fc3
 	}
5e6fc3
 
5e6fc3
 	if (sz < 0)
5e6fc3
diff --git a/src/include/efivar/efivar-dp.h b/src/include/efivar/efivar-dp.h
5e6fc3
index 106d3645e21..1b05775ae7e 100644
5e6fc3
--- a/src/include/efivar/efivar-dp.h
5e6fc3
+++ b/src/include/efivar/efivar-dp.h
5e6fc3
@@ -133,7 +133,7 @@ typedef struct {
5e6fc3
 	/* three ascii string fields follow */
5e6fc3
 	char		hidstr[];
5e6fc3
 } EFIVAR_PACKED efidp_acpi_hid_ex;
5e6fc3
-extern ssize_t __attribute__((__nonnull__ (6,7,8)))
5e6fc3
+extern ssize_t
5e6fc3
 efidp_make_acpi_hid_ex(uint8_t *buf, ssize_t size,
5e6fc3
                        uint32_t hid, uint32_t uid, uint32_t cid,
5e6fc3
                        const char *hidstr, const char *uidstr,
5e6fc3
-- 
5e6fc3
2.17.1
5e6fc3