Beispiel #1
0
/**
 * zfcp_erp_adapter_reopen - Reopen adapter.
 * @adapter: Adapter to reopen.
 * @clear: Status flags to clear.
 * @id: Id for debug trace event.
 * @ref: Reference for debug trace event.
 */
void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
			     char *id, void *ref)
{
	unsigned long flags;

	read_lock_irqsave(&zfcp_data.config_lock, flags);
	write_lock(&adapter->erp_lock);
	_zfcp_erp_adapter_reopen(adapter, clear, id, ref);
	write_unlock(&adapter->erp_lock);
	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
}
static void zfcp_erp_strategy_followup_actions(struct zfcp_erp_action *act)
{
	struct zfcp_adapter *adapter = act->adapter;
	struct zfcp_port *port = act->port;
	struct zfcp_unit *unit = act->unit;
	u32 status = act->status;

	/* initiate follow-up actions depending on success of finished action */
	switch (act->action) {

	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
		if (status == ZFCP_ERP_SUCCEEDED)
			_zfcp_erp_port_reopen_all(adapter, 0, "ersfa_1", NULL);
		else
			_zfcp_erp_adapter_reopen(adapter, 0, "ersfa_2", NULL);
		break;

	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
		if (status == ZFCP_ERP_SUCCEEDED)
			_zfcp_erp_port_reopen(port, 0, "ersfa_3", NULL);
		else
			_zfcp_erp_adapter_reopen(adapter, 0, "ersfa_4", NULL);
		break;

	case ZFCP_ERP_ACTION_REOPEN_PORT:
		if (status == ZFCP_ERP_SUCCEEDED)
			_zfcp_erp_unit_reopen_all(port, 0, "ersfa_5", NULL);
		else
			_zfcp_erp_port_forced_reopen(port, 0, "ersfa_6", NULL);
		break;

	case ZFCP_ERP_ACTION_REOPEN_UNIT:
		if (status != ZFCP_ERP_SUCCEEDED)
			_zfcp_erp_port_reopen(unit->port, 0, "ersfa_7", NULL);
		break;
	}
}
Beispiel #3
0
static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
{
	switch (act->action) {
	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
		_zfcp_erp_adapter_reopen(act->adapter, 0, "ersff_1", NULL);
		break;
	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
		_zfcp_erp_port_forced_reopen(act->port, 0, "ersff_2", NULL);
		break;
	case ZFCP_ERP_ACTION_REOPEN_PORT:
		_zfcp_erp_port_reopen(act->port, 0, "ersff_3", NULL);
		break;
	case ZFCP_ERP_ACTION_REOPEN_UNIT:
		_zfcp_erp_unit_reopen(act->unit, 0, "ersff_4", NULL);
		break;
	}
}
static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
{
    int action = act->action;
    struct zfcp_adapter *adapter = act->adapter;
    struct zfcp_port *port = act->port;
    struct scsi_device *sdev = act->sdev;
    struct zfcp_scsi_dev *zfcp_sdev;
    u32 erp_status = act->status;

    switch (action) {
    case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
        if (zfcp_erp_strat_change_det(&adapter->status, erp_status)) {
            _zfcp_erp_adapter_reopen(adapter,
                                     ZFCP_STATUS_COMMON_ERP_FAILED,
                                     "ersscg1");
            return ZFCP_ERP_EXIT;
        }
        break;

    case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
    case ZFCP_ERP_ACTION_REOPEN_PORT:
        if (zfcp_erp_strat_change_det(&port->status, erp_status)) {
            _zfcp_erp_port_reopen(port,
                                  ZFCP_STATUS_COMMON_ERP_FAILED,
                                  "ersscg2");
            return ZFCP_ERP_EXIT;
        }
        break;

    case ZFCP_ERP_ACTION_REOPEN_LUN:
        zfcp_sdev = sdev_to_zfcp(sdev);
        if (zfcp_erp_strat_change_det(&zfcp_sdev->status, erp_status)) {
            _zfcp_erp_lun_reopen(sdev,
                                 ZFCP_STATUS_COMMON_ERP_FAILED,
                                 "ersscg3", 0);
            return ZFCP_ERP_EXIT;
        }
        break;
    }
    return ret;
}
Beispiel #5
0
static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
{
	int action = act->action;
	struct zfcp_adapter *adapter = act->adapter;
	struct zfcp_port *port = act->port;
	struct zfcp_unit *unit = act->unit;
	u32 erp_status = act->status;

	switch (action) {
	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
		if (zfcp_erp_strat_change_det(&adapter->status, erp_status)) {
			_zfcp_erp_adapter_reopen(adapter,
						 ZFCP_STATUS_COMMON_ERP_FAILED,
						 "ersscg1", NULL);
			return ZFCP_ERP_EXIT;
		}
		break;

	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
	case ZFCP_ERP_ACTION_REOPEN_PORT:
		if (zfcp_erp_strat_change_det(&port->status, erp_status)) {
			_zfcp_erp_port_reopen(port,
					      ZFCP_STATUS_COMMON_ERP_FAILED,
					      "ersscg2", NULL);
			return ZFCP_ERP_EXIT;
		}
		break;

	case ZFCP_ERP_ACTION_REOPEN_UNIT:
		if (zfcp_erp_strat_change_det(&unit->status, erp_status)) {
			_zfcp_erp_unit_reopen(unit,
					      ZFCP_STATUS_COMMON_ERP_FAILED,
					      "ersscg3", NULL);
			return ZFCP_ERP_EXIT;
		}
		break;
	}
	return ret;
}
Beispiel #6
0
static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
{
	int retval;
	struct zfcp_adapter *adapter = erp_action->adapter;
	unsigned long flags;

	read_lock_irqsave(&zfcp_data.config_lock, flags);
	write_lock(&adapter->erp_lock);

	zfcp_erp_strategy_check_fsfreq(erp_action);

	if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
		zfcp_erp_action_dequeue(erp_action);
		retval = ZFCP_ERP_DISMISSED;
		goto unlock;
	}

	if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
		retval = ZFCP_ERP_FAILED;
		goto check_target;
	}

	zfcp_erp_action_to_running(erp_action);

	/* no lock to allow for blocking operations */
	write_unlock(&adapter->erp_lock);
	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
	retval = zfcp_erp_strategy_do_action(erp_action);
	read_lock_irqsave(&zfcp_data.config_lock, flags);
	write_lock(&adapter->erp_lock);

	if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED)
		retval = ZFCP_ERP_CONTINUES;

	switch (retval) {
	case ZFCP_ERP_NOMEM:
		if (!(erp_action->status & ZFCP_STATUS_ERP_LOWMEM)) {
			++adapter->erp_low_mem_count;
			erp_action->status |= ZFCP_STATUS_ERP_LOWMEM;
		}
		if (adapter->erp_total_count == adapter->erp_low_mem_count)
			_zfcp_erp_adapter_reopen(adapter, 0, "erstgy1", NULL);
		else {
			zfcp_erp_strategy_memwait(erp_action);
			retval = ZFCP_ERP_CONTINUES;
		}
		goto unlock;

	case ZFCP_ERP_CONTINUES:
		if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) {
			--adapter->erp_low_mem_count;
			erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM;
		}
		goto unlock;
	}

check_target:
	retval = zfcp_erp_strategy_check_target(erp_action, retval);
	zfcp_erp_action_dequeue(erp_action);
	retval = zfcp_erp_strategy_statechange(erp_action, retval);
	if (retval == ZFCP_ERP_EXIT)
		goto unlock;
	if (retval == ZFCP_ERP_SUCCEEDED)
		zfcp_erp_strategy_followup_success(erp_action);
	if (retval == ZFCP_ERP_FAILED)
		zfcp_erp_strategy_followup_failed(erp_action);

 unlock:
	write_unlock(&adapter->erp_lock);
	read_unlock_irqrestore(&zfcp_data.config_lock, flags);

	if (retval != ZFCP_ERP_CONTINUES)
		zfcp_erp_action_cleanup(erp_action, retval);

	return retval;
}