Commit 6a5f3e66 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Greg Kroah-Hartman

PCI: Separate VF BAR updates from standard BAR updates

[ Upstream commit 6ffa2489 ]

Previously pci_update_resource() used the same code path for updating
standard BARs and VF BARs in SR-IOV capabilities.

Split the VF BAR update into a new pci_iov_update_resource() internal
interface, which makes it simpler to compute the BAR address (we can get
rid of pci_resource_bar() and pci_iov_resource_bar()).

This patch:

  - Renames pci_update_resource() to pci_std_update_resource(),
  - Adds pci_iov_update_resource(),
  - Makes pci_update_resource() a wrapper that calls the appropriate one,

No functional change intended.
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarGavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: default avatarSasha Levin <alexander.levin@verizon.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 29d92878
...@@ -571,6 +571,56 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno) ...@@ -571,6 +571,56 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno)
4 * (resno - PCI_IOV_RESOURCES); 4 * (resno - PCI_IOV_RESOURCES);
} }
/**
* pci_iov_update_resource - update a VF BAR
* @dev: the PCI device
* @resno: the resource number
*
* Update a VF BAR in the SR-IOV capability of a PF.
*/
void pci_iov_update_resource(struct pci_dev *dev, int resno)
{
struct pci_sriov *iov = dev->is_physfn ? dev->sriov : NULL;
struct resource *res = dev->resource + resno;
int vf_bar = resno - PCI_IOV_RESOURCES;
struct pci_bus_region region;
u32 new;
int reg;
/*
* The generic pci_restore_bars() path calls this for all devices,
* including VFs and non-SR-IOV devices. If this is not a PF, we
* have nothing to do.
*/
if (!iov)
return;
/*
* Ignore unimplemented BARs, unused resource slots for 64-bit
* BARs, and non-movable resources, e.g., those described via
* Enhanced Allocation.
*/
if (!res->flags)
return;
if (res->flags & IORESOURCE_UNSET)
return;
if (res->flags & IORESOURCE_PCI_FIXED)
return;
pcibios_resource_to_bus(dev->bus, &region, res);
new = region.start;
new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
reg = iov->pos + PCI_SRIOV_BAR + 4 * vf_bar;
pci_write_config_dword(dev, reg, new);
if (res->flags & IORESOURCE_MEM_64) {
new = region.start >> 16 >> 16;
pci_write_config_dword(dev, reg + 4, new);
}
}
resource_size_t __weak pcibios_iov_resource_alignment(struct pci_dev *dev, resource_size_t __weak pcibios_iov_resource_alignment(struct pci_dev *dev,
int resno) int resno)
{ {
......
...@@ -290,6 +290,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) ...@@ -290,6 +290,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev)
int pci_iov_init(struct pci_dev *dev); int pci_iov_init(struct pci_dev *dev);
void pci_iov_release(struct pci_dev *dev); void pci_iov_release(struct pci_dev *dev);
int pci_iov_resource_bar(struct pci_dev *dev, int resno); int pci_iov_resource_bar(struct pci_dev *dev, int resno);
void pci_iov_update_resource(struct pci_dev *dev, int resno);
resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
void pci_restore_iov_state(struct pci_dev *dev); void pci_restore_iov_state(struct pci_dev *dev);
int pci_iov_bus_range(struct pci_bus *bus); int pci_iov_bus_range(struct pci_bus *bus);
......
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include "pci.h" #include "pci.h"
static void pci_std_update_resource(struct pci_dev *dev, int resno)
void pci_update_resource(struct pci_dev *dev, int resno)
{ {
struct pci_bus_region region; struct pci_bus_region region;
bool disable; bool disable;
...@@ -110,6 +109,16 @@ void pci_update_resource(struct pci_dev *dev, int resno) ...@@ -110,6 +109,16 @@ void pci_update_resource(struct pci_dev *dev, int resno)
pci_write_config_word(dev, PCI_COMMAND, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd);
} }
void pci_update_resource(struct pci_dev *dev, int resno)
{
if (resno <= PCI_ROM_RESOURCE)
pci_std_update_resource(dev, resno);
#ifdef CONFIG_PCI_IOV
else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
pci_iov_update_resource(dev, resno);
#endif
}
int pci_claim_resource(struct pci_dev *dev, int resource) int pci_claim_resource(struct pci_dev *dev, int resource)
{ {
struct resource *res = &dev->resource[resource]; struct resource *res = &dev->resource[resource];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment