Skip to content

Commit

Permalink
libata: relocate and fix post-command processing
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Oct 29, 2007
1 parent 2a397e8 commit 4dbfa39
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 23 deletions.
20 changes: 20 additions & 0 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -5594,6 +5594,9 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
* taken care of.
*/
if (ap->ops->error_handler) {
struct ata_device *dev = qc->dev;
struct ata_eh_info *ehi = &dev->link->eh_info;

WARN_ON(ap->pflags & ATA_PFLAG_FROZEN);

if (unlikely(qc->err_mask))
Expand All @@ -5612,6 +5615,23 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
if (qc->flags & ATA_QCFLAG_RESULT_TF)
fill_result_tf(qc);

/* Some commands need post-processing after successful
* completion.
*/
switch (qc->tf.command) {
case ATA_CMD_SET_FEATURES:
if (qc->tf.feature != SETFEATURES_WC_ON &&
qc->tf.feature != SETFEATURES_WC_OFF)
break;
/* fall through */
case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
case ATA_CMD_SET_MULTI: /* multi_count changed */
/* revalidate device */
ehi->dev_action[dev->devno] |= ATA_EH_REVALIDATE;
ata_port_schedule_eh(ap);
break;
}

__ata_qc_complete(qc);
} else {
if (qc->flags & ATA_QCFLAG_EH_SCHEDULED)
Expand Down
23 changes: 0 additions & 23 deletions drivers/ata/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1361,33 +1361,10 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_eh_info *ehi = &qc->dev->link->eh_info;
struct scsi_cmnd *cmd = qc->scsicmd;
u8 *cdb = cmd->cmnd;
int need_sense = (qc->err_mask != 0);

/* We snoop the SET_FEATURES - Write Cache ON/OFF command, and
* schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
* cache
*/
if (ap->ops->error_handler && !need_sense) {
switch (qc->tf.command) {
case ATA_CMD_SET_FEATURES:
if ((qc->tf.feature == SETFEATURES_WC_ON) ||
(qc->tf.feature == SETFEATURES_WC_OFF)) {
ehi->action |= ATA_EH_REVALIDATE;
ata_port_schedule_eh(ap);
}
break;

case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
case ATA_CMD_SET_MULTI: /* multi_count changed */
ehi->action |= ATA_EH_REVALIDATE;
ata_port_schedule_eh(ap);
break;
}
}

/* For ATA pass thru (SAT) commands, generate a sense block if
* user mandated it or if there's an error. Note that if we
* generate because the user forced us to, a check condition
Expand Down

0 comments on commit 4dbfa39

Please sign in to comment.