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

[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
...@@ -31,6 +31,7 @@ qla2x00_get_ctx_bsg_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size) ...@@ -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) ...@@ -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) ...@@ -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,
......
...@@ -271,6 +271,7 @@ struct srb_iocb { ...@@ -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;
......
...@@ -111,6 +111,7 @@ qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size, ...@@ -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;
......
...@@ -1818,6 +1818,7 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) ...@@ -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) ...@@ -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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment