summaryrefslogtreecommitdiff
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
authorGiridhar Malavali <giridhar.malavali@qlogic.com>2012-02-09 11:15:36 -0800
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 08:14:08 -0600
commit9ba56b95a588906a65664a9299a9f8ac1a0f6a91 (patch)
tree93786c52320c2a7276c99cc4d9b3672ca6e0a50d /drivers/scsi/qla2xxx/qla_os.c
parent69e5f1ea61a3e84c03103c6a18ee9cacef4cbb9e (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_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c206
1 files changed, 83 insertions, 123 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 79c752eef991..a8de6a3de499 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -304,7 +304,6 @@ static int qla2x00_mem_alloc(struct qla_hw_data *, uint16_t, uint16_t,
struct req_que **, struct rsp_que **);
static void qla2x00_free_fw_dump(struct qla_hw_data *);
static void qla2x00_mem_free(struct qla_hw_data *);
-static void qla2x00_sp_free_dma(srb_t *);
/* -------------------------------------------------------------------------- */
static int qla2x00_alloc_queues(struct qla_hw_data *ha)
@@ -559,28 +558,75 @@ qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str)
return str;
}
-static inline srb_t *
-qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
- struct scsi_cmnd *cmd)
+void
+qla2x00_sp_free_dma(void *vha, void *ptr)
{
- srb_t *sp;
- struct qla_hw_data *ha = vha->hw;
+ srb_t *sp = (srb_t *)ptr;
+ struct scsi_cmnd *cmd = GET_CMD_SP(sp);
+ struct qla_hw_data *ha = sp->fcport->vha->hw;
+ void *ctx = GET_CMD_CTX_SP(sp);
- sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC);
- if (!sp) {
- ql_log(ql_log_warn, vha, 0x3006,
- "Memory allocation failed for sp.\n");
- return sp;
+ if (sp->flags & SRB_DMA_VALID) {
+ scsi_dma_unmap(cmd);
+ sp->flags &= ~SRB_DMA_VALID;
}
- atomic_set(&sp->ref_count, 1);
- sp->fcport = fcport;
- sp->cmd = cmd;
- sp->flags = 0;
- CMD_SP(cmd) = (void *)sp;
- sp->ctx = NULL;
+ if (sp->flags & SRB_CRC_PROT_DMA_VALID) {
+ dma_unmap_sg(&ha->pdev->dev, scsi_prot_sglist(cmd),
+ scsi_prot_sg_count(cmd), cmd->sc_data_direction);
+ sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
+ }
+
+ if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
+ /* List assured to be having elements */
+ qla2x00_clean_dsd_pool(ha, sp);
+ sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
+ }
+
+ if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
+ dma_pool_free(ha->dl_dma_pool, ctx,
+ ((struct crc_context *)ctx)->crc_ctx_dma);
+ sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
+ }
+
+ if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
+ struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
+
+ dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
+ ctx1->fcp_cmnd_dma);
+ list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);
+ ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;
+ ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
+ mempool_free(ctx1, ha->ctx_mempool);
+ ctx1 = NULL;
+ }
+
+ CMD_SP(cmd) = NULL;
+ mempool_free(sp, ha->srb_mempool);
+}
+
+static void
+qla2x00_sp_compl(void *data, void *ptr, int res)
+{
+ struct qla_hw_data *ha = (struct qla_hw_data *)data;
+ srb_t *sp = (srb_t *)ptr;
+ struct scsi_cmnd *cmd = GET_CMD_SP(sp);
+
+ cmd->result = res;
+
+ if (atomic_read(&sp->ref_count) == 0) {
+ ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3015,
+ "SP reference-count to ZERO -- sp=%p cmd=%p.\n",
+ sp, GET_CMD_SP(sp));
+ if (ql2xextended_error_logging & ql_dbg_io)
+ BUG();
+ return;
+ }
+ if (!atomic_dec_and_test(&sp->ref_count))
+ return;
- return sp;
+ qla2x00_sp_free_dma(ha, sp);
+ cmd->scsi_done(cmd);
}
static int
@@ -644,10 +690,17 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
goto qc24_target_busy;
}
- sp = qla2x00_get_new_sp(base_vha, fcport, cmd);
+ sp = qla2x00_get_sp(base_vha, fcport, GFP_ATOMIC);
if (!sp)
goto qc24_host_busy;
+ sp->u.scmd.cmd = cmd;
+ sp->type = SRB_SCSI_CMD;
+ atomic_set(&sp->ref_count, 1);
+ CMD_SP(cmd) = (void *)sp;
+ sp->free = qla2x00_sp_free_dma;
+ sp->done = qla2x00_sp_compl;
+
rval = ha->isp_ops->start_scsi(sp);
if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_io, vha, 0x3013,
@@ -658,8 +711,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
return 0;
qc24_host_busy_free_sp:
- qla2x00_sp_free_dma(sp);
- mempool_free(sp, ha->srb_mempool);
+ qla2x00_sp_free_dma(ha, sp);
qc24_host_busy:
return SCSI_MLQUEUE_HOST_BUSY;
@@ -893,7 +945,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
}
spin_lock_irqsave(&ha->hardware_lock, flags);
- qla2x00_sp_compl(ha, sp);
+ sp->done(ha, sp, 0);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
/* Did the command return during mailbox execution? */
@@ -925,6 +977,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
struct qla_hw_data *ha = vha->hw;
struct req_que *req;
srb_t *sp;
+ struct scsi_cmnd *cmd;
status = QLA_SUCCESS;
@@ -935,28 +988,29 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
sp = req->outstanding_cmds[cnt];
if (!sp)
continue;
- if ((sp->ctx) && !IS_PROT_IO(sp))
+ if (sp->type != SRB_SCSI_CMD)
continue;
if (vha->vp_idx != sp->fcport->vha->vp_idx)
continue;
match = 0;
+ cmd = GET_CMD_SP(sp);
switch (type) {
case WAIT_HOST:
match = 1;
break;
case WAIT_TARGET:
- match = sp->cmd->device->id == t;
+ match = cmd->device->id == t;
break;
case WAIT_LUN:
- match = (sp->cmd->device->id == t &&
- sp->cmd->device->lun == l);
+ match = (cmd->device->id == t &&
+ cmd->device->lun == l);
break;
}
if (!match)
continue;
spin_unlock_irqrestore(&ha->hardware_lock, flags);
- status = qla2x00_eh_wait_on_command(sp->cmd);
+ status = qla2x00_eh_wait_on_command(cmd);
spin_lock_irqsave(&ha->hardware_lock, flags);
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -1249,7 +1303,6 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
int que, cnt;
unsigned long flags;
srb_t *sp;
- struct srb_ctx *ctx;
struct qla_hw_data *ha = vha->hw;
struct req_que *req;
@@ -1262,31 +1315,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
sp = req->outstanding_cmds[cnt];
if (sp) {
req->outstanding_cmds[cnt] = NULL;
- if (!sp->ctx ||
- (sp->flags & SRB_FCP_CMND_DMA_VALID) ||
- IS_PROT_IO(sp)) {
- sp->cmd->result = res;
- qla2x00_sp_compl(ha, sp);
- } else {
- ctx = sp->ctx;
- if (ctx->type == SRB_ELS_CMD_RPT ||
- ctx->type == SRB_ELS_CMD_HST ||
- ctx->type == SRB_CT_CMD) {
- struct fc_bsg_job *bsg_job =
- ctx->u.bsg_job;
- if (bsg_job->request->msgcode
- == FC_BSG_HST_CT)
- kfree(sp->fcport);
- bsg_job->req->errors = 0;
- bsg_job->reply->result = res;
- bsg_job->job_done(bsg_job);
- kfree(sp->ctx);
- mempool_free(sp,
- ha->srb_mempool);
- } else {
- ctx->u.iocb_cmd->free(sp);
- }
- }
+ sp->done(vha, sp, res);
}
}
}
@@ -3820,75 +3849,6 @@ qla2x00_rst_aen(scsi_qla_host_t *vha)
}
}
-static void
-qla2x00_sp_free_dma(srb_t *sp)
-{
- struct scsi_cmnd *cmd = sp->cmd;
- struct qla_hw_data *ha = sp->fcport->vha->hw;
-
- if (sp->flags & SRB_DMA_VALID) {
- scsi_dma_unmap(cmd);
- sp->flags &= ~SRB_DMA_VALID;
- }
-
- if (sp->flags & SRB_CRC_PROT_DMA_VALID) {
- dma_unmap_sg(&ha->pdev->dev, scsi_prot_sglist(cmd),
- scsi_prot_sg_count(cmd), cmd->sc_data_direction);
- sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
- }
-
- if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
- /* List assured to be having elements */
- qla2x00_clean_dsd_pool(ha, sp);
- sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
- }
-
- if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
- dma_pool_free(ha->dl_dma_pool, sp->ctx,
- ((struct crc_context *)sp->ctx)->crc_ctx_dma);
- sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
- }
-
- if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
- struct ct6_dsd *ctx = sp->ctx;
- dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd,
- ctx->fcp_cmnd_dma);
- list_splice(&ctx->dsd_list, &ha->gbl_dsd_list);
- ha->gbl_dsd_inuse -= ctx->dsd_use_cnt;
- ha->gbl_dsd_avail += ctx->dsd_use_cnt;
- mempool_free(sp->ctx, ha->ctx_mempool);
- sp->ctx = NULL;
- }
-
- CMD_SP(cmd) = NULL;
-}
-
-static void
-qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
-{
- struct scsi_cmnd *cmd = sp->cmd;
-
- qla2x00_sp_free_dma(sp);
- mempool_free(sp, ha->srb_mempool);
- cmd->scsi_done(cmd);
-}
-
-void
-qla2x00_sp_compl(struct qla_hw_data *ha, srb_t *sp)
-{
- if (atomic_read(&sp->ref_count) == 0) {
- ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3015,
- "SP reference-count to ZERO -- sp=%p cmd=%p.\n",
- sp, sp->cmd);
- if (ql2xextended_error_logging & ql_dbg_io)
- BUG();
- return;
- }
- if (!atomic_dec_and_test(&sp->ref_count))
- return;
- qla2x00_sp_final_compl(ha, sp);
-}
-
/**************************************************************************
* qla2x00_timer
*
@@ -3959,7 +3919,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
sp = req->outstanding_cmds[index];
if (!sp)
continue;
- if (sp->ctx && !IS_PROT_IO(sp))
+ if (sp->type != SRB_SCSI_CMD)
continue;
sfcp = sp->fcport;
if (!(sfcp->flags & FCF_FCP2_DEVICE))