* alloc_wrb_handle - To allocate a wrb handle
* @phba: The hba pointer
* @cid: The cid to use for allocation
+ * @pwrb_context: ptr to ptr to wrb context
*
* This happens under session_lock until submission to chip
*/
-struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid)
+struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
+ struct hwi_wrb_context **pcontext)
{
struct hwi_wrb_context *pwrb_context;
struct hwi_controller *phwi_ctrlr;
- struct wrb_handle *pwrb_handle, *pwrb_handle_tmp;
+ struct wrb_handle *pwrb_handle;
uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
phwi_ctrlr = phba->phwi_ctrlr;
pwrb_context->alloc_index = 0;
else
pwrb_context->alloc_index++;
- pwrb_handle_tmp = pwrb_context->pwrb_handle_base[
- pwrb_context->alloc_index];
- pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index;
+
+ /* Return the context address */
+ *pcontext = pwrb_context;
} else
pwrb_handle = NULL;
return pwrb_handle;
struct beiscsi_offload_params *params)
{
struct wrb_handle *pwrb_handle;
+ struct hwi_wrb_context *pwrb_context = NULL;
struct beiscsi_hba *phba = beiscsi_conn->phba;
struct iscsi_task *task = beiscsi_conn->task;
struct iscsi_session *session = task->conn->session;
beiscsi_cleanup_task(task);
spin_unlock_bh(&session->back_lock);
- pwrb_handle = alloc_wrb_handle(phba, beiscsi_conn->beiscsi_conn_cid);
+ pwrb_handle = alloc_wrb_handle(phba, beiscsi_conn->beiscsi_conn_cid,
+ &pwrb_context);
/* Check for the adapter family */
if (is_chip_be2_be3r(phba))
beiscsi_offload_cxn_v0(params, pwrb_handle,
- phba->init_mem);
+ phba->init_mem,
+ pwrb_context);
else
- beiscsi_offload_cxn_v2(params, pwrb_handle);
+ beiscsi_offload_cxn_v2(params, pwrb_handle,
+ pwrb_context);
be_dws_le_to_cpu(pwrb_handle->pwrb,
sizeof(struct iscsi_target_context_update_wrb));
goto free_hndls;
}
io_task->pwrb_handle = alloc_wrb_handle(phba,
- beiscsi_conn->beiscsi_conn_cid);
+ beiscsi_conn->beiscsi_conn_cid,
+ &io_task->pwrb_context);
if (!io_task->pwrb_handle) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
io_task->psgl_handle;
io_task->pwrb_handle =
alloc_wrb_handle(phba,
- beiscsi_conn->beiscsi_conn_cid);
+ beiscsi_conn->beiscsi_conn_cid,
+ &io_task->pwrb_context);
if (!io_task->pwrb_handle) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_IO |
}
io_task->pwrb_handle =
alloc_wrb_handle(phba,
- beiscsi_conn->beiscsi_conn_cid);
+ beiscsi_conn->beiscsi_conn_cid,
+ &io_task->pwrb_context);
if (!io_task->pwrb_handle) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
hwi_write_sgl_v2(pwrb, sg, num_sg, io_task);
AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb, pwrb,
- io_task->pwrb_handle->nxt_wrb_index);
+ io_task->pwrb_handle->wrb_index);
+ if (io_task->pwrb_context->plast_wrb)
+ AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb,
+ io_task->pwrb_context->plast_wrb,
+ io_task->pwrb_handle->wrb_index);
+ io_task->pwrb_context->plast_wrb = pwrb;
be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
hwi_write_sgl(pwrb, sg, num_sg, io_task);
AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb,
- io_task->pwrb_handle->nxt_wrb_index);
+ io_task->pwrb_handle->wrb_index);
+ if (io_task->pwrb_context->plast_wrb)
+ AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb,
+ io_task->pwrb_context->plast_wrb,
+ io_task->pwrb_handle->wrb_index);
+ io_task->pwrb_context->plast_wrb = pwrb;
+
be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb,
task->data_count);
AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb,
- io_task->pwrb_handle->nxt_wrb_index);
+ io_task->pwrb_handle->wrb_index);
+ if (io_task->pwrb_context->plast_wrb)
+ AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb,
+ io_task->pwrb_context->plast_wrb,
+ io_task->pwrb_handle->wrb_index);
+ io_task->pwrb_context->plast_wrb = pwrb;
+
pwrb_typeoffset = BE_WRB_TYPE_OFFSET;
} else {
AMAP_SET_BITS(struct amap_iscsi_wrb_v2, cmdsn_itt, pwrb,
AMAP_SET_BITS(struct amap_iscsi_wrb_v2, r2t_exp_dtl, pwrb,
task->data_count);
AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb, pwrb,
- io_task->pwrb_handle->nxt_wrb_index);
+ io_task->pwrb_handle->wrb_index);
+ if (io_task->pwrb_context->plast_wrb)
+ AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb,
+ io_task->pwrb_context->plast_wrb,
+ io_task->pwrb_handle->wrb_index);
+ io_task->pwrb_context->plast_wrb = pwrb;
+
pwrb_typeoffset = SKH_WRB_TYPE_OFFSET;
}
void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
struct wrb_handle *pwrb_handle,
- struct be_mem_descriptor *mem_descr)
+ struct be_mem_descriptor *mem_descr,
+ struct hwi_wrb_context *pwrb_context)
{
struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
max_burst_length) / 32]);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
- pwrb, pwrb_handle->nxt_wrb_index);
+ pwrb, pwrb_handle->wrb_index);
+ if (pwrb_context->plast_wrb)
+ AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
+ ptr2nextwrb,
+ pwrb_context->plast_wrb,
+ pwrb_handle->wrb_index);
+ pwrb_context->plast_wrb = pwrb;
+
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
session_state, pwrb, 0);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
}
void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
- struct wrb_handle *pwrb_handle)
+ struct wrb_handle *pwrb_handle,
+ struct hwi_wrb_context *pwrb_context)
{
struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
BE_TGT_CTX_UPDT_CMD);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
ptr2nextwrb,
- pwrb, pwrb_handle->nxt_wrb_index);
+ pwrb, pwrb_handle->wrb_index);
+ if (pwrb_context->plast_wrb)
+ AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
+ ptr2nextwrb,
+ pwrb_context->plast_wrb,
+ pwrb_handle->wrb_index);
+ pwrb_context->plast_wrb = pwrb;
+
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
pwrb, pwrb_handle->wrb_index);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,