|
@@ -57,6 +57,14 @@ static void virtfn_remove_bus(struct pci_bus *physbus, struct pci_bus *virtbus)
|
|
|
pci_remove_bus(virtbus);
|
|
|
}
|
|
|
|
|
|
+resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno)
|
|
|
+{
|
|
|
+ if (!dev->is_physfn)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ return dev->sriov->barsz[resno - PCI_IOV_RESOURCES];
|
|
|
+}
|
|
|
+
|
|
|
static int virtfn_add(struct pci_dev *dev, int id, int reset)
|
|
|
{
|
|
|
int i;
|
|
@@ -92,8 +100,7 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
|
|
|
continue;
|
|
|
virtfn->resource[i].name = pci_name(virtfn);
|
|
|
virtfn->resource[i].flags = res->flags;
|
|
|
- size = resource_size(res);
|
|
|
- do_div(size, iov->total_VFs);
|
|
|
+ size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES);
|
|
|
virtfn->resource[i].start = res->start + size * id;
|
|
|
virtfn->resource[i].end = virtfn->resource[i].start + size - 1;
|
|
|
rc = request_resource(res, &virtfn->resource[i]);
|
|
@@ -311,7 +318,7 @@ static void sriov_disable(struct pci_dev *dev)
|
|
|
|
|
|
static int sriov_init(struct pci_dev *dev, int pos)
|
|
|
{
|
|
|
- int i;
|
|
|
+ int i, bar64;
|
|
|
int rc;
|
|
|
int nres;
|
|
|
u32 pgsz;
|
|
@@ -360,29 +367,29 @@ found:
|
|
|
pgsz &= ~(pgsz - 1);
|
|
|
pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz);
|
|
|
|
|
|
+ iov = kzalloc(sizeof(*iov), GFP_KERNEL);
|
|
|
+ if (!iov)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
nres = 0;
|
|
|
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
|
|
|
res = dev->resource + PCI_IOV_RESOURCES + i;
|
|
|
- i += __pci_read_base(dev, pci_bar_unknown, res,
|
|
|
- pos + PCI_SRIOV_BAR + i * 4);
|
|
|
+ bar64 = __pci_read_base(dev, pci_bar_unknown, res,
|
|
|
+ pos + PCI_SRIOV_BAR + i * 4);
|
|
|
if (!res->flags)
|
|
|
continue;
|
|
|
if (resource_size(res) & (PAGE_SIZE - 1)) {
|
|
|
rc = -EIO;
|
|
|
goto failed;
|
|
|
}
|
|
|
+ iov->barsz[i] = resource_size(res);
|
|
|
res->end = res->start + resource_size(res) * total - 1;
|
|
|
dev_info(&dev->dev, "VF(n) BAR%d space: %pR (contains BAR%d for %d VFs)\n",
|
|
|
i, res, i, total);
|
|
|
+ i += bar64;
|
|
|
nres++;
|
|
|
}
|
|
|
|
|
|
- iov = kzalloc(sizeof(*iov), GFP_KERNEL);
|
|
|
- if (!iov) {
|
|
|
- rc = -ENOMEM;
|
|
|
- goto failed;
|
|
|
- }
|
|
|
-
|
|
|
iov->pos = pos;
|
|
|
iov->nres = nres;
|
|
|
iov->ctrl = ctrl;
|
|
@@ -414,6 +421,7 @@ failed:
|
|
|
res->flags = 0;
|
|
|
}
|
|
|
|
|
|
+ kfree(iov);
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -510,14 +518,7 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno)
|
|
|
*/
|
|
|
resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
|
|
|
{
|
|
|
- struct resource tmp;
|
|
|
- int reg = pci_iov_resource_bar(dev, resno);
|
|
|
-
|
|
|
- if (!reg)
|
|
|
- return 0;
|
|
|
-
|
|
|
- __pci_read_base(dev, pci_bar_unknown, &tmp, reg);
|
|
|
- return resource_alignment(&tmp);
|
|
|
+ return pci_iov_resource_size(dev, resno);
|
|
|
}
|
|
|
|
|
|
/**
|