diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2007-03-05 03:30:07 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-05 10:57:50 -0500 |
commit | f5f2b13129a6541debf8851bae843cbbf48298b7 (patch) | |
tree | 274dc998519074e56259a7dc4bd611652b8d930e /drivers/pci/pci.c | |
parent | 58a53b246b4aed95f3f93b45828c8d9f26b1cfcb (diff) |
[PATCH] msi: sanely support hardware level msi disabling
In some cases when we are not using msi we need a way to ensure that the
hardware does not have an msi capability enabled. Currently the code has been
calling disable_msi_mode to try and achieve that. However disable_msi_mode
has several other side effects and is only available when msi support is
compiled in so it isn't really appropriate.
Instead this patch implements pci_msi_off which disables all msi and msix
capabilities unconditionally with no additional side effects.
pci_disable_device was redundantly clearing the bus master enable flag and
clearing the msi enable bit. A device that is not allowed to perform bus
mastering operations cannot generate intx or msi interrupt messages as those
are essentially a special case of dma, and require bus mastering. So the call
in pci_disable_device to disable msi capabilities was redundant.
quirk_pcie_pxh also called disable_msi_mode and is updated to use pci_msi_off.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: Michael Ellerman <michael@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1e74e1ee8bd8..df495300ce3d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -881,13 +881,6 @@ pci_disable_device(struct pci_dev *dev) | |||
881 | if (atomic_sub_return(1, &dev->enable_cnt) != 0) | 881 | if (atomic_sub_return(1, &dev->enable_cnt) != 0) |
882 | return; | 882 | return; |
883 | 883 | ||
884 | if (dev->msi_enabled) | ||
885 | disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), | ||
886 | PCI_CAP_ID_MSI); | ||
887 | if (dev->msix_enabled) | ||
888 | disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), | ||
889 | PCI_CAP_ID_MSIX); | ||
890 | |||
891 | pci_read_config_word(dev, PCI_COMMAND, &pci_command); | 884 | pci_read_config_word(dev, PCI_COMMAND, &pci_command); |
892 | if (pci_command & PCI_COMMAND_MASTER) { | 885 | if (pci_command & PCI_COMMAND_MASTER) { |
893 | pci_command &= ~PCI_COMMAND_MASTER; | 886 | pci_command &= ~PCI_COMMAND_MASTER; |
@@ -1277,6 +1270,33 @@ pci_intx(struct pci_dev *pdev, int enable) | |||
1277 | } | 1270 | } |
1278 | } | 1271 | } |
1279 | 1272 | ||
1273 | /** | ||
1274 | * pci_msi_off - disables any msi or msix capabilities | ||
1275 | * @pdev: the PCI device to operate on | ||
1276 | * | ||
1277 | * If you want to use msi see pci_enable_msi and friends. | ||
1278 | * This is a lower level primitive that allows us to disable | ||
1279 | * msi operation at the device level. | ||
1280 | */ | ||
1281 | void pci_msi_off(struct pci_dev *dev) | ||
1282 | { | ||
1283 | int pos; | ||
1284 | u16 control; | ||
1285 | |||
1286 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | ||
1287 | if (pos) { | ||
1288 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); | ||
1289 | control &= ~PCI_MSI_FLAGS_ENABLE; | ||
1290 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); | ||
1291 | } | ||
1292 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
1293 | if (pos) { | ||
1294 | pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); | ||
1295 | control &= ~PCI_MSIX_FLAGS_ENABLE; | ||
1296 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | ||
1297 | } | ||
1298 | } | ||
1299 | |||
1280 | #ifndef HAVE_ARCH_PCI_SET_DMA_MASK | 1300 | #ifndef HAVE_ARCH_PCI_SET_DMA_MASK |
1281 | /* | 1301 | /* |
1282 | * These can be overridden by arch-specific implementations | 1302 | * These can be overridden by arch-specific implementations |