mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 08:19:28 +00:00
ata_piix: verify SIDPR access before enabling it
On certain configurations (certain macbooks), even though all the conditions for SIDPR access described in the datasheet are met, actually reading those registers just returns 0 and have no effect on write. Verify SIDPR is actually working before enabling it. This is reported by Ryan Roth in bz#10512. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Ryan Roth <ryan.roth@ch2m.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
parent
78ab88f04f
commit
cb6716c879
1 changed files with 25 additions and 0 deletions
|
@ -1348,6 +1348,8 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
|
||||||
{
|
{
|
||||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||||
struct piix_host_priv *hpriv = host->private_data;
|
struct piix_host_priv *hpriv = host->private_data;
|
||||||
|
struct ata_device *dev0 = &host->ports[0]->link.device[0];
|
||||||
|
u32 scontrol;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* check for availability */
|
/* check for availability */
|
||||||
|
@ -1366,6 +1368,29 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
|
hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
|
||||||
|
|
||||||
|
/* SCR access via SIDPR doesn't work on some configurations.
|
||||||
|
* Give it a test drive by inhibiting power save modes which
|
||||||
|
* we'll do anyway.
|
||||||
|
*/
|
||||||
|
scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
|
||||||
|
|
||||||
|
/* if IPM is already 3, SCR access is probably working. Don't
|
||||||
|
* un-inhibit power save modes as BIOS might have inhibited
|
||||||
|
* them for a reason.
|
||||||
|
*/
|
||||||
|
if ((scontrol & 0xf00) != 0x300) {
|
||||||
|
scontrol |= 0x300;
|
||||||
|
piix_sidpr_write(dev0, SCR_CONTROL, scontrol);
|
||||||
|
scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
|
||||||
|
|
||||||
|
if ((scontrol & 0xf00) != 0x300) {
|
||||||
|
dev_printk(KERN_INFO, host->dev, "SCR access via "
|
||||||
|
"SIDPR is available but doesn't work\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
host->ports[0]->ops = &piix_sidpr_sata_ops;
|
host->ports[0]->ops = &piix_sidpr_sata_ops;
|
||||||
host->ports[1]->ops = &piix_sidpr_sata_ops;
|
host->ports[1]->ops = &piix_sidpr_sata_ops;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue