s390/pci: consolidate SR-IOV specific code
authorNiklas Schnelle <schnelle@linux.ibm.com>
Mon, 17 Aug 2020 08:29:23 +0000 (10:29 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Mon, 14 Sep 2020 09:38:34 +0000 (11:38 +0200)
currently we have multiple #ifdef CONFIG_PCI_IOV blocks spread over
different compliation units and headers, all dealing with SR-IOV
specific behavior.
This violates the style guide which discourages conditionally compiled
code blocks and hinders maintainability by speading SR-IOV functionality
over many files.

Let's move all of this into a conditionally compiled pci_iov.c file and
local header and prefix SR-IOV specific functions with zpci_iov_*.

Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/pci/Makefile
arch/s390/pci/pci.c
arch/s390/pci/pci_bus.c
arch/s390/pci/pci_bus.h
arch/s390/pci/pci_iov.c [new file with mode: 0644]
arch/s390/pci/pci_iov.h [new file with mode: 0644]

index b4e3c84772a164f3314863fd8d4e2cf17da7514a..bf557a1b789c75a3b3bf5a812770269368532be1 100644 (file)
@@ -6,3 +6,4 @@
 obj-$(CONFIG_PCI)      += pci.o pci_irq.o pci_dma.o pci_clp.o pci_sysfs.o \
                           pci_event.o pci_debug.o pci_insn.o pci_mmio.o \
                           pci_bus.o
+obj-$(CONFIG_PCI_IOV)  += pci_iov.o
index fdbb99c4569dc83ed68889e4d1a587ebdb9a52bb..e432318f69372e0860d9ee4e0a6037867e0267d5 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/pci_dma.h>
 
 #include "pci_bus.h"
+#include "pci_iov.h"
 
 /* list of all detected zpci devices */
 static LIST_HEAD(zpci_list);
@@ -413,15 +414,6 @@ static struct pci_ops pci_root_ops = {
        .write = pci_write,
 };
 
-#ifdef CONFIG_PCI_IOV
-static struct resource iov_res = {
-       .name   = "PCI IOV res",
-       .start  = 0,
-       .end    = -1,
-       .flags  = IORESOURCE_MEM,
-};
-#endif
-
 static void zpci_map_resources(struct pci_dev *pdev)
 {
        struct zpci_dev *zdev = to_zpci(pdev);
@@ -442,16 +434,7 @@ static void zpci_map_resources(struct pci_dev *pdev)
                pdev->resource[i].end = pdev->resource[i].start + len - 1;
        }
 
-#ifdef CONFIG_PCI_IOV
-       for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
-               int bar = i + PCI_IOV_RESOURCES;
-
-               len = pci_resource_len(pdev, bar);
-               if (!len)
-                       continue;
-               pdev->resource[bar].parent = &iov_res;
-       }
-#endif
+       zpci_iov_map_resources(pdev);
 }
 
 static void zpci_unmap_resources(struct pci_dev *pdev)
@@ -703,7 +686,7 @@ void zpci_remove_device(struct zpci_dev *zdev)
        pdev = pci_get_slot(zbus->bus, zdev->devfn);
        if (pdev) {
                if (pdev->is_virtfn)
-                       return zpci_remove_virtfn(pdev, zdev->vfn);
+                       return zpci_iov_remove_virtfn(pdev, zdev->vfn);
                pci_stop_and_remove_bus_device_locked(pdev);
        }
 }
index 5967f30141563705e66067efc87c6d452e9b5fb3..0c0db7c3a40420cca2c1761896ed047c0e9ba404 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/pci_dma.h>
 
 #include "pci_bus.h"
+#include "pci_iov.h"
 
 static LIST_HEAD(zbus_list);
 static DEFINE_SPINLOCK(zbus_list_lock);
@@ -126,69 +127,6 @@ static struct zpci_bus *zpci_bus_alloc(int pchid)
        return zbus;
 }
 
-#ifdef CONFIG_PCI_IOV
-static int zpci_bus_link_virtfn(struct pci_dev *pdev,
-               struct pci_dev *virtfn, int vfid)
-{
-       int rc;
-
-       rc = pci_iov_sysfs_link(pdev, virtfn, vfid);
-       if (rc)
-               return rc;
-
-       virtfn->is_virtfn = 1;
-       virtfn->multifunction = 0;
-       virtfn->physfn = pci_dev_get(pdev);
-
-       return 0;
-}
-
-static int zpci_bus_setup_virtfn(struct zpci_bus *zbus,
-               struct pci_dev *virtfn, int vfn)
-{
-       int i, cand_devfn;
-       struct zpci_dev *zdev;
-       struct pci_dev *pdev;
-       int vfid = vfn - 1; /* Linux' vfid's start at 0 vfn at 1*/
-       int rc = 0;
-
-       if (!zbus->multifunction)
-               return 0;
-
-       /* If the parent PF for the given VF is also configured in the
-        * instance, it must be on the same zbus.
-        * We can then identify the parent PF by checking what
-        * devfn the VF would have if it belonged to that PF using the PF's
-        * stride and offset. Only if this candidate devfn matches the
-        * actual devfn will we link both functions.
-        */
-       for (i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
-               zdev = zbus->function[i];
-               if (zdev && zdev->is_physfn) {
-                       pdev = pci_get_slot(zbus->bus, zdev->devfn);
-                       if (!pdev)
-                               continue;
-                       cand_devfn = pci_iov_virtfn_devfn(pdev, vfid);
-                       if (cand_devfn == virtfn->devfn) {
-                               rc = zpci_bus_link_virtfn(pdev, virtfn, vfid);
-                               /* balance pci_get_slot() */
-                               pci_dev_put(pdev);
-                               break;
-                       }
-                       /* balance pci_get_slot() */
-                       pci_dev_put(pdev);
-               }
-       }
-       return rc;
-}
-#else
-static inline int zpci_bus_setup_virtfn(struct zpci_bus *zbus,
-               struct pci_dev *virtfn, int vfn)
-{
-       return 0;
-}
-#endif
-
 void pcibios_bus_add_device(struct pci_dev *pdev)
 {
        struct zpci_dev *zdev = to_zpci(pdev);
@@ -198,7 +136,7 @@ void pcibios_bus_add_device(struct pci_dev *pdev)
         * perform PF/VF linking.
         */
        if (zdev->vfn)
-               zpci_bus_setup_virtfn(zdev->zbus, pdev, zdev->vfn);
+               zpci_iov_setup_virtfn(zdev->zbus, pdev, zdev->vfn);
 
 }
 
index 4972433df4581ab5acbbf5b33ac55e6b7db99375..8d19723ed5c03ee2514712fdb5469d85a23fc6b0 100644 (file)
@@ -30,15 +30,3 @@ static inline struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus,
        return (devfn >= ZPCI_FUNCTIONS_PER_BUS) ? NULL : zbus->function[devfn];
 }
 
-#ifdef CONFIG_PCI_IOV
-static inline void zpci_remove_virtfn(struct pci_dev *pdev, int vfn)
-{
-
-       pci_lock_rescan_remove();
-       /* Linux' vfid's start at 0 vfn at 1 */
-       pci_iov_remove_virtfn(pdev->physfn, vfn - 1);
-       pci_unlock_rescan_remove();
-}
-#else /* CONFIG_PCI_IOV */
-static inline void zpci_remove_virtfn(struct pci_dev *pdev, int vfn) {}
-#endif /* CONFIG_PCI_IOV */
diff --git a/arch/s390/pci/pci_iov.c b/arch/s390/pci/pci_iov.c
new file mode 100644 (file)
index 0000000..35fca14
--- /dev/null
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright IBM Corp. 2020
+ *
+ * Author(s):
+ *   Niklas Schnelle <schnelle@linux.ibm.com>
+ *
+ */
+
+#define KMSG_COMPONENT "zpci"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+static struct resource iov_res = {
+       .name   = "PCI IOV res",
+       .start  = 0,
+       .end    = -1,
+       .flags  = IORESOURCE_MEM,
+};
+
+void zpci_iov_map_resources(struct pci_dev *pdev)
+{
+       resource_size_t len;
+       int i;
+
+       for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+               int bar = i + PCI_IOV_RESOURCES;
+
+               len = pci_resource_len(pdev, bar);
+               if (!len)
+                       continue;
+               pdev->resource[bar].parent = &iov_res;
+       }
+}
+
+void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn)
+{
+       pci_lock_rescan_remove();
+       /* Linux' vfid's start at 0 vfn at 1 */
+       pci_iov_remove_virtfn(pdev->physfn, vfn - 1);
+       pci_unlock_rescan_remove();
+}
+
+static int zpci_iov_link_virtfn(struct pci_dev *pdev, struct pci_dev *virtfn, int vfid)
+{
+       int rc;
+
+       rc = pci_iov_sysfs_link(pdev, virtfn, vfid);
+       if (rc)
+               return rc;
+
+       virtfn->is_virtfn = 1;
+       virtfn->multifunction = 0;
+       virtfn->physfn = pci_dev_get(pdev);
+
+       return 0;
+}
+
+int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn)
+{
+       int i, cand_devfn;
+       struct zpci_dev *zdev;
+       struct pci_dev *pdev;
+       int vfid = vfn - 1; /* Linux' vfid's start at 0 vfn at 1*/
+       int rc = 0;
+
+       if (!zbus->multifunction)
+               return 0;
+
+       /* If the parent PF for the given VF is also configured in the
+        * instance, it must be on the same zbus.
+        * We can then identify the parent PF by checking what
+        * devfn the VF would have if it belonged to that PF using the PF's
+        * stride and offset. Only if this candidate devfn matches the
+        * actual devfn will we link both functions.
+        */
+       for (i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
+               zdev = zbus->function[i];
+               if (zdev && zdev->is_physfn) {
+                       pdev = pci_get_slot(zbus->bus, zdev->devfn);
+                       if (!pdev)
+                               continue;
+                       cand_devfn = pci_iov_virtfn_devfn(pdev, vfid);
+                       if (cand_devfn == virtfn->devfn) {
+                               rc = zpci_iov_link_virtfn(pdev, virtfn, vfid);
+                               /* balance pci_get_slot() */
+                               pci_dev_put(pdev);
+                               break;
+                       }
+                       /* balance pci_get_slot() */
+                       pci_dev_put(pdev);
+               }
+       }
+       return rc;
+}
diff --git a/arch/s390/pci/pci_iov.h b/arch/s390/pci/pci_iov.h
new file mode 100644 (file)
index 0000000..b2c8280
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright IBM Corp. 2020
+ *
+ * Author(s):
+ *   Niklas Schnelle <schnelle@linux.ibm.com>
+ *
+ */
+
+#ifndef __S390_PCI_IOV_H
+#define __S390_PCI_IOV_H
+
+#ifdef CONFIG_PCI_IOV
+void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn);
+
+void zpci_iov_map_resources(struct pci_dev *pdev);
+
+int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn);
+
+#else /* CONFIG_PCI_IOV */
+static inline void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn) {}
+
+static inline void zpci_iov_map_resources(struct pci_dev *pdev) {}
+
+static inline int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn)
+{
+       return 0;
+}
+#endif /* CONFIG_PCI_IOV */
+#endif /* __S390_PCI_IOV_h */