struct be_queue_info cq;
 };
 
+struct beiscsi_mcc_tag_state {
+#define MCC_TAG_STATE_COMPLETED 0x00
+#define MCC_TAG_STATE_RUNNING   0x01
+#define MCC_TAG_STATE_TIMEOUT   0x02
+       uint8_t tag_state;
+       struct be_dma_mem tag_mem_state;
+};
+
 struct be_ctrl_info {
        u8 __iomem *csr;
        u8 __iomem *db;         /* Door Bell */
        unsigned short mcc_alloc_index;
        unsigned short mcc_free_index;
        unsigned int mcc_tag_available;
+
+       struct beiscsi_mcc_tag_state ptag_state[MAX_MCC_CMD + 1];
 };
 
 #include "be_cmds.h"
 
  * @phba: Driver private structure
  * @tag: Tag for the MBX Command
  * @wrb: the WRB used for the MBX Command
- * @cmd_hdr: IOCTL Hdr for the MBX Cmd
+ * @mbx_cmd_mem: ptr to memory allocated for MBX Cmd
  *
  * Waits for MBX completion with the passed TAG.
  *
  **/
 int beiscsi_mccq_compl(struct beiscsi_hba *phba,
                uint32_t tag, struct be_mcc_wrb **wrb,
-               void *cmd_hdr)
+               struct be_dma_mem *mbx_cmd_mem)
 {
        int rc = 0;
        uint32_t mcc_tag_response;
        uint16_t status = 0, addl_status = 0, wrb_num = 0;
        struct be_mcc_wrb *temp_wrb;
-       struct be_cmd_req_hdr *ioctl_hdr;
-       struct be_cmd_resp_hdr *ioctl_resp_hdr;
+       struct be_cmd_req_hdr *mbx_hdr;
+       struct be_cmd_resp_hdr *mbx_resp_hdr;
        struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
 
        if (beiscsi_error(phba)) {
                free_mcc_tag(&phba->ctrl, tag);
-               return -EIO;
+               return -EPERM;
        }
 
+       /* Set MBX Tag state to Active */
+       spin_lock(&phba->ctrl.mbox_lock);
+       phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_RUNNING;
+       spin_unlock(&phba->ctrl.mbox_lock);
+
        /* wait for the mccq completion */
        rc = wait_event_interruptible_timeout(
                                phba->ctrl.mcc_wait[tag],
                                BEISCSI_HOST_MBX_TIMEOUT));
 
        if (rc <= 0) {
+               struct be_dma_mem *tag_mem;
+               /* Set MBX Tag state to timeout */
+               spin_lock(&phba->ctrl.mbox_lock);
+               phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_TIMEOUT;
+               spin_unlock(&phba->ctrl.mbox_lock);
+
+               /* Store resource addr to be freed later */
+               tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
+               if (mbx_cmd_mem) {
+                       tag_mem->size = mbx_cmd_mem->size;
+                       tag_mem->va = mbx_cmd_mem->va;
+                       tag_mem->dma = mbx_cmd_mem->dma;
+               } else
+                       tag_mem->size = 0;
+
                beiscsi_log(phba, KERN_ERR,
                            BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
                            BEISCSI_LOG_CONFIG,
                            "BC_%d : MBX Cmd Completion timed out\n");
-               rc = -EBUSY;
-
-               /* decrement the mccq used count */
-               atomic_dec(&phba->ctrl.mcc_obj.q.used);
-
-               goto release_mcc_tag;
-       } else
+               return -EBUSY;
+       } else {
                rc = 0;
+               /* Set MBX Tag state to completed */
+               spin_lock(&phba->ctrl.mbox_lock);
+               phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
+               spin_unlock(&phba->ctrl.mbox_lock);
+       }
 
        mcc_tag_response = phba->ctrl.mcc_numtag[tag];
        status = (mcc_tag_response & CQE_STATUS_MASK);
        addl_status = ((mcc_tag_response & CQE_STATUS_ADDL_MASK) >>
                        CQE_STATUS_ADDL_SHIFT);
 
-       if (cmd_hdr) {
-               ioctl_hdr = (struct be_cmd_req_hdr *)cmd_hdr;
+       if (mbx_cmd_mem) {
+               mbx_hdr = (struct be_cmd_req_hdr *)mbx_cmd_mem->va;
        } else {
                wrb_num = (mcc_tag_response & CQE_STATUS_WRB_MASK) >>
                           CQE_STATUS_WRB_SHIFT;
                temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num);
-               ioctl_hdr = embedded_payload(temp_wrb);
+               mbx_hdr = embedded_payload(temp_wrb);
 
                if (wrb)
                        *wrb = temp_wrb;
        }
 
        if (status || addl_status) {
-               beiscsi_log(phba, KERN_ERR,
+               beiscsi_log(phba, KERN_WARNING,
                            BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
                            BEISCSI_LOG_CONFIG,
                            "BC_%d : MBX Cmd Failed for "
                            "Subsys : %d Opcode : %d with "
                            "Status : %d and Extd_Status : %d\n",
-                           ioctl_hdr->subsystem,
-                           ioctl_hdr->opcode,
+                           mbx_hdr->subsystem,
+                           mbx_hdr->opcode,
                            status, addl_status);
 
                if (status == MCC_STATUS_INSUFFICIENT_BUFFER) {
-                       ioctl_resp_hdr = (struct be_cmd_resp_hdr *) ioctl_hdr;
+                       mbx_resp_hdr = (struct be_cmd_resp_hdr *) mbx_hdr;
                        beiscsi_log(phba, KERN_WARNING,
                                    BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
                                    BEISCSI_LOG_CONFIG,
                                    "BC_%d : Insufficent Buffer Error "
                                    "Resp_Len : %d Actual_Resp_Len : %d\n",
-                                   ioctl_resp_hdr->response_length,
-                                   ioctl_resp_hdr->actual_resp_len);
+                                   mbx_resp_hdr->response_length,
+                                   mbx_resp_hdr->actual_resp_len);
 
                        rc = -EAGAIN;
                        goto release_mcc_tag;
 int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
                                    struct be_mcc_compl *compl)
 {
+       struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
        u16 compl_status, extd_status;
        unsigned short tag;
 
        ctrl->mcc_numtag[tag] |= (compl->tag0 & 0x00FF0000);
        ctrl->mcc_numtag[tag] |= (extd_status & 0x000000FF) << 8;
        ctrl->mcc_numtag[tag] |= (compl_status & 0x000000FF);
-       wake_up_interruptible(&ctrl->mcc_wait[tag]);
+
+       if (ctrl->ptag_state[tag].tag_state == MCC_TAG_STATE_RUNNING) {
+               wake_up_interruptible(&ctrl->mcc_wait[tag]);
+       } else if (ctrl->ptag_state[tag].tag_state == MCC_TAG_STATE_TIMEOUT) {
+               struct be_dma_mem *tag_mem;
+               tag_mem = &ctrl->ptag_state[tag].tag_mem_state;
+
+               beiscsi_log(phba, KERN_WARNING,
+                           BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
+                           BEISCSI_LOG_CONFIG,
+                           "BC_%d : MBX Completion for timeout Command "
+                           "from FW\n");
+               /* Check if memory needs to be freed */
+               if (tag_mem->size)
+                       pci_free_consistent(ctrl->pdev, tag_mem->size,
+                                           tag_mem->va, tag_mem->dma);
+
+               /* Change tag state */
+               spin_lock(&phba->ctrl.mbox_lock);
+               ctrl->ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
+               spin_unlock(&phba->ctrl.mbox_lock);
+
+               /* Free MCC Tag */
+               free_mcc_tag(ctrl, tag);
+       }
+
        return 0;
 }
 
 
 void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
 
 int beiscsi_mccq_compl(struct beiscsi_hba *phba,
-                       uint32_t tag, struct be_mcc_wrb **wrb, void *cmd_va);
+                       uint32_t tag, struct be_mcc_wrb **wrb,
+                       struct be_dma_mem *mbx_cmd_mem);
 /*ISCSI Functuions */
 int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
 int be_cmd_fw_uninit(struct be_ctrl_info *ctrl);
 
                return -EAGAIN;
        }
 
-       ret = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va);
+       ret = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd);
        if (ret) {
                beiscsi_log(phba, KERN_ERR,
                            BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
                            "BS_%d : mgmt_open_connection Failed");
 
-               pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
-                           nonemb_cmd.va, nonemb_cmd.dma);
+               if (ret != -EBUSY)
+                       pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+                                           nonemb_cmd.va, nonemb_cmd.dma);
+
                beiscsi_free_ep(beiscsi_ep);
-               return -EBUSY;
+               return ret;
        }
 
        ptcpcnct_out = (struct tcp_connect_and_offload_out *)nonemb_cmd.va;
 
        struct invalidate_command_table *inv_tbl;
        struct be_dma_mem nonemb_cmd;
        unsigned int cid, tag, num_invalidate;
+       int rc;
 
        cls_session = starget_to_session(scsi_target(sc->device));
        session = cls_session->dd_data;
                return FAILED;
        }
 
-       beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va);
-       pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
-                           nonemb_cmd.va, nonemb_cmd.dma);
+       rc = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd);
+       if (rc != -EBUSY)
+               pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+                                   nonemb_cmd.va, nonemb_cmd.dma);
+
        return iscsi_eh_abort(sc);
 }
 
        struct invalidate_command_table *inv_tbl;
        struct be_dma_mem nonemb_cmd;
        unsigned int cid, tag, i, num_invalidate;
+       int rc;
 
        /* invalidate iocbs */
        cls_session = starget_to_session(scsi_target(sc->device));
                return FAILED;
        }
 
-       beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va);
-       pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
-                           nonemb_cmd.va, nonemb_cmd.dma);
+       rc = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd);
+       if (rc != -EBUSY)
+               pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+                                   nonemb_cmd.va, nonemb_cmd.dma);
        return iscsi_eh_device_reset(sc);
 }
 
                goto boot_freemem;
        }
 
-       ret = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va);
+       ret = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd);
        if (ret) {
                beiscsi_log(phba, KERN_ERR,
                            BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
                            "BM_%d : beiscsi_get_session_info Failed");
-               goto boot_freemem;
+
+               if (ret != -EBUSY)
+                       goto boot_freemem;
+               else
+                       return ret;
        }
 
        session_resp = nonemb_cmd.va ;
                phba->ctrl.mcc_tag[i] = i + 1;
                phba->ctrl.mcc_numtag[i + 1] = 0;
                phba->ctrl.mcc_tag_available++;
+               memset(&phba->ctrl.ptag_state[i].tag_mem_state, 0,
+                      sizeof(struct beiscsi_mcc_tag_state));
        }
 
        phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0;
 
        be_mcc_notify(phba);
        spin_unlock(&ctrl->mbox_lock);
 
-       rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va);
+       rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd);
+
+       if (resp_buf)
+               memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
+
        if (rc) {
-               /* Check if the IOCTL needs to be re-issued */
+               /* Check if the MBX Cmd needs to be re-issued */
                if (rc == -EAGAIN)
                        return rc;
 
-               beiscsi_log(phba, KERN_ERR,
+               beiscsi_log(phba, KERN_WARNING,
                            BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
                            "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
 
-               goto free_cmd;
+               if (rc != -EBUSY)
+                       goto free_cmd;
+               else
+                       return rc;
        }
-
-       if (resp_buf)
-               memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
-
 free_cmd:
        pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
                            nonemb_cmd->va, nonemb_cmd->dma);
 {
        int rc;
        unsigned int tag;
-       struct be_mcc_wrb *wrb = NULL;
 
        tag = be_cmd_set_vlan(phba, vlan_tag);
        if (!tag) {
                return -EBUSY;
        }
 
-       rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
+       rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
        if (rc) {
                beiscsi_log(phba, KERN_ERR,
                            (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),