summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi/be_mgmt.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 19:01:32 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 19:01:32 -0700
commit3151367f8778a1789d6f6e6f6c642681b6cd6d64 (patch)
tree1869d5429a25abd994ae94079808b8db060ec6f3 /drivers/scsi/be2iscsi/be_mgmt.c
parent16642a2e7be23bbda013fc32d8f6c68982eab603 (diff)
parentfe709ed827d370e6b0c0a9f9456da1c22bdcd118 (diff)
Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull first round of SCSI updates from James Bottomley: "This is a large set of updates, mostly for drivers (qla2xxx [including support for new 83xx based card], qla4xxx, mpt2sas, bfa, zfcp, hpsa, be2iscsi, isci, lpfc, ipr, ibmvfc, ibmvscsi, megaraid_sas). There's also a rework for tape adding virtually unlimited numbers of tape drives plus a set of dif fixes for sd and a fix for a live lock on hot remove of SCSI devices. This round includes a signed tag pull of isci-for-3.6 Signed-off-by: James Bottomley <JBottomley@Parallels.com>" Fix up trivial conflict in drivers/scsi/qla2xxx/qla_nx.c due to new PCI helper function use in a function that was removed by this pull. * tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (198 commits) [SCSI] st: remove st_mutex [SCSI] sd: Ensure we correctly disable devices with unknown protection type [SCSI] hpsa: gen8plus Smart Array IDs [SCSI] qla4xxx: Update driver version to 5.03.00-k1 [SCSI] qla4xxx: Disable generating pause frames for ISP83XX [SCSI] qla4xxx: Fix double clearing of risc_intr for ISP83XX [SCSI] qla4xxx: IDC implementation for Loopback [SCSI] qla4xxx: update copyrights in LICENSE.qla4xxx [SCSI] qla4xxx: Fix panic while rmmod [SCSI] qla4xxx: Fail probe_adapter if IRQ allocation fails [SCSI] qla4xxx: Prevent MSI/MSI-X falling back to INTx for ISP82XX [SCSI] qla4xxx: Update idc reg in case of PCI AER [SCSI] qla4xxx: Fix double IDC locking in qla4_8xxx_error_recovery [SCSI] qla4xxx: Clear interrupt while unloading driver for ISP83XX [SCSI] qla4xxx: Print correct IDC version [SCSI] qla4xxx: Added new mbox cmd to pass driver version to FW [SCSI] scsi_dh_alua: Enable STPG for unavailable ports [SCSI] scsi_remove_target: fix softlockup regression on hot remove [SCSI] ibmvscsi: Fix host config length field overflow [SCSI] ibmvscsi: Remove backend abstraction ...
Diffstat (limited to 'drivers/scsi/be2iscsi/be_mgmt.c')
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c314
1 files changed, 263 insertions, 51 deletions
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 2a096795b9a..aab5dd359e2 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -23,6 +23,53 @@
#include "be_mgmt.h"
#include "be_iscsi.h"
+/**
+ * mgmt_reopen_session()- Reopen a session based on reopen_type
+ * @phba: Device priv structure instance
+ * @reopen_type: Type of reopen_session FW should do.
+ * @sess_handle: Session Handle of the session to be re-opened
+ *
+ * return
+ * the TAG used for MBOX Command
+ *
+ **/
+unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
+ unsigned int reopen_type,
+ unsigned int sess_handle)
+{
+ struct be_ctrl_info *ctrl = &phba->ctrl;
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_reopen_session_req *req;
+ unsigned int tag = 0;
+
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BG_%d : In bescsi_get_boot_target\n");
+
+ spin_lock(&ctrl->mbox_lock);
+ tag = alloc_mcc_tag(phba);
+ if (!tag) {
+ spin_unlock(&ctrl->mbox_lock);
+ return tag;
+ }
+
+ wrb = wrb_from_mccq(phba);
+ req = embedded_payload(wrb);
+ wrb->tag0 |= tag;
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
+ OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
+ sizeof(struct be_cmd_reopen_session_resp));
+
+ /* set the reopen_type,sess_handle */
+ req->reopen_type = reopen_type;
+ req->session_handle = sess_handle;
+
+ be_mcc_notify(phba);
+ spin_unlock(&ctrl->mbox_lock);
+ return tag;
+}
+
unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
{
struct be_ctrl_info *ctrl = &phba->ctrl;
@@ -30,7 +77,10 @@ unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
struct be_cmd_get_boot_target_req *req;
unsigned int tag = 0;
- SE_DEBUG(DBG_LVL_8, "In bescsi_get_boot_target\n");
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BG_%d : In bescsi_get_boot_target\n");
+
spin_lock(&ctrl->mbox_lock);
tag = alloc_mcc_tag(phba);
if (!tag) {
@@ -62,7 +112,10 @@ unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
struct be_cmd_get_session_resp *resp;
struct be_sge *sge;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_get_session_info\n");
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BG_%d : In beiscsi_get_session_info\n");
+
spin_lock(&ctrl->mbox_lock);
tag = alloc_mcc_tag(phba);
if (!tag) {
@@ -121,16 +174,16 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
phba->fw_config.iscsi_cid_count =
pfw_cfg->ulp[0].sq_count;
if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) {
- SE_DEBUG(DBG_LVL_8,
- "FW reported MAX CXNS as %d\t"
- "Max Supported = %d.\n",
- phba->fw_config.iscsi_cid_count,
- BE2_MAX_SESSIONS);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BG_%d : FW reported MAX CXNS as %d\t"
+ "Max Supported = %d.\n",
+ phba->fw_config.iscsi_cid_count,
+ BE2_MAX_SESSIONS);
phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2;
}
} else {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed in mgmt_get_fw_config\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BG_%d : Failed in mgmt_get_fw_config\n");
}
spin_unlock(&ctrl->mbox_lock);
@@ -150,9 +203,9 @@ int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
sizeof(struct be_mgmt_controller_attributes),
&nonemb_cmd.dma);
if (nonemb_cmd.va == NULL) {
- SE_DEBUG(DBG_LVL_1,
- "Failed to allocate memory for mgmt_check_supported_fw"
- "\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BG_%d : Failed to allocate memory for "
+ "mgmt_check_supported_fw\n");
return -ENOMEM;
}
nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
@@ -169,18 +222,23 @@ int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
status = be_mbox_notify(ctrl);
if (!status) {
struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
- SE_DEBUG(DBG_LVL_8, "Firmware version of CMD: %s\n",
- resp->params.hba_attribs.flashrom_version_string);
- SE_DEBUG(DBG_LVL_8, "Firmware version is : %s\n",
- resp->params.hba_attribs.firmware_version_string);
- SE_DEBUG(DBG_LVL_8,
- "Developer Build, not performing version check...\n");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BG_%d : Firmware Version of CMD : %s\n"
+ "Firmware Version is : %s\n"
+ "Developer Build, not performing version check...\n",
+ resp->params.hba_attribs
+ .flashrom_version_string,
+ resp->params.hba_attribs.
+ firmware_version_string);
+
phba->fw_config.iscsi_features =
resp->params.hba_attribs.iscsi_features;
- SE_DEBUG(DBG_LVL_8, " phba->fw_config.iscsi_features = %d\n",
- phba->fw_config.iscsi_features);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : phba->fw_config.iscsi_features = %d\n",
+ phba->fw_config.iscsi_features);
} else
- SE_DEBUG(DBG_LVL_1, " Failed in mgmt_check_supported_fw\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BG_%d : Failed in mgmt_check_supported_fw\n");
spin_unlock(&ctrl->mbox_lock);
if (nonemb_cmd.va)
pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
@@ -229,9 +287,10 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
OPCODE_COMMON_READ_FLASH, sizeof(*req));
break;
default:
- shost_printk(KERN_WARNING, phba->shost,
- "Unsupported cmd = 0x%x\n\n", bsg_req->rqst_data.
- h_vendor.vendor_cmd[0]);
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Unsupported cmd = 0x%x\n\n",
+ bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
+
spin_unlock(&ctrl->mbox_lock);
return -ENOSYS;
}
@@ -275,8 +334,8 @@ int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
status = be_mcc_notify_wait(phba);
if (status)
- shost_printk(KERN_WARNING, phba->shost,
- " mgmt_epfw_cleanup , FAILED\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BG_%d : mgmt_epfw_cleanup , FAILED\n");
spin_unlock(&ctrl->mbox_lock);
return status;
}
@@ -459,8 +518,9 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
&daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
beiscsi_ep->ip_type = BE2_IPV6;
} else{
- shost_printk(KERN_ERR, phba->shost, "unknown addr family %d\n",
- dst_addr->sa_family);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BG_%d : unknown addr family %d\n",
+ dst_addr->sa_family);
spin_unlock(&ctrl->mbox_lock);
free_mcc_tag(&phba->ctrl, tag);
return -EINVAL;
@@ -471,7 +531,8 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
if (phba->nxt_cqid == phba->num_cpus)
phba->nxt_cqid = 0;
req->cq_id = phwi_context->be_cq[i].id;
- SE_DEBUG(DBG_LVL_8, "i=%d cq_id=%d\n", i, req->cq_id);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
req->defq_id = def_hdr_id;
req->hdr_ring_id = def_hdr_id;
req->data_ring_id = def_data_id;
@@ -506,8 +567,8 @@ unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
if (!status)
phba->interface_handle = pbe_allid->if_hndl_list[0];
else {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed in mgmt_get_all_if_id\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed in mgmt_get_all_if_id\n");
}
spin_unlock(&ctrl->mbox_lock);
@@ -550,9 +611,10 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
- SE_DEBUG(DBG_LVL_1,
- "mgmt_exec_nonemb_cmd Failed status = %d"
- "extd_status = %d\n", status, extd_status);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BG_%d : mgmt_exec_nonemb_cmd Failed status = %d"
+ "extd_status = %d\n", status, extd_status);
rc = -EIO;
goto free_tag;
}
@@ -573,7 +635,8 @@ static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
{
cmd->va = pci_alloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
if (!cmd->va) {
- SE_DEBUG(DBG_LVL_1, "Failed to allocate memory for if info\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to allocate memory for if info\n");
return -ENOMEM;
}
memset(cmd->va, 0, size);
@@ -629,8 +692,8 @@ mgmt_static_ip_modify(struct beiscsi_hba *phba,
rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
if (rc < 0)
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to Modify existing IP Address\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to Modify existing IP Address\n");
return rc;
}
@@ -684,8 +747,8 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
if (if_info.dhcp_state) {
- shost_printk(KERN_WARNING, phba->shost,
- "DHCP Already Enabled\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : DHCP Already Enabled\n");
return 0;
}
/* The ip_param->len is 1 in DHCP case. Setting
@@ -712,8 +775,9 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
if (rc < 0) {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to Delete existing dhcp\n");
+ beiscsi_log(phba, KERN_WARNING,
+ BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to Delete existing dhcp\n");
return rc;
}
}
@@ -732,8 +796,8 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
if (rc) {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to Get Gateway Addr\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to Get Gateway Addr\n");
return rc;
}
@@ -743,8 +807,9 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
IP_ACTION_DEL, IP_V4_LEN);
if (rc) {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to clear Gateway Addr Set\n");
+ beiscsi_log(phba, KERN_WARNING,
+ BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to clear Gateway Addr Set\n");
return rc;
}
}
@@ -783,8 +848,8 @@ int mgmt_set_gateway(struct beiscsi_hba *phba,
memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
if (rt_val) {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to Get Gateway Addr\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to Get Gateway Addr\n");
return rt_val;
}
@@ -793,8 +858,8 @@ int mgmt_set_gateway(struct beiscsi_hba *phba,
rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
gateway_param->len);
if (rt_val) {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to clear Gateway Addr Set\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to clear Gateway Addr Set\n");
return rt_val;
}
}
@@ -804,8 +869,8 @@ int mgmt_set_gateway(struct beiscsi_hba *phba,
gateway_param->len);
if (rt_val)
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to Set Gateway Addr\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to Set Gateway Addr\n");
return rt_val;
}
@@ -924,3 +989,150 @@ unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
spin_unlock(&ctrl->mbox_lock);
return tag;
}
+
+/**
+ * be_mgmt_get_boot_shandle()- Get the session handle
+ * @phba: device priv structure instance
+ * @s_handle: session handle returned for boot session.
+ *
+ * Get the boot target session handle. In case of
+ * crashdump mode driver has to issue and MBX Cmd
+ * for FW to login to boot target
+ *
+ * return
+ * Success: 0
+ * Failure: Non-Zero value
+ *
+ **/
+int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
+ unsigned int *s_handle)
+{
+ struct be_cmd_get_boot_target_resp *boot_resp;
+ struct be_mcc_wrb *wrb;
+ unsigned int tag, wrb_num;
+ uint8_t boot_retry = 3;
+ unsigned short status, extd_status;
+ struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
+
+ do {
+ /* Get the Boot Target Session Handle and Count*/
+ tag = mgmt_get_boot_target(phba);
+ if (!tag) {
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
+ "BG_%d : Getting Boot Target Info Failed\n");
+ return -EAGAIN;
+ } else
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+
+ wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+ extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+ status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+ if (status || extd_status) {
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BG_%d : mgmt_get_boot_target Failed"
+ " status = %d extd_status = %d\n",
+ status, extd_status);
+ free_mcc_tag(&phba->ctrl, tag);
+ return -EBUSY;
+ }
+ wrb = queue_get_wrb(mccq, wrb_num);
+ free_mcc_tag(&phba->ctrl, tag);
+ boot_resp = embedded_payload(wrb);
+
+ /* Check if the there are any Boot targets configured */
+ if (!boot_resp->boot_session_count) {
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BG_%d ;No boot targets configured\n");
+ return -ENXIO;
+ }
+
+ /* FW returns the session handle of the boot session */
+ if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
+ *s_handle = boot_resp->boot_session_handle;
+ return 0;
+ }
+
+ /* Issue MBX Cmd to FW to login to the boot target */
+ tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
+ INVALID_SESS_HANDLE);
+ if (!tag) {
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BG_%d : mgmt_reopen_session Failed\n");
+ return -EAGAIN;
+ } else
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+
+ wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+ extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+ status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+ if (status || extd_status) {
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BG_%d : mgmt_reopen_session Failed"
+ " status = %d extd_status = %d\n",
+ status, extd_status);
+ free_mcc_tag(&phba->ctrl, tag);
+ return -EBUSY;
+ }
+ free_mcc_tag(&phba->ctrl, tag);
+
+ } while (--boot_retry);
+
+ /* Couldn't log into the boot target */
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BG_%d : Login to Boot Target Failed\n");
+ return -ENXIO;
+}
+
+/**
+ * mgmt_set_vlan()- Issue and wait for CMD completion
+ * @phba: device private structure instance
+ * @vlan_tag: VLAN tag
+ *
+ * Issue the MBX Cmd and wait for the completion of the
+ * command.
+ *
+ * returns
+ * Success: 0
+ * Failure: Non-Xero Value
+ **/
+int mgmt_set_vlan(struct beiscsi_hba *phba,
+ uint16_t vlan_tag)
+{
+ unsigned int tag, wrb_num;
+ unsigned short status, extd_status;
+
+ tag = be_cmd_set_vlan(phba, vlan_tag);
+ if (!tag) {
+ beiscsi_log(phba, KERN_ERR,
+ (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
+ "BG_%d : VLAN Setting Failed\n");
+ return -EBUSY;
+ } else
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+
+ wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+ extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+ status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+
+ if (status || extd_status) {
+ beiscsi_log(phba, KERN_ERR,
+ (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
+ "BS_%d : status : %d extd_status : %d\n",
+ status, extd_status);
+
+ free_mcc_tag(&phba->ctrl, tag);
+ return -EAGAIN;
+ }
+
+ free_mcc_tag(&phba->ctrl, tag);
+ return 0;
+}