Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73133261 authored by John Soni Jose's avatar John Soni Jose Committed by James Bottomley
Browse files

[SCSI] be2iscsi: Fix Task Completion Event handling



The completion events returned by adapter differs based on the
adapter. This fix checks for the adapter type and process the
completion event.

Signed-off-by: default avatarJohn Soni Jose <sony.john-n@emulex.com>
Signed-off-by: default avatarJayamohan Kallickal <jayamohan.kallickal@emulex.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent acb9693c
Loading
Loading
Loading
Loading
+53 −0
Original line number Original line Diff line number Diff line
@@ -826,6 +826,59 @@ struct amap_sol_cqe_ring {
	u8 valid;		/* dword 3 */
	u8 valid;		/* dword 3 */
} __packed;
} __packed;


struct amap_sol_cqe_v2 {
	u8 hw_sts[8];   /* dword 0 */
	u8 i_sts[8];    /* dword 0 */
	u8 wrb_index[16];   /* dword 0 */
	u8 i_exp_cmd_sn[32];    /* dword 1 */
	u8 code[6]; /* dword 2 */
	u8 cmd_cmpl;    /* dword 2 */
	u8 rsvd0;   /* dword 2 */
	u8 i_cmd_wnd[8];    /* dword 2 */
	u8 cid[13]; /* dword 2 */
	u8 u;   /* dword 2 */
	u8 o;   /* dword 2 */
	u8 s;   /* dword 2 */
	u8 i_res_cnt[31];   /* dword 3 */
	u8 valid;   /* dword 3 */
} __packed;

struct common_sol_cqe {
	u32 exp_cmdsn;
	u32 res_cnt;
	u16 wrb_index;
	u16 cid;
	u8 hw_sts;
	u8 cmd_wnd;
	u8 res_flag; /* the s feild of structure */
	u8 i_resp; /* for skh if cmd_complete is set then i_sts is response */
	u8 i_flags; /* for skh or the u and o feilds */
	u8 i_sts; /* for skh if cmd_complete is not-set then i_sts is status */
};

/*** iSCSI ack/driver message completions ***/
struct amap_it_dmsg_cqe {
	u8 ack_num[32]; /* DWORD 0 */
	u8 pdu_bytes_rcvd[32];  /* DWORD 1 */
	u8 code[6]; /* DWORD 2 */
	u8 cid[10]; /* DWORD 2 */
	u8 wrb_idx[8];  /* DWORD 2 */
	u8 rsvd0[8];    /* DWORD 2*/
	u8 rsvd1[31];   /* DWORD 3*/
	u8 valid;   /* DWORD 3 */
} __packed;

struct amap_it_dmsg_cqe_v2 {
	u8 ack_num[32]; /* DWORD 0 */
	u8 pdu_bytes_rcvd[32];  /* DWORD 1 */
	u8 code[6]; /* DWORD 2 */
	u8 rsvd0[10];   /* DWORD 2 */
	u8 wrb_idx[16]; /* DWORD 2 */
	u8 rsvd1[16];   /* DWORD 3 */
	u8 cid[13]; /* DWORD 3 */
	u8 rsvd2[2];    /* DWORD 3 */
	u8 valid;   /* DWORD 3 */
} __packed;




/**
/**
+163 −104
Original line number Original line Diff line number Diff line
@@ -1248,7 +1248,8 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)


static void
static void
be_complete_io(struct beiscsi_conn *beiscsi_conn,
be_complete_io(struct beiscsi_conn *beiscsi_conn,
	       struct iscsi_task *task, struct sol_cqe *psol)
		struct iscsi_task *task,
		struct common_sol_cqe *csol_cqe)
{
{
	struct beiscsi_io_task *io_task = task->dd_data;
	struct beiscsi_io_task *io_task = task->dd_data;
	struct be_status_bhs *sts_bhs =
	struct be_status_bhs *sts_bhs =
@@ -1258,20 +1259,14 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
	u32 resid = 0, exp_cmdsn, max_cmdsn;
	u32 resid = 0, exp_cmdsn, max_cmdsn;
	u8 rsp, status, flags;
	u8 rsp, status, flags;


	exp_cmdsn = (psol->
	exp_cmdsn = csol_cqe->exp_cmdsn;
			dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
	max_cmdsn = (csol_cqe->exp_cmdsn +
			& SOL_EXP_CMD_SN_MASK);
		     csol_cqe->cmd_wnd - 1);
	max_cmdsn = ((psol->
	rsp = csol_cqe->i_resp;
			dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
	status = csol_cqe->i_sts;
			& SOL_EXP_CMD_SN_MASK) +
	flags = csol_cqe->i_flags;
			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
	resid = csol_cqe->res_cnt;
				/ 32] & SOL_CMD_WND_MASK) >> 24) - 1);

	rsp = ((psol->dw[offsetof(struct amap_sol_cqe, i_resp) / 32]
						& SOL_RESP_MASK) >> 16);
	status = ((psol->dw[offsetof(struct amap_sol_cqe, i_sts) / 32]
						& SOL_STS_MASK) >> 8);
	flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
					& SOL_FLAGS_MASK) >> 24) | 0x80;
	if (!task->sc) {
	if (!task->sc) {
		if (io_task->scsi_cmnd)
		if (io_task->scsi_cmnd)
			scsi_dma_unmap(io_task->scsi_cmnd);
			scsi_dma_unmap(io_task->scsi_cmnd);
@@ -1286,9 +1281,6 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,


	/* bidi not initially supported */
	/* bidi not initially supported */
	if (flags & (ISCSI_FLAG_CMD_UNDERFLOW | ISCSI_FLAG_CMD_OVERFLOW)) {
	if (flags & (ISCSI_FLAG_CMD_UNDERFLOW | ISCSI_FLAG_CMD_OVERFLOW)) {
		resid = (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) /
				32] & SOL_RES_CNT_MASK);

		if (!status && (flags & ISCSI_FLAG_CMD_OVERFLOW))
		if (!status && (flags & ISCSI_FLAG_CMD_OVERFLOW))
			task->sc->result = DID_ERROR << 16;
			task->sc->result = DID_ERROR << 16;


@@ -1310,13 +1302,8 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
		       min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
		       min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
	}
	}


	if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) {
	if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ)
		if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
		conn->rxdata_octets += resid;
							& SOL_RES_CNT_MASK)
			 conn->rxdata_octets += (psol->
			     dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
			     & SOL_RES_CNT_MASK);
	}
unmap:
unmap:
	scsi_dma_unmap(io_task->scsi_cmnd);
	scsi_dma_unmap(io_task->scsi_cmnd);
	iscsi_complete_scsi_task(task, exp_cmdsn, max_cmdsn);
	iscsi_complete_scsi_task(task, exp_cmdsn, max_cmdsn);
@@ -1324,7 +1311,8 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,


static void
static void
be_complete_logout(struct beiscsi_conn *beiscsi_conn,
be_complete_logout(struct beiscsi_conn *beiscsi_conn,
		   struct iscsi_task *task, struct sol_cqe *psol)
		    struct iscsi_task *task,
		    struct common_sol_cqe *csol_cqe)
{
{
	struct iscsi_logout_rsp *hdr;
	struct iscsi_logout_rsp *hdr;
	struct beiscsi_io_task *io_task = task->dd_data;
	struct beiscsi_io_task *io_task = task->dd_data;
@@ -1334,18 +1322,11 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn,
	hdr->opcode = ISCSI_OP_LOGOUT_RSP;
	hdr->opcode = ISCSI_OP_LOGOUT_RSP;
	hdr->t2wait = 5;
	hdr->t2wait = 5;
	hdr->t2retain = 0;
	hdr->t2retain = 0;
	hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
	hdr->flags = csol_cqe->i_flags;
					& SOL_FLAGS_MASK) >> 24) | 0x80;
	hdr->response = csol_cqe->i_resp;
	hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) /
	hdr->exp_cmdsn = csol_cqe->exp_cmdsn;
					32] & SOL_RESP_MASK);
	hdr->max_cmdsn = (csol_cqe->exp_cmdsn + csol_cqe->cmd_wnd - 1);
	hdr->exp_cmdsn = cpu_to_be32(psol->

			dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
					& SOL_EXP_CMD_SN_MASK);
	hdr->max_cmdsn = be32_to_cpu((psol->
			 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
					& SOL_EXP_CMD_SN_MASK) +
			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
					/ 32] & SOL_CMD_WND_MASK) >> 24) - 1);
	hdr->dlength[0] = 0;
	hdr->dlength[0] = 0;
	hdr->dlength[1] = 0;
	hdr->dlength[1] = 0;
	hdr->dlength[2] = 0;
	hdr->dlength[2] = 0;
@@ -1356,7 +1337,8 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn,


static void
static void
be_complete_tmf(struct beiscsi_conn *beiscsi_conn,
be_complete_tmf(struct beiscsi_conn *beiscsi_conn,
		struct iscsi_task *task, struct sol_cqe *psol)
		 struct iscsi_task *task,
		 struct common_sol_cqe *csol_cqe)
{
{
	struct iscsi_tm_rsp *hdr;
	struct iscsi_tm_rsp *hdr;
	struct iscsi_conn *conn = beiscsi_conn->conn;
	struct iscsi_conn *conn = beiscsi_conn->conn;
@@ -1364,16 +1346,12 @@ be_complete_tmf(struct beiscsi_conn *beiscsi_conn,


	hdr = (struct iscsi_tm_rsp *)task->hdr;
	hdr = (struct iscsi_tm_rsp *)task->hdr;
	hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP;
	hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP;
	hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
	hdr->flags = csol_cqe->i_flags;
					& SOL_FLAGS_MASK) >> 24) | 0x80;
	hdr->response = csol_cqe->i_resp;
	hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) /
	hdr->exp_cmdsn = csol_cqe->exp_cmdsn;
					32] & SOL_RESP_MASK);
	hdr->max_cmdsn = (csol_cqe->exp_cmdsn +
	hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe,
			  csol_cqe->cmd_wnd - 1);
				    i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK);

	hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe,
			i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) +
			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
			/ 32] & SOL_CMD_WND_MASK) >> 24) - 1);
	hdr->itt = io_task->libiscsi_itt;
	hdr->itt = io_task->libiscsi_itt;
	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
}
}
@@ -1389,15 +1367,24 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
	struct beiscsi_io_task *io_task;
	struct beiscsi_io_task *io_task;
	struct iscsi_conn *conn = beiscsi_conn->conn;
	struct iscsi_conn *conn = beiscsi_conn->conn;
	struct iscsi_session *session = conn->session;
	struct iscsi_session *session = conn->session;
	uint16_t wrb_index, cid;


	phwi_ctrlr = phba->phwi_ctrlr;
	phwi_ctrlr = phba->phwi_ctrlr;
	pwrb_context = &phwi_ctrlr->wrb_context[((psol->
	if (chip_skh_r(phba->pcidev)) {
				dw[offsetof(struct amap_sol_cqe, cid) / 32] &
		wrb_index = AMAP_GET_BITS(struct amap_it_dmsg_cqe_v2,
				SOL_CID_MASK) >> 6) -
					  wrb_idx, psol);
				phba->fw_config.iscsi_cid_start];
		cid = AMAP_GET_BITS(struct amap_it_dmsg_cqe_v2,
	pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
				    cid, psol);
				dw[offsetof(struct amap_sol_cqe, wrb_index) /
	} else {
				32] & SOL_WRB_INDEX_MASK) >> 16)];
		wrb_index = AMAP_GET_BITS(struct amap_it_dmsg_cqe,
					  wrb_idx, psol);
		cid = AMAP_GET_BITS(struct amap_it_dmsg_cqe,
				    cid, psol);
	}

	pwrb_context = &phwi_ctrlr->wrb_context[
			cid - phba->fw_config.iscsi_cid_start];
	pwrb_handle = pwrb_context->pwrb_handle_basestd[wrb_index];
	task = pwrb_handle->pio_handle;
	task = pwrb_handle->pio_handle;


	io_task = task->dd_data;
	io_task = task->dd_data;
@@ -1411,26 +1398,78 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,


static void
static void
be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn,
be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn,
		       struct iscsi_task *task, struct sol_cqe *psol)
			struct iscsi_task *task,
			struct common_sol_cqe *csol_cqe)
{
{
	struct iscsi_nopin *hdr;
	struct iscsi_nopin *hdr;
	struct iscsi_conn *conn = beiscsi_conn->conn;
	struct iscsi_conn *conn = beiscsi_conn->conn;
	struct beiscsi_io_task *io_task = task->dd_data;
	struct beiscsi_io_task *io_task = task->dd_data;


	hdr = (struct iscsi_nopin *)task->hdr;
	hdr = (struct iscsi_nopin *)task->hdr;
	hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
	hdr->flags = csol_cqe->i_flags;
			& SOL_FLAGS_MASK) >> 24) | 0x80;
	hdr->exp_cmdsn = cpu_to_be32(csol_cqe->exp_cmdsn);
	hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe,
	hdr->max_cmdsn = be32_to_cpu(hdr->exp_cmdsn +
				     i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK);
			 csol_cqe->cmd_wnd - 1);
	hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe,

			i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) +
			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
			/ 32] & SOL_CMD_WND_MASK) >> 24) - 1);
	hdr->opcode = ISCSI_OP_NOOP_IN;
	hdr->opcode = ISCSI_OP_NOOP_IN;
	hdr->itt = io_task->libiscsi_itt;
	hdr->itt = io_task->libiscsi_itt;
	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
}
}


static void adapter_get_sol_cqe(struct beiscsi_hba *phba,
		struct sol_cqe *psol,
		struct common_sol_cqe *csol_cqe)
{
	if (chip_skh_r(phba->pcidev)) {
		csol_cqe->exp_cmdsn = AMAP_GET_BITS(struct amap_sol_cqe_v2,
						    i_exp_cmd_sn, psol);
		csol_cqe->res_cnt = AMAP_GET_BITS(struct amap_sol_cqe_v2,
						  i_res_cnt, psol);
		csol_cqe->wrb_index = AMAP_GET_BITS(struct amap_sol_cqe_v2,
						    wrb_index, psol);
		csol_cqe->cid = AMAP_GET_BITS(struct amap_sol_cqe_v2,
					      cid, psol);
		csol_cqe->hw_sts = AMAP_GET_BITS(struct amap_sol_cqe_v2,
						 hw_sts, psol);
		csol_cqe->cmd_wnd = AMAP_GET_BITS(struct amap_sol_cqe,
						  i_cmd_wnd, psol);
		if (AMAP_GET_BITS(struct amap_sol_cqe_v2,
				  cmd_cmpl, psol))
			csol_cqe->i_sts = AMAP_GET_BITS(struct amap_sol_cqe_v2,
							i_sts, psol);
		else
			csol_cqe->i_resp = AMAP_GET_BITS(struct amap_sol_cqe_v2,
							 i_sts, psol);
		if (AMAP_GET_BITS(struct amap_sol_cqe_v2,
				  u, psol))
			csol_cqe->i_flags = ISCSI_FLAG_CMD_UNDERFLOW;

		if (AMAP_GET_BITS(struct amap_sol_cqe_v2,
				  o, psol))
			csol_cqe->i_flags |= ISCSI_FLAG_CMD_OVERFLOW;
	} else {
		csol_cqe->exp_cmdsn = AMAP_GET_BITS(struct amap_sol_cqe,
						    i_exp_cmd_sn, psol);
		csol_cqe->res_cnt = AMAP_GET_BITS(struct amap_sol_cqe,
						  i_res_cnt, psol);
		csol_cqe->cmd_wnd = AMAP_GET_BITS(struct amap_sol_cqe,
						  i_cmd_wnd, psol);
		csol_cqe->wrb_index = AMAP_GET_BITS(struct amap_sol_cqe,
						    wrb_index, psol);
		csol_cqe->cid = AMAP_GET_BITS(struct amap_sol_cqe,
					      cid, psol);
		csol_cqe->hw_sts = AMAP_GET_BITS(struct amap_sol_cqe,
						 hw_sts, psol);
		csol_cqe->i_resp = AMAP_GET_BITS(struct amap_sol_cqe,
						 i_resp, psol);
		csol_cqe->i_sts = AMAP_GET_BITS(struct amap_sol_cqe,
						i_sts, psol);
		csol_cqe->i_flags = AMAP_GET_BITS(struct amap_sol_cqe,
						  i_flags, psol);
	}
}


static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
			     struct beiscsi_hba *phba, struct sol_cqe *psol)
			     struct beiscsi_hba *phba, struct sol_cqe *psol)
{
{
@@ -1442,19 +1481,22 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
	unsigned int type;
	unsigned int type;
	struct iscsi_conn *conn = beiscsi_conn->conn;
	struct iscsi_conn *conn = beiscsi_conn->conn;
	struct iscsi_session *session = conn->session;
	struct iscsi_session *session = conn->session;
	struct common_sol_cqe csol_cqe = {0};


	phwi_ctrlr = phba->phwi_ctrlr;
	phwi_ctrlr = phba->phwi_ctrlr;
	pwrb_context = &phwi_ctrlr->wrb_context[((psol->dw[offsetof

				(struct amap_sol_cqe, cid) / 32]
	/* Copy the elements to a common structure */
				& SOL_CID_MASK) >> 6) -
	adapter_get_sol_cqe(phba, psol, &csol_cqe);
				phba->fw_config.iscsi_cid_start];

	pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
	pwrb_context = &phwi_ctrlr->wrb_context[
				dw[offsetof(struct amap_sol_cqe, wrb_index) /
			csol_cqe.cid - phba->fw_config.iscsi_cid_start];
				32] & SOL_WRB_INDEX_MASK) >> 16)];

	pwrb_handle = pwrb_context->pwrb_handle_basestd[
		      csol_cqe.wrb_index];

	task = pwrb_handle->pio_handle;
	task = pwrb_handle->pio_handle;
	pwrb = pwrb_handle->pwrb;
	pwrb = pwrb_handle->pwrb;
	type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] &
	type = ((struct beiscsi_io_task *)task->dd_data)->wrb_type;
				 WRB_TYPE_MASK) >> 28;


	spin_lock_bh(&session->lock);
	spin_lock_bh(&session->lock);
	switch (type) {
	switch (type) {
@@ -1462,17 +1504,16 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
	case HWH_TYPE_IO_RD:
	case HWH_TYPE_IO_RD:
		if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
		if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
		     ISCSI_OP_NOOP_OUT)
		     ISCSI_OP_NOOP_OUT)
			be_complete_nopin_resp(beiscsi_conn, task, psol);
			be_complete_nopin_resp(beiscsi_conn, task, &csol_cqe);
		else
		else
			be_complete_io(beiscsi_conn, task, psol);
			be_complete_io(beiscsi_conn, task, &csol_cqe);
		break;
		break;


	case HWH_TYPE_LOGOUT:
	case HWH_TYPE_LOGOUT:
		if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
		if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
			be_complete_logout(beiscsi_conn, task, psol);
			be_complete_logout(beiscsi_conn, task, &csol_cqe);
		else
		else
			be_complete_tmf(beiscsi_conn, task, psol);
			be_complete_tmf(beiscsi_conn, task, &csol_cqe);

		break;
		break;


	case HWH_TYPE_LOGIN:
	case HWH_TYPE_LOGIN:
@@ -1483,7 +1524,7 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
		break;
		break;


	case HWH_TYPE_NOP:
	case HWH_TYPE_NOP:
		be_complete_nopin_resp(beiscsi_conn, task, psol);
		be_complete_nopin_resp(beiscsi_conn, task, &csol_cqe);
		break;
		break;


	default:
	default:
@@ -1491,10 +1532,8 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
			    "BM_%d : In hwi_complete_cmd, unknown type = %d"
			    "BM_%d : In hwi_complete_cmd, unknown type = %d"
			    "wrb_index 0x%x CID 0x%x\n", type,
			    "wrb_index 0x%x CID 0x%x\n", type,
			    ((psol->dw[offsetof(struct amap_iscsi_wrb,
			    csol_cqe.wrb_index,
			    type) / 32] & SOL_WRB_INDEX_MASK) >> 16),
			    csol_cqe.cid);
			    ((psol->dw[offsetof(struct amap_sol_cqe,
			    cid) / 32] & SOL_CID_MASK) >> 6));
		break;
		break;
	}
	}


@@ -1522,13 +1561,26 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
	struct list_head *pbusy_list;
	struct list_head *pbusy_list;
	struct async_pdu_handle *pasync_handle = NULL;
	struct async_pdu_handle *pasync_handle = NULL;
	unsigned char is_header = 0;
	unsigned char is_header = 0;
	unsigned int index, dpl;

	if (chip_skh_r(phba->pcidev)) {
		dpl = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe_v2,
				    dpl, pdpdu_cqe);
		index = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe_v2,
				      index, pdpdu_cqe);
	} else {
		dpl = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe,
				    dpl, pdpdu_cqe);
		index = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe,
				      index, pdpdu_cqe);
	}


	phys_addr.u.a32.address_lo =
	phys_addr.u.a32.address_lo =
	    pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, db_addr_lo) / 32] -
		(pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
	    ((pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32]
					db_addr_lo) / 32] - dpl);
						& PDUCQE_DPL_MASK) >> 16);
	phys_addr.u.a32.address_hi =
	phys_addr.u.a32.address_hi =
	    pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, db_addr_hi) / 32];
		pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
				       db_addr_hi) / 32];


	phys_addr.u.a64.address =
	phys_addr.u.a64.address =
			*((unsigned long long *)(&phys_addr.u.a64.address));
			*((unsigned long long *)(&phys_addr.u.a64.address));
@@ -1538,14 +1590,12 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
	case UNSOL_HDR_NOTIFY:
	case UNSOL_HDR_NOTIFY:
		is_header = 1;
		is_header = 1;


		pbusy_list = hwi_get_async_busy_list(pasync_ctx, 1,
		 pbusy_list = hwi_get_async_busy_list(pasync_ctx,
			(pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
						      is_header, index);
			index) / 32] & PDUCQE_INDEX_MASK));
		break;
		break;
	case UNSOL_DATA_NOTIFY:
	case UNSOL_DATA_NOTIFY:
		pbusy_list = hwi_get_async_busy_list(pasync_ctx, 0, (pdpdu_cqe->
		 pbusy_list = hwi_get_async_busy_list(pasync_ctx,
					dw[offsetof(struct amap_i_t_dpdu_cqe,
						      is_header, index);
					index) / 32] & PDUCQE_INDEX_MASK));
		break;
		break;
	default:
	default:
		pbusy_list = NULL;
		pbusy_list = NULL;
@@ -1568,12 +1618,9 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
	pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid -
	pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid -
					     phba->fw_config.iscsi_cid_start;
					     phba->fw_config.iscsi_cid_start;
	pasync_handle->is_header = is_header;
	pasync_handle->is_header = is_header;
	pasync_handle->buffer_len = ((pdpdu_cqe->
	pasync_handle->buffer_len = dpl;
			dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32]
	*pcq_index = index;
			& PDUCQE_DPL_MASK) >> 16);


	*pcq_index = (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
			index) / 32] & PDUCQE_INDEX_MASK);
	return pasync_handle;
	return pasync_handle;
}
}


@@ -1979,12 +2026,24 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
	       CQE_VALID_MASK) {
	       CQE_VALID_MASK) {
		be_dws_le_to_cpu(sol, sizeof(struct sol_cqe));
		be_dws_le_to_cpu(sol, sizeof(struct sol_cqe));


		cid = ((sol->dw[offsetof(struct amap_sol_cqe, cid)/32] &
		 code = (sol->dw[offsetof(struct amap_sol_cqe, code) /
		      CQE_CID_MASK) >> 6);
			 32] & CQE_CODE_MASK);
		code = (sol->dw[offsetof(struct amap_sol_cqe, code)/32] &
		       CQE_CODE_MASK);
		ep = phba->ep_array[cid - phba->fw_config.iscsi_cid_start];


		 /* Get the CID */
		if (chip_skh_r(phba->pcidev)) {
			if ((code == DRIVERMSG_NOTIFY) ||
			    (code == UNSOL_HDR_NOTIFY) ||
			    (code == UNSOL_DATA_NOTIFY))
				cid = AMAP_GET_BITS(
						    struct amap_i_t_dpdu_cqe_v2,
						    cid, sol);
			 else
				 cid = AMAP_GET_BITS(struct amap_sol_cqe_v2,
						     cid, sol);
		   } else
			 cid = AMAP_GET_BITS(struct amap_sol_cqe, cid, sol);

		ep = phba->ep_array[cid - phba->fw_config.iscsi_cid_start];
		beiscsi_ep = ep->dd_data;
		beiscsi_ep = ep->dd_data;
		beiscsi_conn = beiscsi_ep->conn;
		beiscsi_conn = beiscsi_ep->conn;


+14 −0
Original line number Original line Diff line number Diff line
@@ -587,6 +587,20 @@ struct amap_i_t_dpdu_cqe {
	u8 valid;
	u8 valid;
} __packed;
} __packed;


struct amap_i_t_dpdu_cqe_v2 {
	u8 db_addr_hi[32];  /* DWORD 0 */
	u8 db_addr_lo[32];  /* DWORD 1 */
	u8 code[6]; /* DWORD 2 */
	u8 num_cons; /* DWORD 2*/
	u8 rsvd0[8]; /* DWORD 2 */
	u8 dpl[17]; /* DWORD 2 */
	u8 index[16]; /* DWORD 3 */
	u8 cid[13]; /* DWORD 3 */
	u8 rsvd1; /* DWORD 3 */
	u8 final; /* DWORD 3 */
	u8 valid; /* DWORD 3 */
} __packed;

#define CQE_VALID_MASK	0x80000000
#define CQE_VALID_MASK	0x80000000
#define CQE_CODE_MASK	0x0000003F
#define CQE_CODE_MASK	0x0000003F
#define CQE_CID_MASK	0x0000FFC0
#define CQE_CID_MASK	0x0000FFC0