summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristen Carlson Accardi <kristen@linux.intel.com>2011-03-04 10:24:11 -0800
committerJeff Garzik <jgarzik@pobox.com>2011-05-19 20:50:53 -0400
commit8a745f1f39b7a20047a362b67ce9151c07d14440 (patch)
treef8f08be7a284d195f30a8b2e6fc63b714e4f7f21
parent0afc6f5ba95419fd505e60637f7645425f16e407 (diff)
downloadlinux-8a745f1f39b7a20047a362b67ce9151c07d14440.tar.gz
linux-8a745f1f39b7a20047a362b67ce9151c07d14440.tar.bz2
linux-8a745f1f39b7a20047a362b67ce9151c07d14440.zip
libata: Power off empty ports
Give users the option of completely powering off unoccupied SATA ports using the existing min_power link_power_management_policy option. When the use selects this option on an empty port, we will power the port off by setting DET to off. For occupied ports, behavior is unchanged. Signed-off-by: Kristen Carlson Accardi <kristen@linux.intel.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r--drivers/ata/libata-core.c10
-rw-r--r--drivers/ata/libata-eh.c2
-rw-r--r--include/linux/libata.h1
3 files changed, 10 insertions, 3 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 76c3c15cb1e6..736bee5dafeb 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3619,8 +3619,14 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
scontrol |= (0x2 << 8);
break;
case ATA_LPM_MIN_POWER:
- /* no restrictions on LPM transitions */
- scontrol &= ~(0x3 << 8);
+ if (ata_link_nr_enabled(link) > 0)
+ /* no restrictions on LPM transitions */
+ scontrol &= ~(0x3 << 8);
+ else {
+ /* empty port, power off */
+ scontrol &= ~0xf;
+ scontrol |= (0x1 << 2);
+ }
break;
default:
WARN_ON(1);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index dad9fd660f37..dfb6e9d3d759 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -3423,7 +3423,7 @@ fail:
return rc;
}
-static int ata_link_nr_enabled(struct ata_link *link)
+int ata_link_nr_enabled(struct ata_link *link)
{
struct ata_device *dev;
int cnt = 0;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 04f32a3eb26b..5a9926b34072 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1151,6 +1151,7 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
ata_postreset_fn_t postreset);
extern void ata_std_error_handler(struct ata_port *ap);
+extern int ata_link_nr_enabled(struct ata_link *link);
/*
* Base operations to inherit from and initializers for sht