]> Pileus Git - ~andy/linux/commitdiff
[SCSI] lpfc 8.3.43: Fixed invalid Total_Data_Placed value received for els and ct...
authorJames Smart <james.smart@emulex.com>
Thu, 10 Oct 2013 16:23:10 +0000 (12:23 -0400)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 25 Oct 2013 08:58:18 +0000 (09:58 +0100)
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/lpfc/lpfc_hw4.h
drivers/scsi/lpfc/lpfc_sli.c

index 205b4e38030e62666efdb7e20589fe46be537b38..5464b116d3287b77796e580a62e3ecbc7243167d 100644 (file)
@@ -3439,7 +3439,8 @@ struct els_request64_wqe {
 #define els_req64_hopcnt_SHIFT      24
 #define els_req64_hopcnt_MASK       0x000000ff
 #define els_req64_hopcnt_WORD       word13
-       uint32_t reserved[2];
+       uint32_t word14;
+       uint32_t max_response_payload_len;
 };
 
 struct xmit_els_rsp64_wqe {
@@ -3554,7 +3555,8 @@ struct gen_req64_wqe {
        uint32_t relative_offset;
        struct wqe_rctl_dfctl wge_ctl; /* word 5 */
        struct wqe_common wqe_com;     /* words 6-11 */
-       uint32_t rsvd_12_15[4];
+       uint32_t rsvd_12_14[3];
+       uint32_t max_response_payload_len;
 };
 
 struct create_xri_wqe {
index 3850949c8a793ee66c76b6f3529801d3ed072b3a..a262d22bca449fb465b4cec58b4957bbfd630349 100644 (file)
@@ -8188,6 +8188,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
                bf_set(wqe_qosd, &wqe->els_req.wqe_com, 1);
                bf_set(wqe_lenloc, &wqe->els_req.wqe_com, LPFC_WQE_LENLOC_NONE);
                bf_set(wqe_ebde_cnt, &wqe->els_req.wqe_com, 0);
+               wqe->els_req.max_response_payload_len = total_len - xmit_len;
                break;
        case CMD_XMIT_SEQUENCE64_CX:
                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,
                bf_set(wqe_qosd, &wqe->gen_req.wqe_com, 1);
                bf_set(wqe_lenloc, &wqe->gen_req.wqe_com, LPFC_WQE_LENLOC_NONE);
                bf_set(wqe_ebde_cnt, &wqe->gen_req.wqe_com, 0);
+               wqe->gen_req.max_response_payload_len = total_len - xmit_len;
                command_type = OTHER_COMMAND;
                break;
        case CMD_XMIT_ELS_RSP64_CX:
@@ -11195,8 +11197,11 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba,
                              struct lpfc_iocbq *pIocbOut,
                              struct lpfc_wcqe_complete *wcqe)
 {
+       int numBdes, i;
        unsigned long iflags;
-       uint32_t status;
+       uint32_t status, max_response;
+       struct lpfc_dmabuf *dmabuf;
+       struct ulp_bde64 *bpl, bde;
        size_t offset = offsetof(struct lpfc_iocbq, iocb);
 
        memcpy((char *)pIocbIn + offset, (char *)pIocbOut + offset,
@@ -11213,7 +11218,36 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba,
                        pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
        else {
                pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
-               pIocbIn->iocb.un.genreq64.bdl.bdeSize = wcqe->total_data_placed;
+               switch (pIocbOut->iocb.ulpCommand) {
+               case CMD_ELS_REQUEST64_CR:
+                       dmabuf = (struct lpfc_dmabuf *)pIocbOut->context3;
+                       bpl  = (struct ulp_bde64 *)dmabuf->virt;
+                       bde.tus.w = le32_to_cpu(bpl[1].tus.w);
+                       max_response = bde.tus.f.bdeSize;
+                       break;
+               case CMD_GEN_REQUEST64_CR:
+                       max_response = 0;
+                       if (!pIocbOut->context3)
+                               break;
+                       numBdes = pIocbOut->iocb.un.genreq64.bdl.bdeSize/
+                                       sizeof(struct ulp_bde64);
+                       dmabuf = (struct lpfc_dmabuf *)pIocbOut->context3;
+                       bpl = (struct ulp_bde64 *)dmabuf->virt;
+                       for (i = 0; i < numBdes; i++) {
+                               bde.tus.w = le32_to_cpu(bpl[i].tus.w);
+                               if (bde.tus.f.bdeFlags != BUFF_TYPE_BDE_64)
+                                       max_response += bde.tus.f.bdeSize;
+                       }
+                       break;
+               default:
+                       max_response = wcqe->total_data_placed;
+                       break;
+               }
+               if (max_response < wcqe->total_data_placed)
+                       pIocbIn->iocb.un.genreq64.bdl.bdeSize = max_response;
+               else
+                       pIocbIn->iocb.un.genreq64.bdl.bdeSize =
+                               wcqe->total_data_placed;
        }
 
        /* Convert BG errors for completion status */