diff options
Diffstat (limited to 'drivers/pci/iov.c')
-rw-r--r-- | drivers/pci/iov.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index ac41c8be9200..6bacb8995e96 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -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); |