diff options
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 22 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 21 |
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 * | |||
237 | lpfc_sli4_eq_get(struct lpfc_queue *q) | 238 | lpfc_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 * | |||
321 | lpfc_sli4_cq_get(struct lpfc_queue *q) | 324 | lpfc_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 | ||