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

Commit d736a27b authored by Andreas Herrmann's avatar Andreas Herrmann Committed by James Bottomley
Browse files

[SCSI] zfcp: fix handling of port boxed and lun boxed fsf states



From: Maxim Shchetynin <maxim@de.ibm.com>

Signed-off-by: default avatarAndreas Herrmann <aherrman@de.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent cd8a383e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -490,6 +490,7 @@ do { \
#define ZFCP_STATUS_COMMON_CLOSING              0x02000000
#define ZFCP_STATUS_COMMON_ERP_INUSE		0x01000000
#define ZFCP_STATUS_COMMON_ACCESS_DENIED	0x00800000
#define ZFCP_STATUS_COMMON_ACCESS_BOXED		0x00400000

/* adapter status */
#define ZFCP_STATUS_ADAPTER_QDIOUP		0x00000002
+58 −10
Original line number Diff line number Diff line
@@ -3481,6 +3481,45 @@ zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action)
	list_move(&erp_action->list, &erp_action->adapter->erp_ready_head);
}

/*
 * function:	zfcp_erp_port_boxed
 *
 * purpose:
 */
void
zfcp_erp_port_boxed(struct zfcp_port *port)
{
	struct zfcp_adapter *adapter = port->adapter;
	unsigned long flags;

	debug_text_event(adapter->erp_dbf, 3, "p_access_boxed");
	debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
	read_lock_irqsave(&zfcp_data.config_lock, flags);
	zfcp_erp_modify_port_status(port,
			ZFCP_STATUS_COMMON_ACCESS_BOXED,
			ZFCP_SET);
	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
	zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED);
}

/*
 * function:	zfcp_erp_unit_boxed
 *
 * purpose:
 */
void
zfcp_erp_unit_boxed(struct zfcp_unit *unit)
{
	struct zfcp_adapter *adapter = unit->port->adapter;

	debug_text_event(adapter->erp_dbf, 3, "u_access_boxed");
	debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
	zfcp_erp_modify_unit_status(unit,
			ZFCP_STATUS_COMMON_ACCESS_BOXED,
			ZFCP_SET);
	zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
}

/*
 * function:	zfcp_erp_port_access_denied
 *
@@ -3492,11 +3531,13 @@ zfcp_erp_port_access_denied(struct zfcp_port *port)
	struct zfcp_adapter *adapter = port->adapter;
	unsigned long flags;

	debug_text_event(adapter->erp_dbf, 3, "p_access_block");
	debug_text_event(adapter->erp_dbf, 3, "p_access_denied");
	debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
	read_lock_irqsave(&zfcp_data.config_lock, flags);
	zfcp_erp_modify_port_status(port, ZFCP_STATUS_COMMON_ERP_FAILED |
				    ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
	zfcp_erp_modify_port_status(port,
			ZFCP_STATUS_COMMON_ERP_FAILED |
			ZFCP_STATUS_COMMON_ACCESS_DENIED,
			ZFCP_SET);
	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
}

@@ -3510,10 +3551,12 @@ zfcp_erp_unit_access_denied(struct zfcp_unit *unit)
{
	struct zfcp_adapter *adapter = unit->port->adapter;

	debug_text_event(adapter->erp_dbf, 3, "u_access_block");
	debug_text_event(adapter->erp_dbf, 3, "u_access_denied");
	debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
	zfcp_erp_modify_unit_status(unit, ZFCP_STATUS_COMMON_ERP_FAILED |
				    ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
	zfcp_erp_modify_unit_status(unit,
			ZFCP_STATUS_COMMON_ERP_FAILED |
			ZFCP_STATUS_COMMON_ACCESS_DENIED,
			ZFCP_SET);
}

/*
@@ -3527,7 +3570,7 @@ zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
	struct zfcp_port *port;
	unsigned long flags;

	debug_text_event(adapter->erp_dbf, 3, "a_access_unblock");
	debug_text_event(adapter->erp_dbf, 3, "a_access_recover");
	debug_event(adapter->erp_dbf, 3, &adapter->name, 8);

	read_lock_irqsave(&zfcp_data.config_lock, flags);
@@ -3550,10 +3593,12 @@ zfcp_erp_port_access_changed(struct zfcp_port *port)
	struct zfcp_adapter *adapter = port->adapter;
	struct zfcp_unit *unit;

	debug_text_event(adapter->erp_dbf, 3, "p_access_unblock");
	debug_text_event(adapter->erp_dbf, 3, "p_access_recover");
	debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));

	if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
			      &port->status) &&
	    !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
			      &port->status)) {
		if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
			list_for_each_entry(unit, &port->unit_list_head, list)
@@ -3580,10 +3625,13 @@ zfcp_erp_unit_access_changed(struct zfcp_unit *unit)
{
	struct zfcp_adapter *adapter = unit->port->adapter;

	debug_text_event(adapter->erp_dbf, 3, "u_access_unblock");
	debug_text_event(adapter->erp_dbf, 3, "u_access_recover");
	debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));

	if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, &unit->status))
	if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
			      &unit->status) &&
	    !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
			      &unit->status))
		return;

	ZFCP_LOG_NORMAL("reopen of unit 0x%016Lx on port 0x%016Lx "
+2 −0
Original line number Diff line number Diff line
@@ -171,6 +171,8 @@ extern int zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long);

extern int  zfcp_test_link(struct zfcp_port *);

extern void zfcp_erp_port_boxed(struct zfcp_port *);
extern void zfcp_erp_unit_boxed(struct zfcp_unit *);
extern void zfcp_erp_port_access_denied(struct zfcp_port *);
extern void zfcp_erp_unit_access_denied(struct zfcp_unit *);
extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *);
+14 −18
Original line number Diff line number Diff line
@@ -1228,7 +1228,7 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
			      zfcp_get_busid_by_unit(unit));
		debug_text_event(new_fsf_req->adapter->erp_dbf, 2,
				 "fsf_s_pboxed");
		zfcp_erp_port_reopen(unit->port, 0);
		zfcp_erp_port_boxed(unit->port);
		new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
		    | ZFCP_STATUS_FSFREQ_RETRY;
		break;
@@ -1240,10 +1240,7 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
                        unit->fcp_lun, unit->port->wwpn,
                        zfcp_get_busid_by_unit(unit));
                debug_text_event(new_fsf_req->adapter->erp_dbf, 1, "fsf_s_lboxed");
                zfcp_erp_unit_reopen(unit, 0);
                zfcp_cmd_dbf_event_fsf("unitbox", new_fsf_req,
                        &new_fsf_req->qtcb->header.fsf_status_qual,
                        sizeof(union fsf_status_qual));
		zfcp_erp_unit_boxed(unit);
                new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
                        | ZFCP_STATUS_FSFREQ_RETRY;
                break;
@@ -1573,7 +1570,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
			      "(adapter %s, port d_id=0x%08x)\n",
			      zfcp_get_busid_by_port(port), port->d_id);
		debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed");
		zfcp_erp_port_reopen(port, 0);
		zfcp_erp_port_boxed(port);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
		    | ZFCP_STATUS_FSFREQ_RETRY;
		break;
@@ -2460,6 +2457,9 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
		/* mark port as open */
		atomic_set_mask(ZFCP_STATUS_COMMON_OPEN |
				ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
		atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
		                  ZFCP_STATUS_COMMON_ACCESS_BOXED,
		                  &port->status);
		retval = 0;
		/* check whether D_ID has changed during open */
		/*
@@ -2803,7 +2803,7 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req)
			       port->wwpn,
			       zfcp_get_busid_by_port(port));
		debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_pboxed");
		zfcp_erp_port_reopen(port, 0);
		zfcp_erp_port_boxed(port);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
			ZFCP_STATUS_FSFREQ_RETRY;
		break;
@@ -3035,7 +3035,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
			       "needs to be reopened\n",
			       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
		debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed");
		zfcp_erp_port_reopen(unit->port, 0);
		zfcp_erp_port_boxed(unit->port);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
			ZFCP_STATUS_FSFREQ_RETRY;
		break;
@@ -3145,7 +3145,9 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
			       unit->handle);
		/* mark unit as open */
		atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status);

		atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
		                  ZFCP_STATUS_COMMON_ACCESS_BOXED,
		                  &unit->status);
		if (adapter->supported_features & FSF_FEATURE_LUN_SHARING){
			if (!exclusive)
		                atomic_set_mask(ZFCP_STATUS_UNIT_SHARED,
@@ -3335,7 +3337,7 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
			       unit->port->wwpn,
			       zfcp_get_busid_by_unit(unit));
		debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_pboxed");
		zfcp_erp_port_reopen(unit->port, 0);
		zfcp_erp_port_boxed(unit->port);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
			ZFCP_STATUS_FSFREQ_RETRY;
		break;
@@ -3881,10 +3883,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
			       "needs to be reopened\n",
			       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
		debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_pboxed");
		zfcp_erp_port_reopen(unit->port, 0);
		zfcp_cmd_dbf_event_fsf("portbox", fsf_req,
				       &header->fsf_status_qual,
				       sizeof (union fsf_status_qual));
		zfcp_erp_port_boxed(unit->port);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
			ZFCP_STATUS_FSFREQ_RETRY;
		break;
@@ -3895,10 +3894,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
				zfcp_get_busid_by_unit(unit),
				unit->port->wwpn, unit->fcp_lun);
		debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_lboxed");
		zfcp_erp_unit_reopen(unit, 0);
		zfcp_cmd_dbf_event_fsf("unitbox", fsf_req,
				       &header->fsf_status_qual,
				       sizeof(union fsf_status_qual));
		zfcp_erp_unit_boxed(unit);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
			| ZFCP_STATUS_FSFREQ_RETRY;
		break;