[systemd-devel] [RFC][PATCH] udev: net_id - support multi-function, multi-port enpo* device names

2015-04-01 Thread Tom Gundersen
I'd argue that having firmware labels for such devices makes no sense, but they 
exist, so make sure
we handle them as best as we can.
---
 src/udev/udev-builtin-net_id.c | 64 --
 1 file changed, 43 insertions(+), 21 deletions(-)

diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 71f3a59..1a72190 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -35,7 +35,7 @@
  * Type of names:
  *   b -- BCMA bus core number
  *   ccw -- CCW bus group name
- *   o  -- on-board device index number
+ *   o[f][d]-- on-board device index number
  *   s[f][d] -- hotplug slot index number
  *   x-- MAC address
  *   [P]ps[f][d]
@@ -126,11 +126,38 @@ struct netnames {
 char ccw_group[IFNAMSIZ];
 };
 
+/* read the 256 bytes PCI configuration space to check the multi-function bit 
*/
+static bool is_pci_multifunction(struct udev_device *dev) {
+_cleanup_fclose_ FILE *f = NULL;
+const char *filename;
+uint8_t config[64];
+
+filename = strjoina(udev_device_get_syspath(dev), "/config");
+f = fopen(filename, "re");
+if (!f)
+return false;
+if (fread(&config, sizeof(config), 1, f) != 1)
+return false;
+
+/* bit 0-6 header type, bit 7 multi/single function device */
+if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
+return true;
+
+return false;
+}
+
 /* retrieve on-board index number and label from firmware */
 static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
+unsigned func, dev_port = 0;
+size_t l;
+char *s;
+const char *attr;
 const char *index;
 int idx;
 
+if (sscanf(udev_device_get_sysname(names->pcidev), "%*x:%*x:%*x.%u", 
&func) != 1)
+return -ENOENT;
+
 /* ACPI _DSM  -- device specific method for naming a PCI or PCI 
Express device */
 index = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
 /* SMBIOS type 41 -- Onboard Devices Extended Information */
@@ -141,30 +168,25 @@ static int dev_pci_onboard(struct udev_device *dev, 
struct netnames *names) {
 idx = strtoul(index, NULL, 0);
 if (idx <= 0)
 return -EINVAL;
-snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx);
 
-names->pci_onboard_label = 
udev_device_get_sysattr_value(names->pcidev, "label");
-return 0;
-}
-
-/* read the 256 bytes PCI configuration space to check the multi-function bit 
*/
-static bool is_pci_multifunction(struct udev_device *dev) {
-_cleanup_fclose_ FILE *f = NULL;
-const char *filename;
-uint8_t config[64];
+/* kernel provided multi-device index */
+attr = udev_device_get_sysattr_value(dev, "dev_port");
+if (attr)
+dev_port = strtol(attr, NULL, 10);
 
-filename = strjoina(udev_device_get_syspath(dev), "/config");
-f = fopen(filename, "re");
-if (!f)
-return false;
-if (fread(&config, sizeof(config), 1, f) != 1)
-return false;
+s = names->pci_onboard;
+l = sizeof(names->pci_onboard);
+l = strpcpyf(&s, l, "o%d", idx);
+if (func > 0 || is_pci_multifunction(names->pcidev))
+l = strpcpyf(&s, l, "f%d", func);
+if (dev_port > 0)
+l = strpcpyf(&s, l, "d%d", dev_port);
+if (l == 0)
+names->pci_onboard[0] = '\0';
 
-/* bit 0-6 header type, bit 7 multi/single function device */
-if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
-return true;
+names->pci_onboard_label = 
udev_device_get_sysattr_value(names->pcidev, "label");
 
-return false;
+return 0;
 }
 
 static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
-- 
2.3.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [RFC][PATCH] udev: net_id - support multi-function, multi-port enpo* device names

2015-04-01 Thread Tom Gundersen
I pushed a version of this only handling the multi-port devices. We
can deal with multi-function if and when they appear in the wild.

-t

On Wed, Apr 1, 2015 at 4:52 PM, Tom Gundersen  wrote:
> I'd argue that having firmware labels for such devices makes no sense, but 
> they exist, so make sure
> we handle them as best as we can.
> ---
>  src/udev/udev-builtin-net_id.c | 64 
> --
>  1 file changed, 43 insertions(+), 21 deletions(-)
>
> diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
> index 71f3a59..1a72190 100644
> --- a/src/udev/udev-builtin-net_id.c
> +++ b/src/udev/udev-builtin-net_id.c
> @@ -35,7 +35,7 @@
>   * Type of names:
>   *   b -- BCMA bus core number
>   *   ccw -- CCW bus group name
> - *   o  -- on-board device index number
> + *   o[f][d]-- on-board device index number
>   *   s[f][d] -- hotplug slot index number
>   *   x-- MAC address
>   *   [P]ps[f][d]
> @@ -126,11 +126,38 @@ struct netnames {
>  char ccw_group[IFNAMSIZ];
>  };
>
> +/* read the 256 bytes PCI configuration space to check the multi-function 
> bit */
> +static bool is_pci_multifunction(struct udev_device *dev) {
> +_cleanup_fclose_ FILE *f = NULL;
> +const char *filename;
> +uint8_t config[64];
> +
> +filename = strjoina(udev_device_get_syspath(dev), "/config");
> +f = fopen(filename, "re");
> +if (!f)
> +return false;
> +if (fread(&config, sizeof(config), 1, f) != 1)
> +return false;
> +
> +/* bit 0-6 header type, bit 7 multi/single function device */
> +if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
> +return true;
> +
> +return false;
> +}
> +
>  /* retrieve on-board index number and label from firmware */
>  static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
> +unsigned func, dev_port = 0;
> +size_t l;
> +char *s;
> +const char *attr;
>  const char *index;
>  int idx;
>
> +if (sscanf(udev_device_get_sysname(names->pcidev), "%*x:%*x:%*x.%u", 
> &func) != 1)
> +return -ENOENT;
> +
>  /* ACPI _DSM  -- device specific method for naming a PCI or PCI 
> Express device */
>  index = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
>  /* SMBIOS type 41 -- Onboard Devices Extended Information */
> @@ -141,30 +168,25 @@ static int dev_pci_onboard(struct udev_device *dev, 
> struct netnames *names) {
>  idx = strtoul(index, NULL, 0);
>  if (idx <= 0)
>  return -EINVAL;
> -snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx);
>
> -names->pci_onboard_label = 
> udev_device_get_sysattr_value(names->pcidev, "label");
> -return 0;
> -}
> -
> -/* read the 256 bytes PCI configuration space to check the multi-function 
> bit */
> -static bool is_pci_multifunction(struct udev_device *dev) {
> -_cleanup_fclose_ FILE *f = NULL;
> -const char *filename;
> -uint8_t config[64];
> +/* kernel provided multi-device index */
> +attr = udev_device_get_sysattr_value(dev, "dev_port");
> +if (attr)
> +dev_port = strtol(attr, NULL, 10);
>
> -filename = strjoina(udev_device_get_syspath(dev), "/config");
> -f = fopen(filename, "re");
> -if (!f)
> -return false;
> -if (fread(&config, sizeof(config), 1, f) != 1)
> -return false;
> +s = names->pci_onboard;
> +l = sizeof(names->pci_onboard);
> +l = strpcpyf(&s, l, "o%d", idx);
> +if (func > 0 || is_pci_multifunction(names->pcidev))
> +l = strpcpyf(&s, l, "f%d", func);
> +if (dev_port > 0)
> +l = strpcpyf(&s, l, "d%d", dev_port);
> +if (l == 0)
> +names->pci_onboard[0] = '\0';
>
> -/* bit 0-6 header type, bit 7 multi/single function device */
> -if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
> -return true;
> +names->pci_onboard_label = 
> udev_device_get_sysattr_value(names->pcidev, "label");
>
> -return false;
> +return 0;
>  }
>
>  static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
> --
> 2.3.4
>
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [RFC][PATCH] udev: net_id - support multi-function, multi-port enpo* device names

2015-07-15 Thread Michael Marineau
Found one of these fabaled multi-function network devices you dropped
from the patch, an Intel I350 Gigabit device on a Supermicro
X9DRI-LN4F+ motherboard. The 4 different network interfaces are all
are fighting over the 'eno1' name and are functions 06:00.0, 06:00.1,
06:00.2, and 06:00.3.

On Wed, Apr 1, 2015 at 1:58 PM, Tom Gundersen  wrote:
> I pushed a version of this only handling the multi-port devices. We
> can deal with multi-function if and when they appear in the wild.
>
> -t
>
> On Wed, Apr 1, 2015 at 4:52 PM, Tom Gundersen  wrote:
>> I'd argue that having firmware labels for such devices makes no sense, but 
>> they exist, so make sure
>> we handle them as best as we can.
>> ---
>>  src/udev/udev-builtin-net_id.c | 64 
>> --
>>  1 file changed, 43 insertions(+), 21 deletions(-)
>>
>> diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
>> index 71f3a59..1a72190 100644
>> --- a/src/udev/udev-builtin-net_id.c
>> +++ b/src/udev/udev-builtin-net_id.c
>> @@ -35,7 +35,7 @@
>>   * Type of names:
>>   *   b -- BCMA bus core number
>>   *   ccw -- CCW bus group name
>> - *   o  -- on-board device index number
>> + *   o[f][d]-- on-board device index number
>>   *   s[f][d] -- hotplug slot index number
>>   *   x-- MAC address
>>   *   [P]ps[f][d]
>> @@ -126,11 +126,38 @@ struct netnames {
>>  char ccw_group[IFNAMSIZ];
>>  };
>>
>> +/* read the 256 bytes PCI configuration space to check the multi-function 
>> bit */
>> +static bool is_pci_multifunction(struct udev_device *dev) {
>> +_cleanup_fclose_ FILE *f = NULL;
>> +const char *filename;
>> +uint8_t config[64];
>> +
>> +filename = strjoina(udev_device_get_syspath(dev), "/config");
>> +f = fopen(filename, "re");
>> +if (!f)
>> +return false;
>> +if (fread(&config, sizeof(config), 1, f) != 1)
>> +return false;
>> +
>> +/* bit 0-6 header type, bit 7 multi/single function device */
>> +if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
>> +return true;
>> +
>> +return false;
>> +}
>> +
>>  /* retrieve on-board index number and label from firmware */
>>  static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) 
>> {
>> +unsigned func, dev_port = 0;
>> +size_t l;
>> +char *s;
>> +const char *attr;
>>  const char *index;
>>  int idx;
>>
>> +if (sscanf(udev_device_get_sysname(names->pcidev), 
>> "%*x:%*x:%*x.%u", &func) != 1)
>> +return -ENOENT;
>> +
>>  /* ACPI _DSM  -- device specific method for naming a PCI or PCI 
>> Express device */
>>  index = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
>>  /* SMBIOS type 41 -- Onboard Devices Extended Information */
>> @@ -141,30 +168,25 @@ static int dev_pci_onboard(struct udev_device *dev, 
>> struct netnames *names) {
>>  idx = strtoul(index, NULL, 0);
>>  if (idx <= 0)
>>  return -EINVAL;
>> -snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", 
>> idx);
>>
>> -names->pci_onboard_label = 
>> udev_device_get_sysattr_value(names->pcidev, "label");
>> -return 0;
>> -}
>> -
>> -/* read the 256 bytes PCI configuration space to check the multi-function 
>> bit */
>> -static bool is_pci_multifunction(struct udev_device *dev) {
>> -_cleanup_fclose_ FILE *f = NULL;
>> -const char *filename;
>> -uint8_t config[64];
>> +/* kernel provided multi-device index */
>> +attr = udev_device_get_sysattr_value(dev, "dev_port");
>> +if (attr)
>> +dev_port = strtol(attr, NULL, 10);
>>
>> -filename = strjoina(udev_device_get_syspath(dev), "/config");
>> -f = fopen(filename, "re");
>> -if (!f)
>> -return false;
>> -if (fread(&config, sizeof(config), 1, f) != 1)
>> -return false;
>> +s = names->pci_onboard;
>> +l = sizeof(names->pci_onboard);
>> +l = strpcpyf(&s, l, "o%d", idx);
>> +if (func > 0 || is_pci_multifunction(names->pcidev))
>> +l = strpcpyf(&s, l, "f%d", func);
>> +if (dev_port > 0)
>> +l = strpcpyf(&s, l, "d%d", dev_port);
>> +if (l == 0)
>> +names->pci_onboard[0] = '\0';
>>
>> -/* bit 0-6 header type, bit 7 multi/single function device */
>> -if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
>> -return true;
>> +names->pci_onboard_label = 
>> udev_device_get_sysattr_value(names->pcidev, "label");
>>
>> -return false;
>> +return 0;
>>  }
>>
>>  static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
>> --
>> 2.3.4
>>
> __