|
@@ -219,6 +219,7 @@ struct nv_adma_port_priv {
|
|
|
void __iomem * gen_block;
|
|
|
void __iomem * notifier_clear_block;
|
|
|
u8 flags;
|
|
|
+ int last_issue_ncq;
|
|
|
};
|
|
|
|
|
|
struct nv_host_priv {
|
|
@@ -1260,6 +1261,7 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc)
|
|
|
{
|
|
|
struct nv_adma_port_priv *pp = qc->ap->private_data;
|
|
|
void __iomem *mmio = pp->ctl_block;
|
|
|
+ int curr_ncq = (qc->tf.protocol == ATA_PROT_NCQ);
|
|
|
|
|
|
VPRINTK("ENTER\n");
|
|
|
|
|
@@ -1274,6 +1276,14 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc)
|
|
|
/* write append register, command tag in lower 8 bits
|
|
|
and (number of cpbs to append -1) in top 8 bits */
|
|
|
wmb();
|
|
|
+
|
|
|
+ if(curr_ncq != pp->last_issue_ncq) {
|
|
|
+ /* Seems to need some delay before switching between NCQ and non-NCQ
|
|
|
+ commands, else we get command timeouts and such. */
|
|
|
+ udelay(20);
|
|
|
+ pp->last_issue_ncq = curr_ncq;
|
|
|
+ }
|
|
|
+
|
|
|
writew(qc->tag, mmio + NV_ADMA_APPEND);
|
|
|
|
|
|
DPRINTK("Issued tag %u\n",qc->tag);
|