📄 zfcp_fsf.c
字号:
case FSF_PROT_ERROR_STATE: ZFCP_LOG_NORMAL("error: The adapter %s " "has entered the error state. " "Restarting all operations on this " "adapter.\n", zfcp_get_busid_by_adapter(adapter)); zfcp_erp_adapter_reopen(adapter, 0); fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; default: ZFCP_LOG_NORMAL("bug: Transfer protocol status information " "provided by the adapter %s " "is not compatible with the device driver. " "Stopping all operations on this adapter. " "(debug info 0x%x).\n", zfcp_get_busid_by_adapter(adapter), qtcb->prefix.prot_status); zfcp_erp_adapter_shutdown(adapter, 0); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; } skip_protstatus: /* * always call specific handlers to give them a chance to do * something meaningful even in error cases */ zfcp_fsf_fsfstatus_eval(fsf_req); return retval;}/* * function: zfcp_fsf_fsfstatus_eval * * purpose: evaluates FSF status of completed FSF request * and acts accordingly * * returns: */static intzfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *fsf_req){ int retval = 0; if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) { goto skip_fsfstatus; } /* evaluate FSF Status */ switch (fsf_req->qtcb->header.fsf_status) { case FSF_UNKNOWN_COMMAND: ZFCP_LOG_NORMAL("bug: Command issued by the device driver is " "not known by the adapter %s " "Stopping all operations on this adapter. " "(debug info 0x%x).\n", zfcp_get_busid_by_adapter(fsf_req->adapter), fsf_req->qtcb->header.fsf_command); zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_FCP_RSP_AVAILABLE: ZFCP_LOG_DEBUG("FCP Sense data will be presented to the " "SCSI stack.\n"); break; case FSF_ADAPTER_STATUS_AVAILABLE: zfcp_fsf_fsfstatus_qual_eval(fsf_req); break; } skip_fsfstatus: /* * always call specific handlers to give them a chance to do * something meaningful even in error cases */ zfcp_fsf_req_dispatch(fsf_req); return retval;}/* * function: zfcp_fsf_fsfstatus_qual_eval * * purpose: evaluates FSF status-qualifier of completed FSF request * and acts accordingly * * returns: */static intzfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req){ int retval = 0; switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) { case FSF_SQ_FCP_RSP_AVAILABLE: break; case FSF_SQ_RETRY_IF_POSSIBLE: /* The SCSI-stack may now issue retries or escalate */ fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_SQ_COMMAND_ABORTED: /* Carry the aborted state on to upper layer */ fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTED; fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_SQ_NO_RECOM: ZFCP_LOG_NORMAL("bug: No recommendation could be given for a" "problem on the adapter %s " "Stopping all operations on this adapter. ", zfcp_get_busid_by_adapter(fsf_req->adapter)); zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_SQ_ULP_PROGRAMMING_ERROR: ZFCP_LOG_NORMAL("error: not enough SBALs for data transfer " "(adapter %s)\n", zfcp_get_busid_by_adapter(fsf_req->adapter)); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: case FSF_SQ_NO_RETRY_POSSIBLE: case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: /* dealt with in the respective functions */ break; default: ZFCP_LOG_NORMAL("bug: Additional status info could " "not be interpreted properly.\n"); ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, (char *) &fsf_req->qtcb->header.fsf_status_qual, sizeof (union fsf_status_qual)); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } return retval;}/** * zfcp_fsf_link_down_info_eval - evaluate link down information block */static voidzfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter, struct fsf_link_down_info *link_down){ if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status)) return; atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); if (link_down == NULL) { zfcp_erp_adapter_reopen(adapter, 0); return; } switch (link_down->error_code) { case FSF_PSQ_LINK_NO_LIGHT: ZFCP_LOG_NORMAL("The local link to adapter %s is down " "(no light detected)\n", zfcp_get_busid_by_adapter(adapter)); break; case FSF_PSQ_LINK_WRAP_PLUG: ZFCP_LOG_NORMAL("The local link to adapter %s is down " "(wrap plug detected)\n", zfcp_get_busid_by_adapter(adapter)); break; case FSF_PSQ_LINK_NO_FCP: ZFCP_LOG_NORMAL("The local link to adapter %s is down " "(adjacent node on link does not support FCP)\n", zfcp_get_busid_by_adapter(adapter)); break; case FSF_PSQ_LINK_FIRMWARE_UPDATE: ZFCP_LOG_NORMAL("The local link to adapter %s is down " "(firmware update in progress)\n", zfcp_get_busid_by_adapter(adapter)); break; case FSF_PSQ_LINK_INVALID_WWPN: ZFCP_LOG_NORMAL("The local link to adapter %s is down " "(duplicate or invalid WWPN detected)\n", zfcp_get_busid_by_adapter(adapter)); break; case FSF_PSQ_LINK_NO_NPIV_SUPPORT: ZFCP_LOG_NORMAL("The local link to adapter %s is down " "(no support for NPIV by Fabric)\n", zfcp_get_busid_by_adapter(adapter)); break; case FSF_PSQ_LINK_NO_FCP_RESOURCES: ZFCP_LOG_NORMAL("The local link to adapter %s is down " "(out of resource in FCP daughtercard)\n", zfcp_get_busid_by_adapter(adapter)); break; case FSF_PSQ_LINK_NO_FABRIC_RESOURCES: ZFCP_LOG_NORMAL("The local link to adapter %s is down " "(out of resource in Fabric)\n", zfcp_get_busid_by_adapter(adapter)); break; case FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE: ZFCP_LOG_NORMAL("The local link to adapter %s is down " "(unable to Fabric login)\n", zfcp_get_busid_by_adapter(adapter)); break; case FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED: ZFCP_LOG_NORMAL("WWPN assignment file corrupted on adapter %s\n", zfcp_get_busid_by_adapter(adapter)); break; case FSF_PSQ_LINK_MODE_TABLE_CURRUPTED: ZFCP_LOG_NORMAL("Mode table corrupted on adapter %s\n", zfcp_get_busid_by_adapter(adapter)); break; case FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT: ZFCP_LOG_NORMAL("No WWPN for assignment table on adapter %s\n", zfcp_get_busid_by_adapter(adapter)); break; default: ZFCP_LOG_NORMAL("The local link to adapter %s is down " "(warning: unknown reason code %d)\n", zfcp_get_busid_by_adapter(adapter), link_down->error_code); } if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) ZFCP_LOG_DEBUG("Debug information to link down: " "primary_status=0x%02x " "ioerr_code=0x%02x " "action_code=0x%02x " "reason_code=0x%02x " "explanation_code=0x%02x " "vendor_specific_code=0x%02x\n", link_down->primary_status, link_down->ioerr_code, link_down->action_code, link_down->reason_code, link_down->explanation_code, link_down->vendor_specific_code); switch (link_down->error_code) { case FSF_PSQ_LINK_NO_LIGHT: case FSF_PSQ_LINK_WRAP_PLUG: case FSF_PSQ_LINK_NO_FCP: case FSF_PSQ_LINK_FIRMWARE_UPDATE: zfcp_erp_adapter_reopen(adapter, 0); break; default: zfcp_erp_adapter_failed(adapter); }}/* * function: zfcp_fsf_req_dispatch * * purpose: calls the appropriate command specific handler * * returns: */static intzfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req){ struct zfcp_erp_action *erp_action = fsf_req->erp_action; struct zfcp_adapter *adapter = fsf_req->adapter; int retval = 0; switch (fsf_req->fsf_command) { case FSF_QTCB_FCP_CMND: zfcp_fsf_send_fcp_command_handler(fsf_req); break; case FSF_QTCB_ABORT_FCP_CMND: zfcp_fsf_abort_fcp_command_handler(fsf_req); break; case FSF_QTCB_SEND_GENERIC: zfcp_fsf_send_ct_handler(fsf_req); break; case FSF_QTCB_OPEN_PORT_WITH_DID: zfcp_fsf_open_port_handler(fsf_req); break; case FSF_QTCB_OPEN_LUN: zfcp_fsf_open_unit_handler(fsf_req); break; case FSF_QTCB_CLOSE_LUN: zfcp_fsf_close_unit_handler(fsf_req); break; case FSF_QTCB_CLOSE_PORT: zfcp_fsf_close_port_handler(fsf_req); break; case FSF_QTCB_CLOSE_PHYSICAL_PORT: zfcp_fsf_close_physical_port_handler(fsf_req); break; case FSF_QTCB_EXCHANGE_CONFIG_DATA: zfcp_fsf_exchange_config_data_handler(fsf_req); break; case FSF_QTCB_EXCHANGE_PORT_DATA: zfcp_fsf_exchange_port_data_handler(fsf_req); break; case FSF_QTCB_SEND_ELS: zfcp_fsf_send_els_handler(fsf_req); break; case FSF_QTCB_DOWNLOAD_CONTROL_FILE: zfcp_fsf_control_file_handler(fsf_req); break; case FSF_QTCB_UPLOAD_CONTROL_FILE: zfcp_fsf_control_file_handler(fsf_req); break; default: fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; ZFCP_LOG_NORMAL("bug: Command issued by the device driver is " "not supported by the adapter %s\n", zfcp_get_busid_by_adapter(adapter)); if (fsf_req->fsf_command != fsf_req->qtcb->header.fsf_command) ZFCP_LOG_NORMAL ("bug: Command issued by the device driver differs " "from the command returned by the adapter %s " "(debug info 0x%x, 0x%x).\n", zfcp_get_busid_by_adapter(adapter), fsf_req->fsf_command, fsf_req->qtcb->header.fsf_command); } if (!erp_action) return retval; zfcp_erp_async_handler(erp_action, 0); return retval;}/* * function: zfcp_fsf_status_read * * purpose: initiates a Status Read command at the specified adapter * * returns: */intzfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags){ struct zfcp_fsf_req *fsf_req; struct fsf_status_read_buffer *status_buffer; unsigned long lock_flags; volatile struct qdio_buffer_element *sbale; int retval = 0; /* setup new FSF request */ retval = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS, req_flags | ZFCP_REQ_NO_QTCB, adapter->pool.fsf_req_status_read, &lock_flags, &fsf_req); if (retval < 0) { ZFCP_LOG_INFO("error: Could not create unsolicited status " "buffer for adapter %s.\n", zfcp_get_busid_by_adapter(adapter)); goto failed_req_create; } sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); sbale[0].flags |= SBAL_FLAGS0_TYPE_STATUS; sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY; fsf_req->sbale_curr = 2; status_buffer = mempool_alloc(adapter->pool.data_status_read, GFP_ATOMIC); if (!status_buffer) { ZFCP_LOG_NORMAL("bug: could not get some buffer\n"); goto failed_buf; } memset(status_buffer, 0, sizeof (struct fsf_status_read_buffer)); fsf_req->data = (unsigned long) status_buffer; /* insert pointer to respective buffer */ sbale = zfcp_qdio_sbale_curr(fsf_req); sbale->addr = (void *) status_buffer; sbale->length = sizeof(struct fsf_status_read_buffer); /* start QDIO request for this FSF request */ retval = zfcp_fsf_req_send(fsf_req, NULL); if (retval) { ZFCP_LOG_DEBUG("error: Could not set-up unsolicited status " "environment.\n"); goto failed_req_send; } ZFCP_LOG_TRACE("Status Read request initiated (adapter%s)\n", zfcp_get_busid_by_adapter(adapter)); goto out; failed_req_send: mempool_free(status_buffer, adapter->pool.data_status_read); failed_buf: zfcp_fsf_req_free(fsf_req); failed_req_create: zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); out: write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); return retval;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -