diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2008-12-22 22:08:29 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-01-07 14:13:23 -0500 |
commit | 6a479079c07211bf348ac8a79754f26bea258f26 (patch) | |
tree | 1587c0ed9446c7d0d6ab8a38d1524132e2faae35 /drivers | |
parent | b8d9cb2a2226118fd71f657c80b06b670a653022 (diff) |
PCI: Add pci_clear_master() as opposite of pci_set_master()
During an online device reset it may be useful to disable bus-mastering.
pci_disable_device() does that, and far more besides, so is not suitable
for an online reset.
Add pci_clear_master() which does just this.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Reviewed-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/pci.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c824dc8d617..f3fd55df67d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1667,6 +1667,22 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) | |||
1667 | ((1 << 6) - 1), res_name); | 1667 | ((1 << 6) - 1), res_name); |
1668 | } | 1668 | } |
1669 | 1669 | ||
1670 | static void __pci_set_master(struct pci_dev *dev, bool enable) | ||
1671 | { | ||
1672 | u16 old_cmd, cmd; | ||
1673 | |||
1674 | pci_read_config_word(dev, PCI_COMMAND, &old_cmd); | ||
1675 | if (enable) | ||
1676 | cmd = old_cmd | PCI_COMMAND_MASTER; | ||
1677 | else | ||
1678 | cmd = old_cmd & ~PCI_COMMAND_MASTER; | ||
1679 | if (cmd != old_cmd) { | ||
1680 | dev_dbg(&dev->dev, "%s bus mastering\n", | ||
1681 | enable ? "enabling" : "disabling"); | ||
1682 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
1683 | } | ||
1684 | dev->is_busmaster = enable; | ||
1685 | } | ||
1670 | 1686 | ||
1671 | /** | 1687 | /** |
1672 | * pci_set_master - enables bus-mastering for device dev | 1688 | * pci_set_master - enables bus-mastering for device dev |
@@ -1675,21 +1691,21 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) | |||
1675 | * Enables bus-mastering on the device and calls pcibios_set_master() | 1691 | * Enables bus-mastering on the device and calls pcibios_set_master() |
1676 | * to do the needed arch specific settings. | 1692 | * to do the needed arch specific settings. |
1677 | */ | 1693 | */ |
1678 | void | 1694 | void pci_set_master(struct pci_dev *dev) |
1679 | pci_set_master(struct pci_dev *dev) | ||
1680 | { | 1695 | { |
1681 | u16 cmd; | 1696 | __pci_set_master(dev, true); |
1682 | |||
1683 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
1684 | if (! (cmd & PCI_COMMAND_MASTER)) { | ||
1685 | dev_dbg(&dev->dev, "enabling bus mastering\n"); | ||
1686 | cmd |= PCI_COMMAND_MASTER; | ||
1687 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
1688 | } | ||
1689 | dev->is_busmaster = 1; | ||
1690 | pcibios_set_master(dev); | 1697 | pcibios_set_master(dev); |
1691 | } | 1698 | } |
1692 | 1699 | ||
1700 | /** | ||
1701 | * pci_clear_master - disables bus-mastering for device dev | ||
1702 | * @dev: the PCI device to disable | ||
1703 | */ | ||
1704 | void pci_clear_master(struct pci_dev *dev) | ||
1705 | { | ||
1706 | __pci_set_master(dev, false); | ||
1707 | } | ||
1708 | |||
1693 | #ifdef PCI_DISABLE_MWI | 1709 | #ifdef PCI_DISABLE_MWI |
1694 | int pci_set_mwi(struct pci_dev *dev) | 1710 | int pci_set_mwi(struct pci_dev *dev) |
1695 | { | 1711 | { |
@@ -2346,6 +2362,7 @@ EXPORT_SYMBOL(pci_release_selected_regions); | |||
2346 | EXPORT_SYMBOL(pci_request_selected_regions); | 2362 | EXPORT_SYMBOL(pci_request_selected_regions); |
2347 | EXPORT_SYMBOL(pci_request_selected_regions_exclusive); | 2363 | EXPORT_SYMBOL(pci_request_selected_regions_exclusive); |
2348 | EXPORT_SYMBOL(pci_set_master); | 2364 | EXPORT_SYMBOL(pci_set_master); |
2365 | EXPORT_SYMBOL(pci_clear_master); | ||
2349 | EXPORT_SYMBOL(pci_set_mwi); | 2366 | EXPORT_SYMBOL(pci_set_mwi); |
2350 | EXPORT_SYMBOL(pci_try_set_mwi); | 2367 | EXPORT_SYMBOL(pci_try_set_mwi); |
2351 | EXPORT_SYMBOL(pci_clear_mwi); | 2368 | EXPORT_SYMBOL(pci_clear_mwi); |