Commit d127ea7b authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik

libata: restore SControl on detach

Save SControl during probing and restore it on detach.  This prevents
adjustments made by libata drivers to seep into the next driver which
gets attached (be it a libata one or not).

It's not clear whether SControl also needs to be restored on suspend.
The next system to have control (ACPI or kexec'd kernel) would
probably like to see the original SControl value but there's no
guarantee that a link is gonna keep working after SControl is adjusted
without a reset and adding a reset and modified recovery cycle soley
for this is an overkill.  For now, do it only for detach.
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent da0e21d3
...@@ -5199,15 +5199,14 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp) ...@@ -5199,15 +5199,14 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
*/ */
int sata_link_init_spd(struct ata_link *link) int sata_link_init_spd(struct ata_link *link)
{ {
u32 scontrol;
u8 spd; u8 spd;
int rc; int rc;
rc = sata_scr_read(link, SCR_CONTROL, &scontrol); rc = sata_scr_read(link, SCR_CONTROL, &link->saved_scontrol);
if (rc) if (rc)
return rc; return rc;
spd = (scontrol >> 4) & 0xf; spd = (link->saved_scontrol >> 4) & 0xf;
if (spd) if (spd)
link->hw_sata_spd_limit &= (1 << spd) - 1; link->hw_sata_spd_limit &= (1 << spd) - 1;
...@@ -5794,9 +5793,10 @@ static void ata_port_detach(struct ata_port *ap) ...@@ -5794,9 +5793,10 @@ static void ata_port_detach(struct ata_port *ap)
ata_port_wait_eh(ap); ata_port_wait_eh(ap);
/* EH is now guaranteed to see UNLOADING - EH context belongs /* EH is now guaranteed to see UNLOADING - EH context belongs
* to us. Disable all existing devices. * to us. Restore SControl and disable all existing devices.
*/ */
ata_port_for_each_link(link, ap) { __ata_port_for_each_link(link, ap) {
sata_scr_write(link, SCR_CONTROL, link->saved_scontrol);
ata_link_for_each_dev(dev, link) ata_link_for_each_dev(dev, link)
ata_dev_disable(dev); ata_dev_disable(dev);
} }
......
...@@ -647,6 +647,7 @@ struct ata_link { ...@@ -647,6 +647,7 @@ struct ata_link {
unsigned int flags; /* ATA_LFLAG_xxx */ unsigned int flags; /* ATA_LFLAG_xxx */
u32 saved_scontrol; /* SControl on probe */
unsigned int hw_sata_spd_limit; unsigned int hw_sata_spd_limit;
unsigned int sata_spd_limit; unsigned int sata_spd_limit;
unsigned int sata_spd; /* current SATA PHY speed */ unsigned int sata_spd; /* current SATA PHY speed */
......
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