[SCSI] be2iscsi: WRB Initialization and Failure code path change
authorJayamohan Kallickal <jayamohan.kallickal@emulex.com>
Wed, 4 Apr 2012 04:41:38 +0000 (23:41 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 25 Apr 2012 08:00:38 +0000 (09:00 +0100)
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>
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_mgmt.h

index fef6f073c4ab90a6de2e833ac045e485db8c6880..23344c8c5b79c13e7c8d8b7c34ce93cc1292ac02 100644 (file)
@@ -2211,7 +2211,7 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba)
        struct mem_array *mem_arr, *mem_arr_orig;
        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)
                return -ENOMEM;
 
@@ -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);
 }
 
-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 wrb_handle *pwrb_handle;
+       struct wrb_handle *pwrb_handle = NULL;
        struct hwi_controller *phwi_ctrlr;
        struct hwi_wrb_context *pwrb_context;
-       struct iscsi_wrb *pwrb;
-       unsigned int num_cxn_wrbh;
-       unsigned int num_cxn_wrb, j, idx, index;
+       struct iscsi_wrb *pwrb = NULL;
+       unsigned int num_cxn_wrbh = 0;
+       unsigned int num_cxn_wrb = 0, j, idx = 0, index;
 
        mem_descr_wrbh = phba->init_mem;
        mem_descr_wrbh += HWI_MEM_WRBH;
 
        mem_descr_wrb = phba->init_mem;
        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;
 
        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)
                pwrb_context->pwrb_handle_base =
                                kzalloc(sizeof(struct wrb_handle *) *
                                        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 =
                                kzalloc(sizeof(struct wrb_handle *) *
                                        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) {
-                       pwrb_context->alloc_index = 0;
-                       pwrb_context->wrb_handles_available = 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] =
@@ -2373,49 +2387,21 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
                                pwrb_handle->wrb_index = j;
                                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--;
                }
        }
        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) {
                pwrb_context = &phwi_ctrlr->wrb_context[index];
-               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++;
+               if (!num_cxn_wrb) {
                        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));
+                               ((sizeof(struct iscsi_wrb) *
+                                 phba->params.wrbs_per_cxn));
+                       idx++;
+               }
+
+               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;
@@ -2424,6 +2410,14 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
                        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)
@@ -3237,7 +3231,9 @@ static int hwi_init_controller(struct beiscsi_hba *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);
        if (hwi_init_port(phba) != 0) {
                shost_printk(KERN_ERR, phba->shost,
@@ -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_max = sizeof(struct be_cmd_bhs);
        io_task->psgl_handle = NULL;
-       io_task->psgl_handle = NULL;
+       io_task->pwrb_handle = NULL;
 
        if (task->sc) {
                spin_lock(&phba->io_sgl_lock);
index 08428824ace239517784ea9e4ddd00a132a2c996..d7fdfceb656433d9895af2ea8024c85f8a82c0e4 100644 (file)
@@ -219,9 +219,9 @@ struct be_mgmt_controller_attributes_resp {
                                /* the CMD_RESPONSE_HEADER  */
 
 #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;  \
-    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;  \
 }