libata: add qc_fill_rtf port operation

On command completion, ata_qc_complete() directly called ops->tf_read
to fill qc->result_tf.  This patch adds ops->qc_fill_rtf to replace
hardcoded ops->tf_read usage.

ata_sff_qc_fill_rtf() which uses ops->tf_read to fill result_tf is
implemented and set in ata_base_port_ops and other ops tables which
don't inherit from ata_base_port_ops, so this patch doesn't introduce
any behavior change.

ops->qc_fill_rtf() is similar to ops->sff_tf_read() but can only be
called when a command finishes.  As some non-SFF controllers don't
have TF registers defined unless they're associated with in-flight
commands, this limited operation makes life easier for those drivers
and help lifting SFF assumptions from libata core layer.

Signed-off-by: Tejun Heo <htejun@gmail.com>
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 51876b9..3b82212 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -74,6 +74,7 @@
 const unsigned long sata_deb_timing_long[]		= { 100, 2000, 5000 };
 
 const struct ata_port_operations ata_base_port_ops = {
+	.qc_fill_rtf		= ata_sff_qc_fill_rtf,
 	.prereset		= ata_std_prereset,
 	.postreset		= ata_std_postreset,
 	.error_handler		= ata_std_error_handler,
@@ -4562,7 +4563,7 @@
 	struct ata_port *ap = qc->ap;
 
 	qc->result_tf.flags = qc->tf.flags;
-	ap->ops->sff_tf_read(ap, &qc->result_tf);
+	ap->ops->qc_fill_rtf(qc);
 }
 
 static void ata_verify_xfer(struct ata_queued_cmd *qc)
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 5be8a60..5ae813f 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1408,6 +1408,25 @@
 }
 
 /**
+ *	ata_sff_qc_fill_rtf - fill result TF using ->sff_tf_read
+ *	@qc: qc to fill result TF for
+ *
+ *	@qc is finished and result TF needs to be filled.  Fill it
+ *	using ->sff_tf_read.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host lock)
+ *
+ *	RETURNS:
+ *	true indicating that result TF is successfully filled.
+ */
+bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc)
+{
+	qc->ap->ops->sff_tf_read(qc->ap, &qc->result_tf);
+	return true;
+}
+
+/**
  *	ata_sff_host_intr - Handle host interrupt for given (port, task)
  *	@ap: Port on which interrupt arrived (possibly...)
  *	@qc: Taskfile currently active in engine
@@ -2724,6 +2743,7 @@
 EXPORT_SYMBOL_GPL(ata_sff_irq_clear);
 EXPORT_SYMBOL_GPL(ata_sff_hsm_move);
 EXPORT_SYMBOL_GPL(ata_sff_qc_issue);
+EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
 EXPORT_SYMBOL_GPL(ata_sff_host_intr);
 EXPORT_SYMBOL_GPL(ata_sff_interrupt);
 EXPORT_SYMBOL_GPL(ata_sff_freeze);
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index 6107eff..ec04b8d 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -251,6 +251,7 @@
 	.phy_reset		= pdc_20621_phy_reset,
 	.qc_prep		= pdc20621_qc_prep,
 	.qc_issue		= pdc20621_qc_issue,
+	.qc_fill_rtf		= ata_sff_qc_fill_rtf,
 	.sff_data_xfer		= ata_sff_data_xfer,
 	.eng_timeout		= pdc_eng_timeout,
 	.sff_irq_clear		= pdc20621_irq_clear,
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 5bddae1..2ecd329 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5280,6 +5280,7 @@
 	.sff_tf_read = ipr_tf_read,
 	.qc_prep = ata_noop_qc_prep,
 	.qc_issue = ipr_qc_issue,
+	.qc_fill_rtf = ata_sff_qc_fill_rtf,
 	.port_start = ata_sas_port_start,
 	.port_stop = ata_sas_port_stop
 };
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index a1664b8..2ec2558 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -356,6 +356,7 @@
 	.sff_tf_read		= sas_ata_tf_read,
 	.qc_prep		= ata_noop_qc_prep,
 	.qc_issue		= sas_ata_qc_issue,
+	.qc_fill_rtf		= ata_sff_qc_fill_rtf,
 	.port_start		= ata_sas_port_start,
 	.port_stop		= ata_sas_port_stop,
 	.scr_read		= sas_ata_scr_read,
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 2b5a0b7..bb4200d 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -715,6 +715,7 @@
 	int  (*check_atapi_dma)(struct ata_queued_cmd *qc);
 	void (*qc_prep)(struct ata_queued_cmd *qc);
 	unsigned int (*qc_issue)(struct ata_queued_cmd *qc);
+	bool (*qc_fill_rtf)(struct ata_queued_cmd *qc);
 
 	/*
 	 * Configuration and exception handling
@@ -1385,6 +1386,7 @@
 extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
 			    u8 status, int in_wq);
 extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc);
+extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc);
 extern unsigned int ata_sff_host_intr(struct ata_port *ap,
 				      struct ata_queued_cmd *qc);
 extern irqreturn_t ata_sff_interrupt(int irq, void *dev_instance);