Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf13c082 authored by Swen Schillig's avatar Swen Schillig Committed by James Bottomley
Browse files

[SCSI] zfcp: prevent adapter close on initial adapter open



An adapter close was always performed whether it was required,
(e.g. in an error scenario) or not (e.g. initial open).
This patch is changing the process in only doing an
adapter close when it is required.

Signed-off-by: default avatarSwen Schillig <swen@vnet.ibm.com>
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 21283916
Loading
Loading
Loading
Loading
+34 −35
Original line number Original line Diff line number Diff line
@@ -705,32 +705,10 @@ static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *act)
	return ZFCP_ERP_SUCCEEDED;
	return ZFCP_ERP_SUCCEEDED;
}
}


static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *act,
static void zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *act)
					     int close)
{
{
	int retval = ZFCP_ERP_SUCCEEDED;
	struct zfcp_adapter *adapter = act->adapter;
	struct zfcp_adapter *adapter = act->adapter;


	if (close)
		goto close_only;

	retval = zfcp_erp_adapter_strategy_open_qdio(act);
	if (retval != ZFCP_ERP_SUCCEEDED)
		goto failed_qdio;

	retval = zfcp_erp_adapter_strategy_open_fsf(act);
	if (retval != ZFCP_ERP_SUCCEEDED)
		goto failed_openfcp;

	atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &act->adapter->status);

	return ZFCP_ERP_SUCCEEDED;

 close_only:
	atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
			  &act->adapter->status);

 failed_openfcp:
	/* close queues to ensure that buffers are not accessed by adapter */
	/* close queues to ensure that buffers are not accessed by adapter */
	zfcp_qdio_close(adapter);
	zfcp_qdio_close(adapter);
	zfcp_fsf_req_dismiss_all(adapter);
	zfcp_fsf_req_dismiss_all(adapter);
@@ -738,27 +716,48 @@ static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *act,
	/* all ports and units are closed */
	/* all ports and units are closed */
	zfcp_erp_modify_adapter_status(adapter, 24, NULL,
	zfcp_erp_modify_adapter_status(adapter, 24, NULL,
				       ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
				       ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
 failed_qdio:

	atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
			  ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
}

static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *act)
{
	struct zfcp_adapter *adapter = act->adapter;

	if (zfcp_erp_adapter_strategy_open_qdio(act)) {
		atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
		atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
				  ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
				  ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
			  &act->adapter->status);
				  &adapter->status);
	return retval;
		return ZFCP_ERP_FAILED;
	}

	if (zfcp_erp_adapter_strategy_open_fsf(act)) {
		zfcp_erp_adapter_strategy_close(act);
		return ZFCP_ERP_FAILED;
	}

	atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &adapter->status);

	return ZFCP_ERP_SUCCEEDED;
}
}


static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act)
static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act)
{
{
	int retval;
	struct zfcp_adapter *adapter = act->adapter;


	zfcp_erp_adapter_strategy_generic(act, 1); /* close */
	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN) {
		zfcp_erp_adapter_strategy_close(act);
		if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
		if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
			return ZFCP_ERP_EXIT;
			return ZFCP_ERP_EXIT;
	}


	retval = zfcp_erp_adapter_strategy_generic(act, 0); /* open */
	if (zfcp_erp_adapter_strategy_open(act)) {

	if (retval == ZFCP_ERP_FAILED)
		ssleep(8);
		ssleep(8);
		return ZFCP_ERP_FAILED;
	}


	return retval;
	return ZFCP_ERP_SUCCEEDED;
}
}


static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act)
static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act)