Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2
biosdevname
bug-706505
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
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;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor