static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action) { int retries; int sleep = 1; struct zfcp_adapter *adapter = erp_action->adapter; atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status); for (retries = 7; retries; retries--) { atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, &adapter->status); write_lock_irq(&adapter->erp_lock); zfcp_erp_action_to_running(erp_action); write_unlock_irq(&adapter->erp_lock); if (zfcp_fsf_exchange_config_data(erp_action)) { atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, &adapter->status); return ZFCP_ERP_FAILED; } zfcp_dbf_rec_thread_lock("erasfx1", adapter->dbf); wait_event(adapter->erp_ready_wq, !list_empty(&adapter->erp_ready_head)); zfcp_dbf_rec_thread_lock("erasfx2", adapter->dbf); if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) break; if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_HOST_CON_INIT)) break; ssleep(sleep); sleep *= 2; } atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, &adapter->status); if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_XCONFIG_OK)) return ZFCP_ERP_FAILED; if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) zfcp_erp_enqueue_ptp_port(adapter); return ZFCP_ERP_SUCCEEDED; }
static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act) { int ret; struct zfcp_adapter *adapter = act->adapter; write_lock_irq(&adapter->erp_lock); zfcp_erp_action_to_running(act); write_unlock_irq(&adapter->erp_lock); ret = zfcp_fsf_exchange_port_data(act); if (ret == -EOPNOTSUPP) return ZFCP_ERP_SUCCEEDED; if (ret) return ZFCP_ERP_FAILED; zfcp_rec_dbf_event_thread_lock("erasox1", adapter); down(&adapter->erp_ready_sem); zfcp_rec_dbf_event_thread_lock("erasox2", adapter); if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) return ZFCP_ERP_FAILED; return ZFCP_ERP_SUCCEEDED; }
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; }