aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/sata_nv.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 3dd5ca16a2ba..19817b376161 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1159,16 +1159,31 @@ static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb)
1159 cpb->next_aprd = cpu_to_le64(((u64)(pp->aprd_dma + NV_ADMA_SGTBL_SZ * qc->tag))); 1159 cpb->next_aprd = cpu_to_le64(((u64)(pp->aprd_dma + NV_ADMA_SGTBL_SZ * qc->tag)));
1160} 1160}
1161 1161
1162static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc)
1163{
1164 struct nv_adma_port_priv *pp = qc->ap->private_data;
1165
1166 /* ADMA engine can only be used for non-ATAPI DMA commands,
1167 or interrupt-driven no-data commands. */
1168 if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) ||
1169 (qc->tf.flags & ATA_TFLAG_POLLING))
1170 return 1;
1171
1172 if((qc->flags & ATA_QCFLAG_DMAMAP) ||
1173 (qc->tf.protocol == ATA_PROT_NODATA))
1174 return 0;
1175
1176 return 1;
1177}
1178
1162static void nv_adma_qc_prep(struct ata_queued_cmd *qc) 1179static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
1163{ 1180{
1164 struct nv_adma_port_priv *pp = qc->ap->private_data; 1181 struct nv_adma_port_priv *pp = qc->ap->private_data;
1165 struct nv_adma_cpb *cpb = &pp->cpb[qc->tag]; 1182 struct nv_adma_cpb *cpb = &pp->cpb[qc->tag];
1166 u8 ctl_flags = NV_CPB_CTL_CPB_VALID | 1183 u8 ctl_flags = NV_CPB_CTL_CPB_VALID |
1167 NV_CPB_CTL_APRD_VALID |
1168 NV_CPB_CTL_IEN; 1184 NV_CPB_CTL_IEN;
1169 1185
1170 if (!(qc->flags & ATA_QCFLAG_DMAMAP) || 1186 if (nv_adma_use_reg_mode(qc)) {
1171 (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) {
1172 nv_adma_register_mode(qc->ap); 1187 nv_adma_register_mode(qc->ap);
1173 ata_qc_prep(qc); 1188 ata_qc_prep(qc);
1174 return; 1189 return;
@@ -1188,7 +1203,11 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
1188 1203
1189 nv_adma_tf_to_cpb(&qc->tf, cpb->tf); 1204 nv_adma_tf_to_cpb(&qc->tf, cpb->tf);
1190 1205
1191 nv_adma_fill_sg(qc, cpb); 1206 if(qc->flags & ATA_QCFLAG_DMAMAP) {
1207 nv_adma_fill_sg(qc, cpb);
1208 ctl_flags |= NV_CPB_CTL_APRD_VALID;
1209 } else
1210 memset(&cpb->aprd[0], 0, sizeof(struct nv_adma_prd) * 5);
1192 1211
1193 /* Be paranoid and don't let the device see NV_CPB_CTL_CPB_VALID until we are 1212 /* Be paranoid and don't let the device see NV_CPB_CTL_CPB_VALID until we are
1194 finished filling in all of the contents */ 1213 finished filling in all of the contents */
@@ -1203,10 +1222,9 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc)
1203 1222
1204 VPRINTK("ENTER\n"); 1223 VPRINTK("ENTER\n");
1205 1224
1206 if (!(qc->flags & ATA_QCFLAG_DMAMAP) || 1225 if (nv_adma_use_reg_mode(qc)) {
1207 (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) {
1208 /* use ATA register mode */ 1226 /* use ATA register mode */
1209 VPRINTK("no dmamap or ATAPI, using ATA register mode: 0x%lx\n", qc->flags); 1227 VPRINTK("using ATA register mode: 0x%lx\n", qc->flags);
1210 nv_adma_register_mode(qc->ap); 1228 nv_adma_register_mode(qc->ap);
1211 return ata_qc_issue_prot(qc); 1229 return ata_qc_issue_prot(qc);
1212 } else 1230 } else