aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2012-08-03 12:35:44 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-09-14 09:38:33 -0400
commit027140eab7d45f406e3397cc9373767d191ac6b4 (patch)
treec88a6d3debb9bfd0f4dca64250b8eba3eef52006
parent7e56aa25e3510ae72f0feada4b2d04eda48f95db (diff)
[SCSI] lpfc 8.3.33: Misc changes to optimize critical path
Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c22
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c21
2 files changed, 29 insertions, 14 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index bb9a2249b75d..f035f3c7ec09 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -3919,6 +3919,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
3919 struct lpfc_iocbq *piocbq = &(lpfc_cmd->cur_iocbq); 3919 struct lpfc_iocbq *piocbq = &(lpfc_cmd->cur_iocbq);
3920 int datadir = scsi_cmnd->sc_data_direction; 3920 int datadir = scsi_cmnd->sc_data_direction;
3921 char tag[2]; 3921 char tag[2];
3922 uint8_t *ptr;
3923 bool sli4;
3922 3924
3923 if (!pnode || !NLP_CHK_NODE_ACT(pnode)) 3925 if (!pnode || !NLP_CHK_NODE_ACT(pnode))
3924 return; 3926 return;
@@ -3930,8 +3932,13 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
3930 int_to_scsilun(lpfc_cmd->pCmd->device->lun, 3932 int_to_scsilun(lpfc_cmd->pCmd->device->lun,
3931 &lpfc_cmd->fcp_cmnd->fcp_lun); 3933 &lpfc_cmd->fcp_cmnd->fcp_lun);
3932 3934
3933 memset(&fcp_cmnd->fcpCdb[0], 0, LPFC_FCP_CDB_LEN); 3935 ptr = &fcp_cmnd->fcpCdb[0];
3934 memcpy(&fcp_cmnd->fcpCdb[0], scsi_cmnd->cmnd, scsi_cmnd->cmd_len); 3936 memcpy(ptr, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
3937 if (scsi_cmnd->cmd_len < LPFC_FCP_CDB_LEN) {
3938 ptr += scsi_cmnd->cmd_len;
3939 memset(ptr, 0, (LPFC_FCP_CDB_LEN - scsi_cmnd->cmd_len));
3940 }
3941
3935 if (scsi_populate_tag_msg(scsi_cmnd, tag)) { 3942 if (scsi_populate_tag_msg(scsi_cmnd, tag)) {
3936 switch (tag[0]) { 3943 switch (tag[0]) {
3937 case HEAD_OF_QUEUE_TAG: 3944 case HEAD_OF_QUEUE_TAG:
@@ -3947,6 +3954,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
3947 } else 3954 } else
3948 fcp_cmnd->fcpCntl1 = 0; 3955 fcp_cmnd->fcpCntl1 = 0;
3949 3956
3957 sli4 = (phba->sli_rev == LPFC_SLI_REV4);
3958
3950 /* 3959 /*
3951 * There are three possibilities here - use scatter-gather segment, use 3960 * There are three possibilities here - use scatter-gather segment, use
3952 * the single mapping, or neither. Start the lpfc command prep by 3961 * the single mapping, or neither. Start the lpfc command prep by
@@ -3956,11 +3965,12 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
3956 if (scsi_sg_count(scsi_cmnd)) { 3965 if (scsi_sg_count(scsi_cmnd)) {
3957 if (datadir == DMA_TO_DEVICE) { 3966 if (datadir == DMA_TO_DEVICE) {
3958 iocb_cmd->ulpCommand = CMD_FCP_IWRITE64_CR; 3967 iocb_cmd->ulpCommand = CMD_FCP_IWRITE64_CR;
3959 if (phba->sli_rev < LPFC_SLI_REV4) { 3968 if (sli4)
3969 iocb_cmd->ulpPU = PARM_READ_CHECK;
3970 else {
3960 iocb_cmd->un.fcpi.fcpi_parm = 0; 3971 iocb_cmd->un.fcpi.fcpi_parm = 0;
3961 iocb_cmd->ulpPU = 0; 3972 iocb_cmd->ulpPU = 0;
3962 } else 3973 }
3963 iocb_cmd->ulpPU = PARM_READ_CHECK;
3964 fcp_cmnd->fcpCntl3 = WRITE_DATA; 3974 fcp_cmnd->fcpCntl3 = WRITE_DATA;
3965 phba->fc4OutputRequests++; 3975 phba->fc4OutputRequests++;
3966 } else { 3976 } else {
@@ -3984,7 +3994,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
3984 * of the scsi_cmnd request_buffer 3994 * of the scsi_cmnd request_buffer
3985 */ 3995 */
3986 piocbq->iocb.ulpContext = pnode->nlp_rpi; 3996 piocbq->iocb.ulpContext = pnode->nlp_rpi;
3987 if (phba->sli_rev == LPFC_SLI_REV4) 3997 if (sli4)
3988 piocbq->iocb.ulpContext = 3998 piocbq->iocb.ulpContext =
3989 phba->sli4_hba.rpi_ids[pnode->nlp_rpi]; 3999 phba->sli4_hba.rpi_ids[pnode->nlp_rpi];
3990 if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE) 4000 if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE)
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 51c7fc746de1..d7afd0fb4579 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -94,6 +94,7 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
94 union lpfc_wqe *temp_wqe; 94 union lpfc_wqe *temp_wqe;
95 struct lpfc_register doorbell; 95 struct lpfc_register doorbell;
96 uint32_t host_index; 96 uint32_t host_index;
97 uint32_t idx;
97 98
98 /* sanity check on queue memory */ 99 /* sanity check on queue memory */
99 if (unlikely(!q)) 100 if (unlikely(!q))
@@ -101,7 +102,8 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
101 temp_wqe = q->qe[q->host_index].wqe; 102 temp_wqe = q->qe[q->host_index].wqe;
102 103
103 /* If the host has not yet processed the next entry then we are done */ 104 /* If the host has not yet processed the next entry then we are done */
104 if (((q->host_index + 1) % q->entry_count) == q->hba_index) { 105 idx = ((q->host_index + 1) % q->entry_count);
106 if (idx == q->hba_index) {
105 q->WQ_overflow++; 107 q->WQ_overflow++;
106 return -ENOMEM; 108 return -ENOMEM;
107 } 109 }
@@ -115,7 +117,8 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
115 117
116 /* Update the host index before invoking device */ 118 /* Update the host index before invoking device */
117 host_index = q->host_index; 119 host_index = q->host_index;
118 q->host_index = ((q->host_index + 1) % q->entry_count); 120
121 q->host_index = idx;
119 122
120 /* Ring Doorbell */ 123 /* Ring Doorbell */
121 doorbell.word0 = 0; 124 doorbell.word0 = 0;
@@ -123,7 +126,6 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
123 bf_set(lpfc_wq_doorbell_index, &doorbell, host_index); 126 bf_set(lpfc_wq_doorbell_index, &doorbell, host_index);
124 bf_set(lpfc_wq_doorbell_id, &doorbell, q->queue_id); 127 bf_set(lpfc_wq_doorbell_id, &doorbell, q->queue_id);
125 writel(doorbell.word0, q->phba->sli4_hba.WQDBregaddr); 128 writel(doorbell.word0, q->phba->sli4_hba.WQDBregaddr);
126 readl(q->phba->sli4_hba.WQDBregaddr); /* Flush */
127 129
128 return 0; 130 return 0;
129} 131}
@@ -197,7 +199,6 @@ lpfc_sli4_mq_put(struct lpfc_queue *q, struct lpfc_mqe *mqe)
197 bf_set(lpfc_mq_doorbell_num_posted, &doorbell, 1); 199 bf_set(lpfc_mq_doorbell_num_posted, &doorbell, 1);
198 bf_set(lpfc_mq_doorbell_id, &doorbell, q->queue_id); 200 bf_set(lpfc_mq_doorbell_id, &doorbell, q->queue_id);
199 writel(doorbell.word0, q->phba->sli4_hba.MQDBregaddr); 201 writel(doorbell.word0, q->phba->sli4_hba.MQDBregaddr);
200 readl(q->phba->sli4_hba.MQDBregaddr); /* Flush */
201 return 0; 202 return 0;
202} 203}
203 204
@@ -237,6 +238,7 @@ static struct lpfc_eqe *
237lpfc_sli4_eq_get(struct lpfc_queue *q) 238lpfc_sli4_eq_get(struct lpfc_queue *q)
238{ 239{
239 struct lpfc_eqe *eqe; 240 struct lpfc_eqe *eqe;
241 uint32_t idx;
240 242
241 /* sanity check on queue memory */ 243 /* sanity check on queue memory */
242 if (unlikely(!q)) 244 if (unlikely(!q))
@@ -247,10 +249,11 @@ lpfc_sli4_eq_get(struct lpfc_queue *q)
247 if (!bf_get_le32(lpfc_eqe_valid, eqe)) 249 if (!bf_get_le32(lpfc_eqe_valid, eqe))
248 return NULL; 250 return NULL;
249 /* If the host has not yet processed the next entry then we are done */ 251 /* If the host has not yet processed the next entry then we are done */
250 if (((q->hba_index + 1) % q->entry_count) == q->host_index) 252 idx = ((q->hba_index + 1) % q->entry_count);
253 if (idx == q->host_index)
251 return NULL; 254 return NULL;
252 255
253 q->hba_index = ((q->hba_index + 1) % q->entry_count); 256 q->hba_index = idx;
254 return eqe; 257 return eqe;
255} 258}
256 259
@@ -321,6 +324,7 @@ static struct lpfc_cqe *
321lpfc_sli4_cq_get(struct lpfc_queue *q) 324lpfc_sli4_cq_get(struct lpfc_queue *q)
322{ 325{
323 struct lpfc_cqe *cqe; 326 struct lpfc_cqe *cqe;
327 uint32_t idx;
324 328
325 /* sanity check on queue memory */ 329 /* sanity check on queue memory */
326 if (unlikely(!q)) 330 if (unlikely(!q))
@@ -330,11 +334,12 @@ lpfc_sli4_cq_get(struct lpfc_queue *q)
330 if (!bf_get_le32(lpfc_cqe_valid, q->qe[q->hba_index].cqe)) 334 if (!bf_get_le32(lpfc_cqe_valid, q->qe[q->hba_index].cqe))
331 return NULL; 335 return NULL;
332 /* If the host has not yet processed the next entry then we are done */ 336 /* If the host has not yet processed the next entry then we are done */
333 if (((q->hba_index + 1) % q->entry_count) == q->host_index) 337 idx = ((q->hba_index + 1) % q->entry_count);
338 if (idx == q->host_index)
334 return NULL; 339 return NULL;
335 340
336 cqe = q->qe[q->hba_index].cqe; 341 cqe = q->qe[q->hba_index].cqe;
337 q->hba_index = ((q->hba_index + 1) % q->entry_count); 342 q->hba_index = idx;
338 return cqe; 343 return cqe;
339} 344}
340 345