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

Commit 5780790e authored by Andrew Vasquez's avatar Andrew Vasquez Committed by James Bottomley
Browse files

[SCSI] qla2xxx: Ensure there's enough request-queue space for passthru IOCBs.



The driver should ensure there's a sufficient number of IOCBs
to satisfy the number of scatter-gather entries specified in the
command.  Add a 'count' to the control structure, srb_ctx, to use
in qla2x00_alloc_iocbs().

Signed-off-by: default avatarAndrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: default avatarChad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent a00f6296
Loading
Loading
Loading
Loading
+16 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ qla2x00_get_ctx_bsg_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size)
	memset(sp, 0, sizeof(*sp));
	memset(sp, 0, sizeof(*sp));
	sp->fcport = fcport;
	sp->fcport = fcport;
	sp->ctx = ctx;
	sp->ctx = ctx;
	ctx->iocbs = 1;
done:
done:
	return sp;
	return sp;
}
}
@@ -389,6 +390,20 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
	return rval;
	return rval;
}
}


inline uint16_t
qla24xx_calc_ct_iocbs(uint16_t dsds)
{
	uint16_t iocbs;

	iocbs = 1;
	if (dsds > 2) {
		iocbs += (dsds - 2) / 5;
		if ((dsds - 2) % 5)
			iocbs++;
	}
	return iocbs;
}

static int
static int
qla2x00_process_ct(struct fc_bsg_job *bsg_job)
qla2x00_process_ct(struct fc_bsg_job *bsg_job)
{
{
@@ -489,6 +504,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
	ct = sp->ctx;
	ct = sp->ctx;
	ct->type = SRB_CT_CMD;
	ct->type = SRB_CT_CMD;
	ct->name = "bsg_ct";
	ct->name = "bsg_ct";
	ct->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
	ct->u.bsg_job = bsg_job;
	ct->u.bsg_job = bsg_job;


	ql_dbg(ql_dbg_user, vha, 0x7016,
	ql_dbg(ql_dbg_user, vha, 0x7016,
+1 −0
Original line number Original line Diff line number Diff line
@@ -271,6 +271,7 @@ struct srb_iocb {
struct srb_ctx {
struct srb_ctx {
	uint16_t type;
	uint16_t type;
	char *name;
	char *name;
	int iocbs;
	union {
	union {
		struct srb_iocb *iocb_cmd;
		struct srb_iocb *iocb_cmd;
		struct fc_bsg_job *bsg_job;
		struct fc_bsg_job *bsg_job;
+1 −0
Original line number Original line Diff line number Diff line
@@ -111,6 +111,7 @@ qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size,
	memset(sp, 0, sizeof(*sp));
	memset(sp, 0, sizeof(*sp));
	sp->fcport = fcport;
	sp->fcport = fcport;
	sp->ctx = ctx;
	sp->ctx = ctx;
	ctx->iocbs = 1;
	ctx->u.iocb_cmd = iocb;
	ctx->u.iocb_cmd = iocb;
	iocb->free = qla2x00_ctx_sp_free;
	iocb->free = qla2x00_ctx_sp_free;


+9 −2
Original line number Original line Diff line number Diff line
@@ -1818,6 +1818,7 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)
	uint32_t index, handle;
	uint32_t index, handle;
	request_t *pkt;
	request_t *pkt;
	uint16_t cnt, req_cnt;
	uint16_t cnt, req_cnt;
	struct srb_ctx *ctx;


	pkt = NULL;
	pkt = NULL;
	req_cnt = 1;
	req_cnt = 1;
@@ -1846,6 +1847,12 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)
	req->outstanding_cmds[handle] = sp;
	req->outstanding_cmds[handle] = sp;
	sp->handle = handle;
	sp->handle = handle;


	/* Adjust entry-counts as needed. */
	if (sp->ctx) {
		ctx = sp->ctx;
		req_cnt = ctx->iocbs;
	}

skip_cmd_array:
skip_cmd_array:
	/* Check for room on request queue. */
	/* Check for room on request queue. */
	if (req->cnt < req_cnt) {
	if (req->cnt < req_cnt) {