⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zfcp_erp.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	case ZFCP_ERP_ACTION_REOPEN_PORT:		retval = zfcp_erp_port_strategy(erp_action);		break;	case ZFCP_ERP_ACTION_REOPEN_UNIT:		retval = zfcp_erp_unit_strategy(erp_action);		break;	default:		debug_text_exception(adapter->erp_dbf, 1, "a_stda_bug");		debug_event(adapter->erp_dbf, 1, &erp_action->action,			    sizeof (int));		ZFCP_LOG_NORMAL("bug: unknown erp action requested on "				"adapter %s (action=%d)\n",				zfcp_get_busid_by_adapter(erp_action->adapter),				erp_action->action);	}	return retval;}/* * function:	 * * purpose:	triggers retry of this action after a certain amount of time *		by means of timer provided by erp_action * * returns:	ZFCP_ERP_CONTINUES - erp_action sleeps in erp running queue */static intzfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action){	int retval = ZFCP_ERP_CONTINUES;	struct zfcp_adapter *adapter = erp_action->adapter;	debug_text_event(adapter->erp_dbf, 6, "a_mwinit");	debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int));	init_timer(&erp_action->timer);	erp_action->timer.function = zfcp_erp_memwait_handler;	erp_action->timer.data = (unsigned long) erp_action;	erp_action->timer.expires = jiffies + ZFCP_ERP_MEMWAIT_TIMEOUT;	add_timer(&erp_action->timer);	return retval;}/*  * function:    zfcp_erp_adapter_failed * * purpose:     sets the adapter and all underlying devices to ERP_FAILED * */voidzfcp_erp_adapter_failed(struct zfcp_adapter *adapter){	zfcp_erp_modify_adapter_status(adapter,				       ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);	ZFCP_LOG_NORMAL("adapter erp failed on adapter %s\n",			zfcp_get_busid_by_adapter(adapter));	debug_text_event(adapter->erp_dbf, 2, "a_afail");}/*  * function:    zfcp_erp_port_failed * * purpose:     sets the port and all underlying devices to ERP_FAILED * */voidzfcp_erp_port_failed(struct zfcp_port *port){	zfcp_erp_modify_port_status(port,				    ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);	if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))		ZFCP_LOG_NORMAL("port erp failed (adapter %s, "				"port d_id=0x%08x)\n",				zfcp_get_busid_by_port(port), port->d_id);	else		ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n",				zfcp_get_busid_by_port(port), port->wwpn);	debug_text_event(port->adapter->erp_dbf, 2, "p_pfail");	debug_event(port->adapter->erp_dbf, 2, &port->wwpn, sizeof (wwn_t));}/*  * function:    zfcp_erp_unit_failed * * purpose:     sets the unit to ERP_FAILED * */voidzfcp_erp_unit_failed(struct zfcp_unit *unit){	zfcp_erp_modify_unit_status(unit,				    ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);	ZFCP_LOG_NORMAL("unit erp failed on 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(unit->port->adapter->erp_dbf, 2, "u_ufail");	debug_event(unit->port->adapter->erp_dbf, 2,		    &unit->fcp_lun, sizeof (fcp_lun_t));}/* * function:	zfcp_erp_strategy_check_target * * purpose:	increments the erp action count on the device currently in *              recovery if the action failed or resets the count in case of *              success. If a maximum count is exceeded the device is marked *              as ERP_FAILED. *		The 'blocked' state of a target which has been recovered *              successfully is reset. * * returns:	ZFCP_ERP_CONTINUES	- action continues (not considered) *		ZFCP_ERP_SUCCEEDED	- action finished successfully  *		ZFCP_ERP_EXIT		- action failed and will not continue */static intzfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, int result){	struct zfcp_adapter *adapter = erp_action->adapter;	struct zfcp_port *port = erp_action->port;	struct zfcp_unit *unit = erp_action->unit;	debug_text_event(adapter->erp_dbf, 5, "a_stct_norm");	debug_event(adapter->erp_dbf, 5, &erp_action->action, sizeof (int));	debug_event(adapter->erp_dbf, 5, &result, sizeof (int));	switch (erp_action->action) {	case ZFCP_ERP_ACTION_REOPEN_UNIT:		result = zfcp_erp_strategy_check_unit(unit, result);		break;	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:	case ZFCP_ERP_ACTION_REOPEN_PORT:		result = zfcp_erp_strategy_check_port(port, result);		break;	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:		result = zfcp_erp_strategy_check_adapter(adapter, result);		break;	}	return result;}/* * function:	 * * purpose:	 * * returns: */static intzfcp_erp_strategy_statechange(int action,			      u32 status,			      struct zfcp_adapter *adapter,			      struct zfcp_port *port,			      struct zfcp_unit *unit, int retval){	debug_text_event(adapter->erp_dbf, 3, "a_stsc");	debug_event(adapter->erp_dbf, 3, &action, sizeof (int));	switch (action) {	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:		if (zfcp_erp_strategy_statechange_detected(&adapter->status,							   status)) {			zfcp_erp_adapter_reopen_internal(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);			retval = ZFCP_ERP_EXIT;		}		break;	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:	case ZFCP_ERP_ACTION_REOPEN_PORT:		if (zfcp_erp_strategy_statechange_detected(&port->status,							   status)) {			zfcp_erp_port_reopen_internal(port, ZFCP_STATUS_COMMON_ERP_FAILED);			retval = ZFCP_ERP_EXIT;		}		break;	case ZFCP_ERP_ACTION_REOPEN_UNIT:		if (zfcp_erp_strategy_statechange_detected(&unit->status,							   status)) {			zfcp_erp_unit_reopen_internal(unit, ZFCP_STATUS_COMMON_ERP_FAILED);			retval = ZFCP_ERP_EXIT;		}		break;	}	return retval;}/* * function:	 * * purpose:	 * * returns: */static inline intzfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status){	return	    /* take it online */	    (atomic_test_mask(ZFCP_STATUS_COMMON_RUNNING, target_status) &&	     (ZFCP_STATUS_ERP_CLOSE_ONLY & erp_status)) ||	    /* take it offline */	    (!atomic_test_mask(ZFCP_STATUS_COMMON_RUNNING, target_status) &&	     !(ZFCP_STATUS_ERP_CLOSE_ONLY & erp_status));}/* * function:	 * * purpose:	 * * returns: */static intzfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result){	debug_text_event(unit->port->adapter->erp_dbf, 5, "u_stct");	debug_event(unit->port->adapter->erp_dbf, 5, &unit->fcp_lun,		    sizeof (fcp_lun_t));	switch (result) {	case ZFCP_ERP_SUCCEEDED :		atomic_set(&unit->erp_counter, 0);		zfcp_erp_unit_unblock(unit);		break;	case ZFCP_ERP_FAILED :		atomic_inc(&unit->erp_counter);		if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS)			zfcp_erp_unit_failed(unit);		break;	case ZFCP_ERP_EXIT :		/* nothing */		break;	}	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status)) {		zfcp_erp_unit_block(unit, 0); /* for ZFCP_ERP_SUCCEEDED */		result = ZFCP_ERP_EXIT;	}	return result;}/* * function:	 * * purpose:	 * * returns: */static intzfcp_erp_strategy_check_port(struct zfcp_port *port, int result){	debug_text_event(port->adapter->erp_dbf, 5, "p_stct");	debug_event(port->adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));	switch (result) {	case ZFCP_ERP_SUCCEEDED :		atomic_set(&port->erp_counter, 0);		zfcp_erp_port_unblock(port);		break;	case ZFCP_ERP_FAILED :		atomic_inc(&port->erp_counter);		if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS)			zfcp_erp_port_failed(port);		break;	case ZFCP_ERP_EXIT :		/* nothing */		break;	}	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {		zfcp_erp_port_block(port, 0); /* for ZFCP_ERP_SUCCEEDED */		result = ZFCP_ERP_EXIT;	}	return result;}/* * function:	 * * purpose:	 * * returns: */static intzfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result){	debug_text_event(adapter->erp_dbf, 5, "a_stct");	switch (result) {	case ZFCP_ERP_SUCCEEDED :		atomic_set(&adapter->erp_counter, 0);		zfcp_erp_adapter_unblock(adapter);		break;	case ZFCP_ERP_FAILED :		atomic_inc(&adapter->erp_counter);		if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS)			zfcp_erp_adapter_failed(adapter);		break;	case ZFCP_ERP_EXIT :		/* nothing */		break;	}	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) {		zfcp_erp_adapter_block(adapter, 0); /* for ZFCP_ERP_SUCCEEDED */		result = ZFCP_ERP_EXIT;	}	return result;}/* * function:	 * * purpose:	remaining things in good cases, *		escalation in bad cases * * returns: */static intzfcp_erp_strategy_followup_actions(int action,				   struct zfcp_adapter *adapter,				   struct zfcp_port *port,				   struct zfcp_unit *unit, int status){	debug_text_event(adapter->erp_dbf, 5, "a_stfol");	debug_event(adapter->erp_dbf, 5, &action, sizeof (int));	/* initiate follow-up actions depending on success of finished action */	switch (action) {	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:		if (status == ZFCP_ERP_SUCCEEDED)			zfcp_erp_port_reopen_all_internal(adapter, 0);		else			zfcp_erp_adapter_reopen_internal(adapter, 0);		break;	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:		if (status == ZFCP_ERP_SUCCEEDED)			zfcp_erp_port_reopen_internal(port, 0);		else			zfcp_erp_adapter_reopen_internal(adapter, 0);		break;	case ZFCP_ERP_ACTION_REOPEN_PORT:		if (status == ZFCP_ERP_SUCCEEDED)			zfcp_erp_unit_reopen_all_internal(port, 0);		else			zfcp_erp_port_forced_reopen_internal(port, 0);		break;	case ZFCP_ERP_ACTION_REOPEN_UNIT:		if (status == ZFCP_ERP_SUCCEEDED) ;	/* no further action */		else			zfcp_erp_port_reopen_internal(unit->port, 0);		break;	}	return 0;}/* * function:	 * * purpose:	 * * returns: */static intzfcp_erp_strategy_check_queues(struct zfcp_adapter *adapter){	unsigned long flags;	read_lock_irqsave(&zfcp_data.config_lock, flags);	read_lock(&adapter->erp_lock);	if (list_empty(&adapter->erp_ready_head) &&	    list_empty(&adapter->erp_running_head)) {			debug_text_event(adapter->erp_dbf, 4, "a_cq_wake");			atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,					  &adapter->status);			wake_up(&adapter->erp_done_wqh);	} else		debug_text_event(adapter->erp_dbf, 5, "a_cq_notempty");	read_unlock(&adapter->erp_lock);	read_unlock_irqrestore(&zfcp_data.config_lock, flags);	return 0;}/** * zfcp_erp_wait - wait for completion of error recovery on an adapter * @adapter: adapter for which to wait for completion of its error recovery * Return: 0 */intzfcp_erp_wait(struct zfcp_adapter *adapter){	int retval = 0;	wait_event(adapter->erp_done_wqh,		   !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,				     &adapter->status));	return retval;}/* * function:	zfcp_erp_modify_adapter_status * * purpose:	 * */voidzfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter,			       u32 mask, int set_or_clear){	struct zfcp_port *port;	u32 common_mask = mask & ZFCP_COMMON_FLAGS;	if (set_or_clear == ZFCP_SET) {		atomic_set_mask(mask, &adapter->status);		debug_text_event(adapter->erp_dbf, 3, "a_mod_as_s");	} else {		atomic_clear_mask(mask, &adapter->status);		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)			atomic_set(&adapter->erp_counter, 0);		debug_text_event(adapter->erp_dbf, 3, "a_mod_as_c");	}	debug_event(adapter->erp_dbf, 3, &mask, sizeof (u32));	/* Deal with all underlying devices, only pass common_mask */	if (common_mask)		list_for_each_entry(port, &adapter->port_list_head, list)		    zfcp_erp_modify_port_status(port, common_mask,						set_or_clear);}/* * function:	zfcp_erp_modify_port_status * * purpose:	sets the port and all underlying devices to ERP_FAILED * */voidzfcp_erp_modify_port_status(struct zfcp_port *port, u32 mask, int set_or_clear){	struct zfcp_unit *unit;	u32 common_mask = mask & ZFCP_COMMON_FLAGS;

⌨️ 快捷键说明

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