Commit d91cdc745524a1b1ff537712a62803b8413c12d6
Committed by
Jesse Barnes
1 parent
1a9271331a
Exists in
master
and in
4 other branches
PCI: Refactor pci_reset_function()
Separate out function level reset so that pci_reset_function can be more easily extended. Signed-off-by: Sheng Yang <sheng@linux.intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Showing 1 changed file with 40 additions and 26 deletions Side-by-side Diff
drivers/pci/pci.c
... | ... | @@ -1751,24 +1751,7 @@ |
1751 | 1751 | EXPORT_SYMBOL(pci_set_dma_seg_boundary); |
1752 | 1752 | #endif |
1753 | 1753 | |
1754 | -/** | |
1755 | - * pci_execute_reset_function() - Reset a PCI device function | |
1756 | - * @dev: Device function to reset | |
1757 | - * | |
1758 | - * Some devices allow an individual function to be reset without affecting | |
1759 | - * other functions in the same device. The PCI device must be responsive | |
1760 | - * to PCI config space in order to use this function. | |
1761 | - * | |
1762 | - * The device function is presumed to be unused when this function is called. | |
1763 | - * Resetting the device will make the contents of PCI configuration space | |
1764 | - * random, so any caller of this must be prepared to reinitialise the | |
1765 | - * device including MSI, bus mastering, BARs, decoding IO and memory spaces, | |
1766 | - * etc. | |
1767 | - * | |
1768 | - * Returns 0 if the device function was successfully reset or -ENOTTY if the | |
1769 | - * device doesn't support resetting a single function. | |
1770 | - */ | |
1771 | -int pci_execute_reset_function(struct pci_dev *dev) | |
1754 | +static int __pcie_flr(struct pci_dev *dev, int probe) | |
1772 | 1755 | { |
1773 | 1756 | u16 status; |
1774 | 1757 | u32 cap; |
... | ... | @@ -1780,6 +1763,9 @@ |
1780 | 1763 | if (!(cap & PCI_EXP_DEVCAP_FLR)) |
1781 | 1764 | return -ENOTTY; |
1782 | 1765 | |
1766 | + if (probe) | |
1767 | + return 0; | |
1768 | + | |
1783 | 1769 | pci_block_user_cfg_access(dev); |
1784 | 1770 | |
1785 | 1771 | /* Wait for Transaction Pending bit clean */ |
... | ... | @@ -1802,6 +1788,39 @@ |
1802 | 1788 | pci_unblock_user_cfg_access(dev); |
1803 | 1789 | return 0; |
1804 | 1790 | } |
1791 | + | |
1792 | +static int __pci_reset_function(struct pci_dev *pdev, int probe) | |
1793 | +{ | |
1794 | + int res; | |
1795 | + | |
1796 | + res = __pcie_flr(pdev, probe); | |
1797 | + if (res != -ENOTTY) | |
1798 | + return res; | |
1799 | + | |
1800 | + return res; | |
1801 | +} | |
1802 | + | |
1803 | +/** | |
1804 | + * pci_execute_reset_function() - Reset a PCI device function | |
1805 | + * @dev: Device function to reset | |
1806 | + * | |
1807 | + * Some devices allow an individual function to be reset without affecting | |
1808 | + * other functions in the same device. The PCI device must be responsive | |
1809 | + * to PCI config space in order to use this function. | |
1810 | + * | |
1811 | + * The device function is presumed to be unused when this function is called. | |
1812 | + * Resetting the device will make the contents of PCI configuration space | |
1813 | + * random, so any caller of this must be prepared to reinitialise the | |
1814 | + * device including MSI, bus mastering, BARs, decoding IO and memory spaces, | |
1815 | + * etc. | |
1816 | + * | |
1817 | + * Returns 0 if the device function was successfully reset or -ENOTTY if the | |
1818 | + * device doesn't support resetting a single function. | |
1819 | + */ | |
1820 | +int pci_execute_reset_function(struct pci_dev *dev) | |
1821 | +{ | |
1822 | + return __pci_reset_function(dev, 0); | |
1823 | +} | |
1805 | 1824 | EXPORT_SYMBOL_GPL(pci_execute_reset_function); |
1806 | 1825 | |
1807 | 1826 | /** |
1808 | 1827 | |
... | ... | @@ -1822,15 +1841,10 @@ |
1822 | 1841 | */ |
1823 | 1842 | int pci_reset_function(struct pci_dev *dev) |
1824 | 1843 | { |
1825 | - u32 cap; | |
1826 | - int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP); | |
1827 | - int r; | |
1844 | + int r = __pci_reset_function(dev, 1); | |
1828 | 1845 | |
1829 | - if (!exppos) | |
1830 | - return -ENOTTY; | |
1831 | - pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap); | |
1832 | - if (!(cap & PCI_EXP_DEVCAP_FLR)) | |
1833 | - return -ENOTTY; | |
1846 | + if (r < 0) | |
1847 | + return r; | |
1834 | 1848 | |
1835 | 1849 | if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0) |
1836 | 1850 | disable_irq(dev->irq); |