@@ -373,9 +373,11 @@ static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
{
- struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
- struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
- int ret = SUCCESS, fc_ret;
+ struct Scsi_Host *host = scpnt->device->host;
+ struct zfcp_adapter *adapter = (struct zfcp_adapter *)host->hostdata[0];
+ int ret = SUCCESS;
+ unsigned long flags;
+ struct zfcp_port *port;
if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) {
zfcp_erp_port_forced_reopen_all(adapter, 0, "schrh_p");
@@ -383,9 +385,24 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
}
zfcp_erp_adapter_reopen(adapter, 0, "schrh_1");
zfcp_erp_wait(adapter);
- fc_ret = fc_block_scsi_eh(scpnt);
- if (fc_ret)
- ret = fc_ret;
+retry_rport_blocked:
+ spin_lock_irqsave(host->host_lock, flags);
+ list_for_each_entry(port, &adapter->port_list, list) {
+ struct fc_rport *rport = port->rport;
+
+ if (rport->port_state == FC_PORTSTATE_BLOCKED) {
+ if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)
+ ret = FAST_IO_FAIL;
+ else
+ ret = NEEDS_RETRY;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(host->host_lock, flags);
+ if (ret == NEEDS_RETRY) {
+ msleep(1000);
+ goto retry_rport_blocked;
+ }
zfcp_dbf_scsi_eh("schrh_r", adapter, ~0, ret);
return ret;
When issuing a host reset we should be waiting for all ports to become unblocked; just waiting for one might be resulting in host reset to return too early. Signed-off-by: Hannes Reinecke <hare@suse.com> Cc: Steffen Maier <maier@linux.ibm.com> Cc: Benjamin Block <bblock@linux.ibm.com> --- drivers/s390/scsi/zfcp_scsi.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-)