diff options
author | Giridhar Malavali <giridhar.malavali@qlogic.com> | 2012-02-09 14:15:36 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 09:14:08 -0500 |
commit | 9ba56b95a588906a65664a9299a9f8ac1a0f6a91 (patch) | |
tree | 93786c52320c2a7276c99cc4d9b3672ca6e0a50d /drivers/scsi/qla2xxx/qla_bsg.c | |
parent | 69e5f1ea61a3e84c03103c6a18ee9cacef4cbb9e (diff) |
[SCSI] qla2xxx: Consolidation of SRB processing.
Rework the structures related to SRB processing to minimize the memory
allocations per I/O and manage resources associated with and completions
from common routines.
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_bsg.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_bsg.c | 86 |
1 files changed, 44 insertions, 42 deletions
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 6887538d1736..b2b664483ab4 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c | |||
@@ -11,29 +11,36 @@ | |||
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | 12 | ||
13 | /* BSG support for ELS/CT pass through */ | 13 | /* BSG support for ELS/CT pass through */ |
14 | inline srb_t * | 14 | void |
15 | qla2x00_get_ctx_bsg_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size) | 15 | qla2x00_bsg_job_done(void *data, void *ptr, int res) |
16 | { | 16 | { |
17 | srb_t *sp; | 17 | srb_t *sp = (srb_t *)ptr; |
18 | struct scsi_qla_host *vha = (scsi_qla_host_t *)data; | ||
19 | struct fc_bsg_job *bsg_job = sp->u.bsg_job; | ||
20 | |||
21 | bsg_job->reply->result = res; | ||
22 | bsg_job->job_done(bsg_job); | ||
23 | sp->free(vha, sp); | ||
24 | } | ||
25 | |||
26 | void | ||
27 | qla2x00_bsg_sp_free(void *data, void *ptr) | ||
28 | { | ||
29 | srb_t *sp = (srb_t *)ptr; | ||
30 | struct scsi_qla_host *vha = (scsi_qla_host_t *)data; | ||
31 | struct fc_bsg_job *bsg_job = sp->u.bsg_job; | ||
18 | struct qla_hw_data *ha = vha->hw; | 32 | struct qla_hw_data *ha = vha->hw; |
19 | struct srb_ctx *ctx; | ||
20 | 33 | ||
21 | sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL); | 34 | dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, |
22 | if (!sp) | 35 | bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); |
23 | goto done; | ||
24 | ctx = kzalloc(size, GFP_KERNEL); | ||
25 | if (!ctx) { | ||
26 | mempool_free(sp, ha->srb_mempool); | ||
27 | sp = NULL; | ||
28 | goto done; | ||
29 | } | ||
30 | 36 | ||
31 | memset(sp, 0, sizeof(*sp)); | 37 | dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list, |
32 | sp->fcport = fcport; | 38 | bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); |
33 | sp->ctx = ctx; | 39 | |
34 | ctx->iocbs = 1; | 40 | if (sp->type == SRB_CT_CMD || |
35 | done: | 41 | sp->type == SRB_ELS_CMD_HST) |
36 | return sp; | 42 | kfree(sp->fcport); |
43 | mempool_free(sp, vha->hw->srb_mempool); | ||
37 | } | 44 | } |
38 | 45 | ||
39 | int | 46 | int |
@@ -217,6 +224,7 @@ exit_fcp_prio_cfg: | |||
217 | bsg_job->job_done(bsg_job); | 224 | bsg_job->job_done(bsg_job); |
218 | return ret; | 225 | return ret; |
219 | } | 226 | } |
227 | |||
220 | static int | 228 | static int |
221 | qla2x00_process_els(struct fc_bsg_job *bsg_job) | 229 | qla2x00_process_els(struct fc_bsg_job *bsg_job) |
222 | { | 230 | { |
@@ -230,7 +238,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) | |||
230 | int req_sg_cnt, rsp_sg_cnt; | 238 | int req_sg_cnt, rsp_sg_cnt; |
231 | int rval = (DRIVER_ERROR << 16); | 239 | int rval = (DRIVER_ERROR << 16); |
232 | uint16_t nextlid = 0; | 240 | uint16_t nextlid = 0; |
233 | struct srb_ctx *els; | ||
234 | 241 | ||
235 | if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) { | 242 | if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) { |
236 | rport = bsg_job->rport; | 243 | rport = bsg_job->rport; |
@@ -337,20 +344,21 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) | |||
337 | } | 344 | } |
338 | 345 | ||
339 | /* Alloc SRB structure */ | 346 | /* Alloc SRB structure */ |
340 | sp = qla2x00_get_ctx_bsg_sp(vha, fcport, sizeof(struct srb_ctx)); | 347 | sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); |
341 | if (!sp) { | 348 | if (!sp) { |
342 | rval = -ENOMEM; | 349 | rval = -ENOMEM; |
343 | goto done_unmap_sg; | 350 | goto done_unmap_sg; |
344 | } | 351 | } |
345 | 352 | ||
346 | els = sp->ctx; | 353 | sp->type = |
347 | els->type = | ||
348 | (bsg_job->request->msgcode == FC_BSG_RPT_ELS ? | 354 | (bsg_job->request->msgcode == FC_BSG_RPT_ELS ? |
349 | SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST); | 355 | SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST); |
350 | els->name = | 356 | sp->name = |
351 | (bsg_job->request->msgcode == FC_BSG_RPT_ELS ? | 357 | (bsg_job->request->msgcode == FC_BSG_RPT_ELS ? |
352 | "bsg_els_rpt" : "bsg_els_hst"); | 358 | "bsg_els_rpt" : "bsg_els_hst"); |
353 | els->u.bsg_job = bsg_job; | 359 | sp->u.bsg_job = bsg_job; |
360 | sp->free = qla2x00_bsg_sp_free; | ||
361 | sp->done = qla2x00_bsg_job_done; | ||
354 | 362 | ||
355 | ql_dbg(ql_dbg_user, vha, 0x700a, | 363 | ql_dbg(ql_dbg_user, vha, 0x700a, |
356 | "bsg rqst type: %s els type: %x - loop-id=%x " | 364 | "bsg rqst type: %s els type: %x - loop-id=%x " |
@@ -362,7 +370,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) | |||
362 | if (rval != QLA_SUCCESS) { | 370 | if (rval != QLA_SUCCESS) { |
363 | ql_log(ql_log_warn, vha, 0x700e, | 371 | ql_log(ql_log_warn, vha, 0x700e, |
364 | "qla2x00_start_sp failed = %d\n", rval); | 372 | "qla2x00_start_sp failed = %d\n", rval); |
365 | kfree(sp->ctx); | ||
366 | mempool_free(sp, ha->srb_mempool); | 373 | mempool_free(sp, ha->srb_mempool); |
367 | rval = -EIO; | 374 | rval = -EIO; |
368 | goto done_unmap_sg; | 375 | goto done_unmap_sg; |
@@ -409,7 +416,6 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) | |||
409 | uint16_t loop_id; | 416 | uint16_t loop_id; |
410 | struct fc_port *fcport; | 417 | struct fc_port *fcport; |
411 | char *type = "FC_BSG_HST_CT"; | 418 | char *type = "FC_BSG_HST_CT"; |
412 | struct srb_ctx *ct; | ||
413 | 419 | ||
414 | req_sg_cnt = | 420 | req_sg_cnt = |
415 | dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, | 421 | dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, |
@@ -486,19 +492,20 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) | |||
486 | fcport->loop_id = loop_id; | 492 | fcport->loop_id = loop_id; |
487 | 493 | ||
488 | /* Alloc SRB structure */ | 494 | /* Alloc SRB structure */ |
489 | sp = qla2x00_get_ctx_bsg_sp(vha, fcport, sizeof(struct srb_ctx)); | 495 | sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); |
490 | if (!sp) { | 496 | if (!sp) { |
491 | ql_log(ql_log_warn, vha, 0x7015, | 497 | ql_log(ql_log_warn, vha, 0x7015, |
492 | "qla2x00_get_ctx_bsg_sp failed.\n"); | 498 | "qla2x00_get_sp failed.\n"); |
493 | rval = -ENOMEM; | 499 | rval = -ENOMEM; |
494 | goto done_free_fcport; | 500 | goto done_free_fcport; |
495 | } | 501 | } |
496 | 502 | ||
497 | ct = sp->ctx; | 503 | sp->type = SRB_CT_CMD; |
498 | ct->type = SRB_CT_CMD; | 504 | sp->name = "bsg_ct"; |
499 | ct->name = "bsg_ct"; | 505 | sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt); |
500 | ct->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt); | 506 | sp->u.bsg_job = bsg_job; |
501 | ct->u.bsg_job = bsg_job; | 507 | sp->free = qla2x00_bsg_sp_free; |
508 | sp->done = qla2x00_bsg_job_done; | ||
502 | 509 | ||
503 | ql_dbg(ql_dbg_user, vha, 0x7016, | 510 | ql_dbg(ql_dbg_user, vha, 0x7016, |
504 | "bsg rqst type: %s else type: %x - " | 511 | "bsg rqst type: %s else type: %x - " |
@@ -511,7 +518,6 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) | |||
511 | if (rval != QLA_SUCCESS) { | 518 | if (rval != QLA_SUCCESS) { |
512 | ql_log(ql_log_warn, vha, 0x7017, | 519 | ql_log(ql_log_warn, vha, 0x7017, |
513 | "qla2x00_start_sp failed=%d.\n", rval); | 520 | "qla2x00_start_sp failed=%d.\n", rval); |
514 | kfree(sp->ctx); | ||
515 | mempool_free(sp, ha->srb_mempool); | 521 | mempool_free(sp, ha->srb_mempool); |
516 | rval = -EIO; | 522 | rval = -EIO; |
517 | goto done_free_fcport; | 523 | goto done_free_fcport; |
@@ -1669,7 +1675,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job) | |||
1669 | int cnt, que; | 1675 | int cnt, que; |
1670 | unsigned long flags; | 1676 | unsigned long flags; |
1671 | struct req_que *req; | 1677 | struct req_que *req; |
1672 | struct srb_ctx *sp_bsg; | ||
1673 | 1678 | ||
1674 | /* find the bsg job from the active list of commands */ | 1679 | /* find the bsg job from the active list of commands */ |
1675 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1680 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -1681,11 +1686,9 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job) | |||
1681 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | 1686 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { |
1682 | sp = req->outstanding_cmds[cnt]; | 1687 | sp = req->outstanding_cmds[cnt]; |
1683 | if (sp) { | 1688 | if (sp) { |
1684 | sp_bsg = sp->ctx; | 1689 | if (((sp->type == SRB_CT_CMD) || |
1685 | 1690 | (sp->type == SRB_ELS_CMD_HST)) | |
1686 | if (((sp_bsg->type == SRB_CT_CMD) || | 1691 | && (sp->u.bsg_job == bsg_job)) { |
1687 | (sp_bsg->type == SRB_ELS_CMD_HST)) | ||
1688 | && (sp_bsg->u.bsg_job == bsg_job)) { | ||
1689 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1692 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1690 | if (ha->isp_ops->abort_command(sp)) { | 1693 | if (ha->isp_ops->abort_command(sp)) { |
1691 | ql_log(ql_log_warn, vha, 0x7089, | 1694 | ql_log(ql_log_warn, vha, 0x7089, |
@@ -1715,7 +1718,6 @@ done: | |||
1715 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1718 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1716 | if (bsg_job->request->msgcode == FC_BSG_HST_CT) | 1719 | if (bsg_job->request->msgcode == FC_BSG_HST_CT) |
1717 | kfree(sp->fcport); | 1720 | kfree(sp->fcport); |
1718 | kfree(sp->ctx); | ||
1719 | mempool_free(sp, ha->srb_mempool); | 1721 | mempool_free(sp, ha->srb_mempool); |
1720 | return 0; | 1722 | return 0; |
1721 | } | 1723 | } |