aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-15 07:57:40 -0400
committerTejun Heo <htejun@gmail.com>2006-05-15 07:57:40 -0400
commite61e067227bc76b4d9411a50d735c9d87f27b0e2 (patch)
tree007d22539b24aa6ae8e258af6e22a4187490a4c1 /include
parent96bd39ec295e49443c8b0c25a6b69fdace18780f (diff)
[PATCH] libata: implement qc->result_tf
Add qc->result_tf and ATA_QCFLAG_RESULT_TF. This moves the responsibility of loading result TF from post-compltion path to qc execution path. qc->result_tf is loaded if explicitly requested or the qc failsa. This allows more efficient completion implementation and correct handling of result TF for controllers which don't have global TF representation such as sil3124/32. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/libata.h16
1 files changed, 14 insertions, 2 deletions
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 0e1a3be39475..a4b8a419caad 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -162,7 +162,9 @@ enum {
162 ATA_QCFLAG_SINGLE = (1 << 2), /* no s/g, just a single buffer */ 162 ATA_QCFLAG_SINGLE = (1 << 2), /* no s/g, just a single buffer */
163 ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, 163 ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
164 ATA_QCFLAG_IO = (1 << 3), /* standard IO command */ 164 ATA_QCFLAG_IO = (1 << 3), /* standard IO command */
165 ATA_QCFLAG_EH_SCHEDULED = (1 << 4), /* EH scheduled */ 165 ATA_QCFLAG_RESULT_TF = (1 << 4), /* result TF requested */
166
167 ATA_QCFLAG_EH_SCHEDULED = (1 << 16), /* EH scheduled */
166 168
167 /* host set flags */ 169 /* host set flags */
168 ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */ 170 ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */
@@ -343,7 +345,7 @@ struct ata_queued_cmd {
343 struct scatterlist *__sg; 345 struct scatterlist *__sg;
344 346
345 unsigned int err_mask; 347 unsigned int err_mask;
346 348 struct ata_taskfile result_tf;
347 ata_qc_cb_t complete_fn; 349 ata_qc_cb_t complete_fn;
348 350
349 void *private_data; 351 void *private_data;
@@ -824,6 +826,10 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
824 qc->err_mask = 0; 826 qc->err_mask = 0;
825 827
826 ata_tf_init(qc->ap, &qc->tf, qc->dev->devno); 828 ata_tf_init(qc->ap, &qc->tf, qc->dev->devno);
829
830 /* init result_tf such that it indicates normal completion */
831 qc->result_tf.command = ATA_DRDY;
832 qc->result_tf.feature = 0;
827} 833}
828 834
829/** 835/**
@@ -839,9 +845,15 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
839 */ 845 */
840static inline void ata_qc_complete(struct ata_queued_cmd *qc) 846static inline void ata_qc_complete(struct ata_queued_cmd *qc)
841{ 847{
848 struct ata_port *ap = qc->ap;
849
842 if (unlikely(qc->flags & ATA_QCFLAG_EH_SCHEDULED)) 850 if (unlikely(qc->flags & ATA_QCFLAG_EH_SCHEDULED))
843 return; 851 return;
844 852
853 /* read result TF if failed or requested */
854 if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF)
855 ap->ops->tf_read(ap, &qc->result_tf);
856
845 __ata_qc_complete(qc); 857 __ata_qc_complete(qc);
846} 858}
847 859