Message ID | 1243217950-4030-3-git-send-email-yu.zhao@intel.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Yu Zhao wrote: > PCI-to-PCI Bridge 1.2 specifies that the Secondary Bus Reset bit can > force the assertion of RST# on the secondary interface, which can be > used to reset all devices including subordinates under this bus. This > can be used to reset a function if this function is the only device > under this bus. > > Signed-off-by: Yu Zhao <yu.zhao@intel.com> > --- > drivers/pci/pci.c | 31 +++++++++++++++++++++++++++++++ > 1 files changed, 31 insertions(+), 0 deletions(-) > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > index 19a5479..3711e74 100644 > --- a/drivers/pci/pci.c > +++ b/drivers/pci/pci.c > @@ -2160,6 +2160,33 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) > return 0; > } > > +static int pci_secondary_bus_reset(struct pci_dev *dev, int probe) > +{ I guess many people would imagine that pci_secondary_bus_reset() receives the pointer to struct pci_dev corresponding to the bridge and resets bridge's secondary bus, though it does quite different things. So I think the function name should be changed. Thanks, Kenji Kaneshige > + u16 ctrl; > + struct pci_dev *pdev; > + > + if (dev->subordinate) > + return -ENOTTY; > + > + list_for_each_entry(pdev, &dev->bus->devices, bus_list) > + if (pdev != dev) > + return -ENOTTY; > + > + if (probe) > + return 0; > + > + pci_read_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, &ctrl); > + ctrl |= PCI_BRIDGE_CTL_BUS_RESET; > + pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl); > + msleep(100); > + > + ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; > + pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl); > + msleep(100); > + > + return 0; > +} > + > static int pci_dev_reset(struct pci_dev *dev, int probe) > { > int rc; > @@ -2181,6 +2208,10 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) > goto done; > > rc = pci_pm_reset(dev, probe); > + if (rc != -ENOTTY) > + goto done; > + > + rc = pci_secondary_bus_reset(dev, probe); > done: > if (!probe) { > up(&dev->dev.sem); -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 25 May 2009 14:45:22 +0900 Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> wrote: > Yu Zhao wrote: > > PCI-to-PCI Bridge 1.2 specifies that the Secondary Bus Reset bit can > > force the assertion of RST# on the secondary interface, which can be > > used to reset all devices including subordinates under this bus. > > This can be used to reset a function if this function is the only > > device under this bus. > > > > Signed-off-by: Yu Zhao <yu.zhao@intel.com> > > --- > > drivers/pci/pci.c | 31 +++++++++++++++++++++++++++++++ > > 1 files changed, 31 insertions(+), 0 deletions(-) > > > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > > index 19a5479..3711e74 100644 > > --- a/drivers/pci/pci.c > > +++ b/drivers/pci/pci.c > > @@ -2160,6 +2160,33 @@ static int pci_pm_reset(struct pci_dev *dev, > > int probe) return 0; > > } > > > > +static int pci_secondary_bus_reset(struct pci_dev *dev, int probe) > > +{ > > I guess many people would imagine that pci_secondary_bus_reset() > receives the pointer to struct pci_dev corresponding to the bridge > and resets bridge's secondary bus, though it does quite different > things. So I think the function name should be changed. Yu, wanna send me an update with the change? You'll need to refresh it against my linux-next branch to avoid conflicts. Thanks,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 19a5479..3711e74 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2160,6 +2160,33 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) return 0; } +static int pci_secondary_bus_reset(struct pci_dev *dev, int probe) +{ + u16 ctrl; + struct pci_dev *pdev; + + if (dev->subordinate) + return -ENOTTY; + + list_for_each_entry(pdev, &dev->bus->devices, bus_list) + if (pdev != dev) + return -ENOTTY; + + if (probe) + return 0; + + pci_read_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, &ctrl); + ctrl |= PCI_BRIDGE_CTL_BUS_RESET; + pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl); + msleep(100); + + ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; + pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl); + msleep(100); + + return 0; +} + static int pci_dev_reset(struct pci_dev *dev, int probe) { int rc; @@ -2181,6 +2208,10 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) goto done; rc = pci_pm_reset(dev, probe); + if (rc != -ENOTTY) + goto done; + + rc = pci_secondary_bus_reset(dev, probe); done: if (!probe) { up(&dev->dev.sem);
PCI-to-PCI Bridge 1.2 specifies that the Secondary Bus Reset bit can force the assertion of RST# on the secondary interface, which can be used to reset all devices including subordinates under this bus. This can be used to reset a function if this function is the only device under this bus. Signed-off-by: Yu Zhao <yu.zhao@intel.com> --- drivers/pci/pci.c | 31 +++++++++++++++++++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-)