From 40d7b2b2a8bb621f949bda1d7d9c5c1a92417bc4 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 23 Dec 2008 03:08:29 +0000 Subject: [PATCH] --- yaml --- r: 127409 b: refs/heads/master c: 6a479079c07211bf348ac8a79754f26bea258f26 h: refs/heads/master i: 127407: 106d1f62415fc072e07de24b2600bfd2c25692bb v: v3 --- [refs] | 2 +- trunk/Documentation/PCI/pci.txt | 3 ++- trunk/drivers/pci/pci.c | 39 +++++++++++++++++++++++---------- trunk/include/linux/pci.h | 1 + 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/[refs] b/[refs] index 397f282804e6..78cb16bed4a3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b8d9cb2a2226118fd71f657c80b06b670a653022 +refs/heads/master: 6a479079c07211bf348ac8a79754f26bea258f26 diff --git a/trunk/Documentation/PCI/pci.txt b/trunk/Documentation/PCI/pci.txt index fd4907a2968c..7f6de6ea5b47 100644 --- a/trunk/Documentation/PCI/pci.txt +++ b/trunk/Documentation/PCI/pci.txt @@ -294,7 +294,8 @@ NOTE: pci_enable_device() can fail! Check the return value. pci_set_master() will enable DMA by setting the bus master bit in the PCI_COMMAND register. It also fixes the latency timer value if -it's set to something bogus by the BIOS. +it's set to something bogus by the BIOS. pci_clear_master() will +disable DMA by clearing the bus master bit. If the PCI device can use the PCI Memory-Write-Invalidate transaction, call pci_set_mwi(). This enables the PCI_COMMAND bit for Mem-Wr-Inval diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index c824dc8d617c..f3fd55df67db 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -1667,6 +1667,22 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) ((1 << 6) - 1), res_name); } +static void __pci_set_master(struct pci_dev *dev, bool enable) +{ + u16 old_cmd, cmd; + + pci_read_config_word(dev, PCI_COMMAND, &old_cmd); + if (enable) + cmd = old_cmd | PCI_COMMAND_MASTER; + else + cmd = old_cmd & ~PCI_COMMAND_MASTER; + if (cmd != old_cmd) { + dev_dbg(&dev->dev, "%s bus mastering\n", + enable ? "enabling" : "disabling"); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + dev->is_busmaster = enable; +} /** * 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) * Enables bus-mastering on the device and calls pcibios_set_master() * to do the needed arch specific settings. */ -void -pci_set_master(struct pci_dev *dev) +void pci_set_master(struct pci_dev *dev) { - u16 cmd; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - if (! (cmd & PCI_COMMAND_MASTER)) { - dev_dbg(&dev->dev, "enabling bus mastering\n"); - cmd |= PCI_COMMAND_MASTER; - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - dev->is_busmaster = 1; + __pci_set_master(dev, true); pcibios_set_master(dev); } +/** + * pci_clear_master - disables bus-mastering for device dev + * @dev: the PCI device to disable + */ +void pci_clear_master(struct pci_dev *dev) +{ + __pci_set_master(dev, false); +} + #ifdef PCI_DISABLE_MWI int pci_set_mwi(struct pci_dev *dev) { @@ -2346,6 +2362,7 @@ EXPORT_SYMBOL(pci_release_selected_regions); EXPORT_SYMBOL(pci_request_selected_regions); EXPORT_SYMBOL(pci_request_selected_regions_exclusive); EXPORT_SYMBOL(pci_set_master); +EXPORT_SYMBOL(pci_clear_master); EXPORT_SYMBOL(pci_set_mwi); EXPORT_SYMBOL(pci_try_set_mwi); EXPORT_SYMBOL(pci_clear_mwi); diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index 7cbecef19bb6..0f6d2bb1df9c 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -642,6 +642,7 @@ static inline int pci_is_managed(struct pci_dev *pdev) void pci_disable_device(struct pci_dev *dev); void pci_set_master(struct pci_dev *dev); +void pci_clear_master(struct pci_dev *dev); int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state); #define HAVE_PCI_SET_MWI int __must_check pci_set_mwi(struct pci_dev *dev);