diff options
author | Jayamohan Kallickal <jayamohan.kallickal@emulex.com> | 2012-04-04 00:41:38 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-04-25 04:00:38 -0400 |
commit | 3ec7827134a976a3ffffd9e438b8d8dfd6eca9b7 (patch) | |
tree | 4dbe09ed1709e5937f08ae76012a25d272237da6 /drivers/scsi/be2iscsi | |
parent | f2ba02b89a1bfccb152302fa01651e21d98e9d1b (diff) |
[SCSI] be2iscsi: WRB Initialization and Failure code path change
Removing code duplication during the WRB_Handle and WRB
initialization.
Added memory allocation failure handling code during WRB
initialization.
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 98 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.h | 4 |
2 files changed, 49 insertions, 53 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index fef6f073c4ab..23344c8c5b79 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -2211,7 +2211,7 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) | |||
2211 | struct mem_array *mem_arr, *mem_arr_orig; | 2211 | struct mem_array *mem_arr, *mem_arr_orig; |
2212 | unsigned int i, j, alloc_size, curr_alloc_size; | 2212 | unsigned int i, j, alloc_size, curr_alloc_size; |
2213 | 2213 | ||
2214 | phba->phwi_ctrlr = kmalloc(phba->params.hwi_ws_sz, GFP_KERNEL); | 2214 | phba->phwi_ctrlr = kzalloc(phba->params.hwi_ws_sz, GFP_KERNEL); |
2215 | if (!phba->phwi_ctrlr) | 2215 | if (!phba->phwi_ctrlr) |
2216 | return -ENOMEM; | 2216 | return -ENOMEM; |
2217 | 2217 | ||
@@ -2331,27 +2331,21 @@ static void iscsi_init_global_templates(struct beiscsi_hba *phba) | |||
2331 | AMAP_SET_BITS(struct amap_pdu_nop_out, i_bit, pnop_out, 0); | 2331 | AMAP_SET_BITS(struct amap_pdu_nop_out, i_bit, pnop_out, 0); |
2332 | } | 2332 | } |
2333 | 2333 | ||
2334 | static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) | 2334 | static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) |
2335 | { | 2335 | { |
2336 | struct be_mem_descriptor *mem_descr_wrbh, *mem_descr_wrb; | 2336 | struct be_mem_descriptor *mem_descr_wrbh, *mem_descr_wrb; |
2337 | struct wrb_handle *pwrb_handle; | 2337 | struct wrb_handle *pwrb_handle = NULL; |
2338 | struct hwi_controller *phwi_ctrlr; | 2338 | struct hwi_controller *phwi_ctrlr; |
2339 | struct hwi_wrb_context *pwrb_context; | 2339 | struct hwi_wrb_context *pwrb_context; |
2340 | struct iscsi_wrb *pwrb; | 2340 | struct iscsi_wrb *pwrb = NULL; |
2341 | unsigned int num_cxn_wrbh; | 2341 | unsigned int num_cxn_wrbh = 0; |
2342 | unsigned int num_cxn_wrb, j, idx, index; | 2342 | unsigned int num_cxn_wrb = 0, j, idx = 0, index; |
2343 | 2343 | ||
2344 | mem_descr_wrbh = phba->init_mem; | 2344 | mem_descr_wrbh = phba->init_mem; |
2345 | mem_descr_wrbh += HWI_MEM_WRBH; | 2345 | mem_descr_wrbh += HWI_MEM_WRBH; |
2346 | 2346 | ||
2347 | mem_descr_wrb = phba->init_mem; | 2347 | mem_descr_wrb = phba->init_mem; |
2348 | mem_descr_wrb += HWI_MEM_WRB; | 2348 | mem_descr_wrb += HWI_MEM_WRB; |
2349 | |||
2350 | idx = 0; | ||
2351 | pwrb_handle = mem_descr_wrbh->mem_array[idx].virtual_address; | ||
2352 | num_cxn_wrbh = ((mem_descr_wrbh->mem_array[idx].size) / | ||
2353 | ((sizeof(struct wrb_handle)) * | ||
2354 | phba->params.wrbs_per_cxn)); | ||
2355 | phwi_ctrlr = phba->phwi_ctrlr; | 2349 | phwi_ctrlr = phba->phwi_ctrlr; |
2356 | 2350 | ||
2357 | for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { | 2351 | for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { |
@@ -2359,12 +2353,32 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) | |||
2359 | pwrb_context->pwrb_handle_base = | 2353 | pwrb_context->pwrb_handle_base = |
2360 | kzalloc(sizeof(struct wrb_handle *) * | 2354 | kzalloc(sizeof(struct wrb_handle *) * |
2361 | phba->params.wrbs_per_cxn, GFP_KERNEL); | 2355 | phba->params.wrbs_per_cxn, GFP_KERNEL); |
2356 | if (!pwrb_context->pwrb_handle_base) { | ||
2357 | shost_printk(KERN_ERR, phba->shost, | ||
2358 | "Mem Alloc Failed. Failing to load\n"); | ||
2359 | goto init_wrb_hndl_failed; | ||
2360 | } | ||
2362 | pwrb_context->pwrb_handle_basestd = | 2361 | pwrb_context->pwrb_handle_basestd = |
2363 | kzalloc(sizeof(struct wrb_handle *) * | 2362 | kzalloc(sizeof(struct wrb_handle *) * |
2364 | phba->params.wrbs_per_cxn, GFP_KERNEL); | 2363 | phba->params.wrbs_per_cxn, GFP_KERNEL); |
2364 | if (!pwrb_context->pwrb_handle_basestd) { | ||
2365 | shost_printk(KERN_ERR, phba->shost, | ||
2366 | "Mem Alloc Failed. Failing to load\n"); | ||
2367 | goto init_wrb_hndl_failed; | ||
2368 | } | ||
2369 | if (!num_cxn_wrbh) { | ||
2370 | pwrb_handle = | ||
2371 | mem_descr_wrbh->mem_array[idx].virtual_address; | ||
2372 | num_cxn_wrbh = ((mem_descr_wrbh->mem_array[idx].size) / | ||
2373 | ((sizeof(struct wrb_handle)) * | ||
2374 | phba->params.wrbs_per_cxn)); | ||
2375 | idx++; | ||
2376 | } | ||
2377 | pwrb_context->alloc_index = 0; | ||
2378 | pwrb_context->wrb_handles_available = 0; | ||
2379 | pwrb_context->free_index = 0; | ||
2380 | |||
2365 | if (num_cxn_wrbh) { | 2381 | if (num_cxn_wrbh) { |
2366 | pwrb_context->alloc_index = 0; | ||
2367 | pwrb_context->wrb_handles_available = 0; | ||
2368 | for (j = 0; j < phba->params.wrbs_per_cxn; j++) { | 2382 | for (j = 0; j < phba->params.wrbs_per_cxn; j++) { |
2369 | pwrb_context->pwrb_handle_base[j] = pwrb_handle; | 2383 | pwrb_context->pwrb_handle_base[j] = pwrb_handle; |
2370 | pwrb_context->pwrb_handle_basestd[j] = | 2384 | pwrb_context->pwrb_handle_basestd[j] = |
@@ -2373,49 +2387,21 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) | |||
2373 | pwrb_handle->wrb_index = j; | 2387 | pwrb_handle->wrb_index = j; |
2374 | pwrb_handle++; | 2388 | pwrb_handle++; |
2375 | } | 2389 | } |
2376 | pwrb_context->free_index = 0; | ||
2377 | num_cxn_wrbh--; | ||
2378 | } else { | ||
2379 | idx++; | ||
2380 | pwrb_handle = | ||
2381 | mem_descr_wrbh->mem_array[idx].virtual_address; | ||
2382 | num_cxn_wrbh = | ||
2383 | ((mem_descr_wrbh->mem_array[idx].size) / | ||
2384 | ((sizeof(struct wrb_handle)) * | ||
2385 | phba->params.wrbs_per_cxn)); | ||
2386 | pwrb_context->alloc_index = 0; | ||
2387 | for (j = 0; j < phba->params.wrbs_per_cxn; j++) { | ||
2388 | pwrb_context->pwrb_handle_base[j] = pwrb_handle; | ||
2389 | pwrb_context->pwrb_handle_basestd[j] = | ||
2390 | pwrb_handle; | ||
2391 | pwrb_context->wrb_handles_available++; | ||
2392 | pwrb_handle->wrb_index = j; | ||
2393 | pwrb_handle++; | ||
2394 | } | ||
2395 | pwrb_context->free_index = 0; | ||
2396 | num_cxn_wrbh--; | 2390 | num_cxn_wrbh--; |
2397 | } | 2391 | } |
2398 | } | 2392 | } |
2399 | idx = 0; | 2393 | idx = 0; |
2400 | pwrb = mem_descr_wrb->mem_array[idx].virtual_address; | ||
2401 | num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / | ||
2402 | ((sizeof(struct iscsi_wrb) * | ||
2403 | phba->params.wrbs_per_cxn)); | ||
2404 | for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { | 2394 | for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { |
2405 | pwrb_context = &phwi_ctrlr->wrb_context[index]; | 2395 | pwrb_context = &phwi_ctrlr->wrb_context[index]; |
2406 | if (num_cxn_wrb) { | 2396 | if (!num_cxn_wrb) { |
2407 | for (j = 0; j < phba->params.wrbs_per_cxn; j++) { | ||
2408 | pwrb_handle = pwrb_context->pwrb_handle_base[j]; | ||
2409 | pwrb_handle->pwrb = pwrb; | ||
2410 | pwrb++; | ||
2411 | } | ||
2412 | num_cxn_wrb--; | ||
2413 | } else { | ||
2414 | idx++; | ||
2415 | pwrb = mem_descr_wrb->mem_array[idx].virtual_address; | 2397 | pwrb = mem_descr_wrb->mem_array[idx].virtual_address; |
2416 | num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / | 2398 | num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / |
2417 | ((sizeof(struct iscsi_wrb) * | 2399 | ((sizeof(struct iscsi_wrb) * |
2418 | phba->params.wrbs_per_cxn)); | 2400 | phba->params.wrbs_per_cxn)); |
2401 | idx++; | ||
2402 | } | ||
2403 | |||
2404 | if (num_cxn_wrb) { | ||
2419 | for (j = 0; j < phba->params.wrbs_per_cxn; j++) { | 2405 | for (j = 0; j < phba->params.wrbs_per_cxn; j++) { |
2420 | pwrb_handle = pwrb_context->pwrb_handle_base[j]; | 2406 | pwrb_handle = pwrb_context->pwrb_handle_base[j]; |
2421 | pwrb_handle->pwrb = pwrb; | 2407 | pwrb_handle->pwrb = pwrb; |
@@ -2424,6 +2410,14 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) | |||
2424 | num_cxn_wrb--; | 2410 | num_cxn_wrb--; |
2425 | } | 2411 | } |
2426 | } | 2412 | } |
2413 | return 0; | ||
2414 | init_wrb_hndl_failed: | ||
2415 | for (j = index; j > 0; j--) { | ||
2416 | pwrb_context = &phwi_ctrlr->wrb_context[j]; | ||
2417 | kfree(pwrb_context->pwrb_handle_base); | ||
2418 | kfree(pwrb_context->pwrb_handle_basestd); | ||
2419 | } | ||
2420 | return -ENOMEM; | ||
2427 | } | 2421 | } |
2428 | 2422 | ||
2429 | static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) | 2423 | static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) |
@@ -3237,7 +3231,9 @@ static int hwi_init_controller(struct beiscsi_hba *phba) | |||
3237 | } | 3231 | } |
3238 | 3232 | ||
3239 | iscsi_init_global_templates(phba); | 3233 | iscsi_init_global_templates(phba); |
3240 | beiscsi_init_wrb_handle(phba); | 3234 | if (beiscsi_init_wrb_handle(phba)) |
3235 | return -ENOMEM; | ||
3236 | |||
3241 | hwi_init_async_pdu_ctx(phba); | 3237 | hwi_init_async_pdu_ctx(phba); |
3242 | if (hwi_init_port(phba) != 0) { | 3238 | if (hwi_init_port(phba) != 0) { |
3243 | shost_printk(KERN_ERR, phba->shost, | 3239 | shost_printk(KERN_ERR, phba->shost, |
@@ -3824,7 +3820,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) | |||
3824 | task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr; | 3820 | task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr; |
3825 | task->hdr_max = sizeof(struct be_cmd_bhs); | 3821 | task->hdr_max = sizeof(struct be_cmd_bhs); |
3826 | io_task->psgl_handle = NULL; | 3822 | io_task->psgl_handle = NULL; |
3827 | io_task->psgl_handle = NULL; | 3823 | io_task->pwrb_handle = NULL; |
3828 | 3824 | ||
3829 | if (task->sc) { | 3825 | if (task->sc) { |
3830 | spin_lock(&phba->io_sgl_lock); | 3826 | spin_lock(&phba->io_sgl_lock); |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index 08428824ace2..d7fdfceb6564 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h | |||
@@ -219,9 +219,9 @@ struct be_mgmt_controller_attributes_resp { | |||
219 | /* the CMD_RESPONSE_HEADER */ | 219 | /* the CMD_RESPONSE_HEADER */ |
220 | 220 | ||
221 | #define ISCSI_GET_PDU_TEMPLATE_ADDRESS(pc, pa) {\ | 221 | #define ISCSI_GET_PDU_TEMPLATE_ADDRESS(pc, pa) {\ |
222 | pa->lo = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ | 222 | pa->lo = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ |
223 | bus_address.u.a32.address_lo; \ | 223 | bus_address.u.a32.address_lo; \ |
224 | pa->hi = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ | 224 | pa->hi = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ |
225 | bus_address.u.a32.address_hi; \ | 225 | bus_address.u.a32.address_hi; \ |
226 | } | 226 | } |
227 | 227 | ||