aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-03-16 06:14:55 -0400
committerJeff Garzik <jgarzik@pobox.com>2011-04-24 11:32:16 -0400
commitae01b2493c3bf03c504c32ac4ebb01d528508db3 (patch)
treee2f10e9054ca9c883f59aab7fec776ed2aece281 /drivers/ata/libata-eh.c
parent3f7ac1d6671ebca7a955853f7127c937f7befbd3 (diff)
libata: Implement ATA_FLAG_NO_DIPM and apply it to mcp65
NVIDIA mcp65 familiy of controllers cause command timeouts when DIPM is used. Implement ATA_FLAG_NO_DIPM and apply it. This problem was reported by Stefan Bader in the following thread. http://thread.gmane.org/gmane.linux.ide/48841 stable: applicable to 2.6.37 and 38. Signed-off-by: Tejun Heo <tj@kernel.org> Reported-by: Stefan Bader <stefan.bader@canonical.com> Cc: stable@kernel.org Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r--drivers/ata/libata-eh.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 88cd22fa65cd..f26f2fe3480a 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -3316,6 +3316,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
3316 struct ata_eh_context *ehc = &link->eh_context; 3316 struct ata_eh_context *ehc = &link->eh_context;
3317 struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; 3317 struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL;
3318 enum ata_lpm_policy old_policy = link->lpm_policy; 3318 enum ata_lpm_policy old_policy = link->lpm_policy;
3319 bool no_dipm = ap->flags & ATA_FLAG_NO_DIPM;
3319 unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; 3320 unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM;
3320 unsigned int err_mask; 3321 unsigned int err_mask;
3321 int rc; 3322 int rc;
@@ -3332,7 +3333,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
3332 */ 3333 */
3333 ata_for_each_dev(dev, link, ENABLED) { 3334 ata_for_each_dev(dev, link, ENABLED) {
3334 bool hipm = ata_id_has_hipm(dev->id); 3335 bool hipm = ata_id_has_hipm(dev->id);
3335 bool dipm = ata_id_has_dipm(dev->id); 3336 bool dipm = ata_id_has_dipm(dev->id) && !no_dipm;
3336 3337
3337 /* find the first enabled and LPM enabled devices */ 3338 /* find the first enabled and LPM enabled devices */
3338 if (!link_dev) 3339 if (!link_dev)
@@ -3389,7 +3390,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
3389 3390
3390 /* host config updated, enable DIPM if transitioning to MIN_POWER */ 3391 /* host config updated, enable DIPM if transitioning to MIN_POWER */
3391 ata_for_each_dev(dev, link, ENABLED) { 3392 ata_for_each_dev(dev, link, ENABLED) {
3392 if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) { 3393 if (policy == ATA_LPM_MIN_POWER && !no_dipm &&
3394 ata_id_has_dipm(dev->id)) {
3393 err_mask = ata_dev_set_feature(dev, 3395 err_mask = ata_dev_set_feature(dev,
3394 SETFEATURES_SATA_ENABLE, SATA_DIPM); 3396 SETFEATURES_SATA_ENABLE, SATA_DIPM);
3395 if (err_mask && err_mask != AC_ERR_DEV) { 3397 if (err_mask && err_mask != AC_ERR_DEV) {