Blame SOURCES/0001-Cleanup-SRIOV-scanner-code.patch

8ebaa5
From 4834d5d108506c979f0e98e50afd570140503338 Mon Sep 17 00:00:00 2001
8ebaa5
From: Jordan Hargrave <Jordan_Hargrave@dell.com>
8ebaa5
Date: Fri, 28 Feb 2014 14:31:53 -0600
8ebaa5
Subject: [PATCH 1/2] Cleanup SRIOV scanner code
8ebaa5
8ebaa5
---
8ebaa5
 src/pci.c | 166 ++++++++++++++++++++------------------------------------------
8ebaa5
 1 file changed, 54 insertions(+), 112 deletions(-)
8ebaa5
8ebaa5
diff --git a/src/pci.c b/src/pci.c
8ebaa5
index dabb158..9b851df 100644
8ebaa5
--- a/src/pci.c
8ebaa5
+++ b/src/pci.c
8ebaa5
@@ -351,67 +351,15 @@ static int read_pci_sysfs_physfn(char *buf, size_t bufsize, const struct pci_dev
8ebaa5
 	return 0;
8ebaa5
 }
8ebaa5
 
8ebaa5
-static int virtfn_filter(const struct dirent *dent)
8ebaa5
-{
8ebaa5
-        return (!strncmp(dent->d_name,"virtfn",6));
8ebaa5
-}
8ebaa5
-
8ebaa5
-static int _read_virtfn_index(unsigned int *index, const char *path, const char *basename, const char *pci_name)
8ebaa5
-{
8ebaa5
-	char buf[PATH_MAX], *b;
8ebaa5
-	char fullpath[PATH_MAX];
8ebaa5
-	ssize_t size;
8ebaa5
-	unsigned int u=INT_MAX;
8ebaa5
-	int scanned, rc=1;
8ebaa5
-
8ebaa5
-	snprintf(fullpath, sizeof(fullpath), "%s/%s", path, basename);
8ebaa5
-	size = readlink(fullpath, buf, sizeof(buf));
8ebaa5
-	if (size > 0) {
8ebaa5
-		/* form is ../0000:05:10.0 */
8ebaa5
-		b=buf+3; /* skip ../ */
8ebaa5
-		if (strlen(b) == strlen(pci_name) &&
8ebaa5
-		    !strncmp(b, pci_name, strlen(pci_name))) {
8ebaa5
-			scanned = sscanf(basename, "virtfn%u", &u);
8ebaa5
-			if (scanned == 1) {
8ebaa5
-				rc = 0;
8ebaa5
-				*index = u;
8ebaa5
-			}
8ebaa5
-		}
8ebaa5
-	}
8ebaa5
-	return rc;
8ebaa5
-}
8ebaa5
-
8ebaa5
-static int read_virtfn_index(unsigned int *index, const struct pci_dev *pdev)
8ebaa5
-{
8ebaa5
-	char pci_name[16];
8ebaa5
-	char path[PATH_MAX];
8ebaa5
-	char cpath[PATH_MAX];
8ebaa5
-	struct dirent **namelist;
8ebaa5
-	int n, rc=1;
8ebaa5
-
8ebaa5
-	unparse_pci_name(pci_name, sizeof(pci_name), pdev);
8ebaa5
-	snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/physfn", pci_name);
8ebaa5
-	if (realpath(path, cpath) == NULL)
8ebaa5
-		return rc;
8ebaa5
-
8ebaa5
-	n = scandir(cpath, &namelist, virtfn_filter, versionsort);
8ebaa5
-	if (n < 0)
8ebaa5
-		return rc;
8ebaa5
-	else {
8ebaa5
-		while (n--) {
8ebaa5
-			if (rc)
8ebaa5
-				rc = _read_virtfn_index(index, cpath, namelist[n]->d_name, pci_name);
8ebaa5
-			free(namelist[n]);
8ebaa5
-		}
8ebaa5
-		free(namelist);
8ebaa5
-	}
8ebaa5
-
8ebaa5
-	return rc;
8ebaa5
-}
8ebaa5
-
8ebaa5
 static int parse_pci_name(const char *s, int *domain, int *bus, int *dev, int *func)
8ebaa5
 {
8ebaa5
 	int err;
8ebaa5
+	const char *r;
8ebaa5
+
8ebaa5
+	/* Allow parsing pathnames */
8ebaa5
+	if ((r = strrchr(s, '/')) != NULL)
8ebaa5
+		s = r+1;
8ebaa5
+
8ebaa5
 /* The domain part was added in 2.6 kernels.  Test for that first. */
8ebaa5
 	err = sscanf(s, "%x:%2x:%2x.%x", domain, bus, dev, func);
8ebaa5
 	if (err != 4) {
8ebaa5
@@ -431,29 +379,6 @@ static struct pci_dev * find_pdev_by_pci_name(struct pci_access *pacc, const cha
8ebaa5
 	return pci_get_dev(pacc, domain, bus, device, func);
8ebaa5
 }
8ebaa5
 
8ebaa5
-static struct pci_device *
8ebaa5
-find_physfn(struct libbiosdevname_state *state, struct pci_device *dev)
8ebaa5
-{
8ebaa5
-	int rc;
8ebaa5
-	char path[PATH_MAX];
8ebaa5
-	char *c;
8ebaa5
-	struct pci_dev *pdev;
8ebaa5
-	memset(path, 0, sizeof(path));
8ebaa5
-	rc = read_pci_sysfs_physfn(path, sizeof(path), dev->pci_dev);
8ebaa5
-	if (rc != 0)
8ebaa5
-		return NULL;
8ebaa5
-	/* we get back a string like
8ebaa5
-	   ../0000:05:0.0
8ebaa5
-	   where the last component is the parent device
8ebaa5
-	*/
8ebaa5
-	/* find the last backslash */
8ebaa5
-	c = rindex(path, '/');
8ebaa5
-	c++;
8ebaa5
-	pdev = find_pdev_by_pci_name(state->pacc, c);
8ebaa5
-	dev = find_dev_by_pci(state, pdev);
8ebaa5
-	return dev;
8ebaa5
-}
8ebaa5
-
8ebaa5
 static int is_same_pci(const struct pci_dev *a, const struct pci_dev *b)
8ebaa5
 {
8ebaa5
 	if (pci_domain_nr(a) == pci_domain_nr(b) &&
8ebaa5
@@ -464,25 +389,6 @@ static int is_same_pci(const struct pci_dev *a, const struct pci_dev *b)
8ebaa5
 	return 0;
8ebaa5
 }
8ebaa5
 
8ebaa5
-static void try_add_vf_to_pf(struct libbiosdevname_state *state, struct pci_device *vf)
8ebaa5
-{
8ebaa5
-	struct pci_device *pf;
8ebaa5
-	unsigned int index=0;
8ebaa5
-	int rc;
8ebaa5
-	pf = find_physfn(state, vf);
8ebaa5
-
8ebaa5
-	if (!pf)
8ebaa5
-		return;
8ebaa5
-	list_add_tail(&vf->vfnode, &pf->vfs);
8ebaa5
-	rc = read_virtfn_index(&index, vf->pci_dev);
8ebaa5
-	if (!rc) {
8ebaa5
-		vf->vf_index = index;
8ebaa5
-		pf->is_sriov_physical_function = 1;
8ebaa5
-	}
8ebaa5
-	vf->pf = pf;
8ebaa5
-	vf->physical_slot = pf->physical_slot;
8ebaa5
-}
8ebaa5
-
8ebaa5
 static struct pci_device *
8ebaa5
 find_parent(struct libbiosdevname_state *state, struct pci_device *dev)
8ebaa5
 {
8ebaa5
@@ -492,12 +398,6 @@ find_parent(struct libbiosdevname_state *state, struct pci_device *dev)
8ebaa5
 	struct pci_device *physfn;
8ebaa5
 	struct pci_dev *pdev;
8ebaa5
 	memset(path, 0, sizeof(path));
8ebaa5
-	/* if this device has a physfn pointer, then treat _that_ as the parent */
8ebaa5
-	physfn = find_physfn(state, dev);
8ebaa5
-	if (physfn) {
8ebaa5
-		dev->is_sriov_virtual_function=1;
8ebaa5
-		return physfn;
8ebaa5
-	}
8ebaa5
 
8ebaa5
 	rc = read_pci_sysfs_path(path, sizeof(path), dev->pci_dev);
8ebaa5
 	if (rc != 0)
8ebaa5
@@ -715,15 +615,57 @@ static int set_embedded_index(struct libbiosdevname_state *state)
8ebaa5
 	return 0;
8ebaa5
 }
8ebaa5
 
8ebaa5
+static int virtfn_filter(const struct dirent *dent)
8ebaa5
+{
8ebaa5
+        return (!strncmp(dent->d_name,"virtfn",6));
8ebaa5
+}
8ebaa5
 
8ebaa5
-
8ebaa5
-static void set_sriov_pf_vf(struct libbiosdevname_state *state)
8ebaa5
+/* Assign Virtual Function to Physical Function */
8ebaa5
+static void set_sriov(struct libbiosdevname_state *state, struct pci_device *pf, const char *virtpath)
8ebaa5
 {
8ebaa5
 	struct pci_device *vf;
8ebaa5
-	list_for_each_entry(vf, &state->pci_devices, node) {
8ebaa5
-		if (!vf->is_sriov_virtual_function)
8ebaa5
+	char pci_name[32];
8ebaa5
+	char path[PATH_MAX], cpath[PATH_MAX];
8ebaa5
+	int vf_index;
8ebaa5
+
8ebaa5
+	if (sscanf(virtpath, "virtfn%u", &vf_index) != 1)
8ebaa5
+		return;
8ebaa5
+	unparse_pci_name(pci_name, sizeof(pci_name), pf->pci_dev);
8ebaa5
+	snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/%s", pci_name, virtpath);
8ebaa5
+
8ebaa5
+	memset(cpath, 0, sizeof(cpath));
8ebaa5
+	if (readlink(path, cpath, sizeof(cpath)) < 0)
8ebaa5
+		return;
8ebaa5
+	if ((vf = find_dev_by_pci_name(state, cpath)) != NULL) {
8ebaa5
+		vf->is_sriov_virtual_function = 1;
8ebaa5
+		vf->vf_index = vf_index;
8ebaa5
+		vf->pf = pf;
8ebaa5
+		pf->is_sriov_physical_function = 1;
8ebaa5
+		list_add_tail(&vf->vfnode, &pf->vfs);
8ebaa5
+	}
8ebaa5
+}
8ebaa5
+
8ebaa5
+static void scan_sriov(struct libbiosdevname_state *state)
8ebaa5
+{
8ebaa5
+	struct pci_device *pf;
8ebaa5
+	char path[PATH_MAX];
8ebaa5
+	char pci_name[32];
8ebaa5
+	struct dirent **namelist;
8ebaa5
+	int n;
8ebaa5
+
8ebaa5
+	list_for_each_entry(pf, &state->pci_devices, node) {
8ebaa5
+		unparse_pci_name(pci_name, sizeof(pci_name), pf->pci_dev);
8ebaa5
+		snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s", pci_name);
8ebaa5
+
8ebaa5
+		namelist = NULL;
8ebaa5
+		n = scandir(path, &namelist, virtfn_filter, versionsort);
8ebaa5
+		if (n <= 0)
8ebaa5
 			continue;
8ebaa5
-		try_add_vf_to_pf(state, vf);
8ebaa5
+		while (n--) {
8ebaa5
+			set_sriov(state, pf, namelist[n]->d_name);
8ebaa5
+			free(namelist[n]);
8ebaa5
+		}
8ebaa5
+		free(namelist);
8ebaa5
 	}
8ebaa5
 }
8ebaa5
 
8ebaa5
@@ -799,6 +741,7 @@ int get_pci_devices(struct libbiosdevname_state *state)
8ebaa5
 	/* ordering here is important */
8ebaa5
 	dmidecode_main(state);	/* this will fail on Xen guests, that's OK */
8ebaa5
 	sort_device_list(state);
8ebaa5
+	scan_sriov(state);
8ebaa5
 	set_pci_vpd_instance(state);
8ebaa5
 	rc = set_pci_slots(state);
8ebaa5
         if(rc)
8ebaa5
@@ -806,7 +749,6 @@ int get_pci_devices(struct libbiosdevname_state *state)
8ebaa5
 
8ebaa5
         set_embedded_index(state);
8ebaa5
 	set_pci_slot_index(state);
8ebaa5
-	set_sriov_pf_vf(state);
8ebaa5
 
8ebaa5
 out:
8ebaa5
 	return rc;
8ebaa5
-- 
8ebaa5
1.9.0
8ebaa5