File bug-706505 of Package biosdevname

diff -ur biosdevname-0.3.8.old/src/naming_policy.c biosdevname-0.3.8/src/naming_policy.c
--- biosdevname-0.3.8.old/src/naming_policy.c	2011-09-23 14:09:52.000000000 +0200
+++ biosdevname-0.3.8/src/naming_policy.c	2011-09-23 14:10:11.000000000 +0200
@@ -37,38 +37,39 @@
 	char interface[IFNAMSIZ];
 	unsigned int portnum=0;
 	int known=0;
-
-	memset(buffer, 0, sizeof(buffer));
-	memset(location, 0, sizeof(location));
-	memset(port, 0, sizeof(port));
-	memset(interface, 0, sizeof(interface));
+	struct pci_device *vf;
 
 	list_for_each_entry(dev, &state->bios_devices, node) {
 		known = 0;
+		memset(buffer, 0, sizeof(buffer));
+		memset(location, 0, sizeof(location));
+		memset(port, 0, sizeof(port));
+		memset(interface, 0, sizeof(interface));
+
 		if (is_pci(dev)) {
+			vf = dev->pcidev;
 			if (dev->pcidev->physical_slot == 0) { /* embedded devices only */
-				if (dev->pcidev->uses_sysfs & HAS_SYSFS_INDEX) {
-					portnum = dev->pcidev->sysfs_index;
-					snprintf(location, sizeof(location), "%s%u", prefix, portnum);
-					known=1;
-				}
-				else if (dev->pcidev->uses_smbios & HAS_SMBIOS_INSTANCE && is_pci_smbios_type_ethernet(dev->pcidev)) {
-					portnum = dev->pcidev->smbios_instance;
-					snprintf(location, sizeof(location), "%s%u", prefix, portnum);
-					known=1;
-				}
-				else if (dev->pcidev->embedded_index_valid) {
-					portnum = dev->pcidev->embedded_index;
+				portnum = INT_MAX;
+				/* Use master VPD device if available */
+				if (vf->vpd_pf)
+					vf = vf->vpd_pf;
+				if (vf->uses_sysfs & HAS_SYSFS_INDEX)
+					portnum = vf->sysfs_index;
+				else if (vf->uses_smbios & HAS_SMBIOS_INSTANCE && is_pci_smbios_type_ethernet(vf))
+					portnum = vf->smbios_instance;
+				else if (vf->embedded_index_valid)
+					portnum = vf->embedded_index;
+				if (portnum != INT_MAX) {	
 					snprintf(location, sizeof(location), "%s%u", prefix, portnum);
 					known=1;
 				}
 			}
 			else if (dev->pcidev->physical_slot < PHYSICAL_SLOT_UNKNOWN) {
 				snprintf(location, sizeof(location), "p%u", dev->pcidev->physical_slot);
-				if (!dev->pcidev->is_sriov_virtual_function)
-					portnum = dev->pcidev->index_in_slot;
-				else if (dev->pcidev->vpd_port < INT_MAX)
+				if (dev->pcidev->vpd_port < INT_MAX)
 					portnum = dev->pcidev->vpd_port;
+				else if (!dev->pcidev->is_sriov_virtual_function)
+				  	portnum = dev->pcidev->index_in_slot;
 				else
 					portnum = dev->pcidev->pf->index_in_slot;
 				snprintf(port, sizeof(port), "p%u", portnum);
diff -ur biosdevname-0.3.8.old/src/pci.c biosdevname-0.3.8/src/pci.c
--- biosdevname-0.3.8.old/src/pci.c	2011-09-23 14:09:52.000000000 +0200
+++ biosdevname-0.3.8/src/pci.c	2011-09-23 14:10:15.000000000 +0200
@@ -114,9 +114,10 @@
 	return -1;
 }
 
-static int parse_vpd(struct pci_device *pdev, int len, unsigned char *vpd)
+static int parse_vpd(struct libbiosdevname_state *state, struct pci_device *pdev, int len, unsigned char *vpd)
 {
 	int i, j, k, isz, jsz, port, func, pfi;
+	struct pci_device *vf;
 
 	i = pci_vpd_find_tag(vpd, 0, len, 0x90);
 	if (i < 0)
@@ -133,15 +134,6 @@
 	if (memcmp(vpd+j+3, "1028VPDR.VER1.0", 15))
 		return 1;
 	
-	/* Lookup NPY Num Ports */
-	j = pci_vpd_find_info_subkey(vpd, i, isz, "**", "NPY");
-	if (j < 0)
-		return 1;
-	jsz = pci_vpd_info_field_size(&vpd[j]);
-	j += PCI_VPD_INFO_FLD_HDR_SIZE;
-	sscanf((char *)vpd+j+3, "%1x", &port);	
-	pdev->vpd_nports = port;
-
 	/* Lookup Port Mappings */
 	j = pci_vpd_find_info_subkey(vpd, i, isz, "**", "DCM");
 	if (j < 0)
@@ -152,16 +144,21 @@
 	for (k=3; k<jsz; k+=10) {
 		/* Parse Port Info */
 		sscanf((char *)vpd+j+k, "%1x%1x%2x", &port, &func, &pfi);
-		if (func == pdev->pci_dev->func) {
-			pdev->vpd_port = port;
-			pdev->vpd_pfi = pfi;
+		if ((vf = find_pci_dev_by_pci_addr(state, pdev->pci_dev->domain,
+						   pdev->pci_dev->bus,
+						   pdev->pci_dev->dev,
+						   func)) != NULL) {
+			if (vf->vpd_port == INT_MAX) {
+				vf->vpd_port = port;
+				vf->vpd_pfi = pfi;
+			}
 		}
 	}
 	return 0;
 }
 
 /* Read and parse PCI VPD section if it exists */
-static int read_pci_vpd(struct pci_device *pdev)
+static int read_pci_vpd(struct libbiosdevname_state *state, struct pci_device *pdev)
 {
 	char path[PATH_MAX];
 	char pci_name[16];
@@ -172,13 +169,13 @@
 
 	unparse_pci_name(pci_name, sizeof(pci_name), pdev->pci_dev);
 	snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/vpd", pci_name);
-	if ((fd = open(path, O_RDONLY)) >= 0) {
+	if ((fd = open(path, O_RDONLY|O_SYNC)) >= 0) {
 		size = pci_vpd_size(pdev, fd);
 		if (size > 0) {
 		        vpd = malloc(size);
 			if (vpd != NULL) {
 				if ((nrd = pread(fd, vpd, size, 0)) > 0)
-					rc = parse_vpd(pdev, nrd, vpd);
+					rc = parse_vpd(state, pdev, nrd, vpd);
 				free(vpd);
 			}
 		}
@@ -189,10 +186,36 @@
 
 static void set_pci_vpd_instance(struct libbiosdevname_state *state)
 {
-	struct pci_device *dev;
+	struct pci_device *dev, *dev2;
+
+	/* Read VPD information for each device */
+	list_for_each_entry(dev, &state->pci_devices, node) {
+		read_pci_vpd(state, dev);
+	}
 
+	/* Now match VPD master device */
 	list_for_each_entry(dev, &state->pci_devices, node) {
-		read_pci_vpd(dev);
+		if (dev->vpd_port == INT_MAX)
+			continue;
+		list_for_each_entry(dev2, &state->pci_devices, node) {
+			if (dev2->pci_dev->domain == dev->pci_dev->domain &&
+			    dev2->pci_dev->bus == dev->pci_dev->bus &&
+			    dev2->pci_dev->dev == dev->pci_dev->dev &&
+			    dev2->vpd_port == dev->vpd_port) {
+			  	dev2->vpd_count++;
+				dev->vpd_pf = dev2;
+				break;
+			}
+		}
+	}
+
+	/* Delete all VPD devices with single function */
+	list_for_each_entry(dev, &state->pci_devices, node) {
+		if (dev->vpd_count == 1) {
+			dev->vpd_port = INT_MAX;
+			dev->vpd_pfi = INT_MAX;
+			dev->vpd_pf = NULL;
+		}
 	}
 }
 
@@ -495,6 +518,7 @@
 	dev->vf_index = INT_MAX;
 	dev->vpd_port = INT_MAX;
 	dev->vpd_pfi  = INT_MAX;
+	dev->vpd_pf = NULL;
 	fill_pci_dev_sysfs(dev, p);
 	list_add(&dev->node, &state->pci_devices);
 }
@@ -559,6 +583,8 @@
 			continue;
 		if (pcidev->is_sriov_virtual_function) /* skip sriov VFs, they're handled later */
 			continue;
+		if (pcidev->vpd_port != INT_MAX)
+			continue;
 		pcidev->embedded_index = index;
 		pcidev->embedded_index_valid = 1;
 		index++;
@@ -644,11 +670,11 @@
 	/* ordering here is important */
 	dmidecode_main(state);	/* this will fail on Xen guests, that's OK */
 	sort_device_list(state);
+	set_pci_vpd_instance(state);
 	set_pci_slots(state);
 	set_embedded_index(state);
 	set_pci_slot_index(state);
 	set_sriov_pf_vf(state);
-	set_pci_vpd_instance(state);
 
 	return rc;
 }
@@ -711,8 +737,8 @@
 	if (p->smbios_type) {
 		s += snprintf(s, size-(s-buf), "SMBIOS Device Type: ");
 		s += unparse_smbios_type41_type(s, size-(s-buf), p->smbios_type);
-		s += snprintf(s, size-(s-buf), "SMBIOS Instance: %u\n", p->smbios_instance);
-		s += snprintf(s, size-(s-buf), "SMBIOS Enabled: %s\n", p->smbios_instance?"True":"False");
+		if (p->smbios_instance)
+			s += snprintf(s, size-(s-buf), "SMBIOS Instance: %u\n", p->smbios_instance);
 	}
 	if (p->uses_smbios & HAS_SMBIOS_LABEL && p->smbios_label)
 		s += snprintf(s, size-(s-buf), "SMBIOS Label: %s\n", p->smbios_label);
@@ -727,7 +753,11 @@
 	if (p->vpd_port < INT_MAX) {
 		s += snprintf(s, size-(s-buf), "VPD Port: %u\n", p->vpd_port);
 		s += snprintf(s, size-(s-buf), "VPD Index: %u\n", p->vpd_pfi);
-		s += snprintf(s, size-(s-buf), "VPD #Ports: %u\n", p->vpd_nports);
+		if (p->vpd_pf) {
+			s += snprintf(s, size-(s-buf), "VPD PCI master: ");
+			s += unparse_pci_name(s, size-(s-buf), p->vpd_pf->pci_dev);
+			s += snprintf(s, size-(s-buf), " count %d\n", p->vpd_pf->vpd_count);
+		}
 	}
 	if (!list_empty(&p->vfs)) {
 		s += snprintf(s, size-(s-buf), "Virtual Functions:\n");
Only in biosdevname-0.3.8/src: pci.c.orig
diff -ur biosdevname-0.3.8.old/src/pci.h biosdevname-0.3.8/src/pci.h
--- biosdevname-0.3.8.old/src/pci.h	2011-09-23 14:09:52.000000000 +0200
+++ biosdevname-0.3.8/src/pci.h	2011-09-23 14:10:15.000000000 +0200
@@ -29,9 +29,10 @@
 	char * sysfs_label;
 	unsigned char uses_sysfs;
 	unsigned int vf_index;
+  	unsigned int vpd_count;
 	unsigned int vpd_pfi;
-	unsigned int vpd_nports;
 	unsigned int vpd_port;
+	struct pci_device *vpd_pf;
 	struct pci_device *pf;
 	struct list_head vfnode;
 	struct list_head vfs;
openSUSE Build Service is sponsored by