aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorKristen Carlson Accardi <kristen.c.accardi@intel.com>2007-10-25 00:58:59 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-29 11:00:35 -0400
commitca77329fb713b7fea6a307068e0dd0248e7aa640 (patch)
tree6a1b987f489d7c3f0bbe81647b4ee2b0216afe8a /include/linux
parentab6fc95f609b372a19e18ea689986846ab1ba29c (diff)
[libata] Link power management infrastructure
Device Initiated Power Management, which is defined in SATA 2.5 can be enabled for disks which support it. This patch enables DIPM when the user sets the link power management policy to "min_power". Additionally, libata drivers can define a function (enable_pm) that will perform hardware specific actions to enable whatever power management policy the user set up for Host Initiated Power management (HIPM). This power management policy will be activated after all disks have been enumerated and intialized. Drivers should also define disable_pm, which will turn off link power management, but not change link power management policy. Documentation/scsi/link_power_management_policy.txt has additional information. Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/ata.h21
-rw-r--r--include/linux/libata.h21
2 files changed, 41 insertions, 1 deletions
diff --git a/include/linux/ata.h b/include/linux/ata.h
index e21c002c3a4a..128dc7ad4901 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -236,6 +236,7 @@ enum {
236 236
237 /* SETFEATURE Sector counts for SATA features */ 237 /* SETFEATURE Sector counts for SATA features */
238 SATA_AN = 0x05, /* Asynchronous Notification */ 238 SATA_AN = 0x05, /* Asynchronous Notification */
239 SATA_DIPM = 0x03, /* Device Initiated Power Management */
239 240
240 /* ATAPI stuff */ 241 /* ATAPI stuff */
241 ATAPI_PKT_DMA = (1 << 0), 242 ATAPI_PKT_DMA = (1 << 0),
@@ -378,6 +379,26 @@ struct ata_taskfile {
378 379
379#define ata_id_cdb_intr(id) (((id)[0] & 0x60) == 0x20) 380#define ata_id_cdb_intr(id) (((id)[0] & 0x60) == 0x20)
380 381
382static inline bool ata_id_has_hipm(const u16 *id)
383{
384 u16 val = id[76];
385
386 if (val == 0 || val == 0xffff)
387 return false;
388
389 return val & (1 << 9);
390}
391
392static inline bool ata_id_has_dipm(const u16 *id)
393{
394 u16 val = id[78];
395
396 if (val == 0 || val == 0xffff)
397 return false;
398
399 return val & (1 << 3);
400}
401
381static inline int ata_id_has_fua(const u16 *id) 402static inline int ata_id_has_fua(const u16 *id)
382{ 403{
383 if ((id[84] & 0xC000) != 0x4000) 404 if ((id[84] & 0xC000) != 0x4000)
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 439d40f86c55..147ccc40c8af 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -133,6 +133,8 @@ enum {
133 ATA_DFLAG_ACPI_PENDING = (1 << 5), /* ACPI resume action pending */ 133 ATA_DFLAG_ACPI_PENDING = (1 << 5), /* ACPI resume action pending */
134 ATA_DFLAG_ACPI_FAILED = (1 << 6), /* ACPI on devcfg has failed */ 134 ATA_DFLAG_ACPI_FAILED = (1 << 6), /* ACPI on devcfg has failed */
135 ATA_DFLAG_AN = (1 << 7), /* AN configured */ 135 ATA_DFLAG_AN = (1 << 7), /* AN configured */
136 ATA_DFLAG_HIPM = (1 << 8), /* device supports HIPM */
137 ATA_DFLAG_DIPM = (1 << 9), /* device supports DIPM */
136 ATA_DFLAG_CFG_MASK = (1 << 12) - 1, 138 ATA_DFLAG_CFG_MASK = (1 << 12) - 1,
137 139
138 ATA_DFLAG_PIO = (1 << 12), /* device limited to PIO mode */ 140 ATA_DFLAG_PIO = (1 << 12), /* device limited to PIO mode */
@@ -186,6 +188,7 @@ enum {
186 ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */ 188 ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */
187 ATA_FLAG_AN = (1 << 18), /* controller supports AN */ 189 ATA_FLAG_AN = (1 << 18), /* controller supports AN */
188 ATA_FLAG_PMP = (1 << 19), /* controller supports PMP */ 190 ATA_FLAG_PMP = (1 << 19), /* controller supports PMP */
191 ATA_FLAG_IPM = (1 << 20), /* driver can handle IPM */
189 192
190 /* The following flag belongs to ap->pflags but is kept in 193 /* The following flag belongs to ap->pflags but is kept in
191 * ap->flags because it's referenced in many LLDs and will be 194 * ap->flags because it's referenced in many LLDs and will be
@@ -302,6 +305,7 @@ enum {
302 ATA_EHI_RESUME_LINK = (1 << 1), /* resume link (reset modifier) */ 305 ATA_EHI_RESUME_LINK = (1 << 1), /* resume link (reset modifier) */
303 ATA_EHI_NO_AUTOPSY = (1 << 2), /* no autopsy */ 306 ATA_EHI_NO_AUTOPSY = (1 << 2), /* no autopsy */
304 ATA_EHI_QUIET = (1 << 3), /* be quiet */ 307 ATA_EHI_QUIET = (1 << 3), /* be quiet */
308 ATA_EHI_LPM = (1 << 4), /* link power management action */
305 309
306 ATA_EHI_DID_SOFTRESET = (1 << 16), /* already soft-reset this port */ 310 ATA_EHI_DID_SOFTRESET = (1 << 16), /* already soft-reset this port */
307 ATA_EHI_DID_HARDRESET = (1 << 17), /* already soft-reset this port */ 311 ATA_EHI_DID_HARDRESET = (1 << 17), /* already soft-reset this port */
@@ -333,6 +337,7 @@ enum {
333 ATA_HORKAGE_BROKEN_HPA = (1 << 4), /* Broken HPA */ 337 ATA_HORKAGE_BROKEN_HPA = (1 << 4), /* Broken HPA */
334 ATA_HORKAGE_SKIP_PM = (1 << 5), /* Skip PM operations */ 338 ATA_HORKAGE_SKIP_PM = (1 << 5), /* Skip PM operations */
335 ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */ 339 ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */
340 ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */
336 341
337 /* DMA mask for user DMA control: User visible values; DO NOT 342 /* DMA mask for user DMA control: User visible values; DO NOT
338 renumber */ 343 renumber */
@@ -378,6 +383,18 @@ typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes,
378 unsigned long deadline); 383 unsigned long deadline);
379typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes); 384typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes);
380 385
386/*
387 * host pm policy: If you alter this, you also need to alter libata-scsi.c
388 * (for the ascii descriptions)
389 */
390enum link_pm {
391 NOT_AVAILABLE,
392 MIN_POWER,
393 MAX_PERFORMANCE,
394 MEDIUM_POWER,
395};
396extern struct class_device_attribute class_device_attr_link_power_management_policy;
397
381struct ata_ioports { 398struct ata_ioports {
382 void __iomem *cmd_addr; 399 void __iomem *cmd_addr;
383 void __iomem *data_addr; 400 void __iomem *data_addr;
@@ -624,6 +641,7 @@ struct ata_port {
624 641
625 pm_message_t pm_mesg; 642 pm_message_t pm_mesg;
626 int *pm_result; 643 int *pm_result;
644 enum link_pm pm_policy;
627 645
628 struct timer_list fastdrain_timer; 646 struct timer_list fastdrain_timer;
629 unsigned long fastdrain_cnt; 647 unsigned long fastdrain_cnt;
@@ -691,7 +709,8 @@ struct ata_port_operations {
691 709
692 int (*port_suspend) (struct ata_port *ap, pm_message_t mesg); 710 int (*port_suspend) (struct ata_port *ap, pm_message_t mesg);
693 int (*port_resume) (struct ata_port *ap); 711 int (*port_resume) (struct ata_port *ap);
694 712 int (*enable_pm) (struct ata_port *ap, enum link_pm policy);
713 void (*disable_pm) (struct ata_port *ap);
695 int (*port_start) (struct ata_port *ap); 714 int (*port_start) (struct ata_port *ap);
696 void (*port_stop) (struct ata_port *ap); 715 void (*port_stop) (struct ata_port *ap);
697 716