aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-15 08:03:45 -0400
committerTejun Heo <htejun@gmail.com>2006-05-15 08:03:45 -0400
commit3dc1d88193b9c65b01b64fb2dc730e486306649f (patch)
tree1ffba999eadfe0e5b704d8ee9163483ef31e0591 /drivers
parentdedaf2b0365ccec50714fbde0b3215e7e94fa47c (diff)
[PATCH] libata-ncq: implement NCQ command translation and exclusion
This patch implements NCQ command translation and exclusion. Note that NCQ commands don't use ata_rwcmd_protocol() to choose ATA command. This is because, unlike non-NCQ RW commands, NCQ commands can only be used for NCQ protocol and FUA handling is done with a flag rather than separate command. NCQ enabled device will have queue depth larger than one but no two non-NCQ commands can be issued simultaneously, neither can a non-NCQ command and NCQ commands. This patch makes ata_scsi_translate() return SCSI_MLQUEUE_DEVICE_BUSY if such exclusion is necessary. SCSI midlayer will retry the command later. As SCSI midlayer always retries once a command completes, this doesn't incur unnecessary delays and as most commands will be NCQ ones for NCQ device, so the overhead should be negligible. Initial implementation is from Jens Axboe and using SCSI_MLQUEUE_DEVICE_BUSY for exclusion is suggested by Jeff Garzik. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers')
-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/**