mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-05-02 05:13:57 +00:00
s390/pci: consolidate SR-IOV specific code
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>
This commit is contained in:
parent
da1694ad9e
commit
abb95b7550
6 changed files with 133 additions and 96 deletions
|
@ -6,3 +6,4 @@
|
||||||
obj-$(CONFIG_PCI) += pci.o pci_irq.o pci_dma.o pci_clp.o pci_sysfs.o \
|
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_event.o pci_debug.o pci_insn.o pci_mmio.o \
|
||||||
pci_bus.o
|
pci_bus.o
|
||||||
|
obj-$(CONFIG_PCI_IOV) += pci_iov.o
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <asm/pci_dma.h>
|
#include <asm/pci_dma.h>
|
||||||
|
|
||||||
#include "pci_bus.h"
|
#include "pci_bus.h"
|
||||||
|
#include "pci_iov.h"
|
||||||
|
|
||||||
/* list of all detected zpci devices */
|
/* list of all detected zpci devices */
|
||||||
static LIST_HEAD(zpci_list);
|
static LIST_HEAD(zpci_list);
|
||||||
|
@ -413,15 +414,6 @@ static struct pci_ops pci_root_ops = {
|
||||||
.write = pci_write,
|
.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)
|
static void zpci_map_resources(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct zpci_dev *zdev = to_zpci(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;
|
pdev->resource[i].end = pdev->resource[i].start + len - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_IOV
|
zpci_iov_map_resources(pdev);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zpci_unmap_resources(struct pci_dev *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);
|
pdev = pci_get_slot(zbus->bus, zdev->devfn);
|
||||||
if (pdev) {
|
if (pdev) {
|
||||||
if (pdev->is_virtfn)
|
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);
|
pci_stop_and_remove_bus_device_locked(pdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <asm/pci_dma.h>
|
#include <asm/pci_dma.h>
|
||||||
|
|
||||||
#include "pci_bus.h"
|
#include "pci_bus.h"
|
||||||
|
#include "pci_iov.h"
|
||||||
|
|
||||||
static LIST_HEAD(zbus_list);
|
static LIST_HEAD(zbus_list);
|
||||||
static DEFINE_SPINLOCK(zbus_list_lock);
|
static DEFINE_SPINLOCK(zbus_list_lock);
|
||||||
|
@ -126,69 +127,6 @@ static struct zpci_bus *zpci_bus_alloc(int pchid)
|
||||||
return zbus;
|
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)
|
void pcibios_bus_add_device(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct zpci_dev *zdev = to_zpci(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.
|
* perform PF/VF linking.
|
||||||
*/
|
*/
|
||||||
if (zdev->vfn)
|
if (zdev->vfn)
|
||||||
zpci_bus_setup_virtfn(zdev->zbus, pdev, zdev->vfn);
|
zpci_iov_setup_virtfn(zdev->zbus, pdev, zdev->vfn);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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];
|
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 */
|
|
||||||
|
|
97
arch/s390/pci/pci_iov.c
Normal file
97
arch/s390/pci/pci_iov.c
Normal file
|
@ -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;
|
||||||
|
}
|
30
arch/s390/pci/pci_iov.h
Normal file
30
arch/s390/pci/pci_iov.h
Normal file
|
@ -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 */
|
Loading…
Add table
Reference in a new issue