On Thu, Sep 01, 2016 at 07:00:00PM -0400, Sinan Kaya wrote: > A secondary bus reset causes settings to be lost by all downstream > devices on the tree. The code is currently saving and restoring device > states only when called from the VFIO path via pci_probe_reset_bus > and pci_reset_bus functions. > > Moving the save and restore into pci_reset_bridge_secondary_bus > so that all users of the API have the same behavior. > > Signed-off-by: Sinan Kaya <okaya@xxxxxxxxxxxxxx> > --- > drivers/pci/pci.c | 36 +++++++++++++++--------------------- > 1 file changed, 15 insertions(+), 21 deletions(-) > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > index aab9d51..b209378 100644 > --- a/drivers/pci/pci.c > +++ b/drivers/pci/pci.c > @@ -3860,19 +3860,6 @@ void __weak pcibios_reset_secondary_bus(struct pci_dev *dev) > pci_reset_secondary_bus(dev); > } > > -/** > - * pci_reset_bridge_secondary_bus - Reset the secondary bus on a PCI bridge. > - * @dev: Bridge device > - * > - * Use the bridge control register to assert reset on the secondary bus. > - * Devices on the secondary bus are left in power-on state. > - */ > -void pci_reset_bridge_secondary_bus(struct pci_dev *dev) > -{ > - pcibios_reset_secondary_bus(dev); > -} > -EXPORT_SYMBOL_GPL(pci_reset_bridge_secondary_bus); > - > static int pci_parent_bus_reset(struct pci_dev *dev, int probe) > { > struct pci_dev *pdev; > @@ -4362,6 +4349,21 @@ static void pci_slot_restore(struct pci_slot *slot) > } > } > > +/** > + * pci_reset_bridge_secondary_bus - Reset the secondary bus on a PCI bridge. > + * @dev: Bridge device > + * > + * Use the bridge control register to assert reset on the secondary bus. > + * Devices on the secondary bus are left in power-on state. > + */ > +void pci_reset_bridge_secondary_bus(struct pci_dev *dev) > +{ > + pci_bus_save_and_disable(dev->bus); > + pcibios_reset_secondary_bus(dev); > + pci_bus_restore(dev->bus); This path eventually writes the Bridge Control register: pci_reset_bridge_secondary_bus pcibios_reset_secondary_bus pci_reset_secondary_bus pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl) But I think it'd be easy to call this on a non-bridge device, and I don't think there's anything in the path that checks whether this is actually a bridge. I wonder if we should check that somewhere, or maybe even change the interface so it takes a struct pci_bus instead of a pci_dev. > +} > +EXPORT_SYMBOL_GPL(pci_reset_bridge_secondary_bus); > + > static int pci_slot_reset(struct pci_slot *slot, int probe) > { > int rc; > @@ -4504,12 +4506,8 @@ int pci_reset_bus(struct pci_bus *bus) > if (rc) > return rc; > > - pci_bus_save_and_disable(bus); > - > rc = pci_bus_reset(bus, 0); > > - pci_bus_restore(bus); > - > return rc; > } > EXPORT_SYMBOL_GPL(pci_reset_bus); > @@ -4528,8 +4526,6 @@ int pci_try_reset_bus(struct pci_bus *bus) > if (rc) > return rc; > > - pci_bus_save_and_disable(bus); > - > if (pci_bus_trylock(bus)) { > might_sleep(); > pci_reset_bridge_secondary_bus(bus->self); > @@ -4537,8 +4533,6 @@ int pci_try_reset_bus(struct pci_bus *bus) > } else > rc = -EAGAIN; > > - pci_bus_restore(bus); > - > return rc; > } > EXPORT_SYMBOL_GPL(pci_try_reset_bus); > -- > 1.9.1 > -- 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