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

📄 zfcp_erp.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (set_or_clear == ZFCP_SET) {		atomic_set_mask(mask, &port->status);		debug_text_event(port->adapter->erp_dbf, 3, "p_mod_ps_s");	} else {		atomic_clear_mask(mask, &port->status);		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)			atomic_set(&port->erp_counter, 0);		debug_text_event(port->adapter->erp_dbf, 3, "p_mod_ps_c");	}	debug_event(port->adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t));	debug_event(port->adapter->erp_dbf, 3, &mask, sizeof (u32));	/* Modify status of all underlying devices, only pass common mask */	if (common_mask)		list_for_each_entry(unit, &port->unit_list_head, list)		    zfcp_erp_modify_unit_status(unit, common_mask,						set_or_clear);}/* * function:	zfcp_erp_modify_unit_status * * purpose:	sets the unit to ERP_FAILED * */voidzfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear){	if (set_or_clear == ZFCP_SET) {		atomic_set_mask(mask, &unit->status);		debug_text_event(unit->port->adapter->erp_dbf, 3, "u_mod_us_s");	} else {		atomic_clear_mask(mask, &unit->status);		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) {			atomic_set(&unit->erp_counter, 0);		}		debug_text_event(unit->port->adapter->erp_dbf, 3, "u_mod_us_c");	}	debug_event(unit->port->adapter->erp_dbf, 3, &unit->fcp_lun,		    sizeof (fcp_lun_t));	debug_event(unit->port->adapter->erp_dbf, 3, &mask, sizeof (u32));}/* * function:	 * * purpose:	Wrappper for zfcp_erp_port_reopen_all_internal *              used to ensure the correct locking * * returns:	0	- initiated action succesfully *		<0	- failed to initiate action */intzfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, int clear_mask){	int retval;	unsigned long flags;	read_lock_irqsave(&zfcp_data.config_lock, flags);	write_lock(&adapter->erp_lock);	retval = zfcp_erp_port_reopen_all_internal(adapter, clear_mask);	write_unlock(&adapter->erp_lock);	read_unlock_irqrestore(&zfcp_data.config_lock, flags);	return retval;}/* * function:	 * * purpose:	 * * returns:	FIXME */static intzfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask){	int retval = 0;	struct zfcp_port *port;	list_for_each_entry(port, &adapter->port_list_head, list)		if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))			zfcp_erp_port_reopen_internal(port, clear_mask);	return retval;}/* * function:	 * * purpose:	 * * returns:	FIXME */static intzfcp_erp_unit_reopen_all_internal(struct zfcp_port *port, int clear_mask){	int retval = 0;	struct zfcp_unit *unit;	list_for_each_entry(unit, &port->unit_list_head, list)	    zfcp_erp_unit_reopen_internal(unit, clear_mask);	return retval;}/* * function:	 * * purpose:	this routine executes the 'Reopen Adapter' action *		(the entire action is processed synchronously, since *		there are no actions which might be run concurrently *		per definition) * * returns:	ZFCP_ERP_SUCCEEDED	- action finished successfully *		ZFCP_ERP_FAILED		- action finished unsuccessfully */static intzfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action){	int retval;	struct zfcp_adapter *adapter = erp_action->adapter;	retval = zfcp_erp_adapter_strategy_close(erp_action);	if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY)		retval = ZFCP_ERP_EXIT;	else		retval = zfcp_erp_adapter_strategy_open(erp_action);	debug_text_event(adapter->erp_dbf, 3, "a_ast/ret");	debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));	debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));	if (retval == ZFCP_ERP_FAILED) {		ZFCP_LOG_INFO("Waiting to allow the adapter %s "			      "to recover itself\n",			      zfcp_get_busid_by_adapter(adapter));		msleep(jiffies_to_msecs(ZFCP_TYPE2_RECOVERY_TIME));	}	return retval;}/* * function:	 * * purpose:	 * * returns:	ZFCP_ERP_SUCCEEDED      - action finished successfully *              ZFCP_ERP_FAILED         - action finished unsuccessfully */static intzfcp_erp_adapter_strategy_close(struct zfcp_erp_action *erp_action){	int retval;	atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING,			&erp_action->adapter->status);	retval = zfcp_erp_adapter_strategy_generic(erp_action, 1);	atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING,			  &erp_action->adapter->status);	return retval;}/* * function:	 * * purpose:	 * * returns:	ZFCP_ERP_SUCCEEDED      - action finished successfully *              ZFCP_ERP_FAILED         - action finished unsuccessfully */static intzfcp_erp_adapter_strategy_open(struct zfcp_erp_action *erp_action){	int retval;	atomic_set_mask(ZFCP_STATUS_COMMON_OPENING,			&erp_action->adapter->status);	retval = zfcp_erp_adapter_strategy_generic(erp_action, 0);	atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING,			  &erp_action->adapter->status);	return retval;}/* * function:    zfcp_register_adapter * * purpose:	allocate the irq associated with this devno and register *		the FSF adapter with the SCSI stack * * returns:	 */static intzfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close){	int retval = ZFCP_ERP_SUCCEEDED;	if (close)		goto close_only;	retval = zfcp_erp_adapter_strategy_open_qdio(erp_action);	if (retval != ZFCP_ERP_SUCCEEDED)		goto failed_qdio;	retval = zfcp_erp_adapter_strategy_open_fsf(erp_action);	if (retval != ZFCP_ERP_SUCCEEDED)		goto failed_openfcp;	atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &erp_action->adapter->status);	goto out; close_only:	atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,			  &erp_action->adapter->status); failed_openfcp:	zfcp_erp_adapter_strategy_close_qdio(erp_action);	zfcp_erp_adapter_strategy_close_fsf(erp_action); failed_qdio: out:	return retval;}/* * function:    zfcp_qdio_init * * purpose:	setup QDIO operation for specified adapter * * returns:	0 - successful setup *		!0 - failed setup */intzfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action){	int retval;	int i;	volatile struct qdio_buffer_element *sbale;	struct zfcp_adapter *adapter = erp_action->adapter;	if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) {		ZFCP_LOG_NORMAL("bug: second attempt to set up QDIO on "				"adapter %s\n",				zfcp_get_busid_by_adapter(adapter));		goto failed_sanity;	}	if (qdio_establish(&adapter->qdio_init_data) != 0) {		ZFCP_LOG_INFO("error: establishment of QDIO queues failed "			      "on adapter %s\n",			      zfcp_get_busid_by_adapter(adapter));		goto failed_qdio_establish;	}	debug_text_event(adapter->erp_dbf, 3, "qdio_est");	if (qdio_activate(adapter->ccw_device, 0) != 0) {		ZFCP_LOG_INFO("error: activation of QDIO queues failed "			      "on adapter %s\n",			      zfcp_get_busid_by_adapter(adapter));		goto failed_qdio_activate;	}	debug_text_event(adapter->erp_dbf, 3, "qdio_act");	/*	 * put buffers into response queue,	 */	for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {		sbale = &(adapter->response_queue.buffer[i]->element[0]);		sbale->length = 0;		sbale->flags = SBAL_FLAGS_LAST_ENTRY;		sbale->addr = 0;	}	ZFCP_LOG_TRACE("calling do_QDIO on adapter %s (flags=0x%x, "		       "queue_no=%i, index_in_queue=%i, count=%i)\n",		       zfcp_get_busid_by_adapter(adapter),		       QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q);	retval = do_QDIO(adapter->ccw_device,			 QDIO_FLAG_SYNC_INPUT,			 0, 0, QDIO_MAX_BUFFERS_PER_Q, NULL);	if (retval) {		ZFCP_LOG_NORMAL("bug: setup of QDIO failed (retval=%d)\n",				retval);		goto failed_do_qdio;	} else {		adapter->response_queue.free_index = 0;		atomic_set(&adapter->response_queue.free_count, 0);		ZFCP_LOG_DEBUG("%i buffers successfully enqueued to "			       "response queue\n", QDIO_MAX_BUFFERS_PER_Q);	}	/* set index of first avalable SBALS / number of available SBALS */	adapter->request_queue.free_index = 0;	atomic_set(&adapter->request_queue.free_count, QDIO_MAX_BUFFERS_PER_Q);	adapter->request_queue.distance_from_int = 0;	/* initialize waitqueue used to wait for free SBALs in requests queue */	init_waitqueue_head(&adapter->request_wq);	/* ok, we did it - skip all cleanups for different failures */	atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);	retval = ZFCP_ERP_SUCCEEDED;	goto out; failed_do_qdio:	/* NOP */ failed_qdio_activate:	debug_text_event(adapter->erp_dbf, 3, "qdio_down1a");	while (qdio_shutdown(adapter->ccw_device,			     QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)		msleep(1000);	debug_text_event(adapter->erp_dbf, 3, "qdio_down1b"); failed_qdio_establish: failed_sanity:	retval = ZFCP_ERP_FAILED; out:	return retval;}/* * function:    zfcp_qdio_cleanup * * purpose:	cleans up QDIO operation for the specified adapter * * returns:	0 - successful cleanup *		!0 - failed cleanup */intzfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action){	int retval = ZFCP_ERP_SUCCEEDED;	int first_used;	int used_count;	struct zfcp_adapter *adapter = erp_action->adapter;	if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) {		ZFCP_LOG_DEBUG("error: attempt to shut down inactive QDIO "			       "queues on adapter %s\n",			       zfcp_get_busid_by_adapter(adapter));		retval = ZFCP_ERP_FAILED;		goto out;	}	/*	 * Get queue_lock and clear QDIOUP flag. Thus it's guaranteed that	 * do_QDIO won't be called while qdio_shutdown is in progress.	 */	write_lock_irq(&adapter->request_queue.queue_lock);	atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);	write_unlock_irq(&adapter->request_queue.queue_lock);	debug_text_event(adapter->erp_dbf, 3, "qdio_down2a");	while (qdio_shutdown(adapter->ccw_device,			     QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)		msleep(1000);	debug_text_event(adapter->erp_dbf, 3, "qdio_down2b");	/*	 * First we had to stop QDIO operation.	 * Now it is safe to take the following actions.	 */	/* Cleanup only necessary when there are unacknowledged buffers */	if (atomic_read(&adapter->request_queue.free_count)	    < QDIO_MAX_BUFFERS_PER_Q) {		first_used = (adapter->request_queue.free_index +			      atomic_read(&adapter->request_queue.free_count))			% QDIO_MAX_BUFFERS_PER_Q;		used_count = QDIO_MAX_BUFFERS_PER_Q -			atomic_read(&adapter->request_queue.free_count);		zfcp_qdio_zero_sbals(adapter->request_queue.buffer,				     first_used, used_count);	}	adapter->response_queue.free_index = 0;	atomic_set(&adapter->response_queue.free_count, 0);	adapter->request_queue.free_index = 0;	atomic_set(&adapter->request_queue.free_count, 0);	adapter->request_queue.distance_from_int = 0; out:	return retval;}static intzfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action){	int retval;	if ((atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,			      &erp_action->adapter->status)) &&	    (erp_action->adapter->adapter_features &	     FSF_FEATURE_HBAAPI_MANAGEMENT)) {		zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);		atomic_set(&erp_action->adapter->erp_counter, 0);		return ZFCP_ERP_FAILED;	}	retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);	if (retval == ZFCP_ERP_FAILED)		return ZFCP_ERP_FAILED;	retval = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);	if (retval == ZFCP_ERP_FAILED)		return ZFCP_ERP_FAILED;	return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);}/* * function:	 * * purpose:	 * * returns: */static intzfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action){	int retval = ZFCP_ERP_SUCCEEDED;	int retries;	int sleep = ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP;	struct zfcp_adapter *adapter = erp_action->adapter;	atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status);	for (retries = ZFCP_EXCHANGE_CONFIG_DATA_RETRIES; retries; retries--) {		atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,				  &adapter->status);		ZFCP_LOG_DEBUG("Doing exchange config data\n");		write_lock(&adapter->erp_lock);		zfcp_erp_action_to_running(erp_action);		write_unlock(&adapter->erp_lock);		zfcp_erp_timeout_init(erp_action);		if (zfcp_fsf_exchange_config_data(erp_action)) {			retval = ZFCP_ERP_FAILED;			debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf");			ZFCP_LOG_INFO("error:  initiation of exchange of "				      "configuration data failed for "				      "adapter %s\n",				      zfcp_get_busid_by_adapter(adapter));			break;		}		debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok");		ZFCP_LOG_DEBUG("Xchange underway\n");		/*		 * Why this works:		 * Both the normal completion handler as well as the timeout		 * handler will do an 'up' when the 'exchange config data'		 * request completes or times out. Thus, the signal to go on		 * won't be lost utilizing this semaphore.		 * Furthermore, this 'adapter_reopen' action is		 * guaranteed to be the only action being there (highest action		 * which prevents other actions from being created).		 * Resulting from that, the wake signal recognized here		 * _must_ be the one belonging to the 'exchange config		 * data' request.	

⌨️ 快捷键说明

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