diff options
| author | Bjorn Helgaas <bhelgaas@google.com> | 2017-11-14 13:11:26 -0500 |
|---|---|---|
| committer | Bjorn Helgaas <bhelgaas@google.com> | 2017-11-14 13:11:26 -0500 |
| commit | 9ceb09cce1a30bdbcff861d1bbbbe0dbb7de05de (patch) | |
| tree | 4dd0b996582d61d658ae8552e355351483f5be21 | |
| parent | 9af21ac53f970b1be81c1e1ca629da74a771a036 (diff) | |
| parent | 832c418a1530afba54fd96a2cca0912ec9036080 (diff) | |
Merge branch 'pci/virtualization' into next
* pci/virtualization:
PCI: Document reset method return values
PCI: Detach driver before procfs & sysfs teardown on device remove
PCI: Apply Cavium ThunderX ACS quirk to more Root Ports
PCI: Set Cavium ACS capability quirk flags to assert RR/CR/SV/UF
PCI: Restore ARI Capable Hierarchy before setting numVFs
PCI: Create SR-IOV virtfn/physfn links before attaching driver
PCI: Expose SR-IOV offset, stride, and VF device ID via sysfs
PCI: Cache the VF device ID in the SR-IOV structure
PCI: Add Kconfig PCI_IOV dependency for PCI_REALLOC_ENABLE_AUTO
PCI: Remove unused function __pci_reset_function()
PCI: Remove reset argument from pci_iov_{add,remove}_virtfn()
| -rw-r--r-- | arch/powerpc/kernel/eeh_driver.c | 4 | ||||
| -rw-r--r-- | drivers/pci/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/pci/iov.c | 34 | ||||
| -rw-r--r-- | drivers/pci/pci-sysfs.c | 33 | ||||
| -rw-r--r-- | drivers/pci/pci.c | 43 | ||||
| -rw-r--r-- | drivers/pci/pci.h | 1 | ||||
| -rw-r--r-- | drivers/pci/quirks.c | 27 | ||||
| -rw-r--r-- | drivers/pci/remove.c | 2 | ||||
| -rw-r--r-- | include/linux/pci.h | 9 |
9 files changed, 95 insertions, 66 deletions
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 8b840191df59..4e1b433f6cb5 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c | |||
| @@ -441,7 +441,7 @@ static void *eeh_add_virt_device(void *data, void *userdata) | |||
| 441 | } | 441 | } |
| 442 | 442 | ||
| 443 | #ifdef CONFIG_PPC_POWERNV | 443 | #ifdef CONFIG_PPC_POWERNV |
| 444 | pci_iov_add_virtfn(edev->physfn, pdn->vf_index, 0); | 444 | pci_iov_add_virtfn(edev->physfn, pdn->vf_index); |
| 445 | #endif | 445 | #endif |
| 446 | return NULL; | 446 | return NULL; |
| 447 | } | 447 | } |
| @@ -499,7 +499,7 @@ static void *eeh_rmv_device(void *data, void *userdata) | |||
| 499 | #ifdef CONFIG_PPC_POWERNV | 499 | #ifdef CONFIG_PPC_POWERNV |
| 500 | struct pci_dn *pdn = eeh_dev_to_pdn(edev); | 500 | struct pci_dn *pdn = eeh_dev_to_pdn(edev); |
| 501 | 501 | ||
| 502 | pci_iov_remove_virtfn(edev->physfn, pdn->vf_index, 0); | 502 | pci_iov_remove_virtfn(edev->physfn, pdn->vf_index); |
| 503 | edev->pdev = NULL; | 503 | edev->pdev = NULL; |
| 504 | 504 | ||
| 505 | /* | 505 | /* |
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 658d40af887a..90944667ccea 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
| @@ -51,13 +51,13 @@ config PCI_DEBUG | |||
| 51 | config PCI_REALLOC_ENABLE_AUTO | 51 | config PCI_REALLOC_ENABLE_AUTO |
| 52 | bool "Enable PCI resource re-allocation detection" | 52 | bool "Enable PCI resource re-allocation detection" |
| 53 | depends on PCI | 53 | depends on PCI |
| 54 | depends on PCI_IOV | ||
| 54 | help | 55 | help |
| 55 | Say Y here if you want the PCI core to detect if PCI resource | 56 | Say Y here if you want the PCI core to detect if PCI resource |
| 56 | re-allocation needs to be enabled. You can always use pci=realloc=on | 57 | re-allocation needs to be enabled. You can always use pci=realloc=on |
| 57 | or pci=realloc=off to override it. Note this feature is a no-op | 58 | or pci=realloc=off to override it. It will automatically |
| 58 | unless PCI_IOV support is also enabled; in that case it will | 59 | re-allocate PCI resources if SR-IOV BARs have not been allocated by |
| 59 | automatically re-allocate PCI resources if SR-IOV BARs have not | 60 | the BIOS. |
| 60 | been allocated by the BIOS. | ||
| 61 | 61 | ||
| 62 | When in doubt, say N. | 62 | When in doubt, say N. |
| 63 | 63 | ||
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) | |||
| 113 | return dev->sriov->barsz[resno - PCI_IOV_RESOURCES]; | 113 | return dev->sriov->barsz[resno - PCI_IOV_RESOURCES]; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) | 116 | int pci_iov_add_virtfn(struct pci_dev *dev, int id) |
| 117 | { | 117 | { |
| 118 | int i; | 118 | int i; |
| 119 | int rc = -ENOMEM; | 119 | int rc = -ENOMEM; |
| @@ -134,7 +134,7 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) | |||
| 134 | 134 | ||
| 135 | virtfn->devfn = pci_iov_virtfn_devfn(dev, id); | 135 | virtfn->devfn = pci_iov_virtfn_devfn(dev, id); |
| 136 | virtfn->vendor = dev->vendor; | 136 | virtfn->vendor = dev->vendor; |
| 137 | pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device); | 137 | virtfn->device = iov->vf_device; |
| 138 | rc = pci_setup_device(virtfn); | 138 | rc = pci_setup_device(virtfn); |
| 139 | if (rc) | 139 | if (rc) |
| 140 | goto failed0; | 140 | goto failed0; |
| @@ -157,12 +157,8 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) | |||
| 157 | BUG_ON(rc); | 157 | BUG_ON(rc); |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | if (reset) | ||
| 161 | __pci_reset_function(virtfn); | ||
| 162 | |||
| 163 | pci_device_add(virtfn, virtfn->bus); | 160 | pci_device_add(virtfn, virtfn->bus); |
| 164 | 161 | ||
| 165 | pci_bus_add_device(virtfn); | ||
| 166 | sprintf(buf, "virtfn%u", id); | 162 | sprintf(buf, "virtfn%u", id); |
| 167 | rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); | 163 | rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); |
| 168 | if (rc) | 164 | if (rc) |
| @@ -173,6 +169,8 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) | |||
| 173 | 169 | ||
| 174 | kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE); | 170 | kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE); |
| 175 | 171 | ||
| 172 | pci_bus_add_device(virtfn); | ||
| 173 | |||
| 176 | return 0; | 174 | return 0; |
| 177 | 175 | ||
| 178 | failed2: | 176 | failed2: |
| @@ -187,7 +185,7 @@ failed: | |||
| 187 | return rc; | 185 | return rc; |
| 188 | } | 186 | } |
| 189 | 187 | ||
| 190 | void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset) | 188 | void pci_iov_remove_virtfn(struct pci_dev *dev, int id) |
| 191 | { | 189 | { |
| 192 | char buf[VIRTFN_ID_LEN]; | 190 | char buf[VIRTFN_ID_LEN]; |
| 193 | struct pci_dev *virtfn; | 191 | struct pci_dev *virtfn; |
| @@ -198,11 +196,6 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset) | |||
| 198 | if (!virtfn) | 196 | if (!virtfn) |
| 199 | return; | 197 | return; |
| 200 | 198 | ||
| 201 | if (reset) { | ||
| 202 | device_release_driver(&virtfn->dev); | ||
| 203 | __pci_reset_function(virtfn); | ||
| 204 | } | ||
| 205 | |||
| 206 | sprintf(buf, "virtfn%u", id); | 199 | sprintf(buf, "virtfn%u", id); |
| 207 | sysfs_remove_link(&dev->dev.kobj, buf); | 200 | sysfs_remove_link(&dev->dev.kobj, buf); |
| 208 | /* | 201 | /* |
| @@ -317,7 +310,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
| 317 | pci_cfg_access_unlock(dev); | 310 | pci_cfg_access_unlock(dev); |
| 318 | 311 | ||
| 319 | for (i = 0; i < initial; i++) { | 312 | for (i = 0; i < initial; i++) { |
| 320 | rc = pci_iov_add_virtfn(dev, i, 0); | 313 | rc = pci_iov_add_virtfn(dev, i); |
| 321 | if (rc) | 314 | if (rc) |
| 322 | goto failed; | 315 | goto failed; |
| 323 | } | 316 | } |
| @@ -329,7 +322,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
| 329 | 322 | ||
| 330 | failed: | 323 | failed: |
| 331 | while (i--) | 324 | while (i--) |
| 332 | pci_iov_remove_virtfn(dev, i, 0); | 325 | pci_iov_remove_virtfn(dev, i); |
| 333 | 326 | ||
| 334 | err_pcibios: | 327 | err_pcibios: |
| 335 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); | 328 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); |
| @@ -356,7 +349,7 @@ static void sriov_disable(struct pci_dev *dev) | |||
| 356 | return; | 349 | return; |
| 357 | 350 | ||
| 358 | for (i = 0; i < iov->num_VFs; i++) | 351 | for (i = 0; i < iov->num_VFs; i++) |
| 359 | pci_iov_remove_virtfn(dev, i, 0); | 352 | pci_iov_remove_virtfn(dev, i); |
| 360 | 353 | ||
| 361 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); | 354 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); |
| 362 | pci_cfg_access_lock(dev); | 355 | pci_cfg_access_lock(dev); |
| @@ -449,6 +442,7 @@ found: | |||
| 449 | iov->nres = nres; | 442 | iov->nres = nres; |
| 450 | iov->ctrl = ctrl; | 443 | iov->ctrl = ctrl; |
| 451 | iov->total_VFs = total; | 444 | iov->total_VFs = total; |
| 445 | pci_read_config_word(dev, pos + PCI_SRIOV_VF_DID, &iov->vf_device); | ||
| 452 | iov->pgsz = pgsz; | 446 | iov->pgsz = pgsz; |
| 453 | iov->self = dev; | 447 | iov->self = dev; |
| 454 | iov->drivers_autoprobe = true; | 448 | iov->drivers_autoprobe = true; |
| @@ -504,6 +498,14 @@ static void sriov_restore_state(struct pci_dev *dev) | |||
| 504 | if (ctrl & PCI_SRIOV_CTRL_VFE) | 498 | if (ctrl & PCI_SRIOV_CTRL_VFE) |
| 505 | return; | 499 | return; |
| 506 | 500 | ||
| 501 | /* | ||
| 502 | * Restore PCI_SRIOV_CTRL_ARI before pci_iov_set_numvfs() because | ||
| 503 | * it reads offset & stride, which depend on PCI_SRIOV_CTRL_ARI. | ||
| 504 | */ | ||
| 505 | ctrl &= ~PCI_SRIOV_CTRL_ARI; | ||
| 506 | ctrl |= iov->ctrl & PCI_SRIOV_CTRL_ARI; | ||
| 507 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, ctrl); | ||
| 508 | |||
| 507 | for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) | 509 | for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) |
| 508 | pci_update_resource(dev, i); | 510 | pci_update_resource(dev, i); |
| 509 | 511 | ||
| @@ -724,7 +726,7 @@ int pci_vfs_assigned(struct pci_dev *dev) | |||
| 724 | * determine the device ID for the VFs, the vendor ID will be the | 726 | * determine the device ID for the VFs, the vendor ID will be the |
| 725 | * same as the PF so there is no need to check for that one | 727 | * same as the PF so there is no need to check for that one |
| 726 | */ | 728 | */ |
| 727 | pci_read_config_word(dev, dev->sriov->pos + PCI_SRIOV_VF_DID, &dev_id); | 729 | dev_id = dev->sriov->vf_device; |
| 728 | 730 | ||
| 729 | /* loop through all the VFs to see if we own any that are assigned */ | 731 | /* loop through all the VFs to see if we own any that are assigned */ |
| 730 | vfdev = pci_get_device(dev->vendor, dev_id, NULL); | 732 | vfdev = pci_get_device(dev->vendor, dev_id, NULL); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 5aa81ad91a88..720090967444 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
| @@ -648,6 +648,33 @@ exit: | |||
| 648 | return count; | 648 | return count; |
| 649 | } | 649 | } |
| 650 | 650 | ||
| 651 | static ssize_t sriov_offset_show(struct device *dev, | ||
| 652 | struct device_attribute *attr, | ||
| 653 | char *buf) | ||
| 654 | { | ||
| 655 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 656 | |||
| 657 | return sprintf(buf, "%u\n", pdev->sriov->offset); | ||
| 658 | } | ||
| 659 | |||
| 660 | static ssize_t sriov_stride_show(struct device *dev, | ||
| 661 | struct device_attribute *attr, | ||
| 662 | char *buf) | ||
| 663 | { | ||
| 664 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 665 | |||
| 666 | return sprintf(buf, "%u\n", pdev->sriov->stride); | ||
| 667 | } | ||
| 668 | |||
| 669 | static ssize_t sriov_vf_device_show(struct device *dev, | ||
| 670 | struct device_attribute *attr, | ||
| 671 | char *buf) | ||
| 672 | { | ||
| 673 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 674 | |||
| 675 | return sprintf(buf, "%x\n", pdev->sriov->vf_device); | ||
| 676 | } | ||
| 677 | |||
| 651 | static ssize_t sriov_drivers_autoprobe_show(struct device *dev, | 678 | static ssize_t sriov_drivers_autoprobe_show(struct device *dev, |
| 652 | struct device_attribute *attr, | 679 | struct device_attribute *attr, |
| 653 | char *buf) | 680 | char *buf) |
| @@ -676,6 +703,9 @@ static struct device_attribute sriov_totalvfs_attr = __ATTR_RO(sriov_totalvfs); | |||
| 676 | static struct device_attribute sriov_numvfs_attr = | 703 | static struct device_attribute sriov_numvfs_attr = |
| 677 | __ATTR(sriov_numvfs, (S_IRUGO|S_IWUSR|S_IWGRP), | 704 | __ATTR(sriov_numvfs, (S_IRUGO|S_IWUSR|S_IWGRP), |
| 678 | sriov_numvfs_show, sriov_numvfs_store); | 705 | sriov_numvfs_show, sriov_numvfs_store); |
| 706 | static struct device_attribute sriov_offset_attr = __ATTR_RO(sriov_offset); | ||
| 707 | static struct device_attribute sriov_stride_attr = __ATTR_RO(sriov_stride); | ||
| 708 | static struct device_attribute sriov_vf_device_attr = __ATTR_RO(sriov_vf_device); | ||
| 679 | static struct device_attribute sriov_drivers_autoprobe_attr = | 709 | static struct device_attribute sriov_drivers_autoprobe_attr = |
| 680 | __ATTR(sriov_drivers_autoprobe, (S_IRUGO|S_IWUSR|S_IWGRP), | 710 | __ATTR(sriov_drivers_autoprobe, (S_IRUGO|S_IWUSR|S_IWGRP), |
| 681 | sriov_drivers_autoprobe_show, sriov_drivers_autoprobe_store); | 711 | sriov_drivers_autoprobe_show, sriov_drivers_autoprobe_store); |
| @@ -1748,6 +1778,9 @@ static const struct attribute_group pci_dev_hp_attr_group = { | |||
| 1748 | static struct attribute *sriov_dev_attrs[] = { | 1778 | static struct attribute *sriov_dev_attrs[] = { |
| 1749 | &sriov_totalvfs_attr.attr, | 1779 | &sriov_totalvfs_attr.attr, |
| 1750 | &sriov_numvfs_attr.attr, | 1780 | &sriov_numvfs_attr.attr, |
| 1781 | &sriov_offset_attr.attr, | ||
| 1782 | &sriov_stride_attr.attr, | ||
| 1783 | &sriov_vf_device_attr.attr, | ||
| 1751 | &sriov_drivers_autoprobe_attr.attr, | 1784 | &sriov_drivers_autoprobe_attr.attr, |
| 1752 | NULL, | 1785 | NULL, |
| 1753 | }; | 1786 | }; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c5172b01164d..50f148f154ab 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -4247,35 +4247,6 @@ static void pci_dev_restore(struct pci_dev *dev) | |||
| 4247 | } | 4247 | } |
| 4248 | 4248 | ||
| 4249 | /** | 4249 | /** |
| 4250 | * __pci_reset_function - reset a PCI device function | ||
| 4251 | * @dev: PCI device to reset | ||
| 4252 | * | ||
| 4253 | * Some devices allow an individual function to be reset without affecting | ||
| 4254 | * other functions in the same device. The PCI device must be responsive | ||
| 4255 | * to PCI config space in order to use this function. | ||
| 4256 | * | ||
| 4257 | * The device function is presumed to be unused when this function is called. | ||
| 4258 | * Resetting the device will make the contents of PCI configuration space | ||
| 4259 | * random, so any caller of this must be prepared to reinitialise the | ||
| 4260 | * device including MSI, bus mastering, BARs, decoding IO and memory spaces, | ||
| 4261 | * etc. | ||
| 4262 | * | ||
| 4263 | * Returns 0 if the device function was successfully reset or negative if the | ||
| 4264 | * device doesn't support resetting a single function. | ||
| 4265 | */ | ||
| 4266 | int __pci_reset_function(struct pci_dev *dev) | ||
| 4267 | { | ||
| 4268 | int ret; | ||
| 4269 | |||
| 4270 | pci_dev_lock(dev); | ||
| 4271 | ret = __pci_reset_function_locked(dev); | ||
| 4272 | pci_dev_unlock(dev); | ||
| 4273 | |||
| 4274 | return ret; | ||
| 4275 | } | ||
| 4276 | EXPORT_SYMBOL_GPL(__pci_reset_function); | ||
| 4277 | |||
| 4278 | /** | ||
| 4279 | * __pci_reset_function_locked - reset a PCI device function while holding | 4250 | * __pci_reset_function_locked - reset a PCI device function while holding |
| 4280 | * the @dev mutex lock. | 4251 | * the @dev mutex lock. |
| 4281 | * @dev: PCI device to reset | 4252 | * @dev: PCI device to reset |
| @@ -4300,6 +4271,14 @@ int __pci_reset_function_locked(struct pci_dev *dev) | |||
| 4300 | 4271 | ||
| 4301 | might_sleep(); | 4272 | might_sleep(); |
| 4302 | 4273 | ||
| 4274 | /* | ||
| 4275 | * A reset method returns -ENOTTY if it doesn't support this device | ||
| 4276 | * and we should try the next method. | ||
| 4277 | * | ||
| 4278 | * If it returns 0 (success), we're finished. If it returns any | ||
| 4279 | * other error, we're also finished: this indicates that further | ||
| 4280 | * reset mechanisms might be broken on the device. | ||
| 4281 | */ | ||
| 4303 | rc = pci_dev_specific_reset(dev, 0); | 4282 | rc = pci_dev_specific_reset(dev, 0); |
| 4304 | if (rc != -ENOTTY) | 4283 | if (rc != -ENOTTY) |
| 4305 | return rc; | 4284 | return rc; |
| @@ -4365,8 +4344,8 @@ int pci_probe_reset_function(struct pci_dev *dev) | |||
| 4365 | * | 4344 | * |
| 4366 | * This function does not just reset the PCI portion of a device, but | 4345 | * This function does not just reset the PCI portion of a device, but |
| 4367 | * clears all the state associated with the device. This function differs | 4346 | * clears all the state associated with the device. This function differs |
| 4368 | * from __pci_reset_function in that it saves and restores device state | 4347 | * from __pci_reset_function_locked() in that it saves and restores device state |
| 4369 | * over the reset. | 4348 | * over the reset and takes the PCI device lock. |
| 4370 | * | 4349 | * |
| 4371 | * Returns 0 if the device function was successfully reset or negative if the | 4350 | * Returns 0 if the device function was successfully reset or negative if the |
| 4372 | * device doesn't support resetting a single function. | 4351 | * device doesn't support resetting a single function. |
| @@ -4401,7 +4380,7 @@ EXPORT_SYMBOL_GPL(pci_reset_function); | |||
| 4401 | * | 4380 | * |
| 4402 | * This function does not just reset the PCI portion of a device, but | 4381 | * This function does not just reset the PCI portion of a device, but |
| 4403 | * clears all the state associated with the device. This function differs | 4382 | * clears all the state associated with the device. This function differs |
| 4404 | * from __pci_reset_function() in that it saves and restores device state | 4383 | * from __pci_reset_function_locked() in that it saves and restores device state |
| 4405 | * over the reset. It also differs from pci_reset_function() in that it | 4384 | * over the reset. It also differs from pci_reset_function() in that it |
| 4406 | * requires the PCI device lock to be held. | 4385 | * requires the PCI device lock to be held. |
| 4407 | * | 4386 | * |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 186278fa6917..39eaacd122d8 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -263,6 +263,7 @@ struct pci_sriov { | |||
| 263 | u16 num_VFs; /* number of VFs available */ | 263 | u16 num_VFs; /* number of VFs available */ |
| 264 | u16 offset; /* first VF Routing ID offset */ | 264 | u16 offset; /* first VF Routing ID offset */ |
| 265 | u16 stride; /* following VF stride */ | 265 | u16 stride; /* following VF stride */ |
| 266 | u16 vf_device; /* VF device ID */ | ||
| 266 | u32 pgsz; /* page size for BAR alignment */ | 267 | u32 pgsz; /* page size for BAR alignment */ |
| 267 | u8 link; /* Function Dependency Link */ | 268 | u8 link; /* Function Dependency Link */ |
| 268 | u8 max_VF_buses; /* max buses consumed by VFs */ | 269 | u8 max_VF_buses; /* max buses consumed by VFs */ |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index a4d33619a7bb..0e22cce05742 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -4211,17 +4211,32 @@ static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags) | |||
| 4211 | #endif | 4211 | #endif |
| 4212 | } | 4212 | } |
| 4213 | 4213 | ||
| 4214 | static bool pci_quirk_cavium_acs_match(struct pci_dev *dev) | ||
| 4215 | { | ||
| 4216 | /* | ||
| 4217 | * Effectively selects all downstream ports for whole ThunderX 1 | ||
| 4218 | * family by 0xf800 mask (which represents 8 SoCs), while the lower | ||
| 4219 | * bits of device ID are used to indicate which subdevice is used | ||
| 4220 | * within the SoC. | ||
| 4221 | */ | ||
| 4222 | return (pci_is_pcie(dev) && | ||
| 4223 | (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) && | ||
| 4224 | ((dev->device & 0xf800) == 0xa000)); | ||
| 4225 | } | ||
| 4226 | |||
| 4214 | static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags) | 4227 | static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags) |
| 4215 | { | 4228 | { |
| 4216 | /* | 4229 | /* |
| 4217 | * Cavium devices matching this quirk do not perform peer-to-peer | 4230 | * Cavium root ports don't advertise an ACS capability. However, |
| 4218 | * with other functions, allowing masking out these bits as if they | 4231 | * the RTL internally implements similar protection as if ACS had |
| 4219 | * were unimplemented in the ACS capability. | 4232 | * Request Redirection, Completion Redirection, Source Validation, |
| 4233 | * and Upstream Forwarding features enabled. Assert that the | ||
| 4234 | * hardware implements and enables equivalent ACS functionality for | ||
| 4235 | * these flags. | ||
| 4220 | */ | 4236 | */ |
| 4221 | acs_flags &= ~(PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR | | 4237 | acs_flags &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_SV | PCI_ACS_UF); |
| 4222 | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT); | ||
| 4223 | 4238 | ||
| 4224 | if (!((dev->device >= 0xa000) && (dev->device <= 0xa0ff))) | 4239 | if (!pci_quirk_cavium_acs_match(dev)) |
| 4225 | return -ENOTTY; | 4240 | return -ENOTTY; |
| 4226 | 4241 | ||
| 4227 | return acs_flags ? 0 : 1; | 4242 | return acs_flags ? 0 : 1; |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 73a03d382590..2fa0dbde36b7 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
| @@ -19,9 +19,9 @@ static void pci_stop_dev(struct pci_dev *dev) | |||
| 19 | pci_pme_active(dev, false); | 19 | pci_pme_active(dev, false); |
| 20 | 20 | ||
| 21 | if (dev->is_added) { | 21 | if (dev->is_added) { |
| 22 | device_release_driver(&dev->dev); | ||
| 22 | pci_proc_detach_device(dev); | 23 | pci_proc_detach_device(dev); |
| 23 | pci_remove_sysfs_dev_files(dev); | 24 | pci_remove_sysfs_dev_files(dev); |
| 24 | device_release_driver(&dev->dev); | ||
| 25 | dev->is_added = 0; | 25 | dev->is_added = 0; |
| 26 | } | 26 | } |
| 27 | 27 | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index f3b6909305ca..d85c626e1228 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -1093,7 +1093,6 @@ int pcie_set_mps(struct pci_dev *dev, int mps); | |||
| 1093 | int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed, | 1093 | int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed, |
| 1094 | enum pcie_link_width *width); | 1094 | enum pcie_link_width *width); |
| 1095 | void pcie_flr(struct pci_dev *dev); | 1095 | void pcie_flr(struct pci_dev *dev); |
| 1096 | int __pci_reset_function(struct pci_dev *dev); | ||
| 1097 | int __pci_reset_function_locked(struct pci_dev *dev); | 1096 | int __pci_reset_function_locked(struct pci_dev *dev); |
| 1098 | int pci_reset_function(struct pci_dev *dev); | 1097 | int pci_reset_function(struct pci_dev *dev); |
| 1099 | int pci_reset_function_locked(struct pci_dev *dev); | 1098 | int pci_reset_function_locked(struct pci_dev *dev); |
| @@ -1965,8 +1964,8 @@ int pci_iov_virtfn_devfn(struct pci_dev *dev, int id); | |||
| 1965 | 1964 | ||
| 1966 | int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); | 1965 | int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); |
| 1967 | void pci_disable_sriov(struct pci_dev *dev); | 1966 | void pci_disable_sriov(struct pci_dev *dev); |
| 1968 | int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset); | 1967 | int pci_iov_add_virtfn(struct pci_dev *dev, int id); |
| 1969 | void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset); | 1968 | void pci_iov_remove_virtfn(struct pci_dev *dev, int id); |
| 1970 | int pci_num_vf(struct pci_dev *dev); | 1969 | int pci_num_vf(struct pci_dev *dev); |
| 1971 | int pci_vfs_assigned(struct pci_dev *dev); | 1970 | int pci_vfs_assigned(struct pci_dev *dev); |
| 1972 | int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); | 1971 | int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); |
| @@ -1983,12 +1982,12 @@ static inline int pci_iov_virtfn_devfn(struct pci_dev *dev, int id) | |||
| 1983 | } | 1982 | } |
| 1984 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) | 1983 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) |
| 1985 | { return -ENODEV; } | 1984 | { return -ENODEV; } |
| 1986 | static inline int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) | 1985 | static inline int pci_iov_add_virtfn(struct pci_dev *dev, int id) |
| 1987 | { | 1986 | { |
| 1988 | return -ENOSYS; | 1987 | return -ENOSYS; |
| 1989 | } | 1988 | } |
| 1990 | static inline void pci_iov_remove_virtfn(struct pci_dev *dev, | 1989 | static inline void pci_iov_remove_virtfn(struct pci_dev *dev, |
| 1991 | int id, int reset) { } | 1990 | int id) { } |
| 1992 | static inline void pci_disable_sriov(struct pci_dev *dev) { } | 1991 | static inline void pci_disable_sriov(struct pci_dev *dev) { } |
| 1993 | static inline int pci_num_vf(struct pci_dev *dev) { return 0; } | 1992 | static inline int pci_num_vf(struct pci_dev *dev) { return 0; } |
| 1994 | static inline int pci_vfs_assigned(struct pci_dev *dev) | 1993 | static inline int pci_vfs_assigned(struct pci_dev *dev) |
