aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libata-core.c1
-rw-r--r--drivers/scsi/libata-scsi.c72
2 files changed, 72 insertions, 1 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index eea1fe9c8b79..14ffb5264b65 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -4416,6 +4416,7 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
4416 struct ata_port *ap = qc->ap; 4416 struct ata_port *ap = qc->ap;
4417 4417
4418 switch (qc->tf.protocol) { 4418 switch (qc->tf.protocol) {
4419 case ATA_PROT_NCQ:
4419 case ATA_PROT_DMA: 4420 case ATA_PROT_DMA:
4420 case ATA_PROT_ATAPI_DMA: 4421 case ATA_PROT_ATAPI_DMA:
4421 return 1; 4422 return 1;
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 96517ca021e3..9bef68c7c1de 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1103,7 +1103,36 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
1103 */ 1103 */
1104 goto nothing_to_do; 1104 goto nothing_to_do;
1105 1105
1106 if (dev->flags & ATA_DFLAG_LBA) { 1106 if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) {
1107 /* yay, NCQ */
1108 if (!lba_48_ok(block, n_block))
1109 goto out_of_range;
1110
1111 tf->protocol = ATA_PROT_NCQ;
1112 tf->flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
1113
1114 if (tf->flags & ATA_TFLAG_WRITE)
1115 tf->command = ATA_CMD_FPDMA_WRITE;
1116 else
1117 tf->command = ATA_CMD_FPDMA_READ;
1118
1119 qc->nsect = n_block;
1120
1121 tf->nsect = qc->tag << 3;
1122 tf->hob_feature = (n_block >> 8) & 0xff;
1123 tf->feature = n_block & 0xff;
1124
1125 tf->hob_lbah = (block >> 40) & 0xff;
1126 tf->hob_lbam = (block >> 32) & 0xff;
1127 tf->hob_lbal = (block >> 24) & 0xff;
1128 tf->lbah = (block >> 16) & 0xff;
1129 tf->lbam = (block >> 8) & 0xff;
1130 tf->lbal = block & 0xff;
1131
1132 tf->device = 1 << 6;
1133 if (tf->flags & ATA_TFLAG_FUA)
1134 tf->device |= 1 << 7;
1135 } else if (dev->flags & ATA_DFLAG_LBA) {
1107 tf->flags |= ATA_TFLAG_LBA; 1136 tf->flags |= ATA_TFLAG_LBA;
1108 1137
1109 if (lba_28_ok(block, n_block)) { 1138 if (lba_28_ok(block, n_block)) {
@@ -1227,6 +1256,39 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
1227} 1256}
1228 1257
1229/** 1258/**
1259 * ata_scmd_need_defer - Check whether we need to defer scmd
1260 * @dev: ATA device to which the command is addressed
1261 * @is_io: Is the command IO (and thus possibly NCQ)?
1262 *
1263 * NCQ and non-NCQ commands cannot run together. As upper layer
1264 * only knows the queue depth, we are responsible for maintaining
1265 * exclusion. This function checks whether a new command can be
1266 * issued to @dev.
1267 *
1268 * LOCKING:
1269 * spin_lock_irqsave(host_set lock)
1270 *
1271 * RETURNS:
1272 * 1 if deferring is needed, 0 otherwise.
1273 */
1274static int ata_scmd_need_defer(struct ata_device *dev, int is_io)
1275{
1276 struct ata_port *ap = dev->ap;
1277
1278 if (!(dev->flags & ATA_DFLAG_NCQ))
1279 return 0;
1280
1281 if (is_io) {
1282 if (!ata_tag_valid(ap->active_tag))
1283 return 0;
1284 } else {
1285 if (!ata_tag_valid(ap->active_tag) && !ap->sactive)
1286 return 0;
1287 }
1288 return 1;
1289}
1290
1291/**
1230 * ata_scsi_translate - Translate then issue SCSI command to ATA device 1292 * ata_scsi_translate - Translate then issue SCSI command to ATA device
1231 * @dev: ATA device to which the command is addressed 1293 * @dev: ATA device to which the command is addressed
1232 * @cmd: SCSI command to execute 1294 * @cmd: SCSI command to execute
@@ -1259,9 +1321,13 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
1259{ 1321{
1260 struct ata_queued_cmd *qc; 1322 struct ata_queued_cmd *qc;
1261 u8 *scsicmd = cmd->cmnd; 1323 u8 *scsicmd = cmd->cmnd;
1324 int is_io = xlat_func == ata_scsi_rw_xlat;
1262 1325
1263 VPRINTK("ENTER\n"); 1326 VPRINTK("ENTER\n");
1264 1327
1328 if (unlikely(ata_scmd_need_defer(dev, is_io)))
1329 goto defer;
1330
1265 qc = ata_scsi_qc_new(dev, cmd, done); 1331 qc = ata_scsi_qc_new(dev, cmd, done);
1266 if (!qc) 1332 if (!qc)
1267 goto err_mem; 1333 goto err_mem;
@@ -1308,6 +1374,10 @@ err_mem:
1308 done(cmd); 1374 done(cmd);
1309 DPRINTK("EXIT - internal\n"); 1375 DPRINTK("EXIT - internal\n");
1310 return 0; 1376 return 0;
1377
1378defer:
1379 DPRINTK("EXIT - defer\n");
1380 return SCSI_MLQUEUE_DEVICE_BUSY;
1311} 1381}
1312 1382
1313/** 1383/**