diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2011-11-18 12:03:20 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-12-15 01:55:11 -0500 |
commit | 5780790ee6836ad64648c0905fcf15e073aad19b (patch) | |
tree | 4ad962c4006eaf84a264f485d0c1d6c6b7837551 | |
parent | a00f6296aaf92ebe89c72eb98c440410992a33c4 (diff) |
[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: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/qla2xxx/qla_bsg.c | 16 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 11 |
4 files changed, 27 insertions, 2 deletions
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index c0bc0c6f084d..b1d0f936bf2d 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c | |||
@@ -31,6 +31,7 @@ qla2x00_get_ctx_bsg_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size) | |||
31 | memset(sp, 0, sizeof(*sp)); | 31 | memset(sp, 0, sizeof(*sp)); |
32 | sp->fcport = fcport; | 32 | sp->fcport = fcport; |
33 | sp->ctx = ctx; | 33 | sp->ctx = ctx; |
34 | ctx->iocbs = 1; | ||
34 | done: | 35 | done: |
35 | return sp; | 36 | return sp; |
36 | } | 37 | } |
@@ -389,6 +390,20 @@ done: | |||
389 | return rval; | 390 | return rval; |
390 | } | 391 | } |
391 | 392 | ||
393 | inline uint16_t | ||
394 | qla24xx_calc_ct_iocbs(uint16_t dsds) | ||
395 | { | ||
396 | uint16_t iocbs; | ||
397 | |||
398 | iocbs = 1; | ||
399 | if (dsds > 2) { | ||
400 | iocbs += (dsds - 2) / 5; | ||
401 | if ((dsds - 2) % 5) | ||
402 | iocbs++; | ||
403 | } | ||
404 | return iocbs; | ||
405 | } | ||
406 | |||
392 | static int | 407 | static int |
393 | qla2x00_process_ct(struct fc_bsg_job *bsg_job) | 408 | qla2x00_process_ct(struct fc_bsg_job *bsg_job) |
394 | { | 409 | { |
@@ -489,6 +504,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) | |||
489 | ct = sp->ctx; | 504 | ct = sp->ctx; |
490 | ct->type = SRB_CT_CMD; | 505 | ct->type = SRB_CT_CMD; |
491 | ct->name = "bsg_ct"; | 506 | ct->name = "bsg_ct"; |
507 | ct->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt); | ||
492 | ct->u.bsg_job = bsg_job; | 508 | ct->u.bsg_job = bsg_job; |
493 | 509 | ||
494 | ql_dbg(ql_dbg_user, vha, 0x7016, | 510 | ql_dbg(ql_dbg_user, vha, 0x7016, |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index d046db1a2ded..a6a4eebce4a8 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -271,6 +271,7 @@ struct srb_iocb { | |||
271 | struct srb_ctx { | 271 | struct srb_ctx { |
272 | uint16_t type; | 272 | uint16_t type; |
273 | char *name; | 273 | char *name; |
274 | int iocbs; | ||
274 | union { | 275 | union { |
275 | struct srb_iocb *iocb_cmd; | 276 | struct srb_iocb *iocb_cmd; |
276 | struct fc_bsg_job *bsg_job; | 277 | struct fc_bsg_job *bsg_job; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 05931e6469aa..1fa067e053d2 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -111,6 +111,7 @@ qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size, | |||
111 | memset(sp, 0, sizeof(*sp)); | 111 | memset(sp, 0, sizeof(*sp)); |
112 | sp->fcport = fcport; | 112 | sp->fcport = fcport; |
113 | sp->ctx = ctx; | 113 | sp->ctx = ctx; |
114 | ctx->iocbs = 1; | ||
114 | ctx->u.iocb_cmd = iocb; | 115 | ctx->u.iocb_cmd = iocb; |
115 | iocb->free = qla2x00_ctx_sp_free; | 116 | iocb->free = qla2x00_ctx_sp_free; |
116 | 117 | ||
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 841ffb34d416..55a96761b5a4 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -1818,6 +1818,7 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) | |||
1818 | uint32_t index, handle; | 1818 | uint32_t index, handle; |
1819 | request_t *pkt; | 1819 | request_t *pkt; |
1820 | uint16_t cnt, req_cnt; | 1820 | uint16_t cnt, req_cnt; |
1821 | struct srb_ctx *ctx; | ||
1821 | 1822 | ||
1822 | pkt = NULL; | 1823 | pkt = NULL; |
1823 | req_cnt = 1; | 1824 | req_cnt = 1; |
@@ -1846,6 +1847,12 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) | |||
1846 | req->outstanding_cmds[handle] = sp; | 1847 | req->outstanding_cmds[handle] = sp; |
1847 | sp->handle = handle; | 1848 | sp->handle = handle; |
1848 | 1849 | ||
1850 | /* Adjust entry-counts as needed. */ | ||
1851 | if (sp->ctx) { | ||
1852 | ctx = sp->ctx; | ||
1853 | req_cnt = ctx->iocbs; | ||
1854 | } | ||
1855 | |||
1849 | skip_cmd_array: | 1856 | skip_cmd_array: |
1850 | /* Check for room on request queue. */ | 1857 | /* Check for room on request queue. */ |
1851 | if (req->cnt < req_cnt) { | 1858 | if (req->cnt < req_cnt) { |
@@ -2622,8 +2629,8 @@ qla2x00_start_sp(srb_t *sp) | |||
2622 | break; | 2629 | break; |
2623 | case SRB_CT_CMD: | 2630 | case SRB_CT_CMD: |
2624 | IS_FWI2_CAPABLE(ha) ? | 2631 | IS_FWI2_CAPABLE(ha) ? |
2625 | qla24xx_ct_iocb(sp, pkt) : | 2632 | qla24xx_ct_iocb(sp, pkt) : |
2626 | qla2x00_ct_iocb(sp, pkt); | 2633 | qla2x00_ct_iocb(sp, pkt); |
2627 | break; | 2634 | break; |
2628 | case SRB_ADISC_CMD: | 2635 | case SRB_ADISC_CMD: |
2629 | IS_FWI2_CAPABLE(ha) ? | 2636 | IS_FWI2_CAPABLE(ha) ? |