aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h6
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c38
2 files changed, 40 insertions, 4 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 205b4e38030e..5464b116d328 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -3439,7 +3439,8 @@ struct els_request64_wqe {
3439#define els_req64_hopcnt_SHIFT 24 3439#define els_req64_hopcnt_SHIFT 24
3440#define els_req64_hopcnt_MASK 0x000000ff 3440#define els_req64_hopcnt_MASK 0x000000ff
3441#define els_req64_hopcnt_WORD word13 3441#define els_req64_hopcnt_WORD word13
3442 uint32_t reserved[2]; 3442 uint32_t word14;
3443 uint32_t max_response_payload_len;
3443}; 3444};
3444 3445
3445struct xmit_els_rsp64_wqe { 3446struct xmit_els_rsp64_wqe {
@@ -3554,7 +3555,8 @@ struct gen_req64_wqe {
3554 uint32_t relative_offset; 3555 uint32_t relative_offset;
3555 struct wqe_rctl_dfctl wge_ctl; /* word 5 */ 3556 struct wqe_rctl_dfctl wge_ctl; /* word 5 */
3556 struct wqe_common wqe_com; /* words 6-11 */ 3557 struct wqe_common wqe_com; /* words 6-11 */
3557 uint32_t rsvd_12_15[4]; 3558 uint32_t rsvd_12_14[3];
3559 uint32_t max_response_payload_len;
3558}; 3560};
3559 3561
3560struct create_xri_wqe { 3562struct create_xri_wqe {
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 3850949c8a79..a262d22bca44 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -8188,6 +8188,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
8188 bf_set(wqe_qosd, &wqe->els_req.wqe_com, 1); 8188 bf_set(wqe_qosd, &wqe->els_req.wqe_com, 1);
8189 bf_set(wqe_lenloc, &wqe->els_req.wqe_com, LPFC_WQE_LENLOC_NONE); 8189 bf_set(wqe_lenloc, &wqe->els_req.wqe_com, LPFC_WQE_LENLOC_NONE);
8190 bf_set(wqe_ebde_cnt, &wqe->els_req.wqe_com, 0); 8190 bf_set(wqe_ebde_cnt, &wqe->els_req.wqe_com, 0);
8191 wqe->els_req.max_response_payload_len = total_len - xmit_len;
8191 break; 8192 break;
8192 case CMD_XMIT_SEQUENCE64_CX: 8193 case CMD_XMIT_SEQUENCE64_CX:
8193 bf_set(wqe_ctxt_tag, &wqe->xmit_sequence.wqe_com, 8194 bf_set(wqe_ctxt_tag, &wqe->xmit_sequence.wqe_com,
@@ -8324,6 +8325,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
8324 bf_set(wqe_qosd, &wqe->gen_req.wqe_com, 1); 8325 bf_set(wqe_qosd, &wqe->gen_req.wqe_com, 1);
8325 bf_set(wqe_lenloc, &wqe->gen_req.wqe_com, LPFC_WQE_LENLOC_NONE); 8326 bf_set(wqe_lenloc, &wqe->gen_req.wqe_com, LPFC_WQE_LENLOC_NONE);
8326 bf_set(wqe_ebde_cnt, &wqe->gen_req.wqe_com, 0); 8327 bf_set(wqe_ebde_cnt, &wqe->gen_req.wqe_com, 0);
8328 wqe->gen_req.max_response_payload_len = total_len - xmit_len;
8327 command_type = OTHER_COMMAND; 8329 command_type = OTHER_COMMAND;
8328 break; 8330 break;
8329 case CMD_XMIT_ELS_RSP64_CX: 8331 case CMD_XMIT_ELS_RSP64_CX:
@@ -11195,8 +11197,11 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba,
11195 struct lpfc_iocbq *pIocbOut, 11197 struct lpfc_iocbq *pIocbOut,
11196 struct lpfc_wcqe_complete *wcqe) 11198 struct lpfc_wcqe_complete *wcqe)
11197{ 11199{
11200 int numBdes, i;
11198 unsigned long iflags; 11201 unsigned long iflags;
11199 uint32_t status; 11202 uint32_t status, max_response;
11203 struct lpfc_dmabuf *dmabuf;
11204 struct ulp_bde64 *bpl, bde;
11200 size_t offset = offsetof(struct lpfc_iocbq, iocb); 11205 size_t offset = offsetof(struct lpfc_iocbq, iocb);
11201 11206
11202 memcpy((char *)pIocbIn + offset, (char *)pIocbOut + offset, 11207 memcpy((char *)pIocbIn + offset, (char *)pIocbOut + offset,
@@ -11213,7 +11218,36 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba,
11213 pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter; 11218 pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
11214 else { 11219 else {
11215 pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter; 11220 pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
11216 pIocbIn->iocb.un.genreq64.bdl.bdeSize = wcqe->total_data_placed; 11221 switch (pIocbOut->iocb.ulpCommand) {
11222 case CMD_ELS_REQUEST64_CR:
11223 dmabuf = (struct lpfc_dmabuf *)pIocbOut->context3;
11224 bpl = (struct ulp_bde64 *)dmabuf->virt;
11225 bde.tus.w = le32_to_cpu(bpl[1].tus.w);
11226 max_response = bde.tus.f.bdeSize;
11227 break;
11228 case CMD_GEN_REQUEST64_CR:
11229 max_response = 0;
11230 if (!pIocbOut->context3)
11231 break;
11232 numBdes = pIocbOut->iocb.un.genreq64.bdl.bdeSize/
11233 sizeof(struct ulp_bde64);
11234 dmabuf = (struct lpfc_dmabuf *)pIocbOut->context3;
11235 bpl = (struct ulp_bde64 *)dmabuf->virt;
11236 for (i = 0; i < numBdes; i++) {
11237 bde.tus.w = le32_to_cpu(bpl[i].tus.w);
11238 if (bde.tus.f.bdeFlags != BUFF_TYPE_BDE_64)
11239 max_response += bde.tus.f.bdeSize;
11240 }
11241 break;
11242 default:
11243 max_response = wcqe->total_data_placed;
11244 break;
11245 }
11246 if (max_response < wcqe->total_data_placed)
11247 pIocbIn->iocb.un.genreq64.bdl.bdeSize = max_response;
11248 else
11249 pIocbIn->iocb.un.genreq64.bdl.bdeSize =
11250 wcqe->total_data_placed;
11217 } 11251 }
11218 11252
11219 /* Convert BG errors for completion status */ 11253 /* Convert BG errors for completion status */