return tag;
}
-void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
+struct be_mcc_wrb *alloc_mcc_wrb(struct beiscsi_hba *phba,
+ unsigned int *ref_tag)
{
+ struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
+ struct be_mcc_wrb *wrb = NULL;
+ unsigned int tag;
+
+ spin_lock_bh(&phba->ctrl.mcc_lock);
+ if (mccq->used == mccq->len) {
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT |
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BC_%d : MCC queue full: WRB used %u tag avail %u\n",
+ mccq->used, phba->ctrl.mcc_tag_available);
+ goto alloc_failed;
+ }
+
+ if (!phba->ctrl.mcc_tag_available)
+ goto alloc_failed;
+
+ tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
+ if (!tag) {
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT |
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BC_%d : MCC tag 0 allocated: tag avail %u alloc index %u\n",
+ phba->ctrl.mcc_tag_available,
+ phba->ctrl.mcc_alloc_index);
+ goto alloc_failed;
+ }
+
+ /* return this tag for further reference */
+ *ref_tag = tag;
+ phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
+ phba->ctrl.mcc_tag_status[tag] = 0;
+ phba->ctrl.ptag_state[tag].tag_state = 0;
+ phba->ctrl.mcc_tag_available--;
+ if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1))
+ phba->ctrl.mcc_alloc_index = 0;
+ else
+ phba->ctrl.mcc_alloc_index++;
+
+ wrb = queue_head_node(mccq);
+ memset(wrb, 0, sizeof(*wrb));
+ wrb->tag0 = tag;
+ wrb->tag0 |= (mccq->head << MCC_Q_WRB_IDX_SHIFT) & MCC_Q_WRB_IDX_MASK;
+ queue_head_inc(mccq);
+ mccq->used++;
+
+alloc_failed:
+ spin_unlock_bh(&phba->ctrl.mcc_lock);
+ return wrb;
+}
+
+void free_mcc_wrb(struct be_ctrl_info *ctrl, unsigned int tag)
+{
+ struct be_queue_info *mccq = &ctrl->mcc_obj.q;
+
spin_lock_bh(&ctrl->mcc_lock);
tag = tag & MCC_Q_CMD_TAG_MASK;
ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
else
ctrl->mcc_free_index++;
ctrl->mcc_tag_available++;
+ mccq->used--;
spin_unlock_bh(&ctrl->mcc_lock);
}
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);
+ if (beiscsi_error(phba))
return -EPERM;
- }
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
}
}
- free_mcc_tag(&phba->ctrl, tag);
+ free_mcc_wrb(&phba->ctrl, tag);
return rc;
}
if (tag_mem->size)
pci_free_consistent(ctrl->pdev, tag_mem->size,
tag_mem->va, tag_mem->dma);
- free_mcc_tag(ctrl, tag);
+ free_mcc_wrb(ctrl, tag);
return 0;
}
struct be_ctrl_info *ctrl = &phba->ctrl;
int i;
+ if (!test_bit(MCC_TAG_STATE_RUNNING,
+ &ctrl->ptag_state[tag].tag_state)) {
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BC_%d: tag %u state not running\n", tag);
+ return 0;
+ }
for (i = 0; i < mcc_timeout; i++) {
if (beiscsi_error(phba))
return -EIO;
beiscsi_process_mcc_cq(phba);
-
+ /* after polling, wrb and tag need to be released */
if (!test_bit(MCC_TAG_STATE_RUNNING,
- &ctrl->ptag_state[tag].tag_state))
+ &ctrl->ptag_state[tag].tag_state)) {
+ free_mcc_wrb(ctrl, tag);
break;
+ }
udelay(100);
}
return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
}
-struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba)
-{
- struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
- struct be_mcc_wrb *wrb;
-
- WARN_ON(atomic_read(&mccq->used) >= mccq->len);
- wrb = queue_head_node(mccq);
- memset(wrb, 0, sizeof(*wrb));
- wrb->tag0 = (mccq->head << MCC_Q_WRB_IDX_SHIFT) & MCC_Q_WRB_IDX_MASK;
- queue_head_inc(mccq);
- atomic_inc(&mccq->used);
- return wrb;
-}
-
-
int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
struct be_queue_info *eq, int eq_delay)
{
int be_cmd_set_vlan(struct beiscsi_hba *phba,
uint16_t vlan_tag)
{
- unsigned int tag = 0;
+ unsigned int tag;
struct be_mcc_wrb *wrb;
struct be_cmd_set_vlan_req *req;
struct be_ctrl_info *ctrl = &phba->ctrl;
if (mutex_lock_interruptible(&ctrl->mbox_lock))
return 0;
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
- return tag;
+ return 0;
}
- wrb = wrb_from_mccq(phba);
req = embedded_payload(wrb);
- wrb->tag0 |= tag;
be_wrb_hdr_prepare(wrb, sizeof(*wrb), true, 0);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
OPCODE_COMMON_ISCSI_NTWK_SET_VLAN,
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb;
struct be_cmd_req_modify_eq_delay *req;
- unsigned int tag = 0;
+ unsigned int tag;
int i;
mutex_lock(&ctrl->mbox_lock);
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
- return tag;
+ return 0;
}
- 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_COMMON,
OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb;
struct be_cmd_reopen_session_req *req;
- unsigned int tag = 0;
+ unsigned int tag;
beiscsi_log(phba, KERN_INFO,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BG_%d : In bescsi_get_boot_target\n");
mutex_lock(&ctrl->mbox_lock);
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
- return tag;
+ return 0;
}
- 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,
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb;
struct be_cmd_get_boot_target_req *req;
- unsigned int tag = 0;
+ unsigned int tag;
beiscsi_log(phba, KERN_INFO,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BG_%d : In bescsi_get_boot_target\n");
mutex_lock(&ctrl->mbox_lock);
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
- return tag;
+ return 0;
}
- 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_BOOT_GET_BOOT_TARGET,
{
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb;
- unsigned int tag = 0;
+ unsigned int tag;
struct be_cmd_get_session_req *req;
struct be_cmd_get_session_resp *resp;
struct be_sge *sge;
"BG_%d : In beiscsi_get_session_info\n");
mutex_lock(&ctrl->mbox_lock);
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
- return tag;
+ return 0;
}
nonemb_cmd->size = sizeof(*resp);
req = nonemb_cmd->va;
memset(req, 0, sizeof(*req));
- wrb = wrb_from_mccq(phba);
sge = nonembedded_sgl(wrb);
- wrb->tag0 |= tag;
-
-
- wrb->tag0 |= tag;
be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
return -ENOSYS;
}
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
- return tag;
+ return 0;
}
- wrb = wrb_from_mccq(phba);
mcc_sge = nonembedded_sgl(wrb);
be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
job->request_payload.sg_cnt);
mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
- wrb->tag0 |= tag;
be_mcc_notify(phba, tag);
int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num)
{
struct be_ctrl_info *ctrl = &phba->ctrl;
- struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
- struct iscsi_cleanup_req *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct iscsi_cleanup_req *req;
unsigned int tag;
int status;
mutex_lock(&ctrl->mbox_lock);
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
return -EBUSY;
}
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
- wrb->tag0 |= tag;
req->chute = (1 << ulp_num);
req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, ulp_num));
struct be_mcc_wrb *wrb;
struct be_sge *sge;
struct invalidate_commands_params_in *req;
- unsigned int i, tag = 0;
+ unsigned int i, tag;
mutex_lock(&ctrl->mbox_lock);
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
- return tag;
+ return 0;
}
req = nonemb_cmd->va;
memset(req, 0, sizeof(*req));
- wrb = wrb_from_mccq(phba);
sge = nonembedded_sgl(wrb);
- wrb->tag0 |= tag;
be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
unsigned int tag = 0;
mutex_lock(&ctrl->mbox_lock);
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
- return tag;
+ return 0;
}
- wrb = wrb_from_mccq(phba);
- wrb->tag0 |= tag;
- req = embedded_payload(wrb);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb;
struct tcp_upload_params_in *req;
- unsigned int tag = 0;
+ unsigned int tag;
mutex_lock(&ctrl->mbox_lock);
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
- return tag;
+ return 0;
}
- wrb = wrb_from_mccq(phba);
- req = embedded_payload(wrb);
- wrb->tag0 |= tag;
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
if (mutex_lock_interruptible(&ctrl->mbox_lock))
return 0;
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
- return tag;
+ return 0;
}
- wrb = wrb_from_mccq(phba);
- sge = nonembedded_sgl(wrb);
+ sge = nonembedded_sgl(wrb);
req = nonemb_cmd->va;
memset(req, 0, sizeof(*req));
- wrb->tag0 |= tag;
be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
if (mutex_lock_interruptible(&ctrl->mbox_lock))
return -EINTR;
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
return -ENOMEM;
}
- 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,
OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
int rc = 0;
mutex_lock(&ctrl->mbox_lock);
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
rc = -ENOMEM;
goto free_cmd;
}
- wrb = wrb_from_mccq(phba);
- wrb->tag0 |= tag;
sge = nonembedded_sgl(wrb);
-
be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
{
- unsigned int tag = 0;
+ unsigned int tag;
struct be_mcc_wrb *wrb;
struct be_cmd_hba_name *req;
struct be_ctrl_info *ctrl = &phba->ctrl;
if (mutex_lock_interruptible(&ctrl->mbox_lock))
return 0;
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
- return tag;
+ return 0;
}
- 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_CFG_GET_HBA_NAME,
"BG_%d : In bescsi_logout_fwboot_sess\n");
mutex_lock(&ctrl->mbox_lock);
- tag = alloc_mcc_tag(phba);
- if (!tag) {
+ wrb = alloc_mcc_wrb(phba, &tag);
+ if (!wrb) {
mutex_unlock(&ctrl->mbox_lock);
beiscsi_log(phba, KERN_INFO,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
return -EINVAL;
}
- 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_SESSION_LOGOUT_TARGET,