aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci.c98
-rw-r--r--include/linux/pci.h2
-rw-r--r--include/linux/pci_regs.h2
3 files changed, 102 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index aee73cf251b6..533aeb5fcbe4 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -18,6 +18,7 @@
18#include <linux/log2.h> 18#include <linux/log2.h>
19#include <linux/pci-aspm.h> 19#include <linux/pci-aspm.h>
20#include <linux/pm_wakeup.h> 20#include <linux/pm_wakeup.h>
21#include <linux/interrupt.h>
21#include <asm/dma.h> /* isa_dma_bridge_buggy */ 22#include <asm/dma.h> /* isa_dma_bridge_buggy */
22#include "pci.h" 23#include "pci.h"
23 24
@@ -1746,6 +1747,103 @@ EXPORT_SYMBOL(pci_set_dma_seg_boundary);
1746#endif 1747#endif
1747 1748
1748/** 1749/**
1750 * pci_execute_reset_function() - Reset a PCI device function
1751 * @dev: Device function to reset
1752 *
1753 * Some devices allow an individual function to be reset without affecting
1754 * other functions in the same device. The PCI device must be responsive
1755 * to PCI config space in order to use this function.
1756 *
1757 * The device function is presumed to be unused when this function is called.
1758 * Resetting the device will make the contents of PCI configuration space
1759 * random, so any caller of this must be prepared to reinitialise the
1760 * device including MSI, bus mastering, BARs, decoding IO and memory spaces,
1761 * etc.
1762 *
1763 * Returns 0 if the device function was successfully reset or -ENOTTY if the
1764 * device doesn't support resetting a single function.
1765 */
1766int pci_execute_reset_function(struct pci_dev *dev)
1767{
1768 u16 status;
1769 u32 cap;
1770 int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
1771
1772 if (!exppos)
1773 return -ENOTTY;
1774 pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap);
1775 if (!(cap & PCI_EXP_DEVCAP_FLR))
1776 return -ENOTTY;
1777
1778 pci_block_user_cfg_access(dev);
1779
1780 /* Wait for Transaction Pending bit clean */
1781 msleep(100);
1782 pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
1783 if (status & PCI_EXP_DEVSTA_TRPND) {
1784 dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
1785 "sleeping for 1 second\n");
1786 ssleep(1);
1787 pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
1788 if (status & PCI_EXP_DEVSTA_TRPND)
1789 dev_info(&dev->dev, "Still busy after 1s; "
1790 "proceeding with reset anyway\n");
1791 }
1792
1793 pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
1794 PCI_EXP_DEVCTL_BCR_FLR);
1795 mdelay(100);
1796
1797 pci_unblock_user_cfg_access(dev);
1798 return 0;
1799}
1800EXPORT_SYMBOL_GPL(pci_execute_reset_function);
1801
1802/**
1803 * pci_reset_function() - quiesce and reset a PCI device function
1804 * @dev: Device function to reset
1805 *
1806 * Some devices allow an individual function to be reset without affecting
1807 * other functions in the same device. The PCI device must be responsive
1808 * to PCI config space in order to use this function.
1809 *
1810 * This function does not just reset the PCI portion of a device, but
1811 * clears all the state associated with the device. This function differs
1812 * from pci_execute_reset_function in that it saves and restores device state
1813 * over the reset.
1814 *
1815 * Returns 0 if the device function was successfully reset or -ENOTTY if the
1816 * device doesn't support resetting a single function.
1817 */
1818int pci_reset_function(struct pci_dev *dev)
1819{
1820 u32 cap;
1821 int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
1822 int r;
1823
1824 if (!exppos)
1825 return -ENOTTY;
1826 pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap);
1827 if (!(cap & PCI_EXP_DEVCAP_FLR))
1828 return -ENOTTY;
1829
1830 if (!dev->msi_enabled && !dev->msix_enabled)
1831 disable_irq(dev->irq);
1832 pci_save_state(dev);
1833
1834 pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
1835
1836 r = pci_execute_reset_function(dev);
1837
1838 pci_restore_state(dev);
1839 if (!dev->msi_enabled && !dev->msix_enabled)
1840 enable_irq(dev->irq);
1841
1842 return r;
1843}
1844EXPORT_SYMBOL_GPL(pci_reset_function);
1845
1846/**
1749 * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count 1847 * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count
1750 * @dev: PCI device to query 1848 * @dev: PCI device to query
1751 * 1849 *
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 085187be29c7..f6f6810296e6 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -626,6 +626,8 @@ int pcix_get_mmrbc(struct pci_dev *dev);
626int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc); 626int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
627int pcie_get_readrq(struct pci_dev *dev); 627int pcie_get_readrq(struct pci_dev *dev);
628int pcie_set_readrq(struct pci_dev *dev, int rq); 628int pcie_set_readrq(struct pci_dev *dev, int rq);
629int pci_reset_function(struct pci_dev *dev);
630int pci_execute_reset_function(struct pci_dev *dev);
629void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); 631void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
630int __must_check pci_assign_resource(struct pci_dev *dev, int i); 632int __must_check pci_assign_resource(struct pci_dev *dev, int i);
631int pci_select_bars(struct pci_dev *dev, unsigned long flags); 633int pci_select_bars(struct pci_dev *dev, unsigned long flags);
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index eb6686b88f9a..e5effd47ed74 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -377,6 +377,7 @@
377#define PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */ 377#define PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */
378#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ 378#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */
379#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ 379#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */
380#define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */
380#define PCI_EXP_DEVCTL 8 /* Device Control */ 381#define PCI_EXP_DEVCTL 8 /* Device Control */
381#define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */ 382#define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */
382#define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */ 383#define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */
@@ -389,6 +390,7 @@
389#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */ 390#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
390#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ 391#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */
391#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ 392#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
393#define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */
392#define PCI_EXP_DEVSTA 10 /* Device Status */ 394#define PCI_EXP_DEVSTA 10 /* Device Status */
393#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */ 395#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */
394#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */ 396#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */