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 + -
显示快捷键?