rk30/rk2928 hdmi:
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / lpfc / lpfc_scsi.c
index 84e4481b24062e21107cf770926bbdfe1d6610c5..eadd241eeff113cffc7a893412c43662ba695828 100644 (file)
@@ -743,7 +743,14 @@ lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *phba)
                if (bcnt == 0)
                        continue;
                /* Now, post the SCSI buffer list sgls as a block */
-               status = lpfc_sli4_post_scsi_sgl_block(phba, &sblist, bcnt);
+               if (!phba->sli4_hba.extents_in_use)
+                       status = lpfc_sli4_post_scsi_sgl_block(phba,
+                                                       &sblist,
+                                                       bcnt);
+               else
+                       status = lpfc_sli4_post_scsi_sgl_blk_ext(phba,
+                                                       &sblist,
+                                                       bcnt);
                /* Reset SCSI buffer count for next round of posting */
                bcnt = 0;
                while (!list_empty(&sblist)) {
@@ -787,7 +794,7 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
        dma_addr_t pdma_phys_fcp_cmd;
        dma_addr_t pdma_phys_fcp_rsp;
        dma_addr_t pdma_phys_bpl, pdma_phys_bpl1;
-       uint16_t iotag, last_xritag = NO_XRI;
+       uint16_t iotag, last_xritag = NO_XRI, lxri = 0;
        int status = 0, index;
        int bcnt;
        int non_sequential_xri = 0;
@@ -823,13 +830,15 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
                        break;
                }
 
-               psb->cur_iocbq.sli4_xritag = lpfc_sli4_next_xritag(phba);
-               if (psb->cur_iocbq.sli4_xritag == NO_XRI) {
+               lxri = lpfc_sli4_next_xritag(phba);
+               if (lxri == NO_XRI) {
                        pci_pool_free(phba->lpfc_scsi_dma_buf_pool,
                              psb->data, psb->dma_handle);
                        kfree(psb);
                        break;
                }
+               psb->cur_iocbq.sli4_lxritag = lxri;
+               psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri];
                if (last_xritag != NO_XRI
                        && psb->cur_iocbq.sli4_xritag != (last_xritag+1)) {
                        non_sequential_xri = 1;
@@ -861,6 +870,7 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
                 */
                sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_cmd));
                sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_cmd));
+               sgl->word2 = le32_to_cpu(sgl->word2);
                bf_set(lpfc_sli4_sge_last, sgl, 0);
                sgl->word2 = cpu_to_le32(sgl->word2);
                sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd));
@@ -869,6 +879,7 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
                /* Setup the physical region for the FCP RSP */
                sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_rsp));
                sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_rsp));
+               sgl->word2 = le32_to_cpu(sgl->word2);
                bf_set(lpfc_sli4_sge_last, sgl, 1);
                sgl->word2 = cpu_to_le32(sgl->word2);
                sgl->sge_len = cpu_to_le32(sizeof(struct fcp_rsp));
@@ -914,7 +925,21 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
                }
        }
        if (bcnt) {
-               status = lpfc_sli4_post_scsi_sgl_block(phba, &sblist, bcnt);
+               if (!phba->sli4_hba.extents_in_use)
+                       status = lpfc_sli4_post_scsi_sgl_block(phba,
+                                                               &sblist,
+                                                               bcnt);
+               else
+                       status = lpfc_sli4_post_scsi_sgl_blk_ext(phba,
+                                                               &sblist,
+                                                               bcnt);
+
+               if (status) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
+                                       "3021 SCSI SGL post error %d\n",
+                                       status);
+                       bcnt = 0;
+               }
                /* Reset SCSI buffer count for next round of posting */
                while (!list_empty(&sblist)) {
                        list_remove_head(&sblist, psb, struct lpfc_scsi_buf,
@@ -1277,13 +1302,13 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
                case SCSI_PROT_NORMAL:
                default:
                        lpfc_printf_log(phba, KERN_ERR, LOG_BG,
-                               "9063 BLKGRD: Bad op/guard:%d/%d combination\n",
-                                       scsi_get_prot_op(sc), guard_type);
+                               "9063 BLKGRD: Bad op/guard:%d/IP combination\n",
+                                       scsi_get_prot_op(sc));
                        ret = 1;
                        break;
 
                }
-       } else if (guard_type == SHOST_DIX_GUARD_CRC) {
+       } else {
                switch (scsi_get_prot_op(sc)) {
                case SCSI_PROT_READ_STRIP:
                case SCSI_PROT_WRITE_INSERT:
@@ -1299,17 +1324,18 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 
                case SCSI_PROT_READ_INSERT:
                case SCSI_PROT_WRITE_STRIP:
+                       *txop = BG_OP_IN_CRC_OUT_NODIF;
+                       *rxop = BG_OP_IN_NODIF_OUT_CRC;
+                       break;
+
                case SCSI_PROT_NORMAL:
                default:
                        lpfc_printf_log(phba, KERN_ERR, LOG_BG,
-                               "9075 BLKGRD: Bad op/guard:%d/%d combination\n",
-                                       scsi_get_prot_op(sc), guard_type);
+                               "9075 BLKGRD: Bad op/guard:%d/CRC combination\n",
+                                       scsi_get_prot_op(sc));
                        ret = 1;
                        break;
                }
-       } else {
-               /* unsupported format */
-               BUG();
        }
 
        return ret;
@@ -1327,45 +1353,6 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc)
        return sc->device->sector_size;
 }
 
-/**
- * lpfc_get_cmd_dif_parms - Extract DIF parameters from SCSI command
- * @sc:             in: SCSI command
- * @apptagmask:     out: app tag mask
- * @apptagval:      out: app tag value
- * @reftag:         out: ref tag (reference tag)
- *
- * Description:
- *   Extract DIF parameters from the command if possible.  Otherwise,
- *   use default parameters.
- *
- **/
-static inline void
-lpfc_get_cmd_dif_parms(struct scsi_cmnd *sc, uint16_t *apptagmask,
-               uint16_t *apptagval, uint32_t *reftag)
-{
-       struct  scsi_dif_tuple *spt;
-       unsigned char op = scsi_get_prot_op(sc);
-       unsigned int protcnt = scsi_prot_sg_count(sc);
-       static int cnt;
-
-       if (protcnt && (op == SCSI_PROT_WRITE_STRIP ||
-                               op == SCSI_PROT_WRITE_PASS)) {
-
-               cnt++;
-               spt = page_address(sg_page(scsi_prot_sglist(sc))) +
-                       scsi_prot_sglist(sc)[0].offset;
-               *apptagmask = 0;
-               *apptagval = 0;
-               *reftag = cpu_to_be32(spt->ref_tag);
-
-       } else {
-               /* SBC defines ref tag to be lower 32bits of LBA */
-               *reftag = (uint32_t) (0xffffffff & scsi_get_lba(sc));
-               *apptagmask = 0;
-               *apptagval = 0;
-       }
-}
-
 /*
  * This function sets up buffer list for protection groups of
  * type LPFC_PG_TYPE_NO_DIF
@@ -1402,9 +1389,8 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
        dma_addr_t physaddr;
        int i = 0, num_bde = 0, status;
        int datadir = sc->sc_data_direction;
-       unsigned blksize;
        uint32_t reftag;
-       uint16_t apptagmask, apptagval;
+       unsigned blksize;
        uint8_t txop, rxop;
 
        status  = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop);
@@ -1413,17 +1399,16 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 
        /* extract some info from the scsi command for pde*/
        blksize = lpfc_cmd_blksize(sc);
-       lpfc_get_cmd_dif_parms(sc, &apptagmask, &apptagval, &reftag);
+       reftag = scsi_get_lba(sc) & 0xffffffff;
 
        /* setup PDE5 with what we have */
        pde5 = (struct lpfc_pde5 *) bpl;
        memset(pde5, 0, sizeof(struct lpfc_pde5));
        bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR);
-       pde5->reftag = reftag;
 
        /* Endianness conversion if necessary for PDE5 */
        pde5->word0 = cpu_to_le32(pde5->word0);
-       pde5->reftag = cpu_to_le32(pde5->reftag);
+       pde5->reftag = cpu_to_le32(reftag);
 
        /* advance bpl and increment bde count */
        num_bde++;
@@ -1438,10 +1423,10 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
        if (datadir == DMA_FROM_DEVICE) {
                bf_set(pde6_ce, pde6, 1);
                bf_set(pde6_re, pde6, 1);
-               bf_set(pde6_ae, pde6, 1);
        }
        bf_set(pde6_ai, pde6, 1);
-       bf_set(pde6_apptagval, pde6, apptagval);
+       bf_set(pde6_ae, pde6, 0);
+       bf_set(pde6_apptagval, pde6, 0);
 
        /* Endianness conversion if necessary for PDE6 */
        pde6->word0 = cpu_to_le32(pde6->word0);
@@ -1526,7 +1511,6 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
        unsigned char pgdone = 0, alldone = 0;
        unsigned blksize;
        uint32_t reftag;
-       uint16_t apptagmask, apptagval;
        uint8_t txop, rxop;
        int num_bde = 0;
 
@@ -1546,7 +1530,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 
        /* extract some info from the scsi command */
        blksize = lpfc_cmd_blksize(sc);
-       lpfc_get_cmd_dif_parms(sc, &apptagmask, &apptagval, &reftag);
+       reftag = scsi_get_lba(sc) & 0xffffffff;
 
        split_offset = 0;
        do {
@@ -1554,11 +1538,10 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
                pde5 = (struct lpfc_pde5 *) bpl;
                memset(pde5, 0, sizeof(struct lpfc_pde5));
                bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR);
-               pde5->reftag = reftag;
 
                /* Endianness conversion if necessary for PDE5 */
                pde5->word0 = cpu_to_le32(pde5->word0);
-               pde5->reftag = cpu_to_le32(pde5->reftag);
+               pde5->reftag = cpu_to_le32(reftag);
 
                /* advance bpl and increment bde count */
                num_bde++;
@@ -1572,9 +1555,9 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
                bf_set(pde6_oprx, pde6, rxop);
                bf_set(pde6_ce, pde6, 1);
                bf_set(pde6_re, pde6, 1);
-               bf_set(pde6_ae, pde6, 1);
                bf_set(pde6_ai, pde6, 1);
-               bf_set(pde6_apptagval, pde6, apptagval);
+               bf_set(pde6_ae, pde6, 0);
+               bf_set(pde6_apptagval, pde6, 0);
 
                /* Endianness conversion if necessary for PDE6 */
                pde6->word0 = cpu_to_le32(pde6->word0);
@@ -1596,8 +1579,8 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
                memset(pde7, 0, sizeof(struct lpfc_pde7));
                bf_set(pde7_type, pde7, LPFC_PDE7_DESCRIPTOR);
 
-               pde7->addrHigh = le32_to_cpu(putPaddrLow(protphysaddr));
-               pde7->addrLow = le32_to_cpu(putPaddrHigh(protphysaddr));
+               pde7->addrHigh = le32_to_cpu(putPaddrHigh(protphysaddr));
+               pde7->addrLow = le32_to_cpu(putPaddrLow(protphysaddr));
 
                protgrp_blks = protgroup_len / 8;
                protgrp_bytes = protgrp_blks * blksize;
@@ -1607,7 +1590,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
                        protgroup_remainder = 0x1000 - (pde7->addrLow & 0xfff);
                        protgroup_offset += protgroup_remainder;
                        protgrp_blks = protgroup_remainder / 8;
-                       protgrp_bytes = protgroup_remainder * blksize;
+                       protgrp_bytes = protgrp_blks * blksize;
                } else {
                        protgroup_offset = 0;
                        curr_prot++;
@@ -1981,16 +1964,21 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd,
        if (lpfc_bgs_get_hi_water_mark_present(bgstat)) {
                /*
                 * setup sense data descriptor 0 per SPC-4 as an information
-                * field, and put the failing LBA in it
+                * field, and put the failing LBA in it.
+                * This code assumes there was also a guard/app/ref tag error
+                * indication.
                 */
-               cmd->sense_buffer[8] = 0;     /* Information */
-               cmd->sense_buffer[9] = 0xa;   /* Add. length */
+               cmd->sense_buffer[7] = 0xc;   /* Additional sense length */
+               cmd->sense_buffer[8] = 0;     /* Information descriptor type */
+               cmd->sense_buffer[9] = 0xa;   /* Additional descriptor length */
+               cmd->sense_buffer[10] = 0x80; /* Validity bit */
                bghm /= cmd->device->sector_size;
 
                failing_sector = scsi_get_lba(cmd);
                failing_sector += bghm;
 
-               put_unaligned_be64(failing_sector, &cmd->sense_buffer[10]);
+               /* Descriptor Information */
+               put_unaligned_be64(failing_sector, &cmd->sense_buffer[12]);
        }
 
        if (!ret) {
@@ -2081,6 +2069,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
                        dma_len = sg_dma_len(sgel);
                        sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr));
                        sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr));
+                       sgl->word2 = le32_to_cpu(sgl->word2);
                        if ((num_bde + 1) == nseg)
                                bf_set(lpfc_sli4_sge_last, sgl, 1);
                        else
@@ -2794,6 +2783,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
         * of the scsi_cmnd request_buffer
         */
        piocbq->iocb.ulpContext = pnode->nlp_rpi;
+       if (phba->sli_rev == LPFC_SLI_REV4)
+               piocbq->iocb.ulpContext =
+                 phba->sli4_hba.rpi_ids[pnode->nlp_rpi];
        if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE)
                piocbq->iocb.ulpFCP2Rcvy = 1;
        else
@@ -2807,7 +2799,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
 }
 
 /**
- * lpfc_scsi_prep_task_mgmt_cmnd - Convert SLI3 scsi TM cmd to FCP info unit
+ * lpfc_scsi_prep_task_mgmt_cmd - Convert SLI3 scsi TM cmd to FCP info unit
  * @vport: The virtual port for which this call is being executed.
  * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure.
  * @lun: Logical unit number.
@@ -2851,6 +2843,10 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport,
                lpfc_fcpcmd_to_iocb(piocb->unsli3.fcp_ext.icd, fcp_cmnd);
        piocb->ulpCommand = CMD_FCP_ICMND64_CR;
        piocb->ulpContext = ndlp->nlp_rpi;
+       if (vport->phba->sli_rev == LPFC_SLI_REV4) {
+               piocb->ulpContext =
+                 vport->phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+       }
        if (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) {
                piocb->ulpFCP2Rcvy = 1;
        }
@@ -3405,9 +3401,10 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
 
        lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
                         "0702 Issue %s to TGT %d LUN %d "
-                        "rpi x%x nlp_flag x%x\n",
+                        "rpi x%x nlp_flag x%x Data: x%x x%x\n",
                         lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id,
-                        pnode->nlp_rpi, pnode->nlp_flag);
+                        pnode->nlp_rpi, pnode->nlp_flag, iocbq->sli4_xritag,
+                        iocbq->iocb_flag);
 
        status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING,
                                          iocbq, iocbqrsp, lpfc_cmd->timeout);
@@ -3419,10 +3416,12 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
                        ret = FAILED;
                lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
                lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
-                        "0727 TMF %s to TGT %d LUN %d failed (%d, %d)\n",
+                        "0727 TMF %s to TGT %d LUN %d failed (%d, %d) "
+                        "iocb_flag x%x\n",
                         lpfc_taskmgmt_name(task_mgmt_cmd),
                         tgt_id, lun_id, iocbqrsp->iocb.ulpStatus,
-                        iocbqrsp->iocb.un.ulpWord[4]);
+                        iocbqrsp->iocb.un.ulpWord[4],
+                        iocbq->iocb_flag);
        } else if (status == IOCB_BUSY)
                ret = FAILED;
        else