[SCSI] be2iscsi: Fix SGL posting for unaligned ICD values
authorJayamohan Kallickal <jayamohank@gmail.com>
Sat, 28 Sep 2013 22:35:59 +0000 (15:35 -0700)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 25 Oct 2013 08:58:10 +0000 (09:58 +0100)
If certain configuration it is possible that ICD range is not page-aligned.
SGL posting failed in these configuration and driver load was not success.
This fix aligns ICD range values and SGL posting for IO is done.

Signed-off-by: John Soni Jose <sony.john-n@emulex.com>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_mgmt.c

index d84ecc5317ff063e2d7c6ddc11bf63aef996eefe..1f375051483a428d24c63c206fb24a40cda06211 100644 (file)
@@ -729,13 +729,60 @@ static void beiscsi_get_params(struct beiscsi_hba *phba)
        total_cid_count = BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP0) +
                          BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP1);
 
-       for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
+       for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
+               uint32_t align_mask = 0;
+               uint32_t icd_post_per_page = 0;
+               uint32_t icd_count_unavailable = 0;
+               uint32_t icd_start = 0, icd_count = 0;
+               uint32_t icd_start_align = 0, icd_count_align = 0;
+
                if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
-                       total_icd_count = phba->fw_config.
-                                         iscsi_icd_count[ulp_num];
+                       icd_start = phba->fw_config.iscsi_icd_start[ulp_num];
+                       icd_count = phba->fw_config.iscsi_icd_count[ulp_num];
+
+                       /* Get ICD count that can be posted on each page */
+                       icd_post_per_page = (PAGE_SIZE / (BE2_SGE *
+                                            sizeof(struct iscsi_sge)));
+                       align_mask = (icd_post_per_page - 1);
+
+                       /* Check if icd_start is aligned ICD per page posting */
+                       if (icd_start % icd_post_per_page) {
+                               icd_start_align = ((icd_start +
+                                                   icd_post_per_page) &
+                                                   ~(align_mask));
+                               phba->fw_config.
+                                       iscsi_icd_start[ulp_num] =
+                                       icd_start_align;
+                       }
+
+                       icd_count_align = (icd_count & ~align_mask);
+
+                       /* ICD discarded in the process of alignment */
+                       if (icd_start_align)
+                               icd_count_unavailable = ((icd_start_align -
+                                                         icd_start) +
+                                                        (icd_count -
+                                                         icd_count_align));
+
+                       /* Updated ICD count available */
+                       phba->fw_config.iscsi_icd_count[ulp_num] = (icd_count -
+                                       icd_count_unavailable);
+
+                       beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+                                       "BM_%d : Aligned ICD values\n"
+                                       "\t ICD Start : %d\n"
+                                       "\t ICD Count : %d\n"
+                                       "\t ICD Discarded : %d\n",
+                                       phba->fw_config.
+                                       iscsi_icd_start[ulp_num],
+                                       phba->fw_config.
+                                       iscsi_icd_count[ulp_num],
+                                       icd_count_unavailable);
                        break;
                }
+       }
 
+       total_icd_count = phba->fw_config.iscsi_icd_count[ulp_num];
        phba->params.ios_per_ctrl = (total_icd_count -
                                    (total_cid_count +
                                     BE2_TMFS + BE2_NOPOUT_REQ));
index 1f2b546a3fc4467213b91065b6529b28c4ada86e..b2fcac78feaa995430fe62e4cd2587735313dabb 100644 (file)
@@ -350,12 +350,18 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
                                beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
                                            "BG_%d : Function loaded on ULP : %d\n"
                                            "\tiscsi_cid_count : %d\n"
-                                           "\t iscsi_icd_count : %d\n",
+                                           "\tiscsi_cid_start : %d\n"
+                                           "\t iscsi_icd_count : %d\n"
+                                           "\t iscsi_icd_start : %d\n",
                                            ulp_num,
                                            phba->fw_config.
                                            iscsi_cid_count[ulp_num],
                                            phba->fw_config.
-                                           iscsi_icd_count[ulp_num]);
+                                           iscsi_cid_start[ulp_num],
+                                           phba->fw_config.
+                                           iscsi_icd_count[ulp_num],
+                                           phba->fw_config.
+                                           iscsi_icd_start[ulp_num]);
                        }
                }