From 264d81cc287fc9fa030c7f28930da0bdf7c41f01e824c3098c18abb9bd085906 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Tue, 25 Mar 2014 13:44:37 +0000 Subject: [PATCH] - Update to version 5.0 plus latest git repo patches (HEAD) including a fix requested by Dell for Enterprise procducts (bnc#836342) Generated tarball manually from git repo (tag v0.5.0) as latest version is not provided by tarball download yet. - Remove: udev-rule-path.patch -> instead copy the udev rule manually in spec file OBS-URL: https://build.opensuse.org/package/show/Base:System/biosdevname?expand=0&rev=21 --- biosdevname.changes | 7 + biosdevname.spec | 5 +- biosdevname_git_v050_to_head.patch | 546 --------- ...e_v0.5.0_to_git_c140ce659a204d67e4cc.patch | 1035 +++++++++++++++++ 4 files changed, 1045 insertions(+), 548 deletions(-) delete mode 100644 biosdevname_git_v050_to_head.patch create mode 100644 biosdevname_v0.5.0_to_git_c140ce659a204d67e4cc.patch diff --git a/biosdevname.changes b/biosdevname.changes index 7104e5d..9302093 100644 --- a/biosdevname.changes +++ b/biosdevname.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Mar 25 13:42:43 UTC 2014 - trenn@suse.de + +- update to latest git repo patches (c140ce659a204d67e4) including a fix + requested by Dell for Enterprise procducts (bnc#836342) +- Pass --no-configure to autogen.sh avoid double calling of ./configure + ------------------------------------------------------------------- Mon Jan 20 16:34:53 UTC 2014 - juwolf@suse.com diff --git a/biosdevname.spec b/biosdevname.spec index b4e53a2..5c653f8 100644 --- a/biosdevname.spec +++ b/biosdevname.spec @@ -16,6 +16,7 @@ # + Name: biosdevname Version: 0.5.0 Release: 0 @@ -31,7 +32,7 @@ ExclusiveArch: %{ix86} x86_64 #Source0: http://linux.dell.com/files/%{name}/%{name}-%{version}/%{name}-%{version}.tar.gz Source0: %{name}-%{version}.tar.bz2 Source1: setup-biosdevname.sh -Patch1: biosdevname_git_v050_to_head.patch +Patch1: biosdevname_v0.5.0_to_git_c140ce659a204d67e4cc.patch Patch2: ignore-broken-BIOSes Patch3: whitelist-dell Patch4: udev-rule-path.patch @@ -68,7 +69,7 @@ You can enable/disable usage of biosdevname with boot option %build # this is a udev rule, so it needs to live in / rather than /usr -./autogen.sh +./autogen.sh --no-configure %configure --disable-rpath --prefix=/ --bindir=/bin --sbindir=/sbin make %{?_smp_mflags} cp %{S:1} . diff --git a/biosdevname_git_v050_to_head.patch b/biosdevname_git_v050_to_head.patch deleted file mode 100644 index a4d5d2d..0000000 --- a/biosdevname_git_v050_to_head.patch +++ /dev/null @@ -1,546 +0,0 @@ -diff --git a/Makefile.am b/Makefile.am -index 28d3e8d..14d9a92 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -6,7 +6,7 @@ dist_noinst_DATA = biosdevname.rules.in biosdevname.spec.fedora biosdevname.spec - - - --CLEANFILES = version src/version.h -+CLEANFILES = version src/bios_dev_name.h - install-data-local: - mkdir -p $(DESTDIR)@RULEDIR@ - $(INSTALL_DATA) $(top_srcdir)/biosdevname.rules.in $(DESTDIR)@RULEDEST@ -diff --git a/biosdevname.1 b/biosdevname.1 -index 7067a56..22a53bd 100644 ---- a/biosdevname.1 -+++ b/biosdevname.1 -@@ -31,16 +31,16 @@ Treat [args] as ethernet devs - .B \-d, \-\-debug - Enable debugging - .TP --.B \-\-policy \fI[physical|all_ethN] -+.B \-p, \-\-policy \fI[physical|all_ethN] - .TP --.B \-\-prefix \fI[string] -+.B \-P, \-\-prefix \fI[string] - string use for embedded NICs in the physical policy (default=em) - .TP --.B \-\-nopirq -+.B \-x, \-\-nopirq - Do not use $PIR table for mapping PCI device to slot. Some BIOS have - incorrect values. - .TP --.B \-\-smbios \fI[x.y] -+.B \-s, \-\-smbios \fI[x.y] - Require minimum SMBIOS version x.y - .SH POLICIES - .br -diff --git a/configure.ac b/configure.ac -index e26ba98..e75e64a 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -88,5 +88,5 @@ echo "PACKAGE_NAME='$PACKAGE_NAME'" > version - echo "PACKAGE_VERSION='$PACKAGE_VERSION'" >> version - echo "PACKAGE_STRING='$PACKAGE_STRING'" >> version - --AC_CONFIG_FILES([Makefile biosdevname.spec.fedora biosdevname.spec.suse src/version.h]) -+AC_CONFIG_FILES([Makefile biosdevname.spec.fedora biosdevname.spec.suse src/bios_dev_name.h]) - AC_OUTPUT -diff --git a/src/bios_dev_name.c b/src/bios_dev_name.c -index 7374f9b..d0a917a 100644 ---- a/src/bios_dev_name.c -+++ b/src/bios_dev_name.c -@@ -10,8 +10,6 @@ - #include - #include - --#include "version.h" -- - #include "libbiosdevname.h" - #include "bios_dev_name.h" - -@@ -27,11 +25,11 @@ static void usage(void) - fprintf(stderr, " Options:\n"); - fprintf(stderr, " -i or --interface treat [args] as ethernet devs\n"); - fprintf(stderr, " -d or --debug enable debugging\n"); -- fprintf(stderr, " --policy [physical | all_ethN ]\n"); -- fprintf(stderr, " --prefix [string] string use for embedded NICs (default='em')\n"); -- fprintf(stderr, " --smbios [x.y] Require SMBIOS x.y or greater\n"); -- fprintf(stderr, " --nopirq Don't use $PIR table for slot numbers\n"); -- fprintf(stderr, " --version Show biosdevname version\n"); -+ fprintf(stderr, " -p or --policy [physical | all_ethN ]\n"); -+ fprintf(stderr, " -P or --prefix [string] string use for embedded NICs (default='em')\n"); -+ fprintf(stderr, " -s or --smbios [x.y] Require SMBIOS x.y or greater\n"); -+ fprintf(stderr, " -x or --nopirq Don't use $PIR table for slot numbers\n"); -+ fprintf(stderr, " -v or --version Show biosdevname version\n"); - fprintf(stderr, " Example: biosdevname -i eth0\n"); - fprintf(stderr, " returns: em1\n"); - fprintf(stderr, " when eth0 is an embedded NIC with label '1' on the chassis.\n"); -@@ -70,7 +68,7 @@ parse_opts(int argc, char **argv) - {0, 0, 0, 0} - }; - c = getopt_long(argc, argv, -- "dinp:", -+ "dip:P:xs:v", - long_options, &option_index); - if (c == -1) - break; -diff --git a/src/bios_dev_name.h b/src/bios_dev_name.h -deleted file mode 100644 -index 636c5e1..0000000 ---- a/src/bios_dev_name.h -+++ /dev/null -@@ -1,20 +0,0 @@ --/* -- * Copyright (c) 2006 Dell, Inc. -- * by Matt Domsch -- * Licensed under the GNU General Public license, version 2. -- */ --#ifndef GLUE_H_INCLUDED --#define GLUE_H_INCLUDED -- --struct bios_dev_name_opts { -- int argc; -- char **argv; -- int optind; -- int sortroutine; -- int namingpolicy; -- const char *prefix; -- unsigned int debug:1; -- unsigned int interface:1; --}; -- --#endif /* GLUE_H_INCLUDED */ -diff --git a/src/bios_dev_name.h.in b/src/bios_dev_name.h.in -new file mode 100644 -index 0000000..444c5e5 ---- /dev/null -+++ b/src/bios_dev_name.h.in -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (c) 2006 Dell, Inc. -+ * by Matt Domsch -+ * Licensed under the GNU General Public license, version 2. -+ */ -+#ifndef GLUE_H_INCLUDED -+#define GLUE_H_INCLUDED -+ -+#define BIOSDEVNAME_VERSION "@PACKAGE_VERSION@" -+ -+struct bios_dev_name_opts { -+ int argc; -+ char **argv; -+ int optind; -+ int sortroutine; -+ int namingpolicy; -+ const char *prefix; -+ unsigned int debug:1; -+ unsigned int interface:1; -+}; -+ -+#endif /* GLUE_H_INCLUDED */ -diff --git a/src/bios_device.c b/src/bios_device.c -index 9e319a3..132877e 100644 ---- a/src/bios_device.c -+++ b/src/bios_device.c -@@ -217,32 +217,6 @@ static void match_pci_and_eth_devs(struct libbiosdevname_state *state) - struct pci_device *p; - struct bios_device *b; - struct network_device *n; -- -- list_for_each_entry(n, &state->network_devices, node) { -- p = find_dev_by_pci_name(state, n->drvinfo.bus_info); -- if (!p) -- continue; -- -- b = malloc(sizeof(*b)); -- if (!b) -- continue; -- memset(b, 0, sizeof(*b)); -- INIT_LIST_HEAD(&b->node); -- b->pcidev = p; -- b->netdev = n; -- b->slot_num = -1; -- b->port_num = -1; -- claim_netdev(b->netdev); -- list_add(&b->node, &state->bios_devices); -- } --} -- -- --static void match_eth_and_pci_devs(struct libbiosdevname_state *state) --{ -- struct pci_device *p; -- struct bios_device *b; -- struct network_device *n; - char pci_name[40]; - - list_for_each_entry(p, &state->pci_devices, node) { -@@ -261,8 +235,6 @@ static void match_eth_and_pci_devs(struct libbiosdevname_state *state) - INIT_LIST_HEAD(&b->node); - b->pcidev = p; - b->netdev = n; -- b->slot_num = -1; -- b->port_num = -1; - claim_netdev(b->netdev); - list_add(&b->node, &state->bios_devices); - } -@@ -286,8 +258,6 @@ static void match_unknown_eths(struct libbiosdevname_state *state) - memset(b, 0, sizeof(*b)); - INIT_LIST_HEAD(&b->node); - b->netdev = n; -- b->slot_num = -1; -- b->port_num = -1; - list_add(&b->node, &state->bios_devices); - } - } -@@ -355,26 +325,6 @@ static void find_duplicates(struct libbiosdevname_state *state) - } - } - --extern int addslot(struct libbiosdevname_state *state, int slot); -- --/* Fix for RHBZ 816536/757743/756164/: Cards with same PCI but multiple ports -- * chelsio, mellanox */ --static void check_ports(struct libbiosdevname_state *state) --{ -- struct pci_device *dev; -- struct bios_device *a; -- -- list_for_each_entry(a, &state->bios_devices, node) { -- dev = a->pcidev; -- if (dev == NULL || dev->is_sriov_virtual_function || dev->vpd_port != INT_MAX) -- continue; -- if (dev->physical_slot != PHYSICAL_SLOT_UNKNOWN) { -- a->slot_num = dev->physical_slot; -- a->port_num = addslot(state, 0x1000 + dev->physical_slot); -- } -- } --} -- - void * setup_bios_devices(int namingpolicy, const char *prefix) - { - int rc=1; -@@ -390,7 +340,6 @@ void * setup_bios_devices(int namingpolicy, const char *prefix) - get_eths(state); - match_all(state); - sort_device_list(state); -- check_ports(state); - rc = assign_bios_network_names(state, namingpolicy, prefix); - if (rc) - goto out; -diff --git a/src/bios_device.h b/src/bios_device.h -index d1ef911..690ed6f 100644 ---- a/src/bios_device.h -+++ b/src/bios_device.h -@@ -19,9 +19,6 @@ struct bios_device { - struct pci_device *pcidev; - char *bios_name; - int duplicate; -- -- int slot_num; -- int port_num; - }; - - static inline int is_pci(const struct bios_device *dev) -diff --git a/src/dmidecode/dmidecode.c b/src/dmidecode/dmidecode.c -index 3f761a9..a7a60be 100644 ---- a/src/dmidecode/dmidecode.c -+++ b/src/dmidecode/dmidecode.c -@@ -361,6 +361,57 @@ static int address_from_efi(size_t *address) - - static const char *devmem = "/dev/mem"; - -+int dmidecode_read_file(const struct libbiosdevname_state *state) -+{ -+#ifdef _JPH -+ FILE *fp; -+ const char *dmidecode_file = "dmidecode.txt"; -+ char line[128], *r; -+ int type = -1, eth=0,s,b,d,f,slot,i; -+ -+ if ((fp = fopen(dmidecode_file, "r")) == NULL) -+ return 0; -+ while ((fgets(line, sizeof(line), fp)) != NULL) { -+ if (strstr(line, " DMI type 41,") != NULL) { -+ type = 41; -+ eth = 0; -+ slot = -1; -+ } else if (strstr(line, " DMI type 9,") != NULL) { -+ type = 9; -+ } else if (strstr(line, " DMI type ") != NULL) { -+ type = -1; -+ } -+ if (type == 41) { -+ if ((r = strstr(line, "Type: Ethernet")) != NULL) { -+ eth = 1; -+ } -+ if ((r = strstr(line, "Type Instance: ")) != NULL) { -+ sscanf(r, "Type Instance: %d", &slot); -+ } -+ if ((r = strstr(line, "Bus Address: ")) != NULL && eth) { -+ sscanf(r, "Bus Address: %x:%x:%x.%x", &s,&b,&d,&f); -+ printf("bus: %.4x:%.2x:%.2x.%x\n", s, b, d, f); -+ smbios_setslot(state, s, b, d, f, 0x5, 0x00, slot, ""); -+ } -+ } -+ if (type == 9) { -+ /* System Slots */ -+ if ((r = strstr(line, "ID: ")) != NULL) { -+ sscanf(r, "ID: %d", &slot); -+ } -+ if ((r = strstr(line, "Bus Address: ")) != NULL) { -+ sscanf(r, "Bus Address: %x:%x:%x.%x", &s,&b,&d,&f); -+ printf("bus: %.4x:%.2x:%.2x.%x = %d\n", s, b, d, f, slot); -+ for (i=0; i<8; i++) -+ smbios_setslot(state, s, b, d, i, 0x00, slot, 0x00, ""); -+ } -+ } -+ } -+ return 1; -+#endif -+ return 0; -+} -+ - int dmidecode_main(const struct libbiosdevname_state *state) - { - int ret=0; /* Returned value */ -@@ -369,6 +420,9 @@ int dmidecode_main(const struct libbiosdevname_state *state) - int efi; - u8 *buf; - -+ if (dmidecode_read_file(state)) -+ return 0; -+ - /* First try EFI (ia64, Intel-based Mac) */ - efi=address_from_efi(&fp); - switch(efi) -diff --git a/src/naming_policy.c b/src/naming_policy.c -index fe7b934..4f2033c 100644 ---- a/src/naming_policy.c -+++ b/src/naming_policy.c -@@ -59,8 +59,8 @@ static void use_physical(const struct libbiosdevname_state *state, const char *p - portnum = vf->sysfs_index; - else if (vf->uses_smbios & HAS_SMBIOS_INSTANCE && is_pci_smbios_type_ethernet(vf)) - portnum = vf->smbios_instance; -- else if (dev->port_num != -1) -- portnum = dev->port_num; -+ else if (vf->embedded_index_valid) -+ portnum = vf->embedded_index; - if (portnum != INT_MAX) { - snprintf(location, sizeof(location), "%s%u", prefix, portnum); - known=1; -@@ -70,8 +70,6 @@ static void use_physical(const struct libbiosdevname_state *state, const char *p - snprintf(location, sizeof(location), "p%u", dev->pcidev->physical_slot); - if (dev->pcidev->vpd_port < INT_MAX) - portnum = dev->pcidev->vpd_port; -- else if (dev->port_num != -1) -- portnum = dev->port_num; - else if (!dev->pcidev->is_sriov_virtual_function) - portnum = dev->pcidev->index_in_slot; - else -diff --git a/src/pci.c b/src/pci.c -index d017c50..67ef464 100644 ---- a/src/pci.c -+++ b/src/pci.c -@@ -30,6 +30,7 @@ extern int is_valid_smbios; - /* Borrowed from kernel vpd code */ - #define PCI_VPD_LRDT 0x80 - #define PCI_VPD_SRDT_END 0x78 -+#define PCI_VPDR_TAG 0x90 - - #define PCI_VPD_SRDT_LEN_MASK 0x7 - #define PCI_VPD_LRDT_TAG_SIZE 3 -@@ -71,7 +72,7 @@ static int pci_vpd_size(struct pci_device *pdev, int fd) - tag = buf[0] & ~PCI_VPD_SRDT_LEN_MASK; - off += PCI_VPD_SRDT_TAG_SIZE + pci_vpd_srdt_size(buf); - } -- if (tag == 0 || tag == 0xFF || tag == PCI_VPD_SRDT_END) -+ if (tag == 0 || tag == 0xFF || tag == PCI_VPD_SRDT_END || tag == PCI_VPDR_TAG) - break; - } - return off; -@@ -125,7 +126,7 @@ static int parse_vpd(struct libbiosdevname_state *state, struct pci_device *pdev - int i, j, k, isz, jsz, port, func, pfi; - struct pci_device *vf; - -- i = pci_vpd_find_tag(vpd, 0, len, 0x90); -+ i = pci_vpd_find_tag(vpd, 0, len, PCI_VPDR_TAG); - if (i < 0) - return 1; - isz = pci_vpd_lrdt_size(&vpd[i]); -@@ -631,24 +632,6 @@ void free_pci_devices(struct libbiosdevname_state *state) - } - } - --int addslot(struct libbiosdevname_state *state, int slot) --{ -- struct slotlist *s; -- -- list_for_each_entry(s, &state->slots, node) { -- if (s->slot == slot) { -- return ++s->count; -- } -- } -- s = malloc(sizeof(*s)); -- INIT_LIST_HEAD(&s->node); -- s->slot = slot; -- s->count = 0; -- list_add(&s->node, &state->slots); -- -- return ++s->count; --} -- - static void set_pci_slots(struct libbiosdevname_state *state) - { - struct pci_device *dev; -@@ -656,21 +639,55 @@ static void set_pci_slots(struct libbiosdevname_state *state) - list_for_each_entry(dev, &state->pci_devices, node) { - dev_to_slot(state, dev); - } -+} - -- /* Get mapping for each slot */ -- list_for_each_entry(dev, &state->pci_devices, node) { -- if (dev->is_sriov_virtual_function || !is_pci_network(dev) || dev->vpd_port != INT_MAX) { -+static int set_pci_slot_index(struct libbiosdevname_state *state) -+{ -+ struct pci_device *pcidev; -+ int prevslot=-1; -+ int index=1; -+ -+ /* only iterate over the PCI devices, because the bios_device list may be incomplete due to renames happening in parallel */ -+ list_for_each_entry(pcidev, &state->pci_devices, node) { -+ if (pcidev->physical_slot == 0) /* skip embedded devices */ - continue; -+ if (!is_pci_network(pcidev)) /* only look at PCI network devices */ -+ continue; -+ if (pcidev->is_sriov_virtual_function) /* skip sriov VFs, they're handled later */ -+ continue; -+ if (pcidev->physical_slot != prevslot) { -+ index=1; -+ prevslot = pcidev->physical_slot; - } -- if (dev->physical_slot == 0) { -- dev->embedded_index_valid = 1; -- dev->embedded_index = addslot(state, 0); -- } else if (dev->physical_slot != PHYSICAL_SLOT_UNKNOWN) { -- dev->index_in_slot = addslot(state, dev->physical_slot); -- } -+ else -+ index++; -+ pcidev->index_in_slot = index; - } -+ return 0; - } - -+static int set_embedded_index(struct libbiosdevname_state *state) -+{ -+ struct pci_device *pcidev; -+ int index=1; -+ -+ list_for_each_entry(pcidev, &state->pci_devices, node) { -+ if (pcidev->physical_slot != 0) /* skip non-embedded devices */ -+ continue; -+ if (!is_pci_network(pcidev)) /* only look at PCI network devices */ -+ 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++; -+ } -+ return 0; -+} -+ -+ - static void set_sriov_pf_vf(struct libbiosdevname_state *state) - { - struct pci_device *vf; -@@ -755,6 +772,8 @@ int get_pci_devices(struct libbiosdevname_state *state) - 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); - - return rc; -diff --git a/src/pirq.c b/src/pirq.c -index 6568c24..0aa4d0c 100644 ---- a/src/pirq.c -+++ b/src/pirq.c -@@ -44,7 +44,53 @@ int pirq_pci_dev_to_slot(struct routing_table *table, int domain, int bus, int d - return INT_MAX; - } - -+struct routing_table *pirq_read_file() -+{ -+#ifdef _JPH -+ FILE *fp; -+ char line[128]; -+ struct routing_table *table; -+ char *r; -+ int count, bus, dev, slot; -+ const char *pirq_file = "biosdecode.txt"; - -+ /* Get count of entries */ -+ if ((fp = fopen(pirq_file, "r")) == NULL) -+ return NULL; -+ count = 0; -+ while (fgets(line, sizeof(line), fp) != NULL) { -+ if (strstr(line, "Slot Entry") != NULL) -+ count++; -+ } -+ fclose(fp); -+ -+ /* Read table */ -+ table = malloc(sizeof(*table) + count * sizeof(struct slot_entry)); -+ table->size = 32 + (sizeof(struct slot_entry) * count); -+ if ((fp = fopen(pirq_file, "r")) == NULL) -+ return NULL; -+ count = 0; -+ while (fgets(line, sizeof(line), fp) != NULL) { -+ if ((r = strstr(line, "Slot Entry")) == NULL) -+ continue; -+ if (sscanf(r, "Slot Entry %*d: ID %x:%x", &bus, &dev) == 2) { -+ table->slot[count].bus = bus; -+ table->slot[count].device = dev << 3; -+ if ((r = strstr(line, "on-board")) != NULL) -+ table->slot[count].slot = 0; -+ else if ((r = strstr(line, "slot number ")) != NULL) { -+ sscanf(r, "slot number %d", &slot); -+ table->slot[count].slot = slot; -+ } -+ printf("%d = %.2x:%.2x = %d\n", count, bus, dev, table->slot[count].slot); -+ count++; -+ } -+ } -+ fclose(fp); -+ return table; -+#endif -+ return NULL; -+} - - struct routing_table * pirq_alloc_read_table() - { -@@ -60,6 +106,9 @@ struct routing_table * pirq_alloc_read_table() - if (nopirq) { - return NULL; - } -+ if ((table = pirq_read_file()) != NULL) -+ return table; -+ - fd = open("/dev/mem", O_RDONLY); - if(fd==-1) - return NULL; -diff --git a/src/version.h.in b/src/version.h.in -deleted file mode 100644 -index bcc0fda..0000000 ---- a/src/version.h.in -+++ /dev/null -@@ -1 +0,0 @@ --#define BIOSDEVNAME_VERSION "@PACKAGE_VERSION@" diff --git a/biosdevname_v0.5.0_to_git_c140ce659a204d67e4cc.patch b/biosdevname_v0.5.0_to_git_c140ce659a204d67e4cc.patch new file mode 100644 index 0000000..a9d5cc0 --- /dev/null +++ b/biosdevname_v0.5.0_to_git_c140ce659a204d67e4cc.patch @@ -0,0 +1,1035 @@ +diff --git a/Makefile.am b/Makefile.am +index 28d3e8d..14d9a92 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -6,7 +6,7 @@ dist_noinst_DATA = biosdevname.rules.in biosdevname.spec.fedora biosdevname.spec + + + +-CLEANFILES = version src/version.h ++CLEANFILES = version src/bios_dev_name.h + install-data-local: + mkdir -p $(DESTDIR)@RULEDIR@ + $(INSTALL_DATA) $(top_srcdir)/biosdevname.rules.in $(DESTDIR)@RULEDEST@ +diff --git a/biosdevname.1 b/biosdevname.1 +index 7067a56..22a53bd 100644 +--- a/biosdevname.1 ++++ b/biosdevname.1 +@@ -31,16 +31,16 @@ Treat [args] as ethernet devs + .B \-d, \-\-debug + Enable debugging + .TP +-.B \-\-policy \fI[physical|all_ethN] ++.B \-p, \-\-policy \fI[physical|all_ethN] + .TP +-.B \-\-prefix \fI[string] ++.B \-P, \-\-prefix \fI[string] + string use for embedded NICs in the physical policy (default=em) + .TP +-.B \-\-nopirq ++.B \-x, \-\-nopirq + Do not use $PIR table for mapping PCI device to slot. Some BIOS have + incorrect values. + .TP +-.B \-\-smbios \fI[x.y] ++.B \-s, \-\-smbios \fI[x.y] + Require minimum SMBIOS version x.y + .SH POLICIES + .br +diff --git a/configure.ac b/configure.ac +index e26ba98..d08d42f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3,7 +3,7 @@ + # vim:tw=0:ts=8:sw=8:et + + AC_PREREQ(2.59) +-AC_INIT([biosdevname],[0.5.0],[Jordan_Hargrave@dell.com]) ++AC_INIT([biosdevname],[0.5.1],[Jordan_Hargrave@dell.com]) + AC_LANG([C]) + AC_USE_SYSTEM_EXTENSIONS + AC_CONFIG_SRCDIR([src/read_proc.c]) +@@ -88,5 +88,5 @@ echo "PACKAGE_NAME='$PACKAGE_NAME'" > version + echo "PACKAGE_VERSION='$PACKAGE_VERSION'" >> version + echo "PACKAGE_STRING='$PACKAGE_STRING'" >> version + +-AC_CONFIG_FILES([Makefile biosdevname.spec.fedora biosdevname.spec.suse src/version.h]) ++AC_CONFIG_FILES([Makefile biosdevname.spec.fedora biosdevname.spec.suse src/bios_dev_name.h]) + AC_OUTPUT +diff --git a/src/bios_dev_name.c b/src/bios_dev_name.c +index 7374f9b..d0a917a 100644 +--- a/src/bios_dev_name.c ++++ b/src/bios_dev_name.c +@@ -10,8 +10,6 @@ + #include + #include + +-#include "version.h" +- + #include "libbiosdevname.h" + #include "bios_dev_name.h" + +@@ -27,11 +25,11 @@ static void usage(void) + fprintf(stderr, " Options:\n"); + fprintf(stderr, " -i or --interface treat [args] as ethernet devs\n"); + fprintf(stderr, " -d or --debug enable debugging\n"); +- fprintf(stderr, " --policy [physical | all_ethN ]\n"); +- fprintf(stderr, " --prefix [string] string use for embedded NICs (default='em')\n"); +- fprintf(stderr, " --smbios [x.y] Require SMBIOS x.y or greater\n"); +- fprintf(stderr, " --nopirq Don't use $PIR table for slot numbers\n"); +- fprintf(stderr, " --version Show biosdevname version\n"); ++ fprintf(stderr, " -p or --policy [physical | all_ethN ]\n"); ++ fprintf(stderr, " -P or --prefix [string] string use for embedded NICs (default='em')\n"); ++ fprintf(stderr, " -s or --smbios [x.y] Require SMBIOS x.y or greater\n"); ++ fprintf(stderr, " -x or --nopirq Don't use $PIR table for slot numbers\n"); ++ fprintf(stderr, " -v or --version Show biosdevname version\n"); + fprintf(stderr, " Example: biosdevname -i eth0\n"); + fprintf(stderr, " returns: em1\n"); + fprintf(stderr, " when eth0 is an embedded NIC with label '1' on the chassis.\n"); +@@ -70,7 +68,7 @@ parse_opts(int argc, char **argv) + {0, 0, 0, 0} + }; + c = getopt_long(argc, argv, +- "dinp:", ++ "dip:P:xs:v", + long_options, &option_index); + if (c == -1) + break; +diff --git a/src/bios_dev_name.h b/src/bios_dev_name.h +deleted file mode 100644 +index 636c5e1..0000000 +--- a/src/bios_dev_name.h ++++ /dev/null +@@ -1,20 +0,0 @@ +-/* +- * Copyright (c) 2006 Dell, Inc. +- * by Matt Domsch +- * Licensed under the GNU General Public license, version 2. +- */ +-#ifndef GLUE_H_INCLUDED +-#define GLUE_H_INCLUDED +- +-struct bios_dev_name_opts { +- int argc; +- char **argv; +- int optind; +- int sortroutine; +- int namingpolicy; +- const char *prefix; +- unsigned int debug:1; +- unsigned int interface:1; +-}; +- +-#endif /* GLUE_H_INCLUDED */ +diff --git a/src/bios_dev_name.h.in b/src/bios_dev_name.h.in +new file mode 100644 +index 0000000..444c5e5 +--- /dev/null ++++ b/src/bios_dev_name.h.in +@@ -0,0 +1,22 @@ ++/* ++ * Copyright (c) 2006 Dell, Inc. ++ * by Matt Domsch ++ * Licensed under the GNU General Public license, version 2. ++ */ ++#ifndef GLUE_H_INCLUDED ++#define GLUE_H_INCLUDED ++ ++#define BIOSDEVNAME_VERSION "@PACKAGE_VERSION@" ++ ++struct bios_dev_name_opts { ++ int argc; ++ char **argv; ++ int optind; ++ int sortroutine; ++ int namingpolicy; ++ const char *prefix; ++ unsigned int debug:1; ++ unsigned int interface:1; ++}; ++ ++#endif /* GLUE_H_INCLUDED */ +diff --git a/src/bios_device.c b/src/bios_device.c +index 9e319a3..ba0661f 100644 +--- a/src/bios_device.c ++++ b/src/bios_device.c +@@ -212,33 +212,17 @@ static void sort_device_list(struct libbiosdevname_state *state) + list_splice(&sorted_devices, &state->bios_devices); + } + +-static void match_pci_and_eth_devs(struct libbiosdevname_state *state) ++/* Check for Mellanox/Chelsio drivers */ ++int ismultiport(const char *driver) + { +- struct pci_device *p; +- struct bios_device *b; +- struct network_device *n; +- +- list_for_each_entry(n, &state->network_devices, node) { +- p = find_dev_by_pci_name(state, n->drvinfo.bus_info); +- if (!p) +- continue; +- +- b = malloc(sizeof(*b)); +- if (!b) +- continue; +- memset(b, 0, sizeof(*b)); +- INIT_LIST_HEAD(&b->node); +- b->pcidev = p; +- b->netdev = n; +- b->slot_num = -1; +- b->port_num = -1; +- claim_netdev(b->netdev); +- list_add(&b->node, &state->bios_devices); +- } ++ if (!strncmp(driver, "mlx", 3)) ++ return 1; ++ if (!strncmp(driver, "cxgb", 4)) ++ return 1; ++ return 0; + } + +- +-static void match_eth_and_pci_devs(struct libbiosdevname_state *state) ++static void match_pci_and_eth_devs(struct libbiosdevname_state *state) + { + struct pci_device *p; + struct bios_device *b; +@@ -249,22 +233,30 @@ static void match_eth_and_pci_devs(struct libbiosdevname_state *state) + if (!is_pci_network(p)) + continue; + ++ /* Loop through all ether devices to find match */ + unparse_pci_name(pci_name, sizeof(pci_name), p->pci_dev); +- n = find_net_device_by_bus_info(state, pci_name); +- if (!n) +- continue; +- +- b = malloc(sizeof(*b)); +- if (!b) +- continue; +- memset(b, 0, sizeof(*b)); +- INIT_LIST_HEAD(&b->node); +- b->pcidev = p; +- b->netdev = n; +- b->slot_num = -1; +- b->port_num = -1; +- claim_netdev(b->netdev); +- list_add(&b->node, &state->bios_devices); ++ list_for_each_entry(n, &state->network_devices, node) { ++ if (strncmp(n->drvinfo.bus_info, pci_name, sizeof(n->drvinfo.bus_info))) ++ continue; ++ b = malloc(sizeof(*b)); ++ if (!b) ++ continue; ++ memset(b, 0, sizeof(*b)); ++ INIT_LIST_HEAD(&b->node); ++ b->pcidev = p; ++ b->netdev = n; ++ b->port = NULL; ++ if (ismultiport(n->drvinfo.driver)) { ++ b->port = malloc(sizeof(struct pci_port)); ++ if (b->port != NULL) { ++ b->port->port = n->devid+1; ++ b->port->pfi = p->is_sriov_virtual_function ? ++ p->vf_index : -1; ++ } ++ } ++ claim_netdev(b->netdev); ++ list_add(&b->node, &state->bios_devices); ++ } + } + } + +@@ -286,8 +278,7 @@ static void match_unknown_eths(struct libbiosdevname_state *state) + memset(b, 0, sizeof(*b)); + INIT_LIST_HEAD(&b->node); + b->netdev = n; +- b->slot_num = -1; +- b->port_num = -1; ++ b->port = NULL; + list_add(&b->node, &state->bios_devices); + } + } +@@ -355,26 +346,6 @@ static void find_duplicates(struct libbiosdevname_state *state) + } + } + +-extern int addslot(struct libbiosdevname_state *state, int slot); +- +-/* Fix for RHBZ 816536/757743/756164/: Cards with same PCI but multiple ports +- * chelsio, mellanox */ +-static void check_ports(struct libbiosdevname_state *state) +-{ +- struct pci_device *dev; +- struct bios_device *a; +- +- list_for_each_entry(a, &state->bios_devices, node) { +- dev = a->pcidev; +- if (dev == NULL || dev->is_sriov_virtual_function || dev->vpd_port != INT_MAX) +- continue; +- if (dev->physical_slot != PHYSICAL_SLOT_UNKNOWN) { +- a->slot_num = dev->physical_slot; +- a->port_num = addslot(state, 0x1000 + dev->physical_slot); +- } +- } +-} +- + void * setup_bios_devices(int namingpolicy, const char *prefix) + { + int rc=1; +@@ -390,7 +361,6 @@ void * setup_bios_devices(int namingpolicy, const char *prefix) + get_eths(state); + match_all(state); + sort_device_list(state); +- check_ports(state); + rc = assign_bios_network_names(state, namingpolicy, prefix); + if (rc) + goto out; +diff --git a/src/bios_device.h b/src/bios_device.h +index d1ef911..158a2af 100644 +--- a/src/bios_device.h ++++ b/src/bios_device.h +@@ -12,16 +12,15 @@ + #include "pci.h" + #include "naming_policy.h" + ++struct pci_port; + + struct bios_device { + struct list_head node; + struct network_device *netdev; + struct pci_device *pcidev; + char *bios_name; ++ struct pci_port *port; + int duplicate; +- +- int slot_num; +- int port_num; + }; + + static inline int is_pci(const struct bios_device *dev) +diff --git a/src/dmidecode/dmidecode.c b/src/dmidecode/dmidecode.c +index 3f761a9..f766b8c 100644 +--- a/src/dmidecode/dmidecode.c ++++ b/src/dmidecode/dmidecode.c +@@ -119,14 +119,15 @@ int smbios_setslot(const struct libbiosdevname_state *state, + struct pci_device *pdev, *n; + int i; + +- dprintf("setslot: %.4x:%.2x:%.2x.%x = slot(%2d %2d) %s\n", +- domain, bus, device, func, slot, index, label); ++ dprintf("setslot: %.4x:%.2x:%.2x.%x = type:%x slot(%2d %2d) %s\n", ++ domain, bus, device, func, type, slot, index, label); + + /* Don't bother with disabled devices */ +- if ((bus == 0 && device == 0 && func == 0) || /* bug on HP systems */ ++ if ((domain == 0xFFFF) || ++ (bus == 0 && device == 0 && func == 0) || /* bug on HP systems */ + (bus == 0xFF && device == 0x1F && func == 0x7)) + { +- dprintf("disabled\n"); ++ dprintf(" disabled\n"); + return; + } + +@@ -153,18 +154,11 @@ int smbios_setslot(const struct libbiosdevname_state *state, + } + + /* Found a PDEV, now is it a bridge? */ +- if (pdev->sbus == -1) +- continue; +- dprintf("scan subbus: %d\n", pdev->sbus); +- list_for_each_entry(n, &state->pci_devices, node) { +- if (matchpci(n, domain, pdev->sbus, -1, -1)) { +- smbios_setslot(state, n->pci_dev->domain, n->pci_dev->bus, +- n->pci_dev->dev, n->pci_dev->func, +- type, slot, index, label); +- } ++ if (pdev->sbus != -1) { ++ smbios_setslot(state, domain, pdev->sbus, -1, -1, type, slot, index, label); + } +- dprintf("done subbus: %d\n", pdev->sbus); + } ++ return 0; + } + + static void dmi_decode(struct dmi_header *h, u16 ver, const struct libbiosdevname_state *state) +@@ -179,12 +173,9 @@ static void dmi_decode(struct dmi_header *h, u16 ver, const struct libbiosdevnam + bus = data[0x0F]; + device = (data[0x10]>>3)&0x1F; + function = data[0x10] & 7; +- if (domain != 0xFFFF) { +- for (i=0; i<8; i++) +- smbios_setslot(state, domain, bus, device, i, +- 0x00, WORD(data+0x09), 0x00, +- dmi_string(h, data[0x04])); +- } ++ smbios_setslot(state, domain, bus, device, -1, ++ 0x00, WORD(data+0x09), 0x00, ++ dmi_string(h, data[0x04])); + } + else { + dprintf("Old Slot: id:%3d, type:%.2x, label:%-7s\n", WORD(data+0x09), data[0x05], dmi_string(h, data[0x04])); +@@ -361,6 +352,57 @@ static int address_from_efi(size_t *address) + + static const char *devmem = "/dev/mem"; + ++int dmidecode_read_file(const struct libbiosdevname_state *state) ++{ ++#ifdef _JPH ++ FILE *fp; ++ const char *dmidecode_file = "dmidecode.txt"; ++ char line[128], *r; ++ int type = -1, eth=0,s,b,d,f,slot,i; ++ ++ if ((fp = fopen(dmidecode_file, "r")) == NULL) ++ return 0; ++ while ((fgets(line, sizeof(line), fp)) != NULL) { ++ if (strstr(line, " DMI type 41,") != NULL) { ++ type = 41; ++ eth = 0; ++ slot = -1; ++ } else if (strstr(line, " DMI type 9,") != NULL) { ++ type = 9; ++ } else if (strstr(line, " DMI type ") != NULL) { ++ type = -1; ++ } ++ if (type == 41) { ++ if ((r = strstr(line, "Type: Ethernet")) != NULL) { ++ eth = 1; ++ } ++ if ((r = strstr(line, "Type Instance: ")) != NULL) { ++ sscanf(r, "Type Instance: %d", &slot); ++ } ++ if ((r = strstr(line, "Bus Address: ")) != NULL && eth) { ++ sscanf(r, "Bus Address: %x:%x:%x.%x", &s,&b,&d,&f); ++ printf("bus: %.4x:%.2x:%.2x.%x\n", s, b, d, f); ++ smbios_setslot(state, s, b, d, f, 0x5, 0x00, slot, ""); ++ } ++ } ++ if (type == 9) { ++ /* System Slots */ ++ if ((r = strstr(line, "ID: ")) != NULL) { ++ sscanf(r, "ID: %d", &slot); ++ } ++ if ((r = strstr(line, "Bus Address: ")) != NULL) { ++ sscanf(r, "Bus Address: %x:%x:%x.%x", &s,&b,&d,&f); ++ printf("bus: %.4x:%.2x:%.2x.%x = %d\n", s, b, d, f, slot); ++ for (i=0; i<8; i++) ++ smbios_setslot(state, s, b, d, i, 0x00, slot, 0x00, ""); ++ } ++ } ++ } ++ return 1; ++#endif ++ return 0; ++} ++ + int dmidecode_main(const struct libbiosdevname_state *state) + { + int ret=0; /* Returned value */ +@@ -369,6 +411,9 @@ int dmidecode_main(const struct libbiosdevname_state *state) + int efi; + u8 *buf; + ++ if (dmidecode_read_file(state)) ++ return 0; ++ + /* First try EFI (ia64, Intel-based Mac) */ + efi=address_from_efi(&fp); + switch(efi) +diff --git a/src/eths.c b/src/eths.c +index bcd02e1..38bb7fe 100644 +--- a/src/eths.c ++++ b/src/eths.c +@@ -34,6 +34,20 @@ char *pr_ether(char *buf, const int size, const unsigned char *s) + return (buf); + } + ++static int eths_get_devid(const char *devname, int *devid) ++{ ++ char path[PATH_MAX]; ++ char *devidstr = NULL; ++ ++ *devid = -1; ++ snprintf(path, sizeof(path), "/sys/class/net/%s/dev_id", devname); ++ if (sysfs_read_file(path, &devidstr) == 0) { ++ sscanf(devidstr, "%i", devid); ++ free(devidstr); ++ } ++ return NULL; ++} ++ + static int eths_get_ifindex(const char *devname, int *ifindex) + { + int fd, err; +@@ -149,6 +163,7 @@ static void fill_eth_dev(struct network_device *dev) + eths_get_ifindex(dev->kernel_name, &dev->ifindex); + eths_get_hwaddr(dev->kernel_name, dev->dev_addr, sizeof(dev->dev_addr), &dev->arphrd_type); + eths_get_permaddr(dev->kernel_name, dev->perm_addr, sizeof(dev->perm_addr)); ++ eths_get_devid(dev->kernel_name, &dev->devid); + rc = eths_get_info(dev->kernel_name, &dev->drvinfo); + if (rc == 0) + dev->drvinfo_valid = 1; +diff --git a/src/eths.h b/src/eths.h +index f686136..12c278b 100644 +--- a/src/eths.h ++++ b/src/eths.h +@@ -27,6 +27,7 @@ struct network_device { + int arphrd_type; /* e.g. ARPHDR_ETHER */ + int hardware_claimed; /* true when recognized as PCI or PCMCIA and added to list of bios_devices */ + int ifindex; ++ int devid; + }; + + extern void get_eths(struct libbiosdevname_state *state); +diff --git a/src/naming_policy.c b/src/naming_policy.c +index fe7b934..7138a4b 100644 +--- a/src/naming_policy.c ++++ b/src/naming_policy.c +@@ -55,12 +55,14 @@ static void use_physical(const struct libbiosdevname_state *state, const char *p + vf = vf->vpd_pf; + if (vf->pf) + vf = vf->pf; +- if (vf->uses_sysfs & HAS_SYSFS_INDEX) ++ if (dev->port) ++ portnum = dev->port->port; ++ else 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 (dev->port_num != -1) +- portnum = dev->port_num; ++ else if (vf->embedded_index_valid) ++ portnum = vf->embedded_index; + if (portnum != INT_MAX) { + snprintf(location, sizeof(location), "%s%u", prefix, portnum); + known=1; +@@ -68,10 +70,10 @@ static void use_physical(const struct libbiosdevname_state *state, const char *p + } + else if (dev->pcidev->physical_slot < PHYSICAL_SLOT_UNKNOWN) { + snprintf(location, sizeof(location), "p%u", dev->pcidev->physical_slot); +- if (dev->pcidev->vpd_port < INT_MAX) ++ if (dev->port) ++ portnum = dev->port->port; ++ else if (dev->pcidev->vpd_port < INT_MAX) + portnum = dev->pcidev->vpd_port; +- else if (dev->port_num != -1) +- portnum = dev->port_num; + else if (!dev->pcidev->is_sriov_virtual_function) + portnum = dev->pcidev->index_in_slot; + else +@@ -80,7 +82,9 @@ static void use_physical(const struct libbiosdevname_state *state, const char *p + known=1; + } + +- if (dev->pcidev->is_sriov_virtual_function) ++ if (dev->port && dev->port->pfi != -1) ++ snprintf(interface, sizeof(interface), "_%u", dev->port->pfi); ++ else if (dev->pcidev->is_sriov_virtual_function) + snprintf(interface, sizeof(interface), "_%u", dev->pcidev->vf_index); + else if (dev->pcidev->vpd_pfi < INT_MAX) + snprintf(interface, sizeof(interface), "_%u", dev->pcidev->vpd_pfi); +diff --git a/src/pci.c b/src/pci.c +index d017c50..7a7cb36 100644 +--- a/src/pci.c ++++ b/src/pci.c +@@ -30,6 +30,7 @@ extern int is_valid_smbios; + /* Borrowed from kernel vpd code */ + #define PCI_VPD_LRDT 0x80 + #define PCI_VPD_SRDT_END 0x78 ++#define PCI_VPDR_TAG 0x90 + + #define PCI_VPD_SRDT_LEN_MASK 0x7 + #define PCI_VPD_LRDT_TAG_SIZE 3 +@@ -71,7 +72,7 @@ static int pci_vpd_size(struct pci_device *pdev, int fd) + tag = buf[0] & ~PCI_VPD_SRDT_LEN_MASK; + off += PCI_VPD_SRDT_TAG_SIZE + pci_vpd_srdt_size(buf); + } +- if (tag == 0 || tag == 0xFF || tag == PCI_VPD_SRDT_END) ++ if (tag == 0 || tag == 0xFF || tag == PCI_VPD_SRDT_END || tag == PCI_VPDR_TAG) + break; + } + return off; +@@ -120,12 +121,31 @@ static int pci_vpd_find_info_subkey(const u8 *buf, unsigned int off, unsigned in + return -1; + } + ++/* Add port identifier(s) to PCI device */ ++static void add_port(struct pci_device *pdev, int port, int pfi) ++{ ++ struct pci_port *p; ++ ++ list_for_each_entry(p, &pdev->ports, node) { ++ if (p->port == port && p->pfi == pfi) ++ return; ++ } ++ p = malloc(sizeof(*p)); ++ if (p == NULL) ++ return; ++ memset(p, 0, sizeof(*p)); ++ INIT_LIST_HEAD(&p->node); ++ p->port = port; ++ p->pfi = pfi; ++ list_add_tail(&p->node, &pdev->ports); ++} ++ + 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); ++ i = pci_vpd_find_tag(vpd, 0, len, PCI_VPDR_TAG); + if (i < 0) + return 1; + isz = pci_vpd_lrdt_size(&vpd[i]); +@@ -154,6 +174,7 @@ static int parse_vpd(struct libbiosdevname_state *state, struct pci_device *pdev + pdev->pci_dev->bus, + pdev->pci_dev->dev, + func)) != NULL) { ++ add_port(vf, port, pfi); + if (vf->vpd_port == INT_MAX) { + vf->vpd_port = port; + vf->vpd_pfi = pfi; +@@ -324,67 +345,15 @@ static int read_pci_sysfs_physfn(char *buf, size_t bufsize, const struct pci_dev + return 0; + } + +-static int virtfn_filter(const struct dirent *dent) +-{ +- return (!strncmp(dent->d_name,"virtfn",6)); +-} +- +-static int _read_virtfn_index(unsigned int *index, const char *path, const char *basename, const char *pci_name) +-{ +- char buf[PATH_MAX], *b; +- char fullpath[PATH_MAX]; +- ssize_t size; +- unsigned int u=INT_MAX; +- int scanned, rc=1; +- +- snprintf(fullpath, sizeof(fullpath), "%s/%s", path, basename); +- size = readlink(fullpath, buf, sizeof(buf)); +- if (size > 0) { +- /* form is ../0000:05:10.0 */ +- b=buf+3; /* skip ../ */ +- if (strlen(b) == strlen(pci_name) && +- !strncmp(b, pci_name, strlen(pci_name))) { +- scanned = sscanf(basename, "virtfn%u", &u); +- if (scanned == 1) { +- rc = 0; +- *index = u; +- } +- } +- } +- return rc; +-} +- +-static int read_virtfn_index(unsigned int *index, const struct pci_dev *pdev) +-{ +- char pci_name[16]; +- char path[PATH_MAX]; +- char cpath[PATH_MAX]; +- struct dirent **namelist; +- int n, rc=1; +- +- unparse_pci_name(pci_name, sizeof(pci_name), pdev); +- snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/physfn", pci_name); +- if (realpath(path, cpath) == NULL) +- return rc; +- +- n = scandir(cpath, &namelist, virtfn_filter, versionsort); +- if (n < 0) +- return rc; +- else { +- while (n--) { +- if (rc) +- rc = _read_virtfn_index(index, cpath, namelist[n]->d_name, pci_name); +- free(namelist[n]); +- } +- free(namelist); +- } +- +- return rc; +-} +- + static int parse_pci_name(const char *s, int *domain, int *bus, int *dev, int *func) + { + int err; ++ const char *r; ++ ++ /* Allow parsing pathnames */ ++ if ((r = strrchr(s, '/')) != NULL) ++ s = r+1; ++ + /* The domain part was added in 2.6 kernels. Test for that first. */ + err = sscanf(s, "%x:%2x:%2x.%x", domain, bus, dev, func); + if (err != 4) { +@@ -404,29 +373,6 @@ static struct pci_dev * find_pdev_by_pci_name(struct pci_access *pacc, const cha + return pci_get_dev(pacc, domain, bus, device, func); + } + +-static struct pci_device * +-find_physfn(struct libbiosdevname_state *state, struct pci_device *dev) +-{ +- int rc; +- char path[PATH_MAX]; +- char *c; +- struct pci_dev *pdev; +- memset(path, 0, sizeof(path)); +- rc = read_pci_sysfs_physfn(path, sizeof(path), dev->pci_dev); +- if (rc != 0) +- return NULL; +- /* we get back a string like +- ../0000:05:0.0 +- where the last component is the parent device +- */ +- /* find the last backslash */ +- c = rindex(path, '/'); +- c++; +- pdev = find_pdev_by_pci_name(state->pacc, c); +- dev = find_dev_by_pci(state, pdev); +- return dev; +-} +- + static int is_same_pci(const struct pci_dev *a, const struct pci_dev *b) + { + if (pci_domain_nr(a) == pci_domain_nr(b) && +@@ -437,25 +383,6 @@ static int is_same_pci(const struct pci_dev *a, const struct pci_dev *b) + return 0; + } + +-static void try_add_vf_to_pf(struct libbiosdevname_state *state, struct pci_device *vf) +-{ +- struct pci_device *pf; +- unsigned int index=0; +- int rc; +- pf = find_physfn(state, vf); +- +- if (!pf) +- return; +- list_add_tail(&vf->vfnode, &pf->vfs); +- rc = read_virtfn_index(&index, vf->pci_dev); +- if (!rc) { +- vf->vf_index = index; +- pf->is_sriov_physical_function = 1; +- } +- vf->pf = pf; +- vf->physical_slot = pf->physical_slot; +-} +- + static struct pci_device * + find_parent(struct libbiosdevname_state *state, struct pci_device *dev) + { +@@ -465,12 +392,6 @@ find_parent(struct libbiosdevname_state *state, struct pci_device *dev) + struct pci_device *physfn; + struct pci_dev *pdev; + memset(path, 0, sizeof(path)); +- /* if this device has a physfn pointer, then treat _that_ as the parent */ +- physfn = find_physfn(state, dev); +- if (physfn) { +- dev->is_sriov_virtual_function=1; +- return physfn; +- } + + rc = read_pci_sysfs_path(path, sizeof(path), dev->pci_dev); + if (rc != 0) +@@ -553,6 +474,7 @@ static int read_pci_sysfs_index(unsigned int *index, const struct pci_dev *pdev) + rc = sysfs_read_file(path, &indexstr); + if (rc == 0) { + rc = sscanf(indexstr, "%u", &i); ++ free(indexstr); + if (rc == 1) { + *index = i; + return 0; +@@ -595,6 +517,7 @@ static void add_pci_dev(struct libbiosdevname_state *state, + INIT_LIST_HEAD(&dev->node); + INIT_LIST_HEAD(&dev->vfnode); + INIT_LIST_HEAD(&dev->vfs); ++ INIT_LIST_HEAD(&dev->ports); + dev->pci_dev = p; + dev->physical_slot = PHYSICAL_SLOT_UNKNOWN; + dev->class = pci_read_word(p, PCI_CLASS_DEVICE); +@@ -631,24 +554,6 @@ void free_pci_devices(struct libbiosdevname_state *state) + } + } + +-int addslot(struct libbiosdevname_state *state, int slot) +-{ +- struct slotlist *s; +- +- list_for_each_entry(s, &state->slots, node) { +- if (s->slot == slot) { +- return ++s->count; +- } +- } +- s = malloc(sizeof(*s)); +- INIT_LIST_HEAD(&s->node); +- s->slot = slot; +- s->count = 0; +- list_add(&s->node, &state->slots); +- +- return ++s->count; +-} +- + static void set_pci_slots(struct libbiosdevname_state *state) + { + struct pci_device *dev; +@@ -656,28 +561,105 @@ static void set_pci_slots(struct libbiosdevname_state *state) + list_for_each_entry(dev, &state->pci_devices, node) { + dev_to_slot(state, dev); + } ++} + +- /* Get mapping for each slot */ +- list_for_each_entry(dev, &state->pci_devices, node) { +- if (dev->is_sriov_virtual_function || !is_pci_network(dev) || dev->vpd_port != INT_MAX) { ++static int set_pci_slot_index(struct libbiosdevname_state *state) ++{ ++ struct pci_device *pcidev; ++ int prevslot=-1; ++ int index=1; ++ ++ /* only iterate over the PCI devices, because the bios_device list may be incomplete due to renames happening in parallel */ ++ list_for_each_entry(pcidev, &state->pci_devices, node) { ++ if (pcidev->physical_slot == 0) /* skip embedded devices */ + continue; ++ if (!is_pci_network(pcidev)) /* only look at PCI network devices */ ++ continue; ++ if (pcidev->is_sriov_virtual_function) /* skip sriov VFs, they're handled later */ ++ continue; ++ if (pcidev->physical_slot != prevslot) { ++ index=1; ++ prevslot = pcidev->physical_slot; + } +- if (dev->physical_slot == 0) { +- dev->embedded_index_valid = 1; +- dev->embedded_index = addslot(state, 0); +- } else if (dev->physical_slot != PHYSICAL_SLOT_UNKNOWN) { +- dev->index_in_slot = addslot(state, dev->physical_slot); +- } ++ else ++ index++; ++ pcidev->index_in_slot = index; ++ } ++ return 0; ++} ++ ++static int set_embedded_index(struct libbiosdevname_state *state) ++{ ++ struct pci_device *pcidev; ++ int index=1; ++ ++ list_for_each_entry(pcidev, &state->pci_devices, node) { ++ if (pcidev->physical_slot != 0) /* skip non-embedded devices */ ++ continue; ++ if (!is_pci_network(pcidev)) /* only look at PCI network devices */ ++ 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++; + } ++ return 0; + } + +-static void set_sriov_pf_vf(struct libbiosdevname_state *state) ++static int virtfn_filter(const struct dirent *dent) ++{ ++ return (!strncmp(dent->d_name,"virtfn",6)); ++} ++ ++/* Assign Virtual Function to Physical Function */ ++static void set_sriov(struct libbiosdevname_state *state, struct pci_device *pf, const char *virtpath) + { + struct pci_device *vf; +- list_for_each_entry(vf, &state->pci_devices, node) { +- if (!vf->is_sriov_virtual_function) ++ char pci_name[32]; ++ char path[PATH_MAX], cpath[PATH_MAX]; ++ int vf_index; ++ ++ if (sscanf(virtpath, "virtfn%u", &vf_index) != 1) ++ return; ++ unparse_pci_name(pci_name, sizeof(pci_name), pf->pci_dev); ++ snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/%s", pci_name, virtpath); ++ ++ memset(cpath, 0, sizeof(cpath)); ++ if (readlink(path, cpath, sizeof(cpath)) < 0) ++ return; ++ if ((vf = find_dev_by_pci_name(state, cpath)) != NULL) { ++ vf->is_sriov_virtual_function = 1; ++ vf->vf_index = vf_index; ++ vf->pf = pf; ++ pf->is_sriov_physical_function = 1; ++ list_add_tail(&vf->vfnode, &pf->vfs); ++ } ++} ++ ++static void scan_sriov(struct libbiosdevname_state *state) ++{ ++ struct pci_device *pf; ++ char path[PATH_MAX]; ++ char pci_name[32]; ++ struct dirent **namelist; ++ int n; ++ ++ list_for_each_entry(pf, &state->pci_devices, node) { ++ unparse_pci_name(pci_name, sizeof(pci_name), pf->pci_dev); ++ snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s", pci_name); ++ ++ namelist = NULL; ++ n = scandir(path, &namelist, virtfn_filter, versionsort); ++ if (n <= 0) + continue; +- try_add_vf_to_pf(state, vf); ++ while (n--) { ++ set_sriov(state, pf, namelist[n]->d_name); ++ free(namelist[n]); ++ } ++ free(namelist); + } + } + +@@ -753,9 +735,11 @@ int get_pci_devices(struct libbiosdevname_state *state) + /* ordering here is important */ + dmidecode_main(state); /* this will fail on Xen guests, that's OK */ + sort_device_list(state); ++ scan_sriov(state); + set_pci_vpd_instance(state); + set_pci_slots(state); +- set_sriov_pf_vf(state); ++ set_embedded_index(state); ++ set_pci_slot_index(state); + + return rc; + } +diff --git a/src/pci.h b/src/pci.h +index 77b4746..eacb539 100644 +--- a/src/pci.h ++++ b/src/pci.h +@@ -20,6 +20,12 @@ struct slotlist + int count; + }; + ++struct pci_port { ++ struct list_head node; ++ int port; ++ int pfi; ++}; ++ + struct pci_device { + struct list_head node; + struct pci_dev *pci_dev; +@@ -44,6 +50,7 @@ struct pci_device { + struct pci_device *pf; + struct list_head vfnode; + struct list_head vfs; ++ struct list_head ports; + unsigned int is_sriov_physical_function:1; + unsigned int is_sriov_virtual_function:1; + unsigned int embedded_index_valid:1; +diff --git a/src/pirq.c b/src/pirq.c +index 6568c24..0aa4d0c 100644 +--- a/src/pirq.c ++++ b/src/pirq.c +@@ -44,7 +44,53 @@ int pirq_pci_dev_to_slot(struct routing_table *table, int domain, int bus, int d + return INT_MAX; + } + ++struct routing_table *pirq_read_file() ++{ ++#ifdef _JPH ++ FILE *fp; ++ char line[128]; ++ struct routing_table *table; ++ char *r; ++ int count, bus, dev, slot; ++ const char *pirq_file = "biosdecode.txt"; + ++ /* Get count of entries */ ++ if ((fp = fopen(pirq_file, "r")) == NULL) ++ return NULL; ++ count = 0; ++ while (fgets(line, sizeof(line), fp) != NULL) { ++ if (strstr(line, "Slot Entry") != NULL) ++ count++; ++ } ++ fclose(fp); ++ ++ /* Read table */ ++ table = malloc(sizeof(*table) + count * sizeof(struct slot_entry)); ++ table->size = 32 + (sizeof(struct slot_entry) * count); ++ if ((fp = fopen(pirq_file, "r")) == NULL) ++ return NULL; ++ count = 0; ++ while (fgets(line, sizeof(line), fp) != NULL) { ++ if ((r = strstr(line, "Slot Entry")) == NULL) ++ continue; ++ if (sscanf(r, "Slot Entry %*d: ID %x:%x", &bus, &dev) == 2) { ++ table->slot[count].bus = bus; ++ table->slot[count].device = dev << 3; ++ if ((r = strstr(line, "on-board")) != NULL) ++ table->slot[count].slot = 0; ++ else if ((r = strstr(line, "slot number ")) != NULL) { ++ sscanf(r, "slot number %d", &slot); ++ table->slot[count].slot = slot; ++ } ++ printf("%d = %.2x:%.2x = %d\n", count, bus, dev, table->slot[count].slot); ++ count++; ++ } ++ } ++ fclose(fp); ++ return table; ++#endif ++ return NULL; ++} + + struct routing_table * pirq_alloc_read_table() + { +@@ -60,6 +106,9 @@ struct routing_table * pirq_alloc_read_table() + if (nopirq) { + return NULL; + } ++ if ((table = pirq_read_file()) != NULL) ++ return table; ++ + fd = open("/dev/mem", O_RDONLY); + if(fd==-1) + return NULL; +diff --git a/src/sysfs.c b/src/sysfs.c +index 71e84e7..e276240 100644 +--- a/src/sysfs.c ++++ b/src/sysfs.c +@@ -32,7 +32,7 @@ int sysfs_path_is_file(const char * path) + int sysfs_read_file(const char * path, char **output) + { + int ret; +- char *result = NULL; ++ char *result = NULL, *n; + int fd; + unsigned long resultsize = 0; + ssize_t length = 0; +@@ -57,8 +57,8 @@ int sysfs_read_file(const char * path, char **output) + goto free_out; + } + result[length] = '\0'; +- if (result[length-1] == '\n') +- result[length-1] = '\0'; ++ if ((n = strchr(result, '\n')) != NULL) ++ *n = '\0'; + *output = result; + ret = 0; + goto out; +diff --git a/src/version.h.in b/src/version.h.in +deleted file mode 100644 +index bcc0fda..0000000 +--- a/src/version.h.in ++++ /dev/null +@@ -1 +0,0 @@ +-#define BIOSDEVNAME_VERSION "@PACKAGE_VERSION@"