summaryrefslogtreecommitdiff
path: root/src/udev/udev-builtin-net_id.c
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-11-30 19:27:42 +0100
committerKay Sievers <kay@vrfy.org>2012-11-30 19:27:42 +0100
commitde892aea1c486b59e04884268b612081d1660514 (patch)
tree30ddd067df49624216e818f6ffdecb0a95fc8cc8 /src/udev/udev-builtin-net_id.c
parent2ab38e24e548e0215596687e4916f5c47dc935a2 (diff)
udev: net_id - suppress function number for single-function devices
Diffstat (limited to 'src/udev/udev-builtin-net_id.c')
-rw-r--r--src/udev/udev-builtin-net_id.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 44a29fe371..bc6ca212db 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -24,16 +24,20 @@
* ww -- wwan
*
* types:
- * o<index> -- on-board device index
- * s<slot>f<function> -- hotplug slot number
- * x<MAC> -- MAC address
- * p<bus>s<slot>f<function> -- PCI/physical location
+ * o<index> -- on-board device index
+ * s<slot>[f<function>] -- hotplug slot number
+ * x<MAC> -- MAC address
+ * p<bus>s<slot>[f<function>] -- PCI/physical location
*
* example:
* ID_NET_NAME_ONBOARD=eno1
- * ID_NET_NAME_SLOT=ens1f0
+ * ID_NET_NAME_SLOT=ens1
+ * ID_NET_NAME_SLOT=ens2f0
+ * ID_NET_NAME_SLOT=ens2f1
* ID_NET_NAME_MAC=enxf0def180d479
- * ID_NET_NAME_PATH=enp19s0f0
+ * ID_NET_NAME_PATH=enp0s25
+ * ID_NET_NAME_PATH=enp19s3f0
+ * ID_NET_NAME_PATH=enp19s3f1
*/
#include <stdio.h>
@@ -42,6 +46,7 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
+#include <linux/pci_regs.h>
#include "udev.h"
@@ -77,6 +82,27 @@ static int dev_pci_onboard(struct udev_device *dev, struct udev_device *parent,
return 0;
}
+static bool is_pci_singlefunction(struct udev_device *dev) {
+ char filename[256];
+ FILE *f;
+ char config[256];
+ bool single = false;
+
+ snprintf(filename, sizeof(filename), "%s/config", udev_device_get_syspath(dev));
+ f = fopen(filename, "re");
+ if (!f)
+ goto out;
+ if (fread(&config, sizeof(config), 1, f) != 1)
+ goto out;
+
+ /* bit 0-6 header type, bit 7 multi/single function device */
+ if ((config[PCI_HEADER_TYPE] & 0x80) == 0)
+ single = true;
+out:
+ fclose(f);
+ return single;
+}
+
static int dev_pci_slot(struct udev_device *dev, struct udev_device *parent, const char *prefix, bool test) {
struct udev *udev = udev_device_get_udev(dev);
unsigned int bus;
@@ -93,7 +119,10 @@ static int dev_pci_slot(struct udev_device *dev, struct udev_device *parent, con
/* compose a name based on the raw kernel's PCI bus, slot numbers */
if (sscanf(udev_device_get_sysname(parent), "0000:%x:%x.%d", &bus, &slot, &func) != 3)
return -ENOENT;
- snprintf(str, sizeof(str), "%sp%ds%df%d", prefix, bus, slot, func);
+ if (func == 0 && is_pci_singlefunction(parent))
+ snprintf(str, sizeof(str), "%sp%ds%d", prefix, bus, slot);
+ else
+ snprintf(str, sizeof(str), "%sp%ds%df%d", prefix, bus, slot, func);
err = udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
if (err < 0)
return err;
@@ -137,7 +166,10 @@ static int dev_pci_slot(struct udev_device *dev, struct udev_device *parent, con
closedir(dir);
if (hotplug_slot > 0) {
- snprintf(str, sizeof(str), "%ss%df%d", prefix, hotplug_slot, func);
+ if (func == 0 && is_pci_singlefunction(parent))
+ snprintf(str, sizeof(str), "%ss%d", prefix, hotplug_slot);
+ else
+ snprintf(str, sizeof(str), "%ss%df%d", prefix, hotplug_slot, func);
err = udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
}
out: