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>
This commit is contained in:
Родитель
2a397e82c7
Коммит
4dbfa39b6c
|
@ -5594,6 +5594,9 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
|
||||||
* taken care of.
|
* taken care of.
|
||||||
*/
|
*/
|
||||||
if (ap->ops->error_handler) {
|
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);
|
WARN_ON(ap->pflags & ATA_PFLAG_FROZEN);
|
||||||
|
|
||||||
if (unlikely(qc->err_mask))
|
if (unlikely(qc->err_mask))
|
||||||
|
@ -5612,6 +5615,23 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
|
||||||
if (qc->flags & ATA_QCFLAG_RESULT_TF)
|
if (qc->flags & ATA_QCFLAG_RESULT_TF)
|
||||||
fill_result_tf(qc);
|
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);
|
__ata_qc_complete(qc);
|
||||||
} else {
|
} else {
|
||||||
if (qc->flags & ATA_QCFLAG_EH_SCHEDULED)
|
if (qc->flags & ATA_QCFLAG_EH_SCHEDULED)
|
||||||
|
|
|
@ -1361,33 +1361,10 @@ nothing_to_do:
|
||||||
static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
|
static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = qc->ap;
|
struct ata_port *ap = qc->ap;
|
||||||
struct ata_eh_info *ehi = &qc->dev->link->eh_info;
|
|
||||||
struct scsi_cmnd *cmd = qc->scsicmd;
|
struct scsi_cmnd *cmd = qc->scsicmd;
|
||||||
u8 *cdb = cmd->cmnd;
|
u8 *cdb = cmd->cmnd;
|
||||||
int need_sense = (qc->err_mask != 0);
|
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
|
/* For ATA pass thru (SAT) commands, generate a sense block if
|
||||||
* user mandated it or if there's an error. Note that if we
|
* user mandated it or if there's an error. Note that if we
|
||||||
* generate because the user forced us to, a check condition
|
* generate because the user forced us to, a check condition
|
||||||
|
|
Загрузка…
Ссылка в новой задаче