diff options
author | Sheng Yang <sheng@linux.intel.com> | 2008-11-11 04:17:47 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-01-07 14:12:23 -0500 |
commit | d91cdc745524a1b1ff537712a62803b8413c12d6 (patch) | |
tree | 812c548b892990344a8f5e4b51ee83c501f4908b /drivers/pci/pci.c | |
parent | 1a9271331ab663f3c7cda78d86b884f2ea86d4d7 (diff) |
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>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 66 |
1 files changed, 40 insertions, 26 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 061d1ee0046a..62978f644a92 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1751,24 +1751,7 @@ int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask) | |||
1751 | EXPORT_SYMBOL(pci_set_dma_seg_boundary); | 1751 | EXPORT_SYMBOL(pci_set_dma_seg_boundary); |
1752 | #endif | 1752 | #endif |
1753 | 1753 | ||
1754 | /** | 1754 | static int __pcie_flr(struct pci_dev *dev, int probe) |
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) | ||
1772 | { | 1755 | { |
1773 | u16 status; | 1756 | u16 status; |
1774 | u32 cap; | 1757 | u32 cap; |
@@ -1780,6 +1763,9 @@ int pci_execute_reset_function(struct pci_dev *dev) | |||
1780 | if (!(cap & PCI_EXP_DEVCAP_FLR)) | 1763 | if (!(cap & PCI_EXP_DEVCAP_FLR)) |
1781 | return -ENOTTY; | 1764 | return -ENOTTY; |
1782 | 1765 | ||
1766 | if (probe) | ||
1767 | return 0; | ||
1768 | |||
1783 | pci_block_user_cfg_access(dev); | 1769 | pci_block_user_cfg_access(dev); |
1784 | 1770 | ||
1785 | /* Wait for Transaction Pending bit clean */ | 1771 | /* Wait for Transaction Pending bit clean */ |
@@ -1802,6 +1788,39 @@ int pci_execute_reset_function(struct pci_dev *dev) | |||
1802 | pci_unblock_user_cfg_access(dev); | 1788 | pci_unblock_user_cfg_access(dev); |
1803 | return 0; | 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 | EXPORT_SYMBOL_GPL(pci_execute_reset_function); | 1824 | EXPORT_SYMBOL_GPL(pci_execute_reset_function); |
1806 | 1825 | ||
1807 | /** | 1826 | /** |
@@ -1822,15 +1841,10 @@ EXPORT_SYMBOL_GPL(pci_execute_reset_function); | |||
1822 | */ | 1841 | */ |
1823 | int pci_reset_function(struct pci_dev *dev) | 1842 | int pci_reset_function(struct pci_dev *dev) |
1824 | { | 1843 | { |
1825 | u32 cap; | 1844 | int r = __pci_reset_function(dev, 1); |
1826 | int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
1827 | int r; | ||
1828 | 1845 | ||
1829 | if (!exppos) | 1846 | if (r < 0) |
1830 | return -ENOTTY; | 1847 | return r; |
1831 | pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap); | ||
1832 | if (!(cap & PCI_EXP_DEVCAP_FLR)) | ||
1833 | return -ENOTTY; | ||
1834 | 1848 | ||
1835 | if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0) | 1849 | if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0) |
1836 | disable_irq(dev->irq); | 1850 | disable_irq(dev->irq); |