aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2008-07-31 03:09:34 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-08-22 02:19:46 -0400
commitd127ea7b8643a93d14d1f3c542974407f14d3663 (patch)
tree2edbaf46167c86faad6b7645f3d3d2ef52bba84a /drivers/ata
parentda0e21d3fa2340114fe24821718a1b57123e4664 (diff)
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: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-core.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index dddcb9fde35a..5f8f57a818fb 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5199,15 +5199,14 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
5199 */ 5199 */
5200int sata_link_init_spd(struct ata_link *link) 5200int sata_link_init_spd(struct ata_link *link)
5201{ 5201{
5202 u32 scontrol;
5203 u8 spd; 5202 u8 spd;
5204 int rc; 5203 int rc;
5205 5204
5206 rc = sata_scr_read(link, SCR_CONTROL, &scontrol); 5205 rc = sata_scr_read(link, SCR_CONTROL, &link->saved_scontrol);
5207 if (rc) 5206 if (rc)
5208 return rc; 5207 return rc;
5209 5208
5210 spd = (scontrol >> 4) & 0xf; 5209 spd = (link->saved_scontrol >> 4) & 0xf;
5211 if (spd) 5210 if (spd)
5212 link->hw_sata_spd_limit &= (1 << spd) - 1; 5211 link->hw_sata_spd_limit &= (1 << spd) - 1;
5213 5212
@@ -5794,9 +5793,10 @@ static void ata_port_detach(struct ata_port *ap)
5794 ata_port_wait_eh(ap); 5793 ata_port_wait_eh(ap);
5795 5794
5796 /* EH is now guaranteed to see UNLOADING - EH context belongs 5795 /* EH is now guaranteed to see UNLOADING - EH context belongs
5797 * to us. Disable all existing devices. 5796 * to us. Restore SControl and disable all existing devices.
5798 */ 5797 */
5799 ata_port_for_each_link(link, ap) { 5798 __ata_port_for_each_link(link, ap) {
5799 sata_scr_write(link, SCR_CONTROL, link->saved_scontrol);
5800 ata_link_for_each_dev(dev, link) 5800 ata_link_for_each_dev(dev, link)
5801 ata_dev_disable(dev); 5801 ata_dev_disable(dev);
5802 } 5802 }