|
@@ -260,6 +260,7 @@ static int nv_adma_port_resume(struct ata_port *ap);
|
|
|
static void nv_adma_error_handler(struct ata_port *ap);
|
|
|
static void nv_adma_host_stop(struct ata_host *host);
|
|
|
static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc);
|
|
|
+static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
|
|
|
|
|
|
enum nv_host_type
|
|
|
{
|
|
@@ -435,7 +436,7 @@ static const struct ata_port_operations nv_ck804_ops = {
|
|
|
static const struct ata_port_operations nv_adma_ops = {
|
|
|
.port_disable = ata_port_disable,
|
|
|
.tf_load = ata_tf_load,
|
|
|
- .tf_read = ata_tf_read,
|
|
|
+ .tf_read = nv_adma_tf_read,
|
|
|
.check_atapi_dma = nv_adma_check_atapi_dma,
|
|
|
.exec_command = ata_exec_command,
|
|
|
.check_status = ata_check_status,
|
|
@@ -667,6 +668,18 @@ static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc)
|
|
|
return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
|
|
|
}
|
|
|
|
|
|
+static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
|
|
+{
|
|
|
+ /* Since commands where a result TF is requested are not
|
|
|
+ executed in ADMA mode, the only time this function will be called
|
|
|
+ in ADMA mode will be if a command fails. In this case we
|
|
|
+ don't care about going into register mode with ADMA commands
|
|
|
+ pending, as the commands will all shortly be aborted anyway. */
|
|
|
+ nv_adma_register_mode(ap);
|
|
|
+
|
|
|
+ ata_tf_read(ap, tf);
|
|
|
+}
|
|
|
+
|
|
|
static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
|
|
|
{
|
|
|
unsigned int idx = 0;
|
|
@@ -738,19 +751,11 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
- if (flags & NV_CPB_RESP_DONE) {
|
|
|
+ if (likely(flags & NV_CPB_RESP_DONE)) {
|
|
|
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
|
|
|
VPRINTK("CPB flags done, flags=0x%x\n", flags);
|
|
|
if (likely(qc)) {
|
|
|
- /* Grab the ATA port status for non-NCQ commands.
|
|
|
- For NCQ commands the current status may have nothing to do with
|
|
|
- the command just completed. */
|
|
|
- if (qc->tf.protocol != ATA_PROT_NCQ) {
|
|
|
- u8 ata_status = readb(pp->ctl_block + (ATA_REG_STATUS * 4));
|
|
|
- qc->err_mask |= ac_err_mask(ata_status);
|
|
|
- }
|
|
|
- DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num,
|
|
|
- qc->err_mask);
|
|
|
+ DPRINTK("Completing qc from tag %d\n",cpb_num);
|
|
|
ata_qc_complete(qc);
|
|
|
} else {
|
|
|
struct ata_eh_info *ehi = &ap->eh_info;
|
|
@@ -1167,9 +1172,11 @@ static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc)
|
|
|
struct nv_adma_port_priv *pp = qc->ap->private_data;
|
|
|
|
|
|
/* ADMA engine can only be used for non-ATAPI DMA commands,
|
|
|
- or interrupt-driven no-data commands. */
|
|
|
+ or interrupt-driven no-data commands, where a result taskfile
|
|
|
+ is not required. */
|
|
|
if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) ||
|
|
|
- (qc->tf.flags & ATA_TFLAG_POLLING))
|
|
|
+ (qc->tf.flags & ATA_TFLAG_POLLING) ||
|
|
|
+ (qc->flags & ATA_QCFLAG_RESULT_TF))
|
|
|
return 1;
|
|
|
|
|
|
if((qc->flags & ATA_QCFLAG_DMAMAP) ||
|