|
@@ -113,7 +113,7 @@ resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno)
|
|
|
return dev->sriov->barsz[resno - PCI_IOV_RESOURCES];
|
|
|
}
|
|
|
|
|
|
-int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
|
|
|
+int pci_iov_add_virtfn(struct pci_dev *dev, int id)
|
|
|
{
|
|
|
int i;
|
|
|
int rc = -ENOMEM;
|
|
@@ -134,7 +134,7 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
|
|
|
|
|
|
virtfn->devfn = pci_iov_virtfn_devfn(dev, id);
|
|
|
virtfn->vendor = dev->vendor;
|
|
|
- pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device);
|
|
|
+ virtfn->device = iov->vf_device;
|
|
|
rc = pci_setup_device(virtfn);
|
|
|
if (rc)
|
|
|
goto failed0;
|
|
@@ -157,12 +157,8 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
|
|
|
BUG_ON(rc);
|
|
|
}
|
|
|
|
|
|
- if (reset)
|
|
|
- __pci_reset_function(virtfn);
|
|
|
-
|
|
|
pci_device_add(virtfn, virtfn->bus);
|
|
|
|
|
|
- pci_bus_add_device(virtfn);
|
|
|
sprintf(buf, "virtfn%u", id);
|
|
|
rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
|
|
|
if (rc)
|
|
@@ -173,6 +169,8 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
|
|
|
|
|
|
kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
|
|
|
|
|
|
+ pci_bus_add_device(virtfn);
|
|
|
+
|
|
|
return 0;
|
|
|
|
|
|
failed2:
|
|
@@ -187,7 +185,7 @@ failed:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset)
|
|
|
+void pci_iov_remove_virtfn(struct pci_dev *dev, int id)
|
|
|
{
|
|
|
char buf[VIRTFN_ID_LEN];
|
|
|
struct pci_dev *virtfn;
|
|
@@ -198,11 +196,6 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset)
|
|
|
if (!virtfn)
|
|
|
return;
|
|
|
|
|
|
- if (reset) {
|
|
|
- device_release_driver(&virtfn->dev);
|
|
|
- __pci_reset_function(virtfn);
|
|
|
- }
|
|
|
-
|
|
|
sprintf(buf, "virtfn%u", id);
|
|
|
sysfs_remove_link(&dev->dev.kobj, buf);
|
|
|
/*
|
|
@@ -317,7 +310,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
|
|
|
pci_cfg_access_unlock(dev);
|
|
|
|
|
|
for (i = 0; i < initial; i++) {
|
|
|
- rc = pci_iov_add_virtfn(dev, i, 0);
|
|
|
+ rc = pci_iov_add_virtfn(dev, i);
|
|
|
if (rc)
|
|
|
goto failed;
|
|
|
}
|
|
@@ -329,7 +322,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
|
|
|
|
|
|
failed:
|
|
|
while (i--)
|
|
|
- pci_iov_remove_virtfn(dev, i, 0);
|
|
|
+ pci_iov_remove_virtfn(dev, i);
|
|
|
|
|
|
err_pcibios:
|
|
|
iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
|
|
@@ -356,7 +349,7 @@ static void sriov_disable(struct pci_dev *dev)
|
|
|
return;
|
|
|
|
|
|
for (i = 0; i < iov->num_VFs; i++)
|
|
|
- pci_iov_remove_virtfn(dev, i, 0);
|
|
|
+ pci_iov_remove_virtfn(dev, i);
|
|
|
|
|
|
iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
|
|
|
pci_cfg_access_lock(dev);
|
|
@@ -449,6 +442,7 @@ found:
|
|
|
iov->nres = nres;
|
|
|
iov->ctrl = ctrl;
|
|
|
iov->total_VFs = total;
|
|
|
+ pci_read_config_word(dev, pos + PCI_SRIOV_VF_DID, &iov->vf_device);
|
|
|
iov->pgsz = pgsz;
|
|
|
iov->self = dev;
|
|
|
iov->drivers_autoprobe = true;
|
|
@@ -504,6 +498,14 @@ static void sriov_restore_state(struct pci_dev *dev)
|
|
|
if (ctrl & PCI_SRIOV_CTRL_VFE)
|
|
|
return;
|
|
|
|
|
|
+ /*
|
|
|
+ * Restore PCI_SRIOV_CTRL_ARI before pci_iov_set_numvfs() because
|
|
|
+ * it reads offset & stride, which depend on PCI_SRIOV_CTRL_ARI.
|
|
|
+ */
|
|
|
+ ctrl &= ~PCI_SRIOV_CTRL_ARI;
|
|
|
+ ctrl |= iov->ctrl & PCI_SRIOV_CTRL_ARI;
|
|
|
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, ctrl);
|
|
|
+
|
|
|
for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++)
|
|
|
pci_update_resource(dev, i);
|
|
|
|
|
@@ -724,7 +726,7 @@ int pci_vfs_assigned(struct pci_dev *dev)
|
|
|
* determine the device ID for the VFs, the vendor ID will be the
|
|
|
* same as the PF so there is no need to check for that one
|
|
|
*/
|
|
|
- pci_read_config_word(dev, dev->sriov->pos + PCI_SRIOV_VF_DID, &dev_id);
|
|
|
+ dev_id = dev->sriov->vf_device;
|
|
|
|
|
|
/* loop through all the VFs to see if we own any that are assigned */
|
|
|
vfdev = pci_get_device(dev->vendor, dev_id, NULL);
|