aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2008-01-31 15:33:48 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-07 19:02:39 -0500
commite87110852d0bd331d50c3de686a7fc9626579d60 (patch)
tree9501f4a06588c14029c6e2487cfdfa0fb710f82e /drivers/scsi/qla2xxx/qla_os.c
parent0afb467b4757adb9c6e3817f2e752d658a494352 (diff)
[SCSI] qla2xxx: Cleanse memory allocation logic during probe.
- Drop loop-till-allocated structure of code within qla2x00_mem_alloc(). - Properly unwind deallcations of memory during failures. - Drop qla2x00_allocate_sp_pool() and qla2x00_free_sp_pool() functions as their implementations can easily be collapsed into the callers. - Defer DMA pool allocation of SFP data until requested. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c328
1 files changed, 98 insertions, 230 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3869e4d174c6..7f78e9400523 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -204,10 +204,8 @@ static int qla2x00_do_dpc(void *data);
204 204
205static void qla2x00_rst_aen(scsi_qla_host_t *); 205static void qla2x00_rst_aen(scsi_qla_host_t *);
206 206
207static uint8_t qla2x00_mem_alloc(scsi_qla_host_t *); 207static int qla2x00_mem_alloc(scsi_qla_host_t *);
208static void qla2x00_mem_free(scsi_qla_host_t *ha); 208static void qla2x00_mem_free(scsi_qla_host_t *ha);
209static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha);
210static void qla2x00_free_sp_pool(scsi_qla_host_t *ha);
211static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *); 209static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *);
212 210
213/* -------------------------------------------------------------------------- */ 211/* -------------------------------------------------------------------------- */
@@ -2032,196 +2030,109 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
2032* 2030*
2033* Returns: 2031* Returns:
2034* 0 = success. 2032* 0 = success.
2035* 1 = failure. 2033* !0 = failure.
2036*/ 2034*/
2037static uint8_t 2035static int
2038qla2x00_mem_alloc(scsi_qla_host_t *ha) 2036qla2x00_mem_alloc(scsi_qla_host_t *ha)
2039{ 2037{
2040 char name[16]; 2038 char name[16];
2041 uint8_t status = 1;
2042 int retry= 10;
2043
2044 do {
2045 /*
2046 * This will loop only once if everything goes well, else some
2047 * number of retries will be performed to get around a kernel
2048 * bug where available mem is not allocated until after a
2049 * little delay and a retry.
2050 */
2051 ha->request_ring = dma_alloc_coherent(&ha->pdev->dev,
2052 (ha->request_q_length + 1) * sizeof(request_t),
2053 &ha->request_dma, GFP_KERNEL);
2054 if (ha->request_ring == NULL) {
2055 qla_printk(KERN_WARNING, ha,
2056 "Memory Allocation failed - request_ring\n");
2057
2058 qla2x00_mem_free(ha);
2059 msleep(100);
2060
2061 continue;
2062 }
2063
2064 ha->response_ring = dma_alloc_coherent(&ha->pdev->dev,
2065 (ha->response_q_length + 1) * sizeof(response_t),
2066 &ha->response_dma, GFP_KERNEL);
2067 if (ha->response_ring == NULL) {
2068 qla_printk(KERN_WARNING, ha,
2069 "Memory Allocation failed - response_ring\n");
2070
2071 qla2x00_mem_free(ha);
2072 msleep(100);
2073
2074 continue;
2075 }
2076
2077 ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE,
2078 &ha->gid_list_dma, GFP_KERNEL);
2079 if (ha->gid_list == NULL) {
2080 qla_printk(KERN_WARNING, ha,
2081 "Memory Allocation failed - gid_list\n");
2082
2083 qla2x00_mem_free(ha);
2084 msleep(100);
2085
2086 continue;
2087 }
2088
2089 /* get consistent memory allocated for init control block */
2090 ha->init_cb = dma_alloc_coherent(&ha->pdev->dev,
2091 ha->init_cb_size, &ha->init_cb_dma, GFP_KERNEL);
2092 if (ha->init_cb == NULL) {
2093 qla_printk(KERN_WARNING, ha,
2094 "Memory Allocation failed - init_cb\n");
2095
2096 qla2x00_mem_free(ha);
2097 msleep(100);
2098
2099 continue;
2100 }
2101 memset(ha->init_cb, 0, ha->init_cb_size);
2102
2103 snprintf(name, sizeof(name), "%s_%ld", QLA2XXX_DRIVER_NAME,
2104 ha->host_no);
2105 ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev,
2106 DMA_POOL_SIZE, 8, 0);
2107 if (ha->s_dma_pool == NULL) {
2108 qla_printk(KERN_WARNING, ha,
2109 "Memory Allocation failed - s_dma_pool\n");
2110
2111 qla2x00_mem_free(ha);
2112 msleep(100);
2113
2114 continue;
2115 }
2116
2117 if (qla2x00_allocate_sp_pool(ha)) {
2118 qla_printk(KERN_WARNING, ha,
2119 "Memory Allocation failed - "
2120 "qla2x00_allocate_sp_pool()\n");
2121
2122 qla2x00_mem_free(ha);
2123 msleep(100);
2124
2125 continue;
2126 }
2127
2128 /* Allocate memory for SNS commands */
2129 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
2130 /* Get consistent memory allocated for SNS commands */
2131 ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev,
2132 sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma,
2133 GFP_KERNEL);
2134 if (ha->sns_cmd == NULL) {
2135 /* error */
2136 qla_printk(KERN_WARNING, ha,
2137 "Memory Allocation failed - sns_cmd\n");
2138
2139 qla2x00_mem_free(ha);
2140 msleep(100);
2141
2142 continue;
2143 }
2144 memset(ha->sns_cmd, 0, sizeof(struct sns_cmd_pkt));
2145 } else {
2146 /* Get consistent memory allocated for MS IOCB */
2147 ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
2148 &ha->ms_iocb_dma);
2149 if (ha->ms_iocb == NULL) {
2150 /* error */
2151 qla_printk(KERN_WARNING, ha,
2152 "Memory Allocation failed - ms_iocb\n");
2153
2154 qla2x00_mem_free(ha);
2155 msleep(100);
2156
2157 continue;
2158 }
2159 memset(ha->ms_iocb, 0, sizeof(ms_iocb_entry_t));
2160
2161 /*
2162 * Get consistent memory allocated for CT SNS
2163 * commands
2164 */
2165 ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev,
2166 sizeof(struct ct_sns_pkt), &ha->ct_sns_dma,
2167 GFP_KERNEL);
2168 if (ha->ct_sns == NULL) {
2169 /* error */
2170 qla_printk(KERN_WARNING, ha,
2171 "Memory Allocation failed - ct_sns\n");
2172
2173 qla2x00_mem_free(ha);
2174 msleep(100);
2175
2176 continue;
2177 }
2178 memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt));
2179
2180 if (IS_FWI2_CAPABLE(ha)) {
2181 /*
2182 * Get consistent memory allocated for SFP
2183 * block.
2184 */
2185 ha->sfp_data = dma_pool_alloc(ha->s_dma_pool,
2186 GFP_KERNEL, &ha->sfp_data_dma);
2187 if (ha->sfp_data == NULL) {
2188 qla_printk(KERN_WARNING, ha,
2189 "Memory Allocation failed - "
2190 "sfp_data\n");
2191
2192 qla2x00_mem_free(ha);
2193 msleep(100);
2194
2195 continue;
2196 }
2197 memset(ha->sfp_data, 0, SFP_BLOCK_SIZE);
2198 }
2199 }
2200
2201 /* Get memory for cached NVRAM */
2202 ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL);
2203 if (ha->nvram == NULL) {
2204 /* error */
2205 qla_printk(KERN_WARNING, ha,
2206 "Memory Allocation failed - nvram cache\n");
2207
2208 qla2x00_mem_free(ha);
2209 msleep(100);
2210
2211 continue;
2212 }
2213 2039
2214 /* Done all allocations without any error. */ 2040 ha->request_ring = dma_alloc_coherent(&ha->pdev->dev,
2215 status = 0; 2041 (ha->request_q_length + 1) * sizeof(request_t), &ha->request_dma,
2042 GFP_KERNEL);
2043 if (!ha->request_ring)
2044 goto fail;
2045
2046 ha->response_ring = dma_alloc_coherent(&ha->pdev->dev,
2047 (ha->response_q_length + 1) * sizeof(response_t),
2048 &ha->response_dma, GFP_KERNEL);
2049 if (!ha->response_ring)
2050 goto fail_free_request_ring;
2051
2052 ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE,
2053 &ha->gid_list_dma, GFP_KERNEL);
2054 if (!ha->gid_list)
2055 goto fail_free_response_ring;
2056
2057 ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size,
2058 &ha->init_cb_dma, GFP_KERNEL);
2059 if (!ha->init_cb)
2060 goto fail_free_gid_list;
2061
2062 snprintf(name, sizeof(name), "%s_%ld", QLA2XXX_DRIVER_NAME,
2063 ha->host_no);
2064 ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev,
2065 DMA_POOL_SIZE, 8, 0);
2066 if (!ha->s_dma_pool)
2067 goto fail_free_init_cb;
2216 2068
2217 } while (retry-- && status != 0); 2069 ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep);
2070 if (!ha->srb_mempool)
2071 goto fail_free_s_dma_pool;
2072
2073 /* Get memory for cached NVRAM */
2074 ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL);
2075 if (!ha->nvram)
2076 goto fail_free_srb_mempool;
2077
2078 /* Allocate memory for SNS commands */
2079 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
2080 /* Get consistent memory allocated for SNS commands */
2081 ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev,
2082 sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma, GFP_KERNEL);
2083 if (!ha->sns_cmd)
2084 goto fail_free_nvram;
2085 } else {
2086 /* Get consistent memory allocated for MS IOCB */
2087 ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
2088 &ha->ms_iocb_dma);
2089 if (!ha->ms_iocb)
2090 goto fail_free_nvram;
2218 2091
2219 if (status) { 2092 /* Get consistent memory allocated for CT SNS commands */
2220 printk(KERN_WARNING 2093 ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev,
2221 "%s(): **** FAILED ****\n", __func__); 2094 sizeof(struct ct_sns_pkt), &ha->ct_sns_dma, GFP_KERNEL);
2095 if (!ha->ct_sns)
2096 goto fail_free_ms_iocb;
2222 } 2097 }
2223 2098
2224 return(status); 2099 return 0;
2100
2101fail_free_ms_iocb:
2102 dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
2103 ha->ms_iocb = NULL;
2104 ha->ms_iocb_dma = 0;
2105fail_free_nvram:
2106 kfree(ha->nvram);
2107 ha->nvram = NULL;
2108fail_free_srb_mempool:
2109 mempool_destroy(ha->srb_mempool);
2110 ha->srb_mempool = NULL;
2111fail_free_s_dma_pool:
2112 dma_pool_destroy(ha->s_dma_pool);
2113 ha->s_dma_pool = NULL;
2114fail_free_init_cb:
2115 dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb,
2116 ha->init_cb_dma);
2117 ha->init_cb = NULL;
2118 ha->init_cb_dma = 0;
2119fail_free_gid_list:
2120 dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
2121 ha->gid_list_dma);
2122 ha->gid_list = NULL;
2123 ha->gid_list_dma = 0;
2124fail_free_response_ring:
2125 dma_free_coherent(&ha->pdev->dev, (ha->response_q_length + 1) *
2126 sizeof(response_t), ha->response_ring, ha->response_dma);
2127 ha->response_ring = NULL;
2128 ha->response_dma = 0;
2129fail_free_request_ring:
2130 dma_free_coherent(&ha->pdev->dev, (ha->request_q_length + 1) *
2131 sizeof(request_t), ha->request_ring, ha->request_dma);
2132 ha->request_ring = NULL;
2133 ha->request_dma = 0;
2134fail:
2135 return -ENOMEM;
2225} 2136}
2226 2137
2227/* 2138/*
@@ -2237,14 +2148,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
2237 struct list_head *fcpl, *fcptemp; 2148 struct list_head *fcpl, *fcptemp;
2238 fc_port_t *fcport; 2149 fc_port_t *fcport;
2239 2150
2240 if (ha == NULL) { 2151 if (ha->srb_mempool)
2241 /* error */ 2152 mempool_destroy(ha->srb_mempool);
2242 DEBUG2(printk("%s(): ERROR invalid ha pointer.\n", __func__));
2243 return;
2244 }
2245
2246 /* free sp pool */
2247 qla2x00_free_sp_pool(ha);
2248 2153
2249 if (ha->fce) 2154 if (ha->fce)
2250 dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce, 2155 dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce,
@@ -2292,6 +2197,7 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
2292 (ha->request_q_length + 1) * sizeof(request_t), 2197 (ha->request_q_length + 1) * sizeof(request_t),
2293 ha->request_ring, ha->request_dma); 2198 ha->request_ring, ha->request_dma);
2294 2199
2200 ha->srb_mempool = NULL;
2295 ha->eft = NULL; 2201 ha->eft = NULL;
2296 ha->eft_dma = 0; 2202 ha->eft_dma = 0;
2297 ha->sns_cmd = NULL; 2203 ha->sns_cmd = NULL;
@@ -2330,44 +2236,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
2330 kfree(ha->nvram); 2236 kfree(ha->nvram);
2331} 2237}
2332 2238
2333/*
2334 * qla2x00_allocate_sp_pool
2335 * This routine is called during initialization to allocate
2336 * memory for local srb_t.
2337 *
2338 * Input:
2339 * ha = adapter block pointer.
2340 *
2341 * Context:
2342 * Kernel context.
2343 */
2344static int
2345qla2x00_allocate_sp_pool(scsi_qla_host_t *ha)
2346{
2347 int rval;
2348
2349 rval = QLA_SUCCESS;
2350 ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep);
2351 if (ha->srb_mempool == NULL) {
2352 qla_printk(KERN_INFO, ha, "Unable to allocate SRB mempool.\n");
2353 rval = QLA_FUNCTION_FAILED;
2354 }
2355 return (rval);
2356}
2357
2358/*
2359 * This routine frees all adapter allocated memory.
2360 *
2361 */
2362static void
2363qla2x00_free_sp_pool( scsi_qla_host_t *ha)
2364{
2365 if (ha->srb_mempool) {
2366 mempool_destroy(ha->srb_mempool);
2367 ha->srb_mempool = NULL;
2368 }
2369}
2370
2371/************************************************************************** 2239/**************************************************************************
2372* qla2x00_do_dpc 2240* qla2x00_do_dpc
2373* This kernel thread is a task that is schedule by the interrupt handler 2241* This kernel thread is a task that is schedule by the interrupt handler