From 4ab8dafa792af9d6fde24b649fa634cb5b375495 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 12 Aug 2024 12:29:22 -0700 Subject: [PATCH] FROMLIST: scsi: core: Retry passthrough commands if SCMD_RETRY_PASSTHROUGH is set The SCSI core does not retry passthrough commands even if the SCSI device reports a retryable unit attention condition. Support retrying in this case by introducing the SCMD_RETRY_PASSTHROUGH flag. Cc: Damien Le Moal Cc: Mike Christie Signed-off-by: Bart Van Assche Signed-off-by: Bart Van Assche Bug: 348341595 Link: https://lore.kernel.org/linux-scsi/yq17ccp1i4b.fsf@ca-mkp.ca.oracle.com/T/#mfdb1a3a0d6d4803afe1098bdafc12fd4168e30e0 Change-Id: I44092a0d8853fd61bf619e5bae6d65eaaddad780 Signed-off-by: Bart Van Assche --- drivers/scsi/scsi_error.c | 5 ++++- include/scsi/scsi_cmnd.h | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index da7dac77f8cd..fc01cbe63ab7 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1816,7 +1816,10 @@ check_type: * assume caller has checked sense and determined * the check condition was retryable. */ - if (req->cmd_flags & REQ_FAILFAST_DEV || blk_rq_is_passthrough(req)) + if (req->cmd_flags & REQ_FAILFAST_DEV) + return true; + if (blk_rq_is_passthrough(req) && + !(scmd->flags & SCMD_RETRY_PASSTHROUGH)) return true; return false; diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index ce930d1fc2cc..dd3bd080bba4 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -54,8 +54,11 @@ struct scsi_pointer { #define SCMD_INITIALIZED (1 << 1) #define SCMD_LAST (1 << 2) #define SCMD_FAIL_IF_RECOVERING (1 << 4) +/* If set, retry a passthrough command in case of a unit attention. */ +#define SCMD_RETRY_PASSTHROUGH (1 << 5) /* flags preserved across unprep / reprep */ -#define SCMD_PRESERVED_FLAGS (SCMD_INITIALIZED | SCMD_FAIL_IF_RECOVERING) +#define SCMD_PRESERVED_FLAGS \ + (SCMD_INITIALIZED | SCMD_FAIL_IF_RECOVERING | SCMD_RETRY_PASSTHROUGH) /* for scmd->state */ #define SCMD_STATE_COMPLETE 0