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) |