On Sat, Dec 13, 2008 at 07:37:30PM +0000, Ben Hutchings wrote: > 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@xxxxxxxxxxxxxx> Reviewed-by: Grant Grundler <grundler@xxxxxxxxxxxxxxxx> > --- > drivers/pci/pci.c | 39 ++++++++++++++++++++++++++++----------- > include/linux/pci.h | 1 + Since this exports a new symbol, can you update Documentation/PCI/pci.txt to include pci_clear_master() where appropriate? I'm ok if it's a separate patch from the two you sent. thanks, grant > 2 files changed, 29 insertions(+), 11 deletions(-) > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > index 3222f90..fbb4cdc 100644 > --- a/drivers/pci/pci.c > +++ b/drivers/pci/pci.c > @@ -1609,6 +1609,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 > @@ -1617,21 +1633,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); Did you want to use dev->is_busmaster here to avoid the Config read? Not sure it's useful to do that...just tossing the idea out there. As-is is fine too. thanks, grant > +} > + > #ifdef PCI_DISABLE_MWI > int pci_set_mwi(struct pci_dev *dev) > { > @@ -2266,6 +2282,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/include/linux/pci.h b/include/linux/pci.h > index 43b863f..2fe7358 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -624,6 +624,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); > -- > 1.5.5 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-pci" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html