zfcp_erp.c

来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 2,360 行 · 第 1/5 页

C
2,360
字号
				      "reason_expl=0x%02x)\n",				      port->wwpn, rjt->reason_expl);			break;		case ZFCP_LS_RJT_LOGICAL_BUSY:			ZFCP_LOG_INFO("logical busy (wwpn=0x%016Lx, "				      "reason_expl=0x%02x)\n",				      port->wwpn, rjt->reason_expl);			break;		case ZFCP_LS_RJT_PROTOCOL_ERROR:			ZFCP_LOG_INFO("protocol error (wwpn=0x%016Lx, "				      "reason_expl=0x%02x)\n",				      port->wwpn, rjt->reason_expl);			break;		case ZFCP_LS_RJT_UNABLE_TO_PERFORM:			ZFCP_LOG_INFO("unable to perform command requested "				      "(wwpn=0x%016Lx, reason_expl=0x%02x)\n",				      port->wwpn, rjt->reason_expl);			break;		case ZFCP_LS_RJT_COMMAND_NOT_SUPPORTED:			ZFCP_LOG_INFO("command not supported (wwpn=0x%016Lx, "				      "command=0x%02x)\n",				      port->wwpn, req_code);			break;		case ZFCP_LS_RJT_VENDOR_UNIQUE_ERROR:			ZFCP_LOG_INFO("vendor specific error (wwpn=0x%016Lx, "				      "vendor_unique=0x%02x)\n",				      port->wwpn, rjt->vendor_unique);			break;		default:			ZFCP_LOG_NORMAL("ELS rejected by remote port 0x%016Lx "					"on adapter %s (reason_code=0x%02x)\n",					port->wwpn,					zfcp_get_busid_by_port(port),					rjt->reason_code);		}		retval = -ENXIO;		break;	case ZFCP_LS_ACC:		switch (req_code) {		case ZFCP_LS_RTV:			rtv = (struct zfcp_ls_rtv_acc*)resp;			ZFCP_LOG_INFO("RTV response from d_id 0x%08x to s_id "				      "0x%08x (R_A_TOV=%ds E_D_TOV=%d%cs)\n",				      port->d_id, port->adapter->s_id,				      rtv->r_a_tov, rtv->e_d_tov,				      rtv->qualifier &				      ZFCP_LS_RTV_E_D_TOV_FLAG ? 'n' : 'm');			break;		case ZFCP_LS_RLS:			rls = (struct zfcp_ls_rls_acc*)resp;			ZFCP_LOG_INFO("RLS response from d_id 0x%08x to s_id "				      "0x%08x (link_failure_count=%u, "				      "loss_of_sync_count=%u, "				      "loss_of_signal_count=%u, "				      "primitive_sequence_protocol_error=%u, "				      "invalid_transmition_word=%u, "				      "invalid_crc_count=%u)\n",				      port->d_id, port->adapter->s_id,				      rls->link_failure_count,				      rls->loss_of_sync_count,				      rls->loss_of_signal_count,				      rls->prim_seq_prot_error,				      rls->invalid_transmition_word,				      rls->invalid_crc_count);			break;		case ZFCP_LS_PDISC:			pdisc = (struct zfcp_ls_pdisc_acc*)resp;			ZFCP_LOG_INFO("PDISC response from d_id 0x%08x to s_id "				      "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "				      "vendor='%-16s')\n", port->d_id,				      port->adapter->s_id, pdisc->wwpn,				      pdisc->wwnn, pdisc->vendor_version);			break;		case ZFCP_LS_ADISC:			adisc = (struct zfcp_ls_adisc_acc*)resp;			ZFCP_LOG_INFO("ADISC response from d_id 0x%08x to s_id "				      "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "				      "hard_nport_id=0x%08x, "				      "nport_id=0x%08x)\n", port->d_id,				      port->adapter->s_id, adisc->wwpn,				      adisc->wwnn, adisc->hard_nport_id,				      adisc->nport_id);			/* FIXME: set wwnn in during open port */			if (port->wwnn == 0)				port->wwnn = adisc->wwnn;			break;		}		break;	default:		ZFCP_LOG_NORMAL("unknown payload code 0x%02x received for "				"request 0x%02x to d_id 0x%08x, reopen needed "				"for port 0x%016Lx on adapter %s\n", resp_code,				req_code, port->d_id,  port->wwpn,				zfcp_get_busid_by_port(port));		retval = zfcp_erp_port_forced_reopen(port, 0);		if (retval != 0) {			ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx on "					"adapter %s failed\n", port->wwpn,					zfcp_get_busid_by_port(port));			retval = -EPERM;		}	}skip_fsfstatus:	__free_pages(send_els->req->page, 0);	kfree(send_els->req);	kfree(send_els->resp);	return retval;}/* * function:    zfcp_test_link * * purpose:     Test a status of a link to a remote port using the ELS command ADISC * * returns:     0       - Link is OK *              -EPERM  - Port forced reopen failed */intzfcp_test_link(struct zfcp_port *port){	int retval;	retval = zfcp_els(port, ZFCP_LS_ADISC);	if (retval != 0) {		ZFCP_LOG_NORMAL("reopen needed for port 0x%016Lx "				"on adapter %s\n ", port->wwpn,				zfcp_get_busid_by_port(port));		retval = zfcp_erp_port_forced_reopen(port, 0);		if (retval != 0) {			ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx "					"on adapter %s failed\n", port->wwpn,					zfcp_get_busid_by_port(port));			retval = -EPERM;		}	}	return retval;}/* * function:	 * * purpose:	called if a port failed to be opened normally *		initiates Forced Reopen recovery which is done *		asynchronously * * returns:	0	- initiated action succesfully *		<0	- failed to initiate action */static intzfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask){	int retval;	struct zfcp_adapter *adapter = port->adapter;	debug_text_event(adapter->erp_dbf, 5, "pf_ro");	debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));	ZFCP_LOG_DEBUG("forced reopen of port 0x%016Lx on adapter %s\n",		       port->wwpn, zfcp_get_busid_by_port(port));	zfcp_erp_port_block(port, clear_mask);	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {		ZFCP_LOG_DEBUG("skipped forced reopen of failed port 0x%016Lx "			       "on adapter %s\n", port->wwpn,			       zfcp_get_busid_by_port(port));		debug_text_event(adapter->erp_dbf, 5, "pf_ro_f");		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));		retval = -EIO;		goto out;	}	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,					 port->adapter, port, NULL); out:	return retval;}/* * function:	 * * purpose:	Wrappper for zfcp_erp_port_forced_reopen_internal *              used to ensure the correct locking * * returns:	0	- initiated action succesfully *		<0	- failed to initiate action */intzfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask){	int retval;	unsigned long flags;	struct zfcp_adapter *adapter;	adapter = port->adapter;	read_lock_irqsave(&zfcp_data.config_lock, flags);	write_lock(&adapter->erp_lock);	retval = zfcp_erp_port_forced_reopen_internal(port, clear_mask);	write_unlock(&adapter->erp_lock);	read_unlock_irqrestore(&zfcp_data.config_lock, flags);	return retval;}/* * function:	 * * purpose:	called if a port is to be opened *		initiates Reopen recovery which is done *		asynchronously * * returns:	0	- initiated action succesfully *		<0	- failed to initiate action */static intzfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask){	int retval;	struct zfcp_adapter *adapter = port->adapter;	debug_text_event(adapter->erp_dbf, 5, "p_ro");	debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));	ZFCP_LOG_DEBUG("reopen of port 0x%016Lx on adapter %s\n",		       port->wwpn, zfcp_get_busid_by_port(port));	zfcp_erp_port_block(port, clear_mask);	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {		ZFCP_LOG_DEBUG("skipped reopen of failed port 0x%016Lx "			       "on adapter %s\n", port->wwpn,			       zfcp_get_busid_by_port(port));		debug_text_event(adapter->erp_dbf, 5, "p_ro_f");		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));		/* ensure propagation of failed status to new devices */		zfcp_erp_port_failed(port);		retval = -EIO;		goto out;	}	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,					 port->adapter, port, NULL); out:	return retval;}/* * function:	 * * purpose:	Wrappper for zfcp_erp_port_reopen_internal *              used to ensure the correct locking * * returns:	0	- initiated action succesfully *		<0	- failed to initiate action */intzfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask){	int retval;	unsigned long flags;	struct zfcp_adapter *adapter = port->adapter;	read_lock_irqsave(&zfcp_data.config_lock, flags);	write_lock(&adapter->erp_lock);	retval = zfcp_erp_port_reopen_internal(port, clear_mask);	write_unlock(&adapter->erp_lock);	read_unlock_irqrestore(&zfcp_data.config_lock, flags);	return retval;}/* * function:	 * * purpose:	called if a unit is to be opened *		initiates Reopen recovery which is done *		asynchronously * * returns:	0	- initiated action succesfully *		<0	- failed to initiate action */static intzfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask){	int retval;	struct zfcp_adapter *adapter = unit->port->adapter;	debug_text_event(adapter->erp_dbf, 5, "u_ro");	debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t));	ZFCP_LOG_DEBUG("reopen of unit 0x%016Lx on port 0x%016Lx "		       "on adapter %s\n", unit->fcp_lun,		       unit->port->wwpn, zfcp_get_busid_by_unit(unit));	zfcp_erp_unit_block(unit, clear_mask);	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status)) {		ZFCP_LOG_DEBUG("skipped reopen of failed unit 0x%016Lx "			       "on port 0x%016Lx on adapter %s\n",			       unit->fcp_lun, unit->port->wwpn,			       zfcp_get_busid_by_unit(unit));		debug_text_event(adapter->erp_dbf, 5, "u_ro_f");		debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,			    sizeof (fcp_lun_t));		retval = -EIO;		goto out;	}	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT,					 unit->port->adapter, unit->port, unit); out:	return retval;}/* * function:	 * * purpose:	Wrappper for zfcp_erp_unit_reopen_internal *              used to ensure the correct locking * * returns:	0	- initiated action succesfully *		<0	- failed to initiate action */intzfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask){	int retval;	unsigned long flags;	struct zfcp_adapter *adapter;	struct zfcp_port *port;	port = unit->port;	adapter = port->adapter;	read_lock_irqsave(&zfcp_data.config_lock, flags);	write_lock(&adapter->erp_lock);	retval = zfcp_erp_unit_reopen_internal(unit, clear_mask);	write_unlock(&adapter->erp_lock);	read_unlock_irqrestore(&zfcp_data.config_lock, flags);	return retval;}/* * function:	 * * purpose:	disable I/O, *		return any open requests and clean them up, *		aim: no pending and incoming I/O * * returns: */static voidzfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask){	debug_text_event(adapter->erp_dbf, 6, "a_bl");	zfcp_erp_modify_adapter_status(adapter,				       ZFCP_STATUS_COMMON_UNBLOCKED |				       clear_mask, ZFCP_CLEAR);}/* * function:	 * * purpose:	enable I/O * * returns: */static voidzfcp_erp_adapter_unblock(struct zfcp_adapter *adapter){	debug_text_event(adapter->erp_dbf, 6, "a_ubl");	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status);}/* * function:	 * * purpose:	disable I/O, *		return any open requests and clean them up, *		aim: no pending and incoming I/O * * returns: */static voidzfcp_erp_port_block(struct zfcp_port *port, int clear_mask){	struct zfcp_adapter *adapter = port->adapter;	debug_text_event(adapter->erp_dbf, 6, "p_bl");	debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));	zfcp_erp_modify_port_status(port,				    ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,				    ZFCP_CLEAR);}/* * function:	 * * purpose:	enable I/O * * returns: */static voidzfcp_erp_port_unblock(struct zfcp_port *port){	struct zfcp_adapter *adapter = port->adapter;	debug_text_event(adapter->erp_dbf, 6, "p_ubl");	debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status);}/* * function:	 * * purpose:	disable I/O, *		return any open requests and clean them up, *		aim: no pending and incoming I/O * * returns: */static voidzfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask){	struct zfcp_adapter *adapter = unit->port->adapter;	debug_text_event(adapter->erp_dbf, 6, "u_bl");	debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));	zfcp_erp_modify_unit_status(unit,				    ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,				    ZFCP_CLEAR);}/* * function:	 * * purpose:	enable I/O * * returns: */static voidzfcp_erp_unit_unblock(struct zfcp_unit *unit){	struct zfcp_adapter *adapter = unit->port->adapter;	debug_text_event(adapter->erp_dbf, 6, "u_ubl");	debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status);}/* * function:	 *

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?