summaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo2007-11-27 11:28:58 +0100
committerJeff Garzik2008-01-23 11:24:11 +0100
commit00115e0f5bc3bfdf3f3855ad89c8895f10458f92 (patch)
tree5f174c1d68e1ec0770fefdb40b813f321a838095 /drivers/ata/libata-core.c
parentlibata: adjust speed down rules (diff)
downloadkernel-qcow2-linux-00115e0f5bc3bfdf3f3855ad89c8895f10458f92.tar.gz
kernel-qcow2-linux-00115e0f5bc3bfdf3f3855ad89c8895f10458f92.tar.xz
kernel-qcow2-linux-00115e0f5bc3bfdf3f3855ad89c8895f10458f92.zip
libata: implement ATA_DFLAG_DUBIOUS_XFER
ATA_DFLAG_DUBIOUS_XFER is set whenever data transfer speed or method changes and gets cleared when data transfer command succeeds in the newly configured transfer mode. This will be used to improve speed down logic. Signed-off-by: Tejun Heo <htejun@gmail.com< Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 86c10cc751e9..124b6f111cc3 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5797,6 +5797,22 @@ static void fill_result_tf(struct ata_queued_cmd *qc)
ap->ops->tf_read(ap, &qc->result_tf);
}
+static void ata_verify_xfer(struct ata_queued_cmd *qc)
+{
+ struct ata_device *dev = qc->dev;
+
+ if (ata_tag_internal(qc->tag))
+ return;
+
+ if (ata_is_nodata(qc->tf.protocol))
+ return;
+
+ if ((dev->mwdma_mask || dev->udma_mask) && ata_is_pio(qc->tf.protocol))
+ return;
+
+ dev->flags &= ~ATA_DFLAG_DUBIOUS_XFER;
+}
+
/**
* ata_qc_complete - Complete an active ATA command
* @qc: Command to complete
@@ -5868,6 +5884,9 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
break;
}
+ if (unlikely(dev->flags & ATA_DFLAG_DUBIOUS_XFER))
+ ata_verify_xfer(qc);
+
__ata_qc_complete(qc);
} else {
if (qc->flags & ATA_QCFLAG_EH_SCHEDULED)