Commit 942146bd authored by David Howells's avatar David Howells Committed by Greg Kroah-Hartman

[PATCH] PCI: Make pci_set_power_state() check register version

The attached patch makes pci_set_power_state() check the PM register version
and ignore non-version 2 registers. Trampling on earlier version PM registers
such as are sported by the Promise 20269 IDE card can cause the system to
hang.
Signed-Off-By: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 82987569
...@@ -245,7 +245,7 @@ int ...@@ -245,7 +245,7 @@ int
pci_set_power_state(struct pci_dev *dev, int state) pci_set_power_state(struct pci_dev *dev, int state)
{ {
int pm; int pm;
u16 pmcsr; u16 pmcsr, pmc;
/* bound the state we're entering */ /* bound the state we're entering */
if (state > 3) state = 3; if (state > 3) state = 3;
...@@ -265,10 +265,16 @@ pci_set_power_state(struct pci_dev *dev, int state) ...@@ -265,10 +265,16 @@ pci_set_power_state(struct pci_dev *dev, int state)
/* abort if the device doesn't support PM capabilities */ /* abort if the device doesn't support PM capabilities */
if (!pm) return -EIO; if (!pm) return -EIO;
pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
if ((pmc & PCI_PM_CAP_VER_MASK) != 2) {
printk(KERN_WARNING
"PCI: %s has unsupported PM cap regs version (%u)\n",
dev->slot_name, pmc & PCI_PM_CAP_VER_MASK);
return -EIO;
}
/* check if this device supports the desired state */ /* check if this device supports the desired state */
if (state == 1 || state == 2) { if (state == 1 || state == 2) {
u16 pmc;
pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
if (state == 1 && !(pmc & PCI_PM_CAP_D1)) return -EIO; if (state == 1 && !(pmc & PCI_PM_CAP_D1)) return -EIO;
else if (state == 2 && !(pmc & PCI_PM_CAP_D2)) return -EIO; else if (state == 2 && !(pmc & PCI_PM_CAP_D2)) return -EIO;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment