diff options
author | James Smart <james.smart@emulex.com> | 2013-04-17 20:16:15 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-05-02 15:46:20 -0400 |
commit | 96f7077f671254e957a2815e54bb20e8d50f0bbc (patch) | |
tree | 491594535761bfcddeea83fbc56976211d8cb961 /drivers/scsi/lpfc/lpfc_scsi.c | |
parent | 09294d4623a3149ae2f5d35acf9d119bd957ddd8 (diff) |
[SCSI] lpfc 8.3.39: Fix driver issues with large s/g lists for BlockGuard
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.c | 229 |
1 files changed, 144 insertions, 85 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index d096402ae4d7..c79b4dc8aa4a 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -536,7 +536,16 @@ lpfc_new_scsi_buf_s3(struct lpfc_vport *vport, int num_to_alloc) | |||
536 | dma_addr_t pdma_phys_fcp_rsp; | 536 | dma_addr_t pdma_phys_fcp_rsp; |
537 | dma_addr_t pdma_phys_bpl; | 537 | dma_addr_t pdma_phys_bpl; |
538 | uint16_t iotag; | 538 | uint16_t iotag; |
539 | int bcnt; | 539 | int bcnt, bpl_size; |
540 | |||
541 | bpl_size = phba->cfg_sg_dma_buf_size - | ||
542 | (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); | ||
543 | |||
544 | lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, | ||
545 | "9067 ALLOC %d scsi_bufs: %d (%d + %d + %d)\n", | ||
546 | num_to_alloc, phba->cfg_sg_dma_buf_size, | ||
547 | (int)sizeof(struct fcp_cmnd), | ||
548 | (int)sizeof(struct fcp_rsp), bpl_size); | ||
540 | 549 | ||
541 | for (bcnt = 0; bcnt < num_to_alloc; bcnt++) { | 550 | for (bcnt = 0; bcnt < num_to_alloc; bcnt++) { |
542 | psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); | 551 | psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); |
@@ -761,7 +770,7 @@ lpfc_sli4_post_scsi_sgl_list(struct lpfc_hba *phba, | |||
761 | struct list_head *post_sblist, int sb_count) | 770 | struct list_head *post_sblist, int sb_count) |
762 | { | 771 | { |
763 | struct lpfc_scsi_buf *psb, *psb_next; | 772 | struct lpfc_scsi_buf *psb, *psb_next; |
764 | int status; | 773 | int status, sgl_size; |
765 | int post_cnt = 0, block_cnt = 0, num_posting = 0, num_posted = 0; | 774 | int post_cnt = 0, block_cnt = 0, num_posting = 0, num_posted = 0; |
766 | dma_addr_t pdma_phys_bpl1; | 775 | dma_addr_t pdma_phys_bpl1; |
767 | int last_xritag = NO_XRI; | 776 | int last_xritag = NO_XRI; |
@@ -773,6 +782,9 @@ lpfc_sli4_post_scsi_sgl_list(struct lpfc_hba *phba, | |||
773 | if (sb_count <= 0) | 782 | if (sb_count <= 0) |
774 | return -EINVAL; | 783 | return -EINVAL; |
775 | 784 | ||
785 | sgl_size = phba->cfg_sg_dma_buf_size - | ||
786 | (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); | ||
787 | |||
776 | list_for_each_entry_safe(psb, psb_next, post_sblist, list) { | 788 | list_for_each_entry_safe(psb, psb_next, post_sblist, list) { |
777 | list_del_init(&psb->list); | 789 | list_del_init(&psb->list); |
778 | block_cnt++; | 790 | block_cnt++; |
@@ -805,7 +817,7 @@ lpfc_sli4_post_scsi_sgl_list(struct lpfc_hba *phba, | |||
805 | post_cnt = block_cnt; | 817 | post_cnt = block_cnt; |
806 | } else if (block_cnt == 1) { | 818 | } else if (block_cnt == 1) { |
807 | /* last single sgl with non-contiguous xri */ | 819 | /* last single sgl with non-contiguous xri */ |
808 | if (phba->cfg_sg_dma_buf_size > SGL_PAGE_SIZE) | 820 | if (sgl_size > SGL_PAGE_SIZE) |
809 | pdma_phys_bpl1 = psb->dma_phys_bpl + | 821 | pdma_phys_bpl1 = psb->dma_phys_bpl + |
810 | SGL_PAGE_SIZE; | 822 | SGL_PAGE_SIZE; |
811 | else | 823 | else |
@@ -925,13 +937,22 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) | |||
925 | IOCB_t *iocb; | 937 | IOCB_t *iocb; |
926 | dma_addr_t pdma_phys_fcp_cmd; | 938 | dma_addr_t pdma_phys_fcp_cmd; |
927 | dma_addr_t pdma_phys_fcp_rsp; | 939 | dma_addr_t pdma_phys_fcp_rsp; |
928 | dma_addr_t pdma_phys_bpl, pdma_phys_bpl1; | 940 | dma_addr_t pdma_phys_bpl; |
929 | uint16_t iotag, lxri = 0; | 941 | uint16_t iotag, lxri = 0; |
930 | int bcnt, num_posted; | 942 | int bcnt, num_posted, sgl_size; |
931 | LIST_HEAD(prep_sblist); | 943 | LIST_HEAD(prep_sblist); |
932 | LIST_HEAD(post_sblist); | 944 | LIST_HEAD(post_sblist); |
933 | LIST_HEAD(scsi_sblist); | 945 | LIST_HEAD(scsi_sblist); |
934 | 946 | ||
947 | sgl_size = phba->cfg_sg_dma_buf_size - | ||
948 | (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); | ||
949 | |||
950 | lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, | ||
951 | "9068 ALLOC %d scsi_bufs: %d (%d + %d + %d)\n", | ||
952 | num_to_alloc, phba->cfg_sg_dma_buf_size, sgl_size, | ||
953 | (int)sizeof(struct fcp_cmnd), | ||
954 | (int)sizeof(struct fcp_rsp)); | ||
955 | |||
935 | for (bcnt = 0; bcnt < num_to_alloc; bcnt++) { | 956 | for (bcnt = 0; bcnt < num_to_alloc; bcnt++) { |
936 | psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); | 957 | psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); |
937 | if (!psb) | 958 | if (!psb) |
@@ -950,6 +971,15 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) | |||
950 | } | 971 | } |
951 | memset(psb->data, 0, phba->cfg_sg_dma_buf_size); | 972 | memset(psb->data, 0, phba->cfg_sg_dma_buf_size); |
952 | 973 | ||
974 | /* Page alignment is CRITICAL, double check to be sure */ | ||
975 | if (((unsigned long)(psb->data) & | ||
976 | (unsigned long)(SLI4_PAGE_SIZE - 1)) != 0) { | ||
977 | pci_pool_free(phba->lpfc_scsi_dma_buf_pool, | ||
978 | psb->data, psb->dma_handle); | ||
979 | kfree(psb); | ||
980 | break; | ||
981 | } | ||
982 | |||
953 | /* Allocate iotag for psb->cur_iocbq. */ | 983 | /* Allocate iotag for psb->cur_iocbq. */ |
954 | iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq); | 984 | iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq); |
955 | if (iotag == 0) { | 985 | if (iotag == 0) { |
@@ -970,17 +1000,14 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) | |||
970 | psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri]; | 1000 | psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri]; |
971 | psb->cur_iocbq.iocb_flag |= LPFC_IO_FCP; | 1001 | psb->cur_iocbq.iocb_flag |= LPFC_IO_FCP; |
972 | psb->fcp_bpl = psb->data; | 1002 | psb->fcp_bpl = psb->data; |
973 | psb->fcp_cmnd = (psb->data + phba->cfg_sg_dma_buf_size) | 1003 | psb->fcp_cmnd = (psb->data + sgl_size); |
974 | - (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); | ||
975 | psb->fcp_rsp = (struct fcp_rsp *)((uint8_t *)psb->fcp_cmnd + | 1004 | psb->fcp_rsp = (struct fcp_rsp *)((uint8_t *)psb->fcp_cmnd + |
976 | sizeof(struct fcp_cmnd)); | 1005 | sizeof(struct fcp_cmnd)); |
977 | 1006 | ||
978 | /* Initialize local short-hand pointers. */ | 1007 | /* Initialize local short-hand pointers. */ |
979 | sgl = (struct sli4_sge *)psb->fcp_bpl; | 1008 | sgl = (struct sli4_sge *)psb->fcp_bpl; |
980 | pdma_phys_bpl = psb->dma_handle; | 1009 | pdma_phys_bpl = psb->dma_handle; |
981 | pdma_phys_fcp_cmd = | 1010 | pdma_phys_fcp_cmd = (psb->dma_handle + sgl_size); |
982 | (psb->dma_handle + phba->cfg_sg_dma_buf_size) | ||
983 | - (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); | ||
984 | pdma_phys_fcp_rsp = pdma_phys_fcp_cmd + sizeof(struct fcp_cmnd); | 1011 | pdma_phys_fcp_rsp = pdma_phys_fcp_cmd + sizeof(struct fcp_cmnd); |
985 | 1012 | ||
986 | /* | 1013 | /* |
@@ -1022,10 +1049,6 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) | |||
1022 | iocb->ulpLe = 1; | 1049 | iocb->ulpLe = 1; |
1023 | iocb->ulpClass = CLASS3; | 1050 | iocb->ulpClass = CLASS3; |
1024 | psb->cur_iocbq.context1 = psb; | 1051 | psb->cur_iocbq.context1 = psb; |
1025 | if (phba->cfg_sg_dma_buf_size > SGL_PAGE_SIZE) | ||
1026 | pdma_phys_bpl1 = pdma_phys_bpl + SGL_PAGE_SIZE; | ||
1027 | else | ||
1028 | pdma_phys_bpl1 = 0; | ||
1029 | psb->dma_phys_bpl = pdma_phys_bpl; | 1052 | psb->dma_phys_bpl = pdma_phys_bpl; |
1030 | 1053 | ||
1031 | /* add the scsi buffer to a post list */ | 1054 | /* add the scsi buffer to a post list */ |
@@ -1270,6 +1293,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
1270 | "dma_map_sg. Config %d, seg_cnt %d\n", | 1293 | "dma_map_sg. Config %d, seg_cnt %d\n", |
1271 | __func__, phba->cfg_sg_seg_cnt, | 1294 | __func__, phba->cfg_sg_seg_cnt, |
1272 | lpfc_cmd->seg_cnt); | 1295 | lpfc_cmd->seg_cnt); |
1296 | lpfc_cmd->seg_cnt = 0; | ||
1273 | scsi_dma_unmap(scsi_cmnd); | 1297 | scsi_dma_unmap(scsi_cmnd); |
1274 | return 1; | 1298 | return 1; |
1275 | } | 1299 | } |
@@ -2147,6 +2171,10 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
2147 | 2171 | ||
2148 | split_offset = 0; | 2172 | split_offset = 0; |
2149 | do { | 2173 | do { |
2174 | /* Check to see if we ran out of space */ | ||
2175 | if (num_bde >= (phba->cfg_total_seg_cnt - 2)) | ||
2176 | return num_bde + 3; | ||
2177 | |||
2150 | /* setup PDE5 with what we have */ | 2178 | /* setup PDE5 with what we have */ |
2151 | pde5 = (struct lpfc_pde5 *) bpl; | 2179 | pde5 = (struct lpfc_pde5 *) bpl; |
2152 | memset(pde5, 0, sizeof(struct lpfc_pde5)); | 2180 | memset(pde5, 0, sizeof(struct lpfc_pde5)); |
@@ -2215,6 +2243,10 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
2215 | pgdone = 0; | 2243 | pgdone = 0; |
2216 | subtotal = 0; /* total bytes processed for current prot grp */ | 2244 | subtotal = 0; /* total bytes processed for current prot grp */ |
2217 | while (!pgdone) { | 2245 | while (!pgdone) { |
2246 | /* Check to see if we ran out of space */ | ||
2247 | if (num_bde >= phba->cfg_total_seg_cnt) | ||
2248 | return num_bde + 1; | ||
2249 | |||
2218 | if (!sgde) { | 2250 | if (!sgde) { |
2219 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 2251 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, |
2220 | "9065 BLKGRD:%s Invalid data segment\n", | 2252 | "9065 BLKGRD:%s Invalid data segment\n", |
@@ -2499,6 +2531,10 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
2499 | 2531 | ||
2500 | split_offset = 0; | 2532 | split_offset = 0; |
2501 | do { | 2533 | do { |
2534 | /* Check to see if we ran out of space */ | ||
2535 | if (num_sge >= (phba->cfg_total_seg_cnt - 2)) | ||
2536 | return num_sge + 3; | ||
2537 | |||
2502 | /* setup DISEED with what we have */ | 2538 | /* setup DISEED with what we have */ |
2503 | diseed = (struct sli4_sge_diseed *) sgl; | 2539 | diseed = (struct sli4_sge_diseed *) sgl; |
2504 | memset(diseed, 0, sizeof(struct sli4_sge_diseed)); | 2540 | memset(diseed, 0, sizeof(struct sli4_sge_diseed)); |
@@ -2558,6 +2594,10 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
2558 | pgdone = 0; | 2594 | pgdone = 0; |
2559 | subtotal = 0; /* total bytes processed for current prot grp */ | 2595 | subtotal = 0; /* total bytes processed for current prot grp */ |
2560 | while (!pgdone) { | 2596 | while (!pgdone) { |
2597 | /* Check to see if we ran out of space */ | ||
2598 | if (num_sge >= phba->cfg_total_seg_cnt) | ||
2599 | return num_sge + 1; | ||
2600 | |||
2561 | if (!sgde) { | 2601 | if (!sgde) { |
2562 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 2602 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, |
2563 | "9086 BLKGRD:%s Invalid data segment\n", | 2603 | "9086 BLKGRD:%s Invalid data segment\n", |
@@ -2713,28 +2753,28 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, | |||
2713 | return 1; | 2753 | return 1; |
2714 | 2754 | ||
2715 | lpfc_cmd->seg_cnt = datasegcnt; | 2755 | lpfc_cmd->seg_cnt = datasegcnt; |
2716 | if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { | 2756 | |
2717 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 2757 | /* First check if data segment count from SCSI Layer is good */ |
2718 | "9067 BLKGRD: %s: Too many sg segments" | 2758 | if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) |
2719 | " from dma_map_sg. Config %d, seg_cnt" | 2759 | goto err; |
2720 | " %d\n", | ||
2721 | __func__, phba->cfg_sg_seg_cnt, | ||
2722 | lpfc_cmd->seg_cnt); | ||
2723 | scsi_dma_unmap(scsi_cmnd); | ||
2724 | return 1; | ||
2725 | } | ||
2726 | 2760 | ||
2727 | prot_group_type = lpfc_prot_group_type(phba, scsi_cmnd); | 2761 | prot_group_type = lpfc_prot_group_type(phba, scsi_cmnd); |
2728 | 2762 | ||
2729 | switch (prot_group_type) { | 2763 | switch (prot_group_type) { |
2730 | case LPFC_PG_TYPE_NO_DIF: | 2764 | case LPFC_PG_TYPE_NO_DIF: |
2765 | |||
2766 | /* Here we need to add a PDE5 and PDE6 to the count */ | ||
2767 | if ((lpfc_cmd->seg_cnt + 2) > phba->cfg_total_seg_cnt) | ||
2768 | goto err; | ||
2769 | |||
2731 | num_bde = lpfc_bg_setup_bpl(phba, scsi_cmnd, bpl, | 2770 | num_bde = lpfc_bg_setup_bpl(phba, scsi_cmnd, bpl, |
2732 | datasegcnt); | 2771 | datasegcnt); |
2733 | /* we should have 2 or more entries in buffer list */ | 2772 | /* we should have 2 or more entries in buffer list */ |
2734 | if (num_bde < 2) | 2773 | if (num_bde < 2) |
2735 | goto err; | 2774 | goto err; |
2736 | break; | 2775 | break; |
2737 | case LPFC_PG_TYPE_DIF_BUF:{ | 2776 | |
2777 | case LPFC_PG_TYPE_DIF_BUF: | ||
2738 | /* | 2778 | /* |
2739 | * This type indicates that protection buffers are | 2779 | * This type indicates that protection buffers are |
2740 | * passed to the driver, so that needs to be prepared | 2780 | * passed to the driver, so that needs to be prepared |
@@ -2749,31 +2789,28 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, | |||
2749 | } | 2789 | } |
2750 | 2790 | ||
2751 | lpfc_cmd->prot_seg_cnt = protsegcnt; | 2791 | lpfc_cmd->prot_seg_cnt = protsegcnt; |
2752 | if (lpfc_cmd->prot_seg_cnt | 2792 | |
2753 | > phba->cfg_prot_sg_seg_cnt) { | 2793 | /* |
2754 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 2794 | * There is a minimun of 4 BPLs used for every |
2755 | "9068 BLKGRD: %s: Too many prot sg " | 2795 | * protection data segment. |
2756 | "segments from dma_map_sg. Config %d," | 2796 | */ |
2757 | "prot_seg_cnt %d\n", __func__, | 2797 | if ((lpfc_cmd->prot_seg_cnt * 4) > |
2758 | phba->cfg_prot_sg_seg_cnt, | 2798 | (phba->cfg_total_seg_cnt - 2)) |
2759 | lpfc_cmd->prot_seg_cnt); | 2799 | goto err; |
2760 | dma_unmap_sg(&phba->pcidev->dev, | ||
2761 | scsi_prot_sglist(scsi_cmnd), | ||
2762 | scsi_prot_sg_count(scsi_cmnd), | ||
2763 | datadir); | ||
2764 | scsi_dma_unmap(scsi_cmnd); | ||
2765 | return 1; | ||
2766 | } | ||
2767 | 2800 | ||
2768 | num_bde = lpfc_bg_setup_bpl_prot(phba, scsi_cmnd, bpl, | 2801 | num_bde = lpfc_bg_setup_bpl_prot(phba, scsi_cmnd, bpl, |
2769 | datasegcnt, protsegcnt); | 2802 | datasegcnt, protsegcnt); |
2770 | /* we should have 3 or more entries in buffer list */ | 2803 | /* we should have 3 or more entries in buffer list */ |
2771 | if (num_bde < 3) | 2804 | if ((num_bde < 3) || |
2805 | (num_bde > phba->cfg_total_seg_cnt)) | ||
2772 | goto err; | 2806 | goto err; |
2773 | break; | 2807 | break; |
2774 | } | 2808 | |
2775 | case LPFC_PG_TYPE_INVALID: | 2809 | case LPFC_PG_TYPE_INVALID: |
2776 | default: | 2810 | default: |
2811 | scsi_dma_unmap(scsi_cmnd); | ||
2812 | lpfc_cmd->seg_cnt = 0; | ||
2813 | |||
2777 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 2814 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
2778 | "9022 Unexpected protection group %i\n", | 2815 | "9022 Unexpected protection group %i\n", |
2779 | prot_group_type); | 2816 | prot_group_type); |
@@ -2814,10 +2851,22 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, | |||
2814 | 2851 | ||
2815 | return 0; | 2852 | return 0; |
2816 | err: | 2853 | err: |
2854 | if (lpfc_cmd->seg_cnt) | ||
2855 | scsi_dma_unmap(scsi_cmnd); | ||
2856 | if (lpfc_cmd->prot_seg_cnt) | ||
2857 | dma_unmap_sg(&phba->pcidev->dev, scsi_prot_sglist(scsi_cmnd), | ||
2858 | scsi_prot_sg_count(scsi_cmnd), | ||
2859 | scsi_cmnd->sc_data_direction); | ||
2860 | |||
2817 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 2861 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
2818 | "9023 Could not setup all needed BDE's" | 2862 | "9023 Cannot setup S/G List for HBA" |
2819 | "prot_group_type=%d, num_bde=%d\n", | 2863 | "IO segs %d/%d BPL %d SCSI %d: %d %d\n", |
2864 | lpfc_cmd->seg_cnt, lpfc_cmd->prot_seg_cnt, | ||
2865 | phba->cfg_total_seg_cnt, phba->cfg_sg_seg_cnt, | ||
2820 | prot_group_type, num_bde); | 2866 | prot_group_type, num_bde); |
2867 | |||
2868 | lpfc_cmd->seg_cnt = 0; | ||
2869 | lpfc_cmd->prot_seg_cnt = 0; | ||
2821 | return 1; | 2870 | return 1; |
2822 | } | 2871 | } |
2823 | 2872 | ||
@@ -3255,6 +3304,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
3255 | "dma_map_sg. Config %d, seg_cnt %d\n", | 3304 | "dma_map_sg. Config %d, seg_cnt %d\n", |
3256 | __func__, phba->cfg_sg_seg_cnt, | 3305 | __func__, phba->cfg_sg_seg_cnt, |
3257 | lpfc_cmd->seg_cnt); | 3306 | lpfc_cmd->seg_cnt); |
3307 | lpfc_cmd->seg_cnt = 0; | ||
3258 | scsi_dma_unmap(scsi_cmnd); | 3308 | scsi_dma_unmap(scsi_cmnd); |
3259 | return 1; | 3309 | return 1; |
3260 | } | 3310 | } |
@@ -3376,14 +3426,14 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, | |||
3376 | struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; | 3426 | struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; |
3377 | struct sli4_sge *sgl = (struct sli4_sge *)(lpfc_cmd->fcp_bpl); | 3427 | struct sli4_sge *sgl = (struct sli4_sge *)(lpfc_cmd->fcp_bpl); |
3378 | IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; | 3428 | IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; |
3379 | uint32_t num_bde = 0; | 3429 | uint32_t num_sge = 0; |
3380 | int datasegcnt, protsegcnt, datadir = scsi_cmnd->sc_data_direction; | 3430 | int datasegcnt, protsegcnt, datadir = scsi_cmnd->sc_data_direction; |
3381 | int prot_group_type = 0; | 3431 | int prot_group_type = 0; |
3382 | int fcpdl; | 3432 | int fcpdl; |
3383 | 3433 | ||
3384 | /* | 3434 | /* |
3385 | * Start the lpfc command prep by bumping the sgl beyond fcp_cmnd | 3435 | * Start the lpfc command prep by bumping the sgl beyond fcp_cmnd |
3386 | * fcp_rsp regions to the first data bde entry | 3436 | * fcp_rsp regions to the first data sge entry |
3387 | */ | 3437 | */ |
3388 | if (scsi_sg_count(scsi_cmnd)) { | 3438 | if (scsi_sg_count(scsi_cmnd)) { |
3389 | /* | 3439 | /* |
@@ -3406,28 +3456,28 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, | |||
3406 | 3456 | ||
3407 | sgl += 1; | 3457 | sgl += 1; |
3408 | lpfc_cmd->seg_cnt = datasegcnt; | 3458 | lpfc_cmd->seg_cnt = datasegcnt; |
3409 | if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { | 3459 | |
3410 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 3460 | /* First check if data segment count from SCSI Layer is good */ |
3411 | "9087 BLKGRD: %s: Too many sg segments" | 3461 | if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) |
3412 | " from dma_map_sg. Config %d, seg_cnt" | 3462 | goto err; |
3413 | " %d\n", | ||
3414 | __func__, phba->cfg_sg_seg_cnt, | ||
3415 | lpfc_cmd->seg_cnt); | ||
3416 | scsi_dma_unmap(scsi_cmnd); | ||
3417 | return 1; | ||
3418 | } | ||
3419 | 3463 | ||
3420 | prot_group_type = lpfc_prot_group_type(phba, scsi_cmnd); | 3464 | prot_group_type = lpfc_prot_group_type(phba, scsi_cmnd); |
3421 | 3465 | ||
3422 | switch (prot_group_type) { | 3466 | switch (prot_group_type) { |
3423 | case LPFC_PG_TYPE_NO_DIF: | 3467 | case LPFC_PG_TYPE_NO_DIF: |
3424 | num_bde = lpfc_bg_setup_sgl(phba, scsi_cmnd, sgl, | 3468 | /* Here we need to add a DISEED to the count */ |
3469 | if ((lpfc_cmd->seg_cnt + 1) > phba->cfg_total_seg_cnt) | ||
3470 | goto err; | ||
3471 | |||
3472 | num_sge = lpfc_bg_setup_sgl(phba, scsi_cmnd, sgl, | ||
3425 | datasegcnt); | 3473 | datasegcnt); |
3474 | |||
3426 | /* we should have 2 or more entries in buffer list */ | 3475 | /* we should have 2 or more entries in buffer list */ |
3427 | if (num_bde < 2) | 3476 | if (num_sge < 2) |
3428 | goto err; | 3477 | goto err; |
3429 | break; | 3478 | break; |
3430 | case LPFC_PG_TYPE_DIF_BUF:{ | 3479 | |
3480 | case LPFC_PG_TYPE_DIF_BUF: | ||
3431 | /* | 3481 | /* |
3432 | * This type indicates that protection buffers are | 3482 | * This type indicates that protection buffers are |
3433 | * passed to the driver, so that needs to be prepared | 3483 | * passed to the driver, so that needs to be prepared |
@@ -3442,31 +3492,28 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, | |||
3442 | } | 3492 | } |
3443 | 3493 | ||
3444 | lpfc_cmd->prot_seg_cnt = protsegcnt; | 3494 | lpfc_cmd->prot_seg_cnt = protsegcnt; |
3445 | if (lpfc_cmd->prot_seg_cnt | 3495 | /* |
3446 | > phba->cfg_prot_sg_seg_cnt) { | 3496 | * There is a minimun of 3 SGEs used for every |
3447 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 3497 | * protection data segment. |
3448 | "9088 BLKGRD: %s: Too many prot sg " | 3498 | */ |
3449 | "segments from dma_map_sg. Config %d," | 3499 | if ((lpfc_cmd->prot_seg_cnt * 3) > |
3450 | "prot_seg_cnt %d\n", __func__, | 3500 | (phba->cfg_total_seg_cnt - 2)) |
3451 | phba->cfg_prot_sg_seg_cnt, | 3501 | goto err; |
3452 | lpfc_cmd->prot_seg_cnt); | ||
3453 | dma_unmap_sg(&phba->pcidev->dev, | ||
3454 | scsi_prot_sglist(scsi_cmnd), | ||
3455 | scsi_prot_sg_count(scsi_cmnd), | ||
3456 | datadir); | ||
3457 | scsi_dma_unmap(scsi_cmnd); | ||
3458 | return 1; | ||
3459 | } | ||
3460 | 3502 | ||
3461 | num_bde = lpfc_bg_setup_sgl_prot(phba, scsi_cmnd, sgl, | 3503 | num_sge = lpfc_bg_setup_sgl_prot(phba, scsi_cmnd, sgl, |
3462 | datasegcnt, protsegcnt); | 3504 | datasegcnt, protsegcnt); |
3505 | |||
3463 | /* we should have 3 or more entries in buffer list */ | 3506 | /* we should have 3 or more entries in buffer list */ |
3464 | if (num_bde < 3) | 3507 | if ((num_sge < 3) || |
3508 | (num_sge > phba->cfg_total_seg_cnt)) | ||
3465 | goto err; | 3509 | goto err; |
3466 | break; | 3510 | break; |
3467 | } | 3511 | |
3468 | case LPFC_PG_TYPE_INVALID: | 3512 | case LPFC_PG_TYPE_INVALID: |
3469 | default: | 3513 | default: |
3514 | scsi_dma_unmap(scsi_cmnd); | ||
3515 | lpfc_cmd->seg_cnt = 0; | ||
3516 | |||
3470 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 3517 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
3471 | "9083 Unexpected protection group %i\n", | 3518 | "9083 Unexpected protection group %i\n", |
3472 | prot_group_type); | 3519 | prot_group_type); |
@@ -3501,10 +3548,22 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, | |||
3501 | 3548 | ||
3502 | return 0; | 3549 | return 0; |
3503 | err: | 3550 | err: |
3551 | if (lpfc_cmd->seg_cnt) | ||
3552 | scsi_dma_unmap(scsi_cmnd); | ||
3553 | if (lpfc_cmd->prot_seg_cnt) | ||
3554 | dma_unmap_sg(&phba->pcidev->dev, scsi_prot_sglist(scsi_cmnd), | ||
3555 | scsi_prot_sg_count(scsi_cmnd), | ||
3556 | scsi_cmnd->sc_data_direction); | ||
3557 | |||
3504 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 3558 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
3505 | "9084 Could not setup all needed BDE's" | 3559 | "9084 Cannot setup S/G List for HBA" |
3506 | "prot_group_type=%d, num_bde=%d\n", | 3560 | "IO segs %d/%d SGL %d SCSI %d: %d %d\n", |
3507 | prot_group_type, num_bde); | 3561 | lpfc_cmd->seg_cnt, lpfc_cmd->prot_seg_cnt, |
3562 | phba->cfg_total_seg_cnt, phba->cfg_sg_seg_cnt, | ||
3563 | prot_group_type, num_sge); | ||
3564 | |||
3565 | lpfc_cmd->seg_cnt = 0; | ||
3566 | lpfc_cmd->prot_seg_cnt = 0; | ||
3508 | return 1; | 3567 | return 1; |
3509 | } | 3568 | } |
3510 | 3569 | ||
@@ -5317,11 +5376,11 @@ lpfc_slave_alloc(struct scsi_device *sdev) | |||
5317 | } | 5376 | } |
5318 | num_allocated = lpfc_new_scsi_buf(vport, num_to_alloc); | 5377 | num_allocated = lpfc_new_scsi_buf(vport, num_to_alloc); |
5319 | if (num_to_alloc != num_allocated) { | 5378 | if (num_to_alloc != num_allocated) { |
5320 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, | 5379 | lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, |
5321 | "0708 Allocation request of %d " | 5380 | "0708 Allocation request of %d " |
5322 | "command buffers did not succeed. " | 5381 | "command buffers did not succeed. " |
5323 | "Allocated %d buffers.\n", | 5382 | "Allocated %d buffers.\n", |
5324 | num_to_alloc, num_allocated); | 5383 | num_to_alloc, num_allocated); |
5325 | } | 5384 | } |
5326 | if (num_allocated > 0) | 5385 | if (num_allocated > 0) |
5327 | phba->total_scsi_bufs += num_allocated; | 5386 | phba->total_scsi_bufs += num_allocated; |