diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/sata_nv.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 44f9e5d9e362..ed5dc7cb50cd 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -791,11 +791,13 @@ static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc) | |||
791 | 791 | ||
792 | static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | 792 | static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf) |
793 | { | 793 | { |
794 | /* Since commands where a result TF is requested are not | 794 | /* Other than when internal or pass-through commands are executed, |
795 | executed in ADMA mode, the only time this function will be called | 795 | the only time this function will be called in ADMA mode will be |
796 | in ADMA mode will be if a command fails. In this case we | 796 | if a command fails. In the failure case we don't care about going |
797 | don't care about going into register mode with ADMA commands | 797 | into register mode with ADMA commands pending, as the commands will |
798 | pending, as the commands will all shortly be aborted anyway. */ | 798 | all shortly be aborted anyway. We assume that NCQ commands are not |
799 | issued via passthrough, which is the only way that switching into | ||
800 | ADMA mode could abort outstanding commands. */ | ||
799 | nv_adma_register_mode(ap); | 801 | nv_adma_register_mode(ap); |
800 | 802 | ||
801 | ata_tf_read(ap, tf); | 803 | ata_tf_read(ap, tf); |
@@ -1359,11 +1361,9 @@ static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc) | |||
1359 | struct nv_adma_port_priv *pp = qc->ap->private_data; | 1361 | struct nv_adma_port_priv *pp = qc->ap->private_data; |
1360 | 1362 | ||
1361 | /* ADMA engine can only be used for non-ATAPI DMA commands, | 1363 | /* ADMA engine can only be used for non-ATAPI DMA commands, |
1362 | or interrupt-driven no-data commands, where a result taskfile | 1364 | or interrupt-driven no-data commands. */ |
1363 | is not required. */ | ||
1364 | if ((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) || | 1365 | if ((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) || |
1365 | (qc->tf.flags & ATA_TFLAG_POLLING) || | 1366 | (qc->tf.flags & ATA_TFLAG_POLLING)) |
1366 | (qc->flags & ATA_QCFLAG_RESULT_TF)) | ||
1367 | return 1; | 1367 | return 1; |
1368 | 1368 | ||
1369 | if ((qc->flags & ATA_QCFLAG_DMAMAP) || | 1369 | if ((qc->flags & ATA_QCFLAG_DMAMAP) || |
@@ -1381,6 +1381,8 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc) | |||
1381 | NV_CPB_CTL_IEN; | 1381 | NV_CPB_CTL_IEN; |
1382 | 1382 | ||
1383 | if (nv_adma_use_reg_mode(qc)) { | 1383 | if (nv_adma_use_reg_mode(qc)) { |
1384 | BUG_ON(!(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) && | ||
1385 | (qc->flags & ATA_QCFLAG_DMAMAP)); | ||
1384 | nv_adma_register_mode(qc->ap); | 1386 | nv_adma_register_mode(qc->ap); |
1385 | ata_qc_prep(qc); | 1387 | ata_qc_prep(qc); |
1386 | return; | 1388 | return; |
@@ -1425,9 +1427,21 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc) | |||
1425 | 1427 | ||
1426 | VPRINTK("ENTER\n"); | 1428 | VPRINTK("ENTER\n"); |
1427 | 1429 | ||
1430 | /* We can't handle result taskfile with NCQ commands, since | ||
1431 | retrieving the taskfile switches us out of ADMA mode and would abort | ||
1432 | existing commands. */ | ||
1433 | if (unlikely(qc->tf.protocol == ATA_PROT_NCQ && | ||
1434 | (qc->flags & ATA_QCFLAG_RESULT_TF))) { | ||
1435 | ata_dev_printk(qc->dev, KERN_ERR, | ||
1436 | "NCQ w/ RESULT_TF not allowed\n"); | ||
1437 | return AC_ERR_SYSTEM; | ||
1438 | } | ||
1439 | |||
1428 | if (nv_adma_use_reg_mode(qc)) { | 1440 | if (nv_adma_use_reg_mode(qc)) { |
1429 | /* use ATA register mode */ | 1441 | /* use ATA register mode */ |
1430 | VPRINTK("using ATA register mode: 0x%lx\n", qc->flags); | 1442 | VPRINTK("using ATA register mode: 0x%lx\n", qc->flags); |
1443 | BUG_ON(!(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) && | ||
1444 | (qc->flags & ATA_QCFLAG_DMAMAP)); | ||
1431 | nv_adma_register_mode(qc->ap); | 1445 | nv_adma_register_mode(qc->ap); |
1432 | return ata_qc_issue_prot(qc); | 1446 | return ata_qc_issue_prot(qc); |
1433 | } else | 1447 | } else |