Commit 3ec78271 authored by Jayamohan Kallickal's avatar Jayamohan Kallickal Committed by James Bottomley

[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: default avatarJayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent f2ba02b8
...@@ -2211,7 +2211,7 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) ...@@ -2211,7 +2211,7 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba)
struct mem_array *mem_arr, *mem_arr_orig; struct mem_array *mem_arr, *mem_arr_orig;
unsigned int i, j, alloc_size, curr_alloc_size; unsigned int i, j, alloc_size, curr_alloc_size;
phba->phwi_ctrlr = kmalloc(phba->params.hwi_ws_sz, GFP_KERNEL); phba->phwi_ctrlr = kzalloc(phba->params.hwi_ws_sz, GFP_KERNEL);
if (!phba->phwi_ctrlr) if (!phba->phwi_ctrlr)
return -ENOMEM; return -ENOMEM;
...@@ -2331,27 +2331,21 @@ static void iscsi_init_global_templates(struct beiscsi_hba *phba) ...@@ -2331,27 +2331,21 @@ static void iscsi_init_global_templates(struct beiscsi_hba *phba)
AMAP_SET_BITS(struct amap_pdu_nop_out, i_bit, pnop_out, 0); AMAP_SET_BITS(struct amap_pdu_nop_out, i_bit, pnop_out, 0);
} }
static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
{ {
struct be_mem_descriptor *mem_descr_wrbh, *mem_descr_wrb; struct be_mem_descriptor *mem_descr_wrbh, *mem_descr_wrb;
struct wrb_handle *pwrb_handle; struct wrb_handle *pwrb_handle = NULL;
struct hwi_controller *phwi_ctrlr; struct hwi_controller *phwi_ctrlr;
struct hwi_wrb_context *pwrb_context; struct hwi_wrb_context *pwrb_context;
struct iscsi_wrb *pwrb; struct iscsi_wrb *pwrb = NULL;
unsigned int num_cxn_wrbh; unsigned int num_cxn_wrbh = 0;
unsigned int num_cxn_wrb, j, idx, index; unsigned int num_cxn_wrb = 0, j, idx = 0, index;
mem_descr_wrbh = phba->init_mem; mem_descr_wrbh = phba->init_mem;
mem_descr_wrbh += HWI_MEM_WRBH; mem_descr_wrbh += HWI_MEM_WRBH;
mem_descr_wrb = phba->init_mem; mem_descr_wrb = phba->init_mem;
mem_descr_wrb += HWI_MEM_WRB; mem_descr_wrb += HWI_MEM_WRB;
idx = 0;
pwrb_handle = mem_descr_wrbh->mem_array[idx].virtual_address;
num_cxn_wrbh = ((mem_descr_wrbh->mem_array[idx].size) /
((sizeof(struct wrb_handle)) *
phba->params.wrbs_per_cxn));
phwi_ctrlr = phba->phwi_ctrlr; phwi_ctrlr = phba->phwi_ctrlr;
for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { 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,12 +2353,32 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
pwrb_context->pwrb_handle_base = pwrb_context->pwrb_handle_base =
kzalloc(sizeof(struct wrb_handle *) * kzalloc(sizeof(struct wrb_handle *) *
phba->params.wrbs_per_cxn, GFP_KERNEL); phba->params.wrbs_per_cxn, GFP_KERNEL);
if (!pwrb_context->pwrb_handle_base) {
shost_printk(KERN_ERR, phba->shost,
"Mem Alloc Failed. Failing to load\n");
goto init_wrb_hndl_failed;
}
pwrb_context->pwrb_handle_basestd = pwrb_context->pwrb_handle_basestd =
kzalloc(sizeof(struct wrb_handle *) * kzalloc(sizeof(struct wrb_handle *) *
phba->params.wrbs_per_cxn, GFP_KERNEL); phba->params.wrbs_per_cxn, GFP_KERNEL);
if (!pwrb_context->pwrb_handle_basestd) {
shost_printk(KERN_ERR, phba->shost,
"Mem Alloc Failed. Failing to load\n");
goto init_wrb_hndl_failed;
}
if (!num_cxn_wrbh) {
pwrb_handle =
mem_descr_wrbh->mem_array[idx].virtual_address;
num_cxn_wrbh = ((mem_descr_wrbh->mem_array[idx].size) /
((sizeof(struct wrb_handle)) *
phba->params.wrbs_per_cxn));
idx++;
}
pwrb_context->alloc_index = 0;
pwrb_context->wrb_handles_available = 0;
pwrb_context->free_index = 0;
if (num_cxn_wrbh) { if (num_cxn_wrbh) {
pwrb_context->alloc_index = 0;
pwrb_context->wrb_handles_available = 0;
for (j = 0; j < phba->params.wrbs_per_cxn; j++) { for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
pwrb_context->pwrb_handle_base[j] = pwrb_handle; pwrb_context->pwrb_handle_base[j] = pwrb_handle;
pwrb_context->pwrb_handle_basestd[j] = pwrb_context->pwrb_handle_basestd[j] =
...@@ -2373,49 +2387,21 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) ...@@ -2373,49 +2387,21 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
pwrb_handle->wrb_index = j; pwrb_handle->wrb_index = j;
pwrb_handle++; pwrb_handle++;
} }
pwrb_context->free_index = 0;
num_cxn_wrbh--;
} else {
idx++;
pwrb_handle =
mem_descr_wrbh->mem_array[idx].virtual_address;
num_cxn_wrbh =
((mem_descr_wrbh->mem_array[idx].size) /
((sizeof(struct wrb_handle)) *
phba->params.wrbs_per_cxn));
pwrb_context->alloc_index = 0;
for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
pwrb_context->pwrb_handle_base[j] = pwrb_handle;
pwrb_context->pwrb_handle_basestd[j] =
pwrb_handle;
pwrb_context->wrb_handles_available++;
pwrb_handle->wrb_index = j;
pwrb_handle++;
}
pwrb_context->free_index = 0;
num_cxn_wrbh--; num_cxn_wrbh--;
} }
} }
idx = 0; idx = 0;
pwrb = mem_descr_wrb->mem_array[idx].virtual_address;
num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
((sizeof(struct iscsi_wrb) *
phba->params.wrbs_per_cxn));
for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
pwrb_context = &phwi_ctrlr->wrb_context[index]; pwrb_context = &phwi_ctrlr->wrb_context[index];
if (num_cxn_wrb) { if (!num_cxn_wrb) {
for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
pwrb_handle = pwrb_context->pwrb_handle_base[j];
pwrb_handle->pwrb = pwrb;
pwrb++;
}
num_cxn_wrb--;
} else {
idx++;
pwrb = mem_descr_wrb->mem_array[idx].virtual_address; pwrb = mem_descr_wrb->mem_array[idx].virtual_address;
num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
((sizeof(struct iscsi_wrb) * ((sizeof(struct iscsi_wrb) *
phba->params.wrbs_per_cxn)); phba->params.wrbs_per_cxn));
idx++;
}
if (num_cxn_wrb) {
for (j = 0; j < phba->params.wrbs_per_cxn; j++) { for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
pwrb_handle = pwrb_context->pwrb_handle_base[j]; pwrb_handle = pwrb_context->pwrb_handle_base[j];
pwrb_handle->pwrb = pwrb; pwrb_handle->pwrb = pwrb;
...@@ -2424,6 +2410,14 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) ...@@ -2424,6 +2410,14 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
num_cxn_wrb--; num_cxn_wrb--;
} }
} }
return 0;
init_wrb_hndl_failed:
for (j = index; j > 0; j--) {
pwrb_context = &phwi_ctrlr->wrb_context[j];
kfree(pwrb_context->pwrb_handle_base);
kfree(pwrb_context->pwrb_handle_basestd);
}
return -ENOMEM;
} }
static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) 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,7 +3231,9 @@ static int hwi_init_controller(struct beiscsi_hba *phba)
} }
iscsi_init_global_templates(phba); iscsi_init_global_templates(phba);
beiscsi_init_wrb_handle(phba); if (beiscsi_init_wrb_handle(phba))
return -ENOMEM;
hwi_init_async_pdu_ctx(phba); hwi_init_async_pdu_ctx(phba);
if (hwi_init_port(phba) != 0) { if (hwi_init_port(phba) != 0) {
shost_printk(KERN_ERR, phba->shost, shost_printk(KERN_ERR, phba->shost,
...@@ -3824,7 +3820,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) ...@@ -3824,7 +3820,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr; task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr;
task->hdr_max = sizeof(struct be_cmd_bhs); task->hdr_max = sizeof(struct be_cmd_bhs);
io_task->psgl_handle = NULL; io_task->psgl_handle = NULL;
io_task->psgl_handle = NULL; io_task->pwrb_handle = NULL;
if (task->sc) { if (task->sc) {
spin_lock(&phba->io_sgl_lock); spin_lock(&phba->io_sgl_lock);
......
...@@ -219,9 +219,9 @@ struct be_mgmt_controller_attributes_resp { ...@@ -219,9 +219,9 @@ struct be_mgmt_controller_attributes_resp {
/* the CMD_RESPONSE_HEADER */ /* the CMD_RESPONSE_HEADER */
#define ISCSI_GET_PDU_TEMPLATE_ADDRESS(pc, pa) {\ #define ISCSI_GET_PDU_TEMPLATE_ADDRESS(pc, pa) {\
pa->lo = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ pa->lo = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\
bus_address.u.a32.address_lo; \ bus_address.u.a32.address_lo; \
pa->hi = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ pa->hi = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\
bus_address.u.a32.address_hi; \ bus_address.u.a32.address_hi; \
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment