aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJayamohan Kallickal <jayamohank@gmail.com>2013-09-28 18:35:49 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-10-25 04:58:07 -0400
commit0a3db7c0a3e566e872aa9b0ac2eaf1353be7ffcc (patch)
treea094e411c38e34925e0067d6ed79c26ea9f744bc
parent4eea99d55da137c1f5aaccba7c24539e6467305d (diff)
[SCSI] be2iscsi: Fix CID allocation/freeing to support Dual chute mode
Configuration parameters returns the number of connection that can be offloaded one each chute. 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>
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c54
-rw-r--r--drivers/scsi/be2iscsi/be_main.c108
-rw-r--r--drivers/scsi/be2iscsi/be_main.h20
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c16
4 files changed, 160 insertions, 38 deletions
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index f698f7aa7ef9..63b2be0f58a8 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -964,15 +964,31 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
964 */ 964 */
965static int beiscsi_get_cid(struct beiscsi_hba *phba) 965static int beiscsi_get_cid(struct beiscsi_hba *phba)
966{ 966{
967 unsigned short cid = 0xFFFF; 967 unsigned short cid = 0xFFFF, cid_from_ulp;
968 968 struct ulp_cid_info *cid_info = NULL;
969 if (!phba->avlbl_cids) 969 uint16_t cid_avlbl_ulp0, cid_avlbl_ulp1;
970 return cid; 970
971 971 /* Find the ULP which has more CID available */
972 cid = phba->cid_array[phba->cid_alloc++]; 972 cid_avlbl_ulp0 = (phba->cid_array_info[BEISCSI_ULP0]) ?
973 if (phba->cid_alloc == phba->params.cxns_per_ctrl) 973 BEISCSI_ULP0_AVLBL_CID(phba) : 0;
974 phba->cid_alloc = 0; 974 cid_avlbl_ulp1 = (phba->cid_array_info[BEISCSI_ULP1]) ?
975 phba->avlbl_cids--; 975 BEISCSI_ULP1_AVLBL_CID(phba) : 0;
976 cid_from_ulp = (cid_avlbl_ulp0 > cid_avlbl_ulp1) ?
977 BEISCSI_ULP0 : BEISCSI_ULP1;
978
979 if (test_bit(cid_from_ulp, (void *)&phba->fw_config.ulp_supported)) {
980 cid_info = phba->cid_array_info[cid_from_ulp];
981 if (!cid_info->avlbl_cids)
982 return cid;
983
984 cid = cid_info->cid_array[cid_info->cid_alloc++];
985
986 if (cid_info->cid_alloc == BEISCSI_GET_CID_COUNT(
987 phba, cid_from_ulp))
988 cid_info->cid_alloc = 0;
989
990 cid_info->avlbl_cids--;
991 }
976 return cid; 992 return cid;
977} 993}
978 994
@@ -983,10 +999,22 @@ static int beiscsi_get_cid(struct beiscsi_hba *phba)
983 */ 999 */
984static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) 1000static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
985{ 1001{
986 phba->avlbl_cids++; 1002 uint16_t cid_post_ulp;
987 phba->cid_array[phba->cid_free++] = cid; 1003 struct hwi_controller *phwi_ctrlr;
988 if (phba->cid_free == phba->params.cxns_per_ctrl) 1004 struct hwi_wrb_context *pwrb_context;
989 phba->cid_free = 0; 1005 struct ulp_cid_info *cid_info = NULL;
1006 uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
1007
1008 phwi_ctrlr = phba->phwi_ctrlr;
1009 pwrb_context = &phwi_ctrlr->wrb_context[cri_index];
1010 cid_post_ulp = pwrb_context->ulp_num;
1011
1012 cid_info = phba->cid_array_info[cid_post_ulp];
1013 cid_info->avlbl_cids++;
1014
1015 cid_info->cid_array[cid_info->cid_free++] = cid;
1016 if (cid_info->cid_free == BEISCSI_GET_CID_COUNT(phba, cid_post_ulp))
1017 cid_info->cid_free = 0;
990} 1018}
991 1019
992/** 1020/**
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 8595908e62dc..b57e5bd62018 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -4079,15 +4079,46 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
4079 4079
4080static int hba_setup_cid_tbls(struct beiscsi_hba *phba) 4080static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
4081{ 4081{
4082 int i; 4082 int ret;
4083 uint16_t i, ulp_num;
4084 struct ulp_cid_info *ptr_cid_info = NULL;
4083 4085
4084 phba->cid_array = kzalloc(sizeof(void *) * phba->params.cxns_per_ctrl, 4086 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
4085 GFP_KERNEL); 4087 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
4086 if (!phba->cid_array) { 4088 ptr_cid_info = kzalloc(sizeof(struct ulp_cid_info),
4087 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 4089 GFP_KERNEL);
4088 "BM_%d : Failed to allocate memory in " 4090
4089 "hba_setup_cid_tbls\n"); 4091 if (!ptr_cid_info) {
4090 return -ENOMEM; 4092 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
4093 "BM_%d : Failed to allocate memory"
4094 "for ULP_CID_INFO for ULP : %d\n",
4095 ulp_num);
4096 ret = -ENOMEM;
4097 goto free_memory;
4098
4099 }
4100
4101 /* Allocate memory for CID array */
4102 ptr_cid_info->cid_array = kzalloc(sizeof(void *) *
4103 BEISCSI_GET_CID_COUNT(phba,
4104 ulp_num), GFP_KERNEL);
4105 if (!ptr_cid_info->cid_array) {
4106 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
4107 "BM_%d : Failed to allocate memory"
4108 "for CID_ARRAY for ULP : %d\n",
4109 ulp_num);
4110 kfree(ptr_cid_info);
4111 ptr_cid_info = NULL;
4112 ret = -ENOMEM;
4113
4114 goto free_memory;
4115 }
4116 ptr_cid_info->avlbl_cids = BEISCSI_GET_CID_COUNT(
4117 phba, ulp_num);
4118
4119 /* Save the cid_info_array ptr */
4120 phba->cid_array_info[ulp_num] = ptr_cid_info;
4121 }
4091 } 4122 }
4092 phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) * 4123 phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) *
4093 phba->params.cxns_per_ctrl, GFP_KERNEL); 4124 phba->params.cxns_per_ctrl, GFP_KERNEL);
@@ -4095,9 +4126,9 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
4095 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 4126 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
4096 "BM_%d : Failed to allocate memory in " 4127 "BM_%d : Failed to allocate memory in "
4097 "hba_setup_cid_tbls\n"); 4128 "hba_setup_cid_tbls\n");
4098 kfree(phba->cid_array); 4129 ret = -ENOMEM;
4099 phba->cid_array = NULL; 4130
4100 return -ENOMEM; 4131 goto free_memory;
4101 } 4132 }
4102 4133
4103 phba->conn_table = kzalloc(sizeof(struct beiscsi_conn *) * 4134 phba->conn_table = kzalloc(sizeof(struct beiscsi_conn *) *
@@ -4107,18 +4138,44 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
4107 "BM_%d : Failed to allocate memory in" 4138 "BM_%d : Failed to allocate memory in"
4108 "hba_setup_cid_tbls\n"); 4139 "hba_setup_cid_tbls\n");
4109 4140
4110 kfree(phba->cid_array);
4111 kfree(phba->ep_array); 4141 kfree(phba->ep_array);
4112 phba->cid_array = NULL;
4113 phba->ep_array = NULL; 4142 phba->ep_array = NULL;
4114 return -ENOMEM; 4143 ret = -ENOMEM;
4115 } 4144 }
4116 4145
4117 for (i = 0; i < phba->params.cxns_per_ctrl; i++) 4146 for (i = 0; i < phba->params.cxns_per_ctrl; i++) {
4118 phba->cid_array[i] = phba->phwi_ctrlr->wrb_context[i].cid; 4147 ulp_num = phba->phwi_ctrlr->wrb_context[i].ulp_num;
4148
4149 ptr_cid_info = phba->cid_array_info[ulp_num];
4150 ptr_cid_info->cid_array[ptr_cid_info->cid_alloc++] =
4151 phba->phwi_ctrlr->wrb_context[i].cid;
4152
4153 }
4154
4155 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
4156 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
4157 ptr_cid_info = phba->cid_array_info[ulp_num];
4119 4158
4120 phba->avlbl_cids = phba->params.cxns_per_ctrl; 4159 ptr_cid_info->cid_alloc = 0;
4160 ptr_cid_info->cid_free = 0;
4161 }
4162 }
4121 return 0; 4163 return 0;
4164
4165free_memory:
4166 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
4167 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
4168 ptr_cid_info = phba->cid_array_info[ulp_num];
4169
4170 if (ptr_cid_info) {
4171 kfree(ptr_cid_info->cid_array);
4172 kfree(ptr_cid_info);
4173 phba->cid_array_info[ulp_num] = NULL;
4174 }
4175 }
4176 }
4177
4178 return ret;
4122} 4179}
4123 4180
4124static void hwi_enable_intr(struct beiscsi_hba *phba) 4181static void hwi_enable_intr(struct beiscsi_hba *phba)
@@ -4373,7 +4430,8 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
4373 4430
4374static void beiscsi_clean_port(struct beiscsi_hba *phba) 4431static void beiscsi_clean_port(struct beiscsi_hba *phba)
4375{ 4432{
4376 int mgmt_status; 4433 int mgmt_status, ulp_num;
4434 struct ulp_cid_info *ptr_cid_info = NULL;
4377 4435
4378 mgmt_status = mgmt_epfw_cleanup(phba, CMD_CONNECTION_CHUTE_0); 4436 mgmt_status = mgmt_epfw_cleanup(phba, CMD_CONNECTION_CHUTE_0);
4379 if (mgmt_status) 4437 if (mgmt_status)
@@ -4384,9 +4442,21 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba)
4384 hwi_cleanup(phba); 4442 hwi_cleanup(phba);
4385 kfree(phba->io_sgl_hndl_base); 4443 kfree(phba->io_sgl_hndl_base);
4386 kfree(phba->eh_sgl_hndl_base); 4444 kfree(phba->eh_sgl_hndl_base);
4387 kfree(phba->cid_array);
4388 kfree(phba->ep_array); 4445 kfree(phba->ep_array);
4389 kfree(phba->conn_table); 4446 kfree(phba->conn_table);
4447
4448 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
4449 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
4450 ptr_cid_info = phba->cid_array_info[ulp_num];
4451
4452 if (ptr_cid_info) {
4453 kfree(ptr_cid_info->cid_array);
4454 kfree(ptr_cid_info);
4455 phba->cid_array_info[ulp_num] = NULL;
4456 }
4457 }
4458 }
4459
4390} 4460}
4391 4461
4392/** 4462/**
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 410efc72bfd9..e5e0d7e32f04 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -297,6 +297,13 @@ struct hwi_wrb_context {
297 uint32_t doorbell_offset; 297 uint32_t doorbell_offset;
298}; 298};
299 299
300struct ulp_cid_info {
301 unsigned short *cid_array;
302 unsigned short avlbl_cids;
303 unsigned short cid_alloc;
304 unsigned short cid_free;
305};
306
300#include "be.h" 307#include "be.h"
301#define chip_be2(phba) (phba->generation == BE_GEN2) 308#define chip_be2(phba) (phba->generation == BE_GEN2)
302#define chip_be3_r(phba) (phba->generation == BE_GEN3) 309#define chip_be3_r(phba) (phba->generation == BE_GEN3)
@@ -307,6 +314,14 @@ struct hwi_wrb_context {
307#define BEISCSI_ULP_COUNT 2 314#define BEISCSI_ULP_COUNT 2
308#define BEISCSI_ULP0_LOADED 0x01 315#define BEISCSI_ULP0_LOADED 0x01
309#define BEISCSI_ULP1_LOADED 0x02 316#define BEISCSI_ULP1_LOADED 0x02
317
318#define BEISCSI_ULP_AVLBL_CID(phba, ulp_num) \
319 (((struct ulp_cid_info *)phba->cid_array_info[ulp_num])->avlbl_cids)
320#define BEISCSI_ULP0_AVLBL_CID(phba) \
321 BEISCSI_ULP_AVLBL_CID(phba, BEISCSI_ULP0)
322#define BEISCSI_ULP1_AVLBL_CID(phba) \
323 BEISCSI_ULP_AVLBL_CID(phba, BEISCSI_ULP1)
324
310struct beiscsi_hba { 325struct beiscsi_hba {
311 struct hba_parameters params; 326 struct hba_parameters params;
312 struct hwi_controller *phwi_ctrlr; 327 struct hwi_controller *phwi_ctrlr;
@@ -343,16 +358,13 @@ struct beiscsi_hba {
343 spinlock_t isr_lock; 358 spinlock_t isr_lock;
344 spinlock_t async_pdu_lock; 359 spinlock_t async_pdu_lock;
345 unsigned int age; 360 unsigned int age;
346 unsigned short avlbl_cids;
347 unsigned short cid_alloc;
348 unsigned short cid_free;
349 struct list_head hba_queue; 361 struct list_head hba_queue;
350#define BE_MAX_SESSION 2048 362#define BE_MAX_SESSION 2048
351#define BE_SET_CID_TO_CRI(cri_index, cid) \ 363#define BE_SET_CID_TO_CRI(cri_index, cid) \
352 (phba->cid_to_cri_map[cid] = cri_index) 364 (phba->cid_to_cri_map[cid] = cri_index)
353#define BE_GET_CRI_FROM_CID(cid) (phba->cid_to_cri_map[cid]) 365#define BE_GET_CRI_FROM_CID(cid) (phba->cid_to_cri_map[cid])
354 unsigned short cid_to_cri_map[BE_MAX_SESSION]; 366 unsigned short cid_to_cri_map[BE_MAX_SESSION];
355 unsigned short *cid_array; 367 struct ulp_cid_info *cid_array_info[BEISCSI_ULP_COUNT];
356 struct iscsi_endpoint **ep_array; 368 struct iscsi_endpoint **ep_array;
357 struct beiscsi_conn **conn_table; 369 struct beiscsi_conn **conn_table;
358 struct iscsi_boot_kset *boot_kset; 370 struct iscsi_boot_kset *boot_kset;
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 75756d722538..fcb9976e5ec6 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -1338,9 +1338,21 @@ beiscsi_active_cid_disp(struct device *dev, struct device_attribute *attr,
1338{ 1338{
1339 struct Scsi_Host *shost = class_to_shost(dev); 1339 struct Scsi_Host *shost = class_to_shost(dev);
1340 struct beiscsi_hba *phba = iscsi_host_priv(shost); 1340 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1341 uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1342
1343 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1344 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1345 avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1346 total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1347 len += snprintf(buf+len, PAGE_SIZE - len,
1348 "ULP%d : %d\n", ulp_num,
1349 (total_cids - avlbl_cids));
1350 } else
1351 len += snprintf(buf+len, PAGE_SIZE - len,
1352 "ULP%d : %d\n", ulp_num, 0);
1353 }
1341 1354
1342 return snprintf(buf, PAGE_SIZE, "%d\n", 1355 return len;
1343 (phba->params.cxns_per_ctrl - phba->avlbl_cids));
1344} 1356}
1345 1357
1346/** 1358/**