aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Hancock <hancockr@shaw.ca>2007-03-27 01:43:36 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-28 14:16:00 -0400
commitf2fb344beadf79f9d265c3fc60e8399bbf917a4d (patch)
tree2f9c3f269329484b60a3d89e2ffb6b60d67dd4a7
parent4dc5200d70a3e81510956c35fbb9fa3c15b440a5 (diff)
sata_nv: don't read shadow registers when in ADMA mode
Reading from the ATA shadow registers while we are in ADMA mode may cause undefined behavior. Don't read the ATA status register when completing commands for this reason, it shouldn't be needed as the controller will notify us if the command failed. Also, don't allow commands with result taskfile requested to execute in ADMA mode, since that requires accessing the shadow registers. We also still need to override tf_read since libata will read the result taskfile on a command failure, and we need to go into port register mode before allowing this. Signed-off-by: Robert Hancock <hancockr@shaw.ca> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/sata_nv.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 9d9670a9b117..8a9473b16ec3 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -260,6 +260,7 @@ static int nv_adma_port_resume(struct ata_port *ap);
260static void nv_adma_error_handler(struct ata_port *ap); 260static void nv_adma_error_handler(struct ata_port *ap);
261static void nv_adma_host_stop(struct ata_host *host); 261static void nv_adma_host_stop(struct ata_host *host);
262static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc); 262static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc);
263static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
263 264
264enum nv_host_type 265enum nv_host_type
265{ 266{
@@ -435,7 +436,7 @@ static const struct ata_port_operations nv_ck804_ops = {
435static const struct ata_port_operations nv_adma_ops = { 436static const struct ata_port_operations nv_adma_ops = {
436 .port_disable = ata_port_disable, 437 .port_disable = ata_port_disable,
437 .tf_load = ata_tf_load, 438 .tf_load = ata_tf_load,
438 .tf_read = ata_tf_read, 439 .tf_read = nv_adma_tf_read,
439 .check_atapi_dma = nv_adma_check_atapi_dma, 440 .check_atapi_dma = nv_adma_check_atapi_dma,
440 .exec_command = ata_exec_command, 441 .exec_command = ata_exec_command,
441 .check_status = ata_check_status, 442 .check_status = ata_check_status,
@@ -667,6 +668,18 @@ static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc)
667 return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE); 668 return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
668} 669}
669 670
671static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
672{
673 /* Since commands where a result TF is requested are not
674 executed in ADMA mode, the only time this function will be called
675 in ADMA mode will be if a command fails. In this case we
676 don't care about going into register mode with ADMA commands
677 pending, as the commands will all shortly be aborted anyway. */
678 nv_adma_register_mode(ap);
679
680 ata_tf_read(ap, tf);
681}
682
670static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb) 683static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
671{ 684{
672 unsigned int idx = 0; 685 unsigned int idx = 0;
@@ -738,19 +751,11 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
738 return 1; 751 return 1;
739 } 752 }
740 753
741 if (flags & NV_CPB_RESP_DONE) { 754 if (likely(flags & NV_CPB_RESP_DONE)) {
742 struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num); 755 struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
743 VPRINTK("CPB flags done, flags=0x%x\n", flags); 756 VPRINTK("CPB flags done, flags=0x%x\n", flags);
744 if (likely(qc)) { 757 if (likely(qc)) {
745 /* Grab the ATA port status for non-NCQ commands. 758 DPRINTK("Completing qc from tag %d\n",cpb_num);
746 For NCQ commands the current status may have nothing to do with
747 the command just completed. */
748 if (qc->tf.protocol != ATA_PROT_NCQ) {
749 u8 ata_status = readb(pp->ctl_block + (ATA_REG_STATUS * 4));
750 qc->err_mask |= ac_err_mask(ata_status);
751 }
752 DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num,
753 qc->err_mask);
754 ata_qc_complete(qc); 759 ata_qc_complete(qc);
755 } else { 760 } else {
756 struct ata_eh_info *ehi = &ap->eh_info; 761 struct ata_eh_info *ehi = &ap->eh_info;
@@ -1167,9 +1172,11 @@ static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc)
1167 struct nv_adma_port_priv *pp = qc->ap->private_data; 1172 struct nv_adma_port_priv *pp = qc->ap->private_data;
1168 1173
1169 /* ADMA engine can only be used for non-ATAPI DMA commands, 1174 /* ADMA engine can only be used for non-ATAPI DMA commands,
1170 or interrupt-driven no-data commands. */ 1175 or interrupt-driven no-data commands, where a result taskfile
1176 is not required. */
1171 if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) || 1177 if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) ||
1172 (qc->tf.flags & ATA_TFLAG_POLLING)) 1178 (qc->tf.flags & ATA_TFLAG_POLLING) ||
1179 (qc->flags & ATA_QCFLAG_RESULT_TF))
1173 return 1; 1180 return 1;
1174 1181
1175 if((qc->flags & ATA_QCFLAG_DMAMAP) || 1182 if((qc->flags & ATA_QCFLAG_DMAMAP) ||