diff options
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 39a621d729e..0ecec9c1b49 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -112,12 +112,26 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, } status = atomic_read(&unit->status); - if (unlikely((status & ZFCP_STATUS_COMMON_ERP_FAILED) || - !(status & ZFCP_STATUS_COMMON_RUNNING))) { + if (unlikely(status & ZFCP_STATUS_COMMON_ERP_FAILED) && + !(atomic_read(&unit->port->status) & + ZFCP_STATUS_COMMON_ERP_FAILED)) { + /* only unit access denied, but port is good + * not covered by FC transport, have to fail here */ zfcp_scsi_command_fail(scpnt, DID_ERROR); return 0; } + if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) { + /* This could be either + * open unit pending: this is temporary, will result in + * open unit or ERP_FAILED, so retry command + * call to rport_delete pending: mimic retry from + * fc_remote_port_chkready until rport is BLOCKED + */ + zfcp_scsi_command_fail(scpnt, DID_IMM_RETRY); + return 0; + } + ret = zfcp_fsf_send_fcp_command_task(unit, scpnt); if (unlikely(ret == -EBUSY)) return SCSI_MLQUEUE_DEVICE_BUSY; |