diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/sata_nv.c | 32 |
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 | ||
1162 | static 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 | |||
1162 | static void nv_adma_qc_prep(struct ata_queued_cmd *qc) | 1179 | static 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 |