Blame SOURCES/0058-sysfs-parsers-make-all-the-sys-block-link-parsers-wo.patch

a43681
From fa9336914ef43d1a1dbc3384c8051362eea12cd7 Mon Sep 17 00:00:00 2001
a43681
From: Peter Jones <pjones@redhat.com>
a43681
Date: Tue, 15 Oct 2019 16:53:27 -0400
a43681
Subject: [PATCH 58/63] sysfs parsers: make all the /sys/block link parsers
a43681
 work the same way
a43681
a43681
Apparently I wrote some of these one way and some the other, and the one
a43681
special case where everything was "current+sz" instead of some form of
a43681
"current += pos; sz += pos; ...; return sz;".
a43681
a43681
Make them all the same, where possible.
a43681
a43681
Signed-off-by: Peter Jones <pjones@redhat.com>
a43681
---
a43681
 src/linux-acpi-root.c    |  65 +++++-----
a43681
 src/linux-pci-root.c     |   9 +-
a43681
 src/linux-pci.c          |  21 ++--
a43681
 src/linux-sata.c         |  56 +++++----
a43681
 src/linux-scsi.c         | 248 ++++++++++++++++++++-------------------
a43681
 src/linux-soc-root.c     |  19 +--
a43681
 src/linux-virtblk.c      |  15 ++-
a43681
 src/linux-virtual-root.c |   2 +-
a43681
 8 files changed, 227 insertions(+), 208 deletions(-)
a43681
a43681
diff --git a/src/linux-acpi-root.c b/src/linux-acpi-root.c
a43681
index 57a648981b3..6bfc1ad9a2b 100644
a43681
--- a/src/linux-acpi-root.c
a43681
+++ b/src/linux-acpi-root.c
a43681
@@ -44,14 +44,13 @@ static ssize_t
a43681
 parse_acpi_root(struct device *dev, const char *current, const char *root UNUSED)
a43681
 {
a43681
 	int rc;
a43681
-	int pos = -1;
a43681
+	int pos0 = -1, pos1 = -1, pos2 = -1;
a43681
+	ssize_t sz = 0;
a43681
 	uint16_t pad0;
a43681
 	uint8_t pad1;
a43681
 	char *acpi_header = NULL;
a43681
 	char *colon;
a43681
 
a43681
-	const char *devpart = current;
a43681
-
a43681
 	debug("entry");
a43681
 
a43681
 	/*
a43681
@@ -61,23 +60,26 @@ parse_acpi_root(struct device *dev, const char *current, const char *root UNUSED
a43681
 	 * This is annoying because "/%04ms%h:%hhx/" won't bind from the right
a43681
 	 * side in sscanf.
a43681
 	 */
a43681
-	rc = sscanf(devpart, "../../devices/platform/%n", &pos;;
a43681
-	debug("current:'%s' rc:%d pos:%d", devpart, rc, pos);
a43681
-	dbgmk("         ", pos);
a43681
-	if (rc != 0 || pos < 1)
a43681
+	rc = sscanf(current, "../../devices/%nplatform/%n", &pos0, &pos1);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
+	if (rc != 0 || pos0 == -1 || pos1 == -1)
a43681
 		return 0;
a43681
-	devpart += pos;
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
 
a43681
+	debug("searching for an ACPI string like A0000:00 or ACPI0000:00");
a43681
+	pos0 = 0;
a43681
 	/*
a43681
 	 * If it's too short to be A0000:00, it's not an ACPI string
a43681
 	 */
a43681
-	if (strlen(devpart) < 8)
a43681
+	if (strlen(current) < 8)
a43681
 		return 0;
a43681
 
a43681
-	colon = strchr(devpart, ':');
a43681
+	colon = strchr(current, ':');
a43681
 	if (!colon)
a43681
 		return 0;
a43681
-	pos = colon - devpart;
a43681
+	pos1 = colon - current;
a43681
 
a43681
 	/*
a43681
 	 * If colon doesn't point at something between one of these:
a43681
@@ -85,40 +87,44 @@ parse_acpi_root(struct device *dev, const char *current, const char *root UNUSED
a43681
 	 *	^ 5	    ^ 8
a43681
 	 * Then it's not an ACPI string.
a43681
 	 */
a43681
-	if (pos < 5 || pos > 8)
a43681
+	if (pos1 < 5 || pos1 > 8)
a43681
 		return 0;
a43681
 
a43681
-	dev->acpi_root.acpi_hid_str = strndup(devpart, pos + 1);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
+
a43681
+	dev->acpi_root.acpi_hid_str = strndup(current, pos1 + 1);
a43681
 	if (!dev->acpi_root.acpi_hid_str) {
a43681
 		efi_error("Could not allocate memory");
a43681
 		return -1;
a43681
 	}
a43681
-	dev->acpi_root.acpi_hid_str[pos] = 0;
a43681
+	dev->acpi_root.acpi_hid_str[pos1] = 0;
a43681
 	debug("acpi_hid_str:'%s'", dev->acpi_root.acpi_hid_str);
a43681
 
a43681
-	pos -= 4;
a43681
-	debug("current:'%s' rc:%d pos:%d", devpart, rc, pos);
a43681
-	dbgmk("         ", pos);
a43681
-	acpi_header = strndupa(devpart, pos);
a43681
+	pos2 = pos1 - 4;
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d", current, rc, pos0, pos2);
a43681
+	dbgmk("         ", pos0, pos2);
a43681
+	acpi_header = strndupa(current, pos2);
a43681
 	if (!acpi_header)
a43681
 		return 0;
a43681
-	acpi_header[pos] = 0;
a43681
-	debug("current:'%s' acpi_header:'%s'", devpart, acpi_header);
a43681
-	devpart += pos;
a43681
+	acpi_header[pos2] = 0;
a43681
+	debug("current:'%s' acpi_header:'%s'", current, acpi_header);
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
 
a43681
 	/*
a43681
 	 * If we can't find these numbers, it's not an ACPI string
a43681
 	 */
a43681
-	rc = sscanf(devpart, "%hx:%hhx/%n", &pad0, &pad1, &pos;;
a43681
+	rc = sscanf(current, "%n%hx:%hhx/%n", &pos0, &pad0, &pad1, &pos1);
a43681
 	if (rc != 2) {
a43681
-		efi_error("Could not parse ACPI path \"%s\"", devpart);
a43681
+		efi_error("Could not parse ACPI path \"%s\"", current);
a43681
 		return 0;
a43681
 	}
a43681
-	debug("current:'%s' parsed:%04hx:%02hhx pos:%d rc:%d",
a43681
-	      devpart, pad0, pad1, pos, rc);
a43681
-	dbgmk("         ", pos);
a43681
-
a43681
-	devpart += pos;
a43681
+	debug("current:'%s' parsed:%04hx:%02hhx rc:%d pos0:%d pos1:%d",
a43681
+	      current, pad0, pad1, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
 
a43681
 	rc = parse_acpi_hid_uid(dev, "devices/platform/%s%04hX:%02hhX",
a43681
 				acpi_header, pad0, pad1);
a43681
@@ -139,8 +145,7 @@ parse_acpi_root(struct device *dev, const char *current, const char *root UNUSED
a43681
 	      dev->acpi_root.acpi_uid_str,
a43681
 	      dev->acpi_root.acpi_cid_str);
a43681
 
a43681
-	size_t sz = devpart - current;
a43681
-	debug("current:'%s' sz:%zd", devpart, sz);
a43681
+	debug("current:'%s' sz:%zd", current, sz);
a43681
 	return sz;
a43681
 }
a43681
 
a43681
diff --git a/src/linux-pci-root.c b/src/linux-pci-root.c
a43681
index c7e279118f5..8f7cfe293bf 100644
a43681
--- a/src/linux-pci-root.c
a43681
+++ b/src/linux-pci-root.c
a43681
@@ -47,7 +47,6 @@ parse_pci_root(struct device *dev, const char *current, const char *root UNUSED)
a43681
 	int pos0 = -1, pos1 = -1;
a43681
 	uint16_t root_domain;
a43681
 	uint8_t root_bus;
a43681
-	const char *devpart = current;
a43681
 
a43681
 	debug("entry");
a43681
 
a43681
@@ -56,8 +55,8 @@ parse_pci_root(struct device *dev, const char *current, const char *root UNUSED)
a43681
 	 * pci0000:00/
a43681
 	 *    ^d   ^p
a43681
 	 */
a43681
-	rc = sscanf(devpart, "%n../../devices/pci%hx:%hhx/%n", &pos0, &root_domain, &root_bus, &pos1);
a43681
-	debug("current:'%s' rc:%d pos0:%d pos1:%d", devpart, rc, pos0, pos1);
a43681
+	rc = sscanf(current, "%n../../devices/pci%hx:%hhx/%n", &pos0, &root_domain, &root_bus, &pos1);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d", current, rc, pos0, pos1);
a43681
 	dbgmk("         ", pos0, pos1);
a43681
 
a43681
 	/*
a43681
@@ -65,7 +64,7 @@ parse_pci_root(struct device *dev, const char *current, const char *root UNUSED)
a43681
 	 */
a43681
 	if (rc != 2)
a43681
 	        return 0;
a43681
-	devpart += pos1;
a43681
+	current += pos1;
a43681
 
a43681
 	dev->pci_root.pci_domain = root_domain;
a43681
 	dev->pci_root.pci_bus = root_bus;
a43681
@@ -76,7 +75,7 @@ parse_pci_root(struct device *dev, const char *current, const char *root UNUSED)
a43681
 	        return -1;
a43681
 
a43681
 	errno = 0;
a43681
-	debug("current:'%s' sz:%d\n", devpart, pos1);
a43681
+	debug("current:'%s' sz:%d\n", current, pos1);
a43681
 	return pos1;
a43681
 }
a43681
 
a43681
diff --git a/src/linux-pci.c b/src/linux-pci.c
a43681
index a3a0dc28afd..ca6f693cd8a 100644
a43681
--- a/src/linux-pci.c
a43681
+++ b/src/linux-pci.c
a43681
@@ -46,8 +46,7 @@ static ssize_t
a43681
 parse_pci(struct device *dev, const char *current, const char *root)
a43681
 {
a43681
 	int rc;
a43681
-	int pos0 = -1, pos1 = -1;
a43681
-	const char *devpart = current;
a43681
+	ssize_t sz = 0;
a43681
 
a43681
 	debug("entry");
a43681
 
a43681
@@ -55,22 +54,24 @@ parse_pci(struct device *dev, const char *current, const char *root)
a43681
 	 * 0000:00:01.0/0000:01:00.0/
a43681
 	 *              ^d   ^b ^d ^f (of the last one in the series)
a43681
 	 */
a43681
-	while (*devpart) {
a43681
+	while (*current) {
a43681
 	        uint16_t domain;
a43681
 	        uint8_t bus, device, function;
a43681
 	        struct pci_dev_info *pci_dev;
a43681
 	        unsigned int i = dev->n_pci_devs;
a43681
 	        struct stat statbuf;
a43681
+		int pos0 = -1, pos1 = -1;
a43681
 
a43681
 	        pos0 = pos1 = -1;
a43681
 	        debug("searching for 0000:00:00.0/");
a43681
-	        rc = sscanf(devpart, "%n%hx:%hhx:%hhx.%hhx/%n",
a43681
+	        rc = sscanf(current, "%n%hx:%hhx:%hhx.%hhx/%n",
a43681
 	                    &pos0, &domain, &bus, &device, &function, &pos1);
a43681
-	        debug("current:'%s' rc:%d pos0:%d pos1:%d", devpart, rc, pos0, pos1);
a43681
+	        debug("current:'%s' rc:%d pos0:%d pos1:%d", current, rc, pos0, pos1);
a43681
 		dbgmk("         ", pos0, pos1);
a43681
 	        if (rc != 4)
a43681
 	                break;
a43681
-	        devpart += pos1;
a43681
+	        current += pos1;
a43681
+		sz += pos1;
a43681
 
a43681
 	        debug("found pci domain %04hx:%02hhx:%02hhx.%02hhx",
a43681
 	              domain, bus, device, function);
a43681
@@ -87,13 +88,13 @@ parse_pci(struct device *dev, const char *current, const char *root)
a43681
 	        dev->pci_dev[i].pci_bus = bus;
a43681
 	        dev->pci_dev[i].pci_device = device;
a43681
 	        dev->pci_dev[i].pci_function = function;
a43681
-	        char *tmp = strndup(root, devpart-root+1);
a43681
+	        char *tmp = strndup(root, current-root+1);
a43681
 	        char *linkbuf = NULL;
a43681
 	        if (!tmp) {
a43681
 	                efi_error("could not allocate memory");
a43681
 	                return -1;
a43681
 	        }
a43681
-	        tmp[devpart - root] = '\0';
a43681
+	        tmp[current - root] = '\0';
a43681
 	        rc = sysfs_stat(&statbuf, "class/block/%s/driver", tmp);
a43681
 	        if (rc < 0 && errno == ENOENT) {
a43681
 	                debug("No driver link for /sys/class/block/%s", tmp);
a43681
@@ -114,8 +115,8 @@ parse_pci(struct device *dev, const char *current, const char *root)
a43681
 	        dev->n_pci_devs += 1;
a43681
 	}
a43681
 
a43681
-	debug("current:'%s' sz:%zd\n", devpart, devpart - current);
a43681
-	return devpart - current;
a43681
+	debug("current:'%s' sz:%zd\n", current, sz);
a43681
+	return sz;
a43681
 }
a43681
 
a43681
 static ssize_t
a43681
diff --git a/src/linux-sata.c b/src/linux-sata.c
a43681
index 4f4e983568e..b49cf99dcb7 100644
a43681
--- a/src/linux-sata.c
a43681
+++ b/src/linux-sata.c
a43681
@@ -138,15 +138,15 @@ sysfs_sata_get_port_info(uint32_t print_id, struct device *dev)
a43681
 }
a43681
 
a43681
 static ssize_t
a43681
-parse_sata(struct device *dev, const char *devlink, const char *root UNUSED)
a43681
+parse_sata(struct device *dev, const char *current, const char *root UNUSED)
a43681
 {
a43681
-	const char *current = devlink;
a43681
 	uint32_t print_id;
a43681
 	uint32_t scsi_bus, tosser0;
a43681
 	uint32_t scsi_device, tosser1;
a43681
 	uint32_t scsi_target, tosser2;
a43681
 	uint64_t scsi_lun, tosser3;
a43681
-	int pos = 0;
a43681
+	int pos0 = -1, pos1 = -1;
a43681
+	size_t sz = 0;
a43681
 	int rc;
a43681
 
a43681
 	debug("entry");
a43681
@@ -160,9 +160,9 @@ parse_sata(struct device *dev, const char *devlink, const char *root UNUSED)
a43681
 	 *    ^dev  ^host   x y z
a43681
 	 */
a43681
 	debug("searching for ata1/");
a43681
-	rc = sscanf(current, "ata%"PRIu32"/%n", &print_id, &pos;;
a43681
-	debug("current:'%s' rc:%d pos:%d\n", current, rc, pos);
a43681
-	dbgmk("         ", pos);
a43681
+	rc = sscanf(current, "%nata%"PRIu32"/%n", &pos0, &print_id, &pos1);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
 	/*
a43681
 	 * If we don't find this one, it isn't an ata device, so return 0 not
a43681
 	 * error.  Later errors mean it is an ata device, but we can't parse
a43681
@@ -170,36 +170,40 @@ parse_sata(struct device *dev, const char *devlink, const char *root UNUSED)
a43681
 	 */
a43681
 	if (rc != 1)
a43681
 	        return 0;
a43681
-	current += pos;
a43681
-	pos = 0;
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
+	pos0 = pos1 = -1;
a43681
 
a43681
 	debug("searching for host0/");
a43681
-	rc = sscanf(current, "host%"PRIu32"/%n", &scsi_bus, &pos;;
a43681
-	debug("current:'%s' rc:%d pos:%d\n", current, rc, pos);
a43681
-	dbgmk("         ", pos);
a43681
+	rc = sscanf(current, "%nhost%"PRIu32"/%n", &pos0, &scsi_bus, &pos1);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
 	if (rc != 1)
a43681
 	        return -1;
a43681
-	current += pos;
a43681
-	pos = 0;
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
+	pos0 = pos1 = -1;
a43681
 
a43681
 	debug("searching for target0:0:0:0/");
a43681
-	rc = sscanf(current, "target%"PRIu32":%"PRIu32":%"PRIu64"/%n",
a43681
-	            &scsi_device, &scsi_target, &scsi_lun, &pos;;
a43681
-	debug("current:'%s' rc:%d pos:%d\n", current, rc, pos);
a43681
-	dbgmk("         ", pos);
a43681
+	rc = sscanf(current, "%ntarget%"PRIu32":%"PRIu32":%"PRIu64"/%n",
a43681
+	            &pos0, &scsi_device, &scsi_target, &scsi_lun, &pos1);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
 	if (rc != 3)
a43681
 	        return -1;
a43681
-	current += pos;
a43681
-	pos = 0;
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
+	pos0 = pos1 = -1;
a43681
 
a43681
 	debug("searching for 0:0:0:0/");
a43681
-	rc = sscanf(current, "%"PRIu32":%"PRIu32":%"PRIu32":%"PRIu64"/%n",
a43681
-	            &tosser0, &tosser1, &tosser2, &tosser3, &pos;;
a43681
-	debug("current:'%s' rc:%d pos:%d\n", current, rc, pos);
a43681
-	dbgmk("         ", pos);
a43681
+	rc = sscanf(current, "%n%"PRIu32":%"PRIu32":%"PRIu32":%"PRIu64"/%n",
a43681
+	            &pos0, &tosser0, &tosser1, &tosser2, &tosser3, &pos1);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
 	if (rc != 4)
a43681
 	        return -1;
a43681
-	current += pos;
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
 
a43681
 	rc = sysfs_sata_get_port_info(print_id, dev);
a43681
 	if (rc < 0)
a43681
@@ -213,8 +217,8 @@ parse_sata(struct device *dev, const char *devlink, const char *root UNUSED)
a43681
 	if (dev->interface_type == unknown)
a43681
 	        dev->interface_type = sata;
a43681
 
a43681
-	debug("current:'%s' sz:%zd\n", current, current - devlink);
a43681
-	return current - devlink;
a43681
+	debug("current:'%s' sz:%zd\n", current, sz);
a43681
+	return sz;
a43681
 }
a43681
 
a43681
 static ssize_t
a43681
diff --git a/src/linux-scsi.c b/src/linux-scsi.c
a43681
index 6b92908d6bc..73db53b3ed6 100644
a43681
--- a/src/linux-scsi.c
a43681
+++ b/src/linux-scsi.c
a43681
@@ -24,6 +24,7 @@
a43681
 #include <fcntl.h>
a43681
 #include <inttypes.h>
a43681
 #include <stdint.h>
a43681
+#include <sys/param.h>
a43681
 #include <unistd.h>
a43681
 
a43681
 #include "efiboot.h"
a43681
@@ -44,7 +45,7 @@ parse_scsi_link(const char *current, uint32_t *scsi_host,
a43681
 {
a43681
 	int rc;
a43681
 	ssize_t sz = 0;
a43681
-	int pos0 = 0, pos1 = 0;
a43681
+	int pos0 = -1, pos1 = -1, pos2 = -1;
a43681
 
a43681
 	debug("entry");
a43681
 	/*
a43681
@@ -99,14 +100,14 @@ parse_scsi_link(const char *current, uint32_t *scsi_host,
a43681
 	 * or host4/port-4:0:0
a43681
 	 */
a43681
 	debug("searching for host4/");
a43681
-	rc = sscanf(current, "host%d/%n", scsi_host, &pos0);
a43681
-	debug("current:'%s' rc:%d pos0:%d\n", current, rc, pos0);
a43681
-	dbgmk("         ", pos0);
a43681
+	rc = sscanf(current, "%nhost%d/%n", scsi_host, &pos0, &pos1);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
 	if (rc != 1)
a43681
 	        return -1;
a43681
-	current += pos0;
a43681
-	sz += pos0;
a43681
-	pos0 = 0;
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
+	pos0 = pos1 = -1;
a43681
 
a43681
 	/*
a43681
 	 * We might have this next:
a43681
@@ -117,96 +118,100 @@ parse_scsi_link(const char *current, uint32_t *scsi_host,
a43681
 	 * port-2:0:2/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda/sda1
a43681
 	 */
a43681
 	debug("searching for port-4:0 or port-4:0:0");
a43681
-	rc = sscanf(current, "port-%d:%d%n:%d%n", &tosser0,
a43681
-	            &tosser1, &pos0, &tosser2, &pos1);
a43681
-	debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
-	dbgmk("         ", pos0, pos1);
a43681
-	if (rc == 2 || rc == 3) {
a43681
-		current += pos0;
a43681
-	        sz += pos0;
a43681
-	        pos0 = 0;
a43681
-	        if (local_port_id && rc == 2)
a43681
-	                *local_port_id = tosser1;
a43681
-	        if (remote_port_id && rc == 3)
a43681
-	                *remote_port_id = tosser2;
a43681
-
a43681
-	        if (current[0] == '/') {
a43681
-			current += 1;
a43681
-	                sz += 1;
a43681
-		}
a43681
-
a43681
-	        /*
a43681
-	         * We might have this next:
a43681
-	         * expander-2:0/port-2:0:2/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda/sda1
a43681
-	         *                       ^ port id
a43681
-	         *                     ^ scsi target id
a43681
-	         *                   ^ host number
a43681
-	         *          ^ host number
a43681
-	         * We don't actually care about either number in expander-.../,
a43681
-	         * because they're replicated in all the other places.  We just need
a43681
-	         * to get past it.
a43681
-	         */
a43681
-	        debug("searching for expander-4:0/");
a43681
-	        rc = sscanf(current, "expander-%d:%d/%n", &tosser0, &tosser1, &pos0);
a43681
-	        debug("current:'%s' rc:%d pos0:%d\n", current, rc, pos0);
a43681
-		dbgmk("         ", pos0);
a43681
-	        if (rc == 2) {
a43681
-	                if (!remote_target_id) {
a43681
-	                        efi_error("Device is PHY is a remote target, but remote_target_id is NULL");
a43681
-	                        return -1;
a43681
-	                }
a43681
-	                *remote_target_id = tosser1;
a43681
-			current += pos0;
a43681
-	                sz += pos0;
a43681
-	                pos0 = 0;
a43681
-
a43681
-	                /*
a43681
-	                 * if we have that, we should have a 3-part port next
a43681
-	                 */
a43681
-	                debug("searching for port-2:0:2/");
a43681
-	                rc = sscanf(current, "port-%d:%d:%d/%n", &tosser0, &tosser1, &tosser2, &pos0);
a43681
-	                debug("current:'%s' rc:%d pos0:%d\n", current, rc, pos0);
a43681
-			dbgmk("         ", pos0);
a43681
-	                if (rc != 3) {
a43681
-	                        efi_error("Couldn't parse port expander port string");
a43681
-	                        return -1;
a43681
-	                }
a43681
-			current += pos0;
a43681
-	                sz += pos0;
a43681
-	        }
a43681
-	        pos0 = 0;
a43681
-
a43681
-	        /* next:
a43681
-	         *    /end_device-4:0
a43681
-	         * or /end_device-4:0:0
a43681
-	         * awesomely these are the exact same fields that go into port-blah,
a43681
-	         * but we don't care for now about any of them anyway.
a43681
-	         */
a43681
-	        debug("searching for end_device-4:0/ or end_device-4:0:0/");
a43681
-	        rc = sscanf(current, "end_device-%d:%d%n", &tosser0, &tosser1, &pos0);
a43681
-	        debug("current:'%s' rc:%d pos0:%d\n", current, rc, pos0);
a43681
-	        if (rc != 2)
a43681
-	                return -1;
a43681
+	rc = sscanf(current, "%nport-%d:%d%n:%d%n",
a43681
+		    &pos0, &tosser0, &tosser1, &pos1, &tosser2, &pos2);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d pos2:%d\n", current, rc, pos0, pos1, pos2);
a43681
+	dbgmk("         ", pos0, MAX(pos1, pos2));
a43681
+	if (rc == 3) {
a43681
+		if (remote_port_id)
a43681
+			*remote_port_id = tosser2;
a43681
+		pos1 = pos2;
a43681
+	} else if (rc == 2) {
a43681
+		if (local_port_id)
a43681
+			*local_port_id = tosser1;
a43681
+	} else if (rc != 0) {
a43681
+		return -1;
a43681
+	} else {
a43681
+		pos1 = 0;
a43681
+	}
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
 
a43681
-	        pos1 = 0;
a43681
-	        rc = sscanf(current + pos0, ":%d%n", &tosser2, &pos1);
a43681
-	        if (rc != 0 && rc != 1)
a43681
-	                return -1;
a43681
-		dbgmk("         ", pos0, pos0+pos1);
a43681
-	        if (remote_port_id && rc == 1)
a43681
-	                *remote_port_id = tosser2;
a43681
-	        if (local_port_id && rc == 0)
a43681
-	                *local_port_id = tosser1;
a43681
-		current += pos0 + pos1;
a43681
-	        sz += pos0 + pos1;
a43681
-	        pos0 = pos1 = 0;
a43681
+	if (current[0] == '/') {
a43681
+		current += 1;
a43681
+		sz += 1;
a43681
+	}
a43681
+	pos0 = pos1 = pos2 = -1;
a43681
+
a43681
+        /*
a43681
+         * We might have this next:
a43681
+         * expander-2:0/port-2:0:2/end_device-2:0:2/target2:0:0/2:0:0:0/block/sda/sda1
a43681
+         *                       ^ port id
a43681
+         *                     ^ scsi target id
a43681
+         *                   ^ host number
a43681
+         *          ^ host number
a43681
+         * We don't actually care about either number in expander-.../,
a43681
+         * because they're replicated in all the other places.  We just need
a43681
+         * to get past it.
a43681
+         */
a43681
+        debug("searching for expander-4:0/");
a43681
+        rc = sscanf(current, "%nexpander-%d:%d/%n", &pos0, &tosser0, &tosser1, &pos1);
a43681
+        debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
+        if (rc == 2) {
a43681
+                if (!remote_target_id) {
a43681
+                        efi_error("Device is PHY is a remote target, but remote_target_id is NULL");
a43681
+                        return -1;
a43681
+                }
a43681
+                *remote_target_id = tosser1;
a43681
+		current += pos1;
a43681
+                sz += pos1;
a43681
+		pos0 = pos1 = -1;
a43681
+
a43681
+                /*
a43681
+                 * if we have that, we should have a 3-part port next
a43681
+                 */
a43681
+                debug("searching for port-2:0:2/");
a43681
+                rc = sscanf(current, "%nport-%d:%d:%d/%n", &pos0, &tosser0, &tosser1, &tosser2, &pos1);
a43681
+                debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
+		dbgmk("         ", pos0, pos1);
a43681
+                if (rc != 3) {
a43681
+                        efi_error("Couldn't parse port expander port string");
a43681
+                        return -1;
a43681
+                }
a43681
+		current += pos1;
a43681
+                sz += pos1;
a43681
+        }
a43681
+	pos0 = pos1 = -1;
a43681
+
a43681
+        /* next:
a43681
+         *    /end_device-4:0
a43681
+         * or /end_device-4:0:0
a43681
+         * awesomely these are the exact same fields that go into port-blah,
a43681
+         * but we don't care for now about any of them anyway.
a43681
+         */
a43681
+        debug("searching for end_device-4:0/ or end_device-4:0:0/");
a43681
+        rc = sscanf(current, "%nend_device-%d:%d%n:%d%n",
a43681
+		    &pos0, &tosser0, &tosser1, &pos1, &tosser2, &pos2);
a43681
+        debug("current:'%s' rc:%d pos0:%d\n", current, rc, pos0);
a43681
+	dbgmk("         ", pos0, MAX(pos1, pos2));
a43681
+	if (rc == 3) {
a43681
+		if (remote_port_id)
a43681
+			*remote_port_id = tosser2;
a43681
+		pos1 = pos2;
a43681
+	} else if (rc == 2) {
a43681
+		if (local_port_id)
a43681
+			*local_port_id = tosser1;
a43681
+	} else {
a43681
+		pos1 = 0;
a43681
+	}
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
+	pos0 = pos1 = pos2 = -1;
a43681
 
a43681
-	        if (current[0] == '/') {
a43681
-			current += sz;
a43681
-	                sz += 1;
a43681
-		}
a43681
-	} else if (rc != 0) {
a43681
-	        return -1;
a43681
+        if (current[0] == '/') {
a43681
+		current += sz;
a43681
+                sz += 1;
a43681
 	}
a43681
 
a43681
 	/* now:
a43681
@@ -214,28 +219,28 @@ parse_scsi_link(const char *current, uint32_t *scsi_host,
a43681
 	 */
a43681
 	uint64_t tosser3;
a43681
 	debug("searching for target4:0:0/");
a43681
-	rc = sscanf(current, "target%d:%d:%"PRIu64"/%n", &tosser0, &tosser1,
a43681
-	            &tosser3, &pos0);
a43681
-	debug("current:'%s' rc:%d pos0:%d\n", current, rc, pos0);
a43681
-	dbgmk("         ", pos0);
a43681
+	rc = sscanf(current, "%ntarget%d:%d:%"PRIu64"/%n",
a43681
+		    &pos0, &tosser0, &tosser1, &tosser3, &pos1);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
 	if (rc != 3)
a43681
 	        return -1;
a43681
-	current += pos0;
a43681
-	sz += pos0;
a43681
-	pos0 = 0;
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
+	pos0 = pos1 = -1;
a43681
 
a43681
 	/* now:
a43681
 	 * %d:%d:%d:%llu/
a43681
 	 */
a43681
 	debug("searching for 4:0:0:0/");
a43681
-	rc = sscanf(current, "%d:%d:%d:%"PRIu64"/%n",
a43681
-	            scsi_bus, scsi_device, scsi_target, scsi_lun, &pos0);
a43681
-	debug("current:'%s' rc:%d pos0:%d\n", current, rc, pos0);
a43681
-	dbgmk("         ", pos0);
a43681
+	rc = sscanf(current, "%n%d:%d:%d:%"PRIu64"/%n",
a43681
+	            &pos0, scsi_bus, scsi_device, scsi_target, scsi_lun, &pos1);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
 	if (rc != 4)
a43681
 	        return -1;
a43681
-	current += pos0;
a43681
-	sz += pos0;
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
 
a43681
 	debug("current:'%s' sz:%zd\n", current, sz);
a43681
 	return sz;
a43681
@@ -246,31 +251,32 @@ parse_scsi(struct device *dev, const char *current, const char *root UNUSED)
a43681
 {
a43681
 	uint32_t scsi_host, scsi_bus, scsi_device, scsi_target;
a43681
 	uint64_t scsi_lun;
a43681
-	ssize_t sz;
a43681
-	int pos;
a43681
+	ssize_t sz = 0;
a43681
+	int pos0, pos1;
a43681
 	int rc;
a43681
 
a43681
 	debug("entry");
a43681
 
a43681
-	debug("searching for ../../../0:0:0:0");
a43681
-	rc = sscanf(dev->device, "../../../%d:%d:%d:%"PRIu64"%n",
a43681
+	debug("searching device for ../../../0:0:0:0");
a43681
+	pos0 = pos1 = -1;
a43681
+	rc = sscanf(dev->device, "../../../%n%d:%d:%d:%"PRIu64"%n",
a43681
+		    &pos0,
a43681
 	            &dev->scsi_info.scsi_bus,
a43681
 	            &dev->scsi_info.scsi_device,
a43681
 	            &dev->scsi_info.scsi_target,
a43681
 	            &dev->scsi_info.scsi_lun,
a43681
-	            &pos;;
a43681
-	debug("current:'%s' rc:%d pos:%d\n", dev->device, rc, pos);
a43681
-	dbgmk("         ", pos);
a43681
+	            &pos1);
a43681
+	debug("device:'%s' rc:%d pos0:%d pos1:%d\n", dev->device, rc, pos0, pos1);
a43681
+	dbgmk("        ", pos0, pos1);
a43681
 	if (rc != 4)
a43681
 	        return 0;
a43681
 
a43681
-	sz = parse_scsi_link(current, &scsi_host,
a43681
-	                      &scsi_bus, &scsi_device,
a43681
-	                      &scsi_target, &scsi_lun,
a43681
-	                      NULL, NULL, NULL);
a43681
-	if (sz < 0)
a43681
+	pos0 = parse_scsi_link(current, &scsi_host, &scsi_bus, &scsi_device,
a43681
+			       &scsi_target, &scsi_lun, NULL, NULL, NULL);
a43681
+	if (pos0 < 0)
a43681
 	        return 0;
a43681
-	current += sz;
a43681
+	current += pos0;
a43681
+	sz += pos0;
a43681
 
a43681
 	/*
a43681
 	 * SCSI disks can have up to 16 partitions, or 4 bits worth
a43681
diff --git a/src/linux-soc-root.c b/src/linux-soc-root.c
a43681
index 9c9e9573dcd..bad37c9f874 100644
a43681
--- a/src/linux-soc-root.c
a43681
+++ b/src/linux-soc-root.c
a43681
@@ -41,20 +41,21 @@ static ssize_t
a43681
 parse_soc_root(struct device *dev UNUSED, const char *current, const char *root UNUSED)
a43681
 {
a43681
 	int rc;
a43681
-	int pos = 0;
a43681
-	const char *devpart = current;
a43681
+	int pos0 = -1, pos1 = -1;
a43681
+	ssize_t sz = 0;
a43681
 
a43681
 	debug("entry");
a43681
 
a43681
-	rc = sscanf(devpart, "../../devices/platform/soc/%*[^/]/%n", &pos;;
a43681
-	if (rc != 0)
a43681
+	rc = sscanf(current, "../../devices/%nplatform/soc/%*[^/]/%n", &pos0, &pos1);
a43681
+	if (rc != 0 || pos0 == -1 || pos1 == -1)
a43681
 	        return 0;
a43681
-	debug("current:'%s' rc:%d pos:%d", current, rc, pos);
a43681
-	dbgmk("         ", pos);
a43681
-	devpart += pos;
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
 
a43681
-	debug("current:'%s' sz:%d\n", devpart, pos);
a43681
-	return pos;
a43681
+	debug("current:'%s' sz:%zd\n", current, sz);
a43681
+	return sz;
a43681
 }
a43681
 
a43681
 enum interface_type soc_root_iftypes[] = { soc_root, unknown };
a43681
diff --git a/src/linux-virtblk.c b/src/linux-virtblk.c
a43681
index df14673dac8..a3366c9c677 100644
a43681
--- a/src/linux-virtblk.c
a43681
+++ b/src/linux-virtblk.c
a43681
@@ -48,15 +48,16 @@ static ssize_t
a43681
 parse_virtblk(struct device *dev, const char *current, const char *root UNUSED)
a43681
 {
a43681
 	uint32_t tosser;
a43681
-	int pos = -1;
a43681
+	int pos0 = -1, pos1 = -1;
a43681
+	ssize_t sz = 0;
a43681
 	int rc;
a43681
 
a43681
 	debug("entry");
a43681
 
a43681
 	debug("searching for virtio0/");
a43681
-	rc = sscanf(current, "virtio%x/%n", &tosser, &pos;;
a43681
-	debug("current:'%s' rc:%d pos:%d\n", current, rc, pos);
a43681
-	dbgmk("         ", pos);
a43681
+	rc = sscanf(current, "%nvirtio%x/%n", &pos0, &tosser, &pos1);
a43681
+	debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
+	dbgmk("         ", pos0, pos1);
a43681
 	/*
a43681
 	 * If we couldn't find virtioX/ then it isn't a virtio device.
a43681
 	 */
a43681
@@ -64,9 +65,11 @@ parse_virtblk(struct device *dev, const char *current, const char *root UNUSED)
a43681
 	        return 0;
a43681
 
a43681
 	dev->interface_type = virtblk;
a43681
+	current += pos1;
a43681
+	sz += pos1;
a43681
 
a43681
-	debug("current:'%s' sz:%d\n", current, pos);
a43681
-	return pos;
a43681
+	debug("current:'%s' sz:%zd\n", current, sz);
a43681
+	return sz;
a43681
 }
a43681
 
a43681
 enum interface_type virtblk_iftypes[] = { virtblk, unknown };
a43681
diff --git a/src/linux-virtual-root.c b/src/linux-virtual-root.c
a43681
index b2d36b4095f..75fbbfc1de6 100644
a43681
--- a/src/linux-virtual-root.c
a43681
+++ b/src/linux-virtual-root.c
a43681
@@ -61,7 +61,7 @@ parse_virtual_root(struct device *dev UNUSED, const char *current, const char *r
a43681
 		pos0 = pos1 = -1;
a43681
 		rc = sscanf(current, subdirs[i].fmt, &pos0, &pos1);
a43681
 		debug("current:'%s' rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
a43681
-		dbgmk("        ", pos0, pos1);
a43681
+		dbgmk("         ", pos0, pos1);
a43681
 		if (rc == 1) {
a43681
 			sz += pos1;
a43681
 			current += pos1;
a43681
-- 
a43681
2.26.2
a43681