summaryrefslogtreecommitdiff
path: root/drivers/pci/setup-res.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/setup-res.c')
-rw-r--r--drivers/pci/setup-res.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index c6657cdd06f6..d2b3ed51e880 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -423,13 +423,39 @@ void pci_release_resource(struct pci_dev *dev, int resno)
}
EXPORT_SYMBOL(pci_release_resource);
+static bool pci_resize_is_memory_decoding_enabled(struct pci_dev *dev,
+ int resno)
+{
+ u16 cmd;
+
+ if (pci_resource_is_iov(resno))
+ return pci_iov_is_memory_decoding_enabled(dev);
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+
+ return cmd & PCI_COMMAND_MEMORY;
+}
+
+static void pci_resize_resource_set_size(struct pci_dev *dev, int resno,
+ int size)
+{
+ resource_size_t res_size = pci_rebar_size_to_bytes(size);
+ struct resource *res = pci_resource_n(dev, resno);
+
+ if (!pci_resource_is_iov(resno)) {
+ resource_set_size(res, res_size);
+ } else {
+ resource_set_size(res, res_size * pci_sriov_get_totalvfs(dev));
+ pci_iov_resource_set_size(dev, resno, res_size);
+ }
+}
+
int pci_resize_resource(struct pci_dev *dev, int resno, int size)
{
struct resource *res = pci_resource_n(dev, resno);
struct pci_host_bridge *host;
int old, ret;
u32 sizes;
- u16 cmd;
/* Check if we must preserve the firmware's resource assignment */
host = pci_find_host_bridge(dev->bus);
@@ -440,8 +466,7 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size)
if (!(res->flags & IORESOURCE_UNSET))
return -EBUSY;
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- if (cmd & PCI_COMMAND_MEMORY)
+ if (pci_resize_is_memory_decoding_enabled(dev, resno))
return -EBUSY;
sizes = pci_rebar_get_possible_sizes(dev, resno);
@@ -459,7 +484,7 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size)
if (ret)
return ret;
- resource_set_size(res, pci_rebar_size_to_bytes(size));
+ pci_resize_resource_set_size(dev, resno, size);
/* Check if the new config works by trying to assign everything. */
if (dev->bus->self) {
@@ -471,7 +496,7 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size)
error_resize:
pci_rebar_set_size(dev, resno, old);
- resource_set_size(res, pci_rebar_size_to_bytes(old));
+ pci_resize_resource_set_size(dev, resno, old);
return ret;
}
EXPORT_SYMBOL(pci_resize_resource);