diff options
author | Jayamohan Kallickal <jayamohank@gmail.com> | 2013-09-28 18:35:49 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-10-25 04:58:07 -0400 |
commit | 0a3db7c0a3e566e872aa9b0ac2eaf1353be7ffcc (patch) | |
tree | a094e411c38e34925e0067d6ed79c26ea9f744bc | |
parent | 4eea99d55da137c1f5aaccba7c24539e6467305d (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.c | 54 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 108 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 20 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 16 |
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 | */ |
965 | static int beiscsi_get_cid(struct beiscsi_hba *phba) | 965 | static 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 | */ |
984 | static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) | 1000 | static 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 | ||
4080 | static int hba_setup_cid_tbls(struct beiscsi_hba *phba) | 4080 | static 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 | |||
4165 | free_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 | ||
4124 | static void hwi_enable_intr(struct beiscsi_hba *phba) | 4181 | static void hwi_enable_intr(struct beiscsi_hba *phba) |
@@ -4373,7 +4430,8 @@ static void hwi_purge_eq(struct beiscsi_hba *phba) | |||
4373 | 4430 | ||
4374 | static void beiscsi_clean_port(struct beiscsi_hba *phba) | 4431 | static 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 | ||
300 | struct 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 | |||
310 | struct beiscsi_hba { | 325 | struct 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 | /** |