diff options
author | Tejun Heo <htejun@gmail.com> | 2007-10-25 05:22:44 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-29 06:15:25 -0400 |
commit | 4dbfa39b6c95eb9d0aedb5bd00bb552b91c31e3d (patch) | |
tree | b3b92aa44fe651af464373d8a21a3da8897fa479 /drivers/ata | |
parent | 2a397e82c7db18019e408f953dd58dc1963a328c (diff) |
libata: relocate and fix post-command processing
Some commands need post-processing after successful completion. This
was done in ata_scsi_qc_complete() till now but this has the following
problems.
* Post-command processing gets executed when qc is completed from EH.
Some qc's are retried from EH with zero err_mask and thus triggers
unnecessary/incorrect post-command processing.
* Command post processing doesn't belong to SAT layer.
* Link-wide revalidation was scheduled where device revalidation
suffices.
This patch moves post-command processing to success completion path of
ata_qc_complete() which is travelled iff the command is going to be
completed without passing through EH and updates post-command
processing such that device-specific action is used. While at it,
restructure code a bit for readability.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 20 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 23 |
2 files changed, 20 insertions, 23 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 081e3dfb64d4..5aedd1af06e6 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -5594,6 +5594,9 @@ void ata_qc_complete(struct ata_queued_cmd *qc) | |||
5594 | * taken care of. | 5594 | * taken care of. |
5595 | */ | 5595 | */ |
5596 | if (ap->ops->error_handler) { | 5596 | if (ap->ops->error_handler) { |
5597 | struct ata_device *dev = qc->dev; | ||
5598 | struct ata_eh_info *ehi = &dev->link->eh_info; | ||
5599 | |||
5597 | WARN_ON(ap->pflags & ATA_PFLAG_FROZEN); | 5600 | WARN_ON(ap->pflags & ATA_PFLAG_FROZEN); |
5598 | 5601 | ||
5599 | if (unlikely(qc->err_mask)) | 5602 | if (unlikely(qc->err_mask)) |
@@ -5612,6 +5615,23 @@ void ata_qc_complete(struct ata_queued_cmd *qc) | |||
5612 | if (qc->flags & ATA_QCFLAG_RESULT_TF) | 5615 | if (qc->flags & ATA_QCFLAG_RESULT_TF) |
5613 | fill_result_tf(qc); | 5616 | fill_result_tf(qc); |
5614 | 5617 | ||
5618 | /* Some commands need post-processing after successful | ||
5619 | * completion. | ||
5620 | */ | ||
5621 | switch (qc->tf.command) { | ||
5622 | case ATA_CMD_SET_FEATURES: | ||
5623 | if (qc->tf.feature != SETFEATURES_WC_ON && | ||
5624 | qc->tf.feature != SETFEATURES_WC_OFF) | ||
5625 | break; | ||
5626 | /* fall through */ | ||
5627 | case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */ | ||
5628 | case ATA_CMD_SET_MULTI: /* multi_count changed */ | ||
5629 | /* revalidate device */ | ||
5630 | ehi->dev_action[dev->devno] |= ATA_EH_REVALIDATE; | ||
5631 | ata_port_schedule_eh(ap); | ||
5632 | break; | ||
5633 | } | ||
5634 | |||
5615 | __ata_qc_complete(qc); | 5635 | __ata_qc_complete(qc); |
5616 | } else { | 5636 | } else { |
5617 | if (qc->flags & ATA_QCFLAG_EH_SCHEDULED) | 5637 | if (qc->flags & ATA_QCFLAG_EH_SCHEDULED) |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index f5d5420a1ba2..f752eddc19ed 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -1361,33 +1361,10 @@ nothing_to_do: | |||
1361 | static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) | 1361 | static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) |
1362 | { | 1362 | { |
1363 | struct ata_port *ap = qc->ap; | 1363 | struct ata_port *ap = qc->ap; |
1364 | struct ata_eh_info *ehi = &qc->dev->link->eh_info; | ||
1365 | struct scsi_cmnd *cmd = qc->scsicmd; | 1364 | struct scsi_cmnd *cmd = qc->scsicmd; |
1366 | u8 *cdb = cmd->cmnd; | 1365 | u8 *cdb = cmd->cmnd; |
1367 | int need_sense = (qc->err_mask != 0); | 1366 | int need_sense = (qc->err_mask != 0); |
1368 | 1367 | ||
1369 | /* We snoop the SET_FEATURES - Write Cache ON/OFF command, and | ||
1370 | * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE | ||
1371 | * cache | ||
1372 | */ | ||
1373 | if (ap->ops->error_handler && !need_sense) { | ||
1374 | switch (qc->tf.command) { | ||
1375 | case ATA_CMD_SET_FEATURES: | ||
1376 | if ((qc->tf.feature == SETFEATURES_WC_ON) || | ||
1377 | (qc->tf.feature == SETFEATURES_WC_OFF)) { | ||
1378 | ehi->action |= ATA_EH_REVALIDATE; | ||
1379 | ata_port_schedule_eh(ap); | ||
1380 | } | ||
1381 | break; | ||
1382 | |||
1383 | case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */ | ||
1384 | case ATA_CMD_SET_MULTI: /* multi_count changed */ | ||
1385 | ehi->action |= ATA_EH_REVALIDATE; | ||
1386 | ata_port_schedule_eh(ap); | ||
1387 | break; | ||
1388 | } | ||
1389 | } | ||
1390 | |||
1391 | /* For ATA pass thru (SAT) commands, generate a sense block if | 1368 | /* For ATA pass thru (SAT) commands, generate a sense block if |
1392 | * user mandated it or if there's an error. Note that if we | 1369 | * user mandated it or if there's an error. Note that if we |
1393 | * generate because the user forced us to, a check condition | 1370 | * generate because the user forced us to, a check condition |