aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_scsi.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2013-04-17 20:18:07 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-05-02 16:02:40 -0400
commita6887e2874916aff0f56ae8f2cded797fa9b2225 (patch)
treea1df62951bea3f1c8b97902d5d75ea747a42f73f /drivers/scsi/lpfc/lpfc_scsi.c
parenta40fc5f0d052d468f66da5fab3be0adb6cb6443d (diff)
[SCSI] lpfc 8.3.39: Fixed BlockGuard to take advantage of rdprotect/wrprotect info when available
Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c181
1 files changed, 115 insertions, 66 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index be11bb9cb176..44995de74a62 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -68,6 +68,10 @@ struct scsi_dif_tuple {
68 __be32 ref_tag; /* Target LBA or indirect LBA */ 68 __be32 ref_tag; /* Target LBA or indirect LBA */
69}; 69};
70 70
71#if !defined(SCSI_PROT_GUARD_CHECK) || !defined(SCSI_PROT_REF_CHECK)
72#define scsi_prot_flagged(sc, flg) sc
73#endif
74
71static void 75static void
72lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb); 76lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
73static void 77static void
@@ -2066,9 +2070,21 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
2066 bf_set(pde6_type, pde6, LPFC_PDE6_DESCRIPTOR); 2070 bf_set(pde6_type, pde6, LPFC_PDE6_DESCRIPTOR);
2067 bf_set(pde6_optx, pde6, txop); 2071 bf_set(pde6_optx, pde6, txop);
2068 bf_set(pde6_oprx, pde6, rxop); 2072 bf_set(pde6_oprx, pde6, rxop);
2073
2074 /*
2075 * We only need to check the data on READs, for WRITEs
2076 * protection data is automatically generated, not checked.
2077 */
2069 if (datadir == DMA_FROM_DEVICE) { 2078 if (datadir == DMA_FROM_DEVICE) {
2070 bf_set(pde6_ce, pde6, checking); 2079 if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK))
2071 bf_set(pde6_re, pde6, checking); 2080 bf_set(pde6_ce, pde6, checking);
2081 else
2082 bf_set(pde6_ce, pde6, 0);
2083
2084 if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK))
2085 bf_set(pde6_re, pde6, checking);
2086 else
2087 bf_set(pde6_re, pde6, 0);
2072 } 2088 }
2073 bf_set(pde6_ai, pde6, 1); 2089 bf_set(pde6_ai, pde6, 1);
2074 bf_set(pde6_ae, pde6, 0); 2090 bf_set(pde6_ae, pde6, 0);
@@ -2221,8 +2237,17 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
2221 bf_set(pde6_type, pde6, LPFC_PDE6_DESCRIPTOR); 2237 bf_set(pde6_type, pde6, LPFC_PDE6_DESCRIPTOR);
2222 bf_set(pde6_optx, pde6, txop); 2238 bf_set(pde6_optx, pde6, txop);
2223 bf_set(pde6_oprx, pde6, rxop); 2239 bf_set(pde6_oprx, pde6, rxop);
2224 bf_set(pde6_ce, pde6, checking); 2240
2225 bf_set(pde6_re, pde6, checking); 2241 if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK))
2242 bf_set(pde6_ce, pde6, checking);
2243 else
2244 bf_set(pde6_ce, pde6, 0);
2245
2246 if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK))
2247 bf_set(pde6_re, pde6, checking);
2248 else
2249 bf_set(pde6_re, pde6, 0);
2250
2226 bf_set(pde6_ai, pde6, 1); 2251 bf_set(pde6_ai, pde6, 1);
2227 bf_set(pde6_ae, pde6, 0); 2252 bf_set(pde6_ae, pde6, 0);
2228 bf_set(pde6_apptagval, pde6, 0); 2253 bf_set(pde6_apptagval, pde6, 0);
@@ -2385,7 +2410,6 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
2385 struct sli4_sge_diseed *diseed = NULL; 2410 struct sli4_sge_diseed *diseed = NULL;
2386 dma_addr_t physaddr; 2411 dma_addr_t physaddr;
2387 int i = 0, num_sge = 0, status; 2412 int i = 0, num_sge = 0, status;
2388 int datadir = sc->sc_data_direction;
2389 uint32_t reftag; 2413 uint32_t reftag;
2390 unsigned blksize; 2414 unsigned blksize;
2391 uint8_t txop, rxop; 2415 uint8_t txop, rxop;
@@ -2423,13 +2447,26 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
2423 diseed->ref_tag = cpu_to_le32(reftag); 2447 diseed->ref_tag = cpu_to_le32(reftag);
2424 diseed->ref_tag_tran = diseed->ref_tag; 2448 diseed->ref_tag_tran = diseed->ref_tag;
2425 2449
2450 /*
2451 * We only need to check the data on READs, for WRITEs
2452 * protection data is automatically generated, not checked.
2453 */
2454 if (sc->sc_data_direction == DMA_FROM_DEVICE) {
2455 if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK))
2456 bf_set(lpfc_sli4_sge_dif_ce, diseed, checking);
2457 else
2458 bf_set(lpfc_sli4_sge_dif_ce, diseed, 0);
2459
2460 if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK))
2461 bf_set(lpfc_sli4_sge_dif_re, diseed, checking);
2462 else
2463 bf_set(lpfc_sli4_sge_dif_re, diseed, 0);
2464 }
2465
2426 /* setup DISEED with the rest of the info */ 2466 /* setup DISEED with the rest of the info */
2427 bf_set(lpfc_sli4_sge_dif_optx, diseed, txop); 2467 bf_set(lpfc_sli4_sge_dif_optx, diseed, txop);
2428 bf_set(lpfc_sli4_sge_dif_oprx, diseed, rxop); 2468 bf_set(lpfc_sli4_sge_dif_oprx, diseed, rxop);
2429 if (datadir == DMA_FROM_DEVICE) { 2469
2430 bf_set(lpfc_sli4_sge_dif_ce, diseed, checking);
2431 bf_set(lpfc_sli4_sge_dif_re, diseed, checking);
2432 }
2433 bf_set(lpfc_sli4_sge_dif_ai, diseed, 1); 2470 bf_set(lpfc_sli4_sge_dif_ai, diseed, 1);
2434 bf_set(lpfc_sli4_sge_dif_me, diseed, 0); 2471 bf_set(lpfc_sli4_sge_dif_me, diseed, 0);
2435 2472
@@ -2571,11 +2608,34 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
2571 diseed->ref_tag = cpu_to_le32(reftag); 2608 diseed->ref_tag = cpu_to_le32(reftag);
2572 diseed->ref_tag_tran = diseed->ref_tag; 2609 diseed->ref_tag_tran = diseed->ref_tag;
2573 2610
2611 if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) {
2612 bf_set(lpfc_sli4_sge_dif_ce, diseed, checking);
2613
2614 } else {
2615 bf_set(lpfc_sli4_sge_dif_ce, diseed, 0);
2616 /*
2617 * When in this mode, the hardware will replace
2618 * the guard tag from the host with a
2619 * newly generated good CRC for the wire.
2620 * Switch to raw mode here to avoid this
2621 * behavior. What the host sends gets put on the wire.
2622 */
2623 if (txop == BG_OP_IN_CRC_OUT_CRC) {
2624 txop = BG_OP_RAW_MODE;
2625 rxop = BG_OP_RAW_MODE;
2626 }
2627 }
2628
2629
2630 if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK))
2631 bf_set(lpfc_sli4_sge_dif_re, diseed, checking);
2632 else
2633 bf_set(lpfc_sli4_sge_dif_re, diseed, 0);
2634
2574 /* setup DISEED with the rest of the info */ 2635 /* setup DISEED with the rest of the info */
2575 bf_set(lpfc_sli4_sge_dif_optx, diseed, txop); 2636 bf_set(lpfc_sli4_sge_dif_optx, diseed, txop);
2576 bf_set(lpfc_sli4_sge_dif_oprx, diseed, rxop); 2637 bf_set(lpfc_sli4_sge_dif_oprx, diseed, rxop);
2577 bf_set(lpfc_sli4_sge_dif_ce, diseed, checking); 2638
2578 bf_set(lpfc_sli4_sge_dif_re, diseed, checking);
2579 bf_set(lpfc_sli4_sge_dif_ai, diseed, 1); 2639 bf_set(lpfc_sli4_sge_dif_ai, diseed, 1);
2580 bf_set(lpfc_sli4_sge_dif_me, diseed, 0); 2640 bf_set(lpfc_sli4_sge_dif_me, diseed, 0);
2581 2641
@@ -2739,6 +2799,47 @@ lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc)
2739} 2799}
2740 2800
2741/** 2801/**
2802 * lpfc_bg_scsi_adjust_dl - Adjust SCSI data length for BlockGuard
2803 * @phba: The Hba for which this call is being executed.
2804 * @lpfc_cmd: The scsi buffer which is going to be adjusted.
2805 *
2806 * Adjust the data length to account for how much data
2807 * is actually on the wire.
2808 *
2809 * returns the adjusted data length
2810 **/
2811static int
2812lpfc_bg_scsi_adjust_dl(struct lpfc_hba *phba,
2813 struct lpfc_scsi_buf *lpfc_cmd)
2814{
2815 struct scsi_cmnd *sc = lpfc_cmd->pCmd;
2816 int fcpdl;
2817
2818 fcpdl = scsi_bufflen(sc);
2819
2820 /* Check if there is protection data on the wire */
2821 if (sc->sc_data_direction == DMA_FROM_DEVICE) {
2822 /* Read */
2823 if (scsi_get_prot_op(sc) == SCSI_PROT_READ_INSERT)
2824 return fcpdl;
2825
2826 } else {
2827 /* Write */
2828 if (scsi_get_prot_op(sc) == SCSI_PROT_WRITE_STRIP)
2829 return fcpdl;
2830 }
2831
2832 /*
2833 * If we are in DIF Type 1 mode every data block has a 8 byte
2834 * DIF (trailer) attached to it. Must ajust FCP data length.
2835 */
2836 if (scsi_prot_flagged(sc, SCSI_PROT_TRANSFER_PI))
2837 fcpdl += (fcpdl / lpfc_cmd_blksize(sc)) * 8;
2838
2839 return fcpdl;
2840}
2841
2842/**
2742 * lpfc_bg_scsi_prep_dma_buf_s3 - DMA mapping for scsi buffer to SLI3 IF spec 2843 * lpfc_bg_scsi_prep_dma_buf_s3 - DMA mapping for scsi buffer to SLI3 IF spec
2743 * @phba: The Hba for which this call is being executed. 2844 * @phba: The Hba for which this call is being executed.
2744 * @lpfc_cmd: The scsi buffer which is going to be prep'ed. 2845 * @lpfc_cmd: The scsi buffer which is going to be prep'ed.
@@ -2758,8 +2859,7 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba,
2758 uint32_t num_bde = 0; 2859 uint32_t num_bde = 0;
2759 int datasegcnt, protsegcnt, datadir = scsi_cmnd->sc_data_direction; 2860 int datasegcnt, protsegcnt, datadir = scsi_cmnd->sc_data_direction;
2760 int prot_group_type = 0; 2861 int prot_group_type = 0;
2761 int diflen, fcpdl; 2862 int fcpdl;
2762 unsigned blksize;
2763 2863
2764 /* 2864 /*
2765 * Start the lpfc command prep by bumping the bpl beyond fcp_cmnd 2865 * Start the lpfc command prep by bumping the bpl beyond fcp_cmnd
@@ -2856,18 +2956,7 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba,
2856 iocb_cmd->ulpBdeCount = 1; 2956 iocb_cmd->ulpBdeCount = 1;
2857 iocb_cmd->ulpLe = 1; 2957 iocb_cmd->ulpLe = 1;
2858 2958
2859 fcpdl = scsi_bufflen(scsi_cmnd); 2959 fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd);
2860
2861 if (scsi_get_prot_type(scsi_cmnd) == SCSI_PROT_DIF_TYPE1) {
2862 /*
2863 * We are in DIF Type 1 mode
2864 * Every data block has a 8 byte DIF (trailer)
2865 * attached to it. Must ajust FCP data length
2866 */
2867 blksize = lpfc_cmd_blksize(scsi_cmnd);
2868 diflen = (fcpdl / blksize) * 8;
2869 fcpdl += diflen;
2870 }
2871 fcp_cmnd->fcpDl = be32_to_cpu(fcpdl); 2960 fcp_cmnd->fcpDl = be32_to_cpu(fcpdl);
2872 2961
2873 /* 2962 /*
@@ -2982,7 +3071,7 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
2982 chk_guard = 1; 3071 chk_guard = 1;
2983 guard_type = scsi_host_get_guard(cmd->device->host); 3072 guard_type = scsi_host_get_guard(cmd->device->host);
2984 3073
2985 start_ref_tag = scsi_get_lba(cmd); 3074 start_ref_tag = (uint32_t)scsi_get_lba(cmd); /* Truncate LBA */
2986 start_app_tag = src->app_tag; 3075 start_app_tag = src->app_tag;
2987 src = (struct scsi_dif_tuple *)sg_virt(sgpe); 3076 src = (struct scsi_dif_tuple *)sg_virt(sgpe);
2988 len = sgpe->length; 3077 len = sgpe->length;
@@ -3398,45 +3487,6 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
3398} 3487}
3399 3488
3400/** 3489/**
3401 * lpfc_bg_scsi_adjust_dl - Adjust SCSI data length for BlockGuard
3402 * @phba: The Hba for which this call is being executed.
3403 * @lpfc_cmd: The scsi buffer which is going to be adjusted.
3404 *
3405 * Adjust the data length to account for how much data
3406 * is actually on the wire.
3407 *
3408 * returns the adjusted data length
3409 **/
3410static int
3411lpfc_bg_scsi_adjust_dl(struct lpfc_hba *phba,
3412 struct lpfc_scsi_buf *lpfc_cmd)
3413{
3414 struct scsi_cmnd *sc = lpfc_cmd->pCmd;
3415 int diflen, fcpdl;
3416 unsigned blksize;
3417
3418 fcpdl = scsi_bufflen(sc);
3419
3420 /* Check if there is protection data on the wire */
3421 if (sc->sc_data_direction == DMA_FROM_DEVICE) {
3422 /* Read */
3423 if (scsi_get_prot_op(sc) == SCSI_PROT_READ_INSERT)
3424 return fcpdl;
3425
3426 } else {
3427 /* Write */
3428 if (scsi_get_prot_op(sc) == SCSI_PROT_WRITE_STRIP)
3429 return fcpdl;
3430 }
3431
3432 /* If protection data on the wire, adjust the count accordingly */
3433 blksize = lpfc_cmd_blksize(sc);
3434 diflen = (fcpdl / blksize) * 8;
3435 fcpdl += diflen;
3436 return fcpdl;
3437}
3438
3439/**
3440 * lpfc_bg_scsi_prep_dma_buf_s4 - DMA mapping for scsi buffer to SLI4 IF spec 3490 * lpfc_bg_scsi_prep_dma_buf_s4 - DMA mapping for scsi buffer to SLI4 IF spec
3441 * @phba: The Hba for which this call is being executed. 3491 * @phba: The Hba for which this call is being executed.
3442 * @lpfc_cmd: The scsi buffer which is going to be mapped. 3492 * @lpfc_cmd: The scsi buffer which is going to be mapped.
@@ -3564,7 +3614,6 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba,
3564 } 3614 }
3565 3615
3566 fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd); 3616 fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd);
3567
3568 fcp_cmnd->fcpDl = be32_to_cpu(fcpdl); 3617 fcp_cmnd->fcpDl = be32_to_cpu(fcpdl);
3569 3618
3570 /* 3619 /*