emlxs_mem.c (bb63f56e) | emlxs_mem.c (82527734) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 7 unchanged lines hidden (view full) --- 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2009 Emulex. All rights reserved. | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 7 unchanged lines hidden (view full) --- 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2009 Emulex. All rights reserved. |
24 * Use is subject to License terms. | 24 * Use is subject to license terms. |
25 */ 26 | 25 */ 26 |
27 |
|
27#include <emlxs.h> 28 29EMLXS_MSG_DEF(EMLXS_MEM_C); 30 31 | 28#include <emlxs.h> 29 30EMLXS_MSG_DEF(EMLXS_MEM_C); 31 32 |
32/* 33 * emlxs_mem_alloc_buffer 34 * 35 * This routine will allocate iocb/data buffer 36 * space and setup the buffers for all rings on 37 * the specified board to use. The data buffers 38 * can be posted to the ring with the 39 * fc_post_buffer routine. The iocb buffers 40 * are used to make a temp copy of the response 41 * ring iocbs. Returns 0 if not enough memory, 42 * Returns 1 if successful. 43 */ 44 45 | |
46extern int32_t 47emlxs_mem_alloc_buffer(emlxs_hba_t *hba) 48{ 49 emlxs_port_t *port = &PPORT; 50 emlxs_config_t *cfg; 51 MBUF_INFO *buf_info; | 33extern int32_t 34emlxs_mem_alloc_buffer(emlxs_hba_t *hba) 35{ 36 emlxs_port_t *port = &PPORT; 37 emlxs_config_t *cfg; 38 MBUF_INFO *buf_info; |
52 uint8_t *bp; 53 uint8_t *oldbp; 54 MEMSEG *mp; 55 MATCHMAP *matp; 56 NODELIST *ndlp; 57 IOCBQ *iocbq; 58 MAILBOXQ *mbox; | 39 MEMSEG *seg; |
59 MBUF_INFO bufinfo; 60 int32_t i; | 40 MBUF_INFO bufinfo; 41 int32_t i; |
61 RING *fcp_rp; 62 RING *ip_rp; 63 RING *els_rp; 64 RING *ct_rp; 65 uint32_t total_iotags; | 42 int32_t cnt; |
66#ifdef EMLXS_SPARC | 43#ifdef EMLXS_SPARC |
67 int32_t j; 68 ULP_BDE64 *p_bpl; 69 ULP_BDE64 *v_bpl; | 44 MATCHMAP *mp; 45 MATCHMAP **fcp_bpl_table; |
70#endif /* EMLXS_SPARC */ 71 72 buf_info = &bufinfo; 73 cfg = &CFG; 74 | 46#endif /* EMLXS_SPARC */ 47 48 buf_info = &bufinfo; 49 cfg = &CFG; 50 |
75 mutex_enter(&EMLXS_MEMGET_LOCK); | 51 bzero(hba->memseg, sizeof (hba->memseg)); |
76 77 /* | 52 53 /* |
78 * Allocate and Initialize MEM_NLP (0) | 54 * Initialize fc_table |
79 */ | 55 */ |
80 mp = &hba->memseg[MEM_NLP]; 81 mp->fc_memsize = sizeof (NODELIST); 82 mp->fc_numblks = (int16_t)hba->max_nodes + 2; 83 mp->fc_total_memsize = mp->fc_memsize * mp->fc_numblks; 84 mp->fc_memstart_virt = kmem_zalloc(mp->fc_total_memsize, KM_SLEEP); 85 mp->fc_memget_cnt = mp->fc_numblks; 86 mp->fc_memput_cnt = 0; 87 mp->fc_memstart_phys = 0; 88 mp->fc_memflag = 0; 89 mp->fc_lowmem = 0; 90 mp->fc_mem_dma_handle = 0; 91 mp->fc_mem_dat_handle = 0; 92 mp->fc_memget_ptr = 0; 93 mp->fc_memget_end = 0; 94 mp->fc_memput_ptr = 0; 95 mp->fc_memput_end = 0; 96 97 if (mp->fc_memstart_virt == NULL) { 98 mutex_exit(&EMLXS_MEMGET_LOCK); 99 100 (void) emlxs_mem_free_buffer(hba); 101 102 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 103 "NLP memory pool."); 104 105 return (0); | 56 cnt = cfg[CFG_NUM_IOTAGS].current; 57 if (cnt) { 58 hba->max_iotag = cnt; |
106 } | 59 } |
107 bzero(mp->fc_memstart_virt, mp->fc_memsize); 108 ndlp = (NODELIST *)mp->fc_memstart_virt; | 60 /* ioatg 0 is not used, iotags 1 thru max_iotag-1 are used */ |
109 | 61 |
110 /* 111 * Link buffer into beginning of list. The first pointer 112 * in each buffer is a forward pointer to the next buffer. 113 */ 114 for (i = 0; i < mp->fc_numblks; i++, ndlp++) { 115 ndlp->flag |= NODE_POOL_ALLOCATED; 116 117 oldbp = mp->fc_memget_ptr; 118 bp = (uint8_t *)ndlp; 119 if (oldbp == NULL) { 120 mp->fc_memget_end = bp; 121 } 122 mp->fc_memget_ptr = bp; 123 *((uint8_t **)bp) = oldbp; 124 } 125 126 127 /* 128 * Allocate and Initialize MEM_IOCB (1) 129 */ 130 mp = &hba->memseg[MEM_IOCB]; 131 mp->fc_memsize = sizeof (IOCBQ); 132 mp->fc_numblks = (uint16_t)cfg[CFG_NUM_IOCBS].current; 133 mp->fc_total_memsize = mp->fc_memsize * mp->fc_numblks; 134 mp->fc_memstart_virt = kmem_zalloc(mp->fc_total_memsize, KM_SLEEP); 135 mp->fc_lowmem = (mp->fc_numblks >> 4); 136 mp->fc_memget_cnt = mp->fc_numblks; 137 mp->fc_memput_cnt = 0; 138 mp->fc_memflag = 0; 139 mp->fc_memstart_phys = 0; 140 mp->fc_mem_dma_handle = 0; 141 mp->fc_mem_dat_handle = 0; 142 mp->fc_memget_ptr = 0; 143 mp->fc_memget_end = 0; 144 mp->fc_memput_ptr = 0; 145 mp->fc_memput_end = 0; 146 147 if (mp->fc_memstart_virt == NULL) { 148 mutex_exit(&EMLXS_MEMGET_LOCK); 149 150 (void) emlxs_mem_free_buffer(hba); 151 152 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 153 "IOCB memory pool."); 154 155 return (0); 156 } 157 bzero(mp->fc_memstart_virt, mp->fc_memsize); 158 iocbq = (IOCBQ *)mp->fc_memstart_virt; 159 160 /* 161 * Link buffer into beginning of list. The first pointer 162 * in each buffer is a forward pointer to the next buffer. 163 */ 164 for (i = 0; i < mp->fc_numblks; i++, iocbq++) { 165 iocbq->flag |= IOCB_POOL_ALLOCATED; 166 167 oldbp = mp->fc_memget_ptr; 168 bp = (uint8_t *)iocbq; 169 if (oldbp == NULL) { 170 mp->fc_memget_end = bp; 171 } 172 mp->fc_memget_ptr = bp; 173 *((uint8_t **)bp) = oldbp; 174 } 175 176 /* 177 * Allocate and Initialize MEM_MBOX (2) 178 */ 179 mp = &hba->memseg[MEM_MBOX]; 180 mp->fc_memsize = sizeof (MAILBOXQ); 181 mp->fc_numblks = (int16_t)hba->max_nodes + 32; 182 mp->fc_total_memsize = mp->fc_memsize * mp->fc_numblks; 183 mp->fc_memstart_virt = kmem_zalloc(mp->fc_total_memsize, KM_SLEEP); 184 mp->fc_lowmem = (mp->fc_numblks >> 3); 185 mp->fc_memget_cnt = mp->fc_numblks; 186 mp->fc_memput_cnt = 0; 187 mp->fc_memflag = 0; 188 mp->fc_memstart_phys = 0; 189 mp->fc_mem_dma_handle = 0; 190 mp->fc_mem_dat_handle = 0; 191 mp->fc_memget_ptr = 0; 192 mp->fc_memget_end = 0; 193 mp->fc_memput_ptr = 0; 194 mp->fc_memput_end = 0; 195 196 if (mp->fc_memstart_virt == NULL) { 197 mutex_exit(&EMLXS_MEMGET_LOCK); 198 199 (void) emlxs_mem_free_buffer(hba); 200 201 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 202 "MBOX memory pool."); 203 204 return (0); 205 } 206 bzero(mp->fc_memstart_virt, mp->fc_memsize); 207 mbox = (MAILBOXQ *)mp->fc_memstart_virt; 208 209 /* 210 * Link buffer into beginning of list. The first pointer 211 * in each buffer is a forward pointer to the next buffer. 212 */ 213 for (i = 0; i < mp->fc_numblks; i++, mbox++) { 214 mbox->flag |= MBQ_POOL_ALLOCATED; 215 216 oldbp = mp->fc_memget_ptr; 217 bp = (uint8_t *)mbox; 218 if (oldbp == NULL) { 219 mp->fc_memget_end = bp; 220 } 221 mp->fc_memget_ptr = bp; 222 *((uint8_t **)bp) = oldbp; 223 } 224 225 /* 226 * Initialize fc_table 227 */ 228 fcp_rp = &hba->ring[FC_FCP_RING]; 229 ip_rp = &hba->ring[FC_IP_RING]; 230 els_rp = &hba->ring[FC_ELS_RING]; 231 ct_rp = &hba->ring[FC_CT_RING]; 232 233 fcp_rp->max_iotag = cfg[CFG_NUM_IOTAGS].current; 234 ip_rp->max_iotag = hba->max_nodes; 235 els_rp->max_iotag = hba->max_nodes; 236 ct_rp->max_iotag = hba->max_nodes; 237 | |
238 /* Allocate the fc_table */ | 62 /* Allocate the fc_table */ |
239 total_iotags = fcp_rp->max_iotag + ip_rp->max_iotag + 240 els_rp->max_iotag + ct_rp->max_iotag; 241 | |
242 bzero(buf_info, sizeof (MBUF_INFO)); | 63 bzero(buf_info, sizeof (MBUF_INFO)); |
243 buf_info->size = total_iotags * sizeof (emlxs_buf_t *); 244 buf_info->align = sizeof (void *); | 64 buf_info->size = (hba->max_iotag * sizeof (emlxs_buf_t *)); |
245 246 (void) emlxs_mem_alloc(hba, buf_info); 247 if (buf_info->virt == NULL) { | 65 66 (void) emlxs_mem_alloc(hba, buf_info); 67 if (buf_info->virt == NULL) { |
248 mutex_exit(&EMLXS_MEMGET_LOCK); | |
249 | 68 |
250 (void) emlxs_mem_free_buffer(hba); 251 | |
252 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 253 "fc_table buffer."); 254 | 69 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 70 "fc_table buffer."); 71 |
255 return (0); | 72 goto failed; |
256 } | 73 } |
257 hba->iotag_table = buf_info->virt; 258 fcp_rp->fc_table = &hba->iotag_table[0]; 259 ip_rp->fc_table = &hba->iotag_table[fcp_rp->max_iotag]; 260 els_rp->fc_table = 261 &hba->iotag_table[fcp_rp->max_iotag + ip_rp->max_iotag]; 262 ct_rp->fc_table = 263 &hba->iotag_table[fcp_rp->max_iotag + ip_rp->max_iotag + 264 els_rp->max_iotag]; | 74 hba->fc_table = buf_info->virt; 75 bzero(hba->fc_table, buf_info->size); |
265 | 76 |
266 | |
267#ifdef EMLXS_SPARC | 77#ifdef EMLXS_SPARC |
78 if (!(hba->model_info.sli_mask & EMLXS_SLI4_MASK)) { |
|
268 /* | 79 /* |
269 * Allocate and Initialize FCP MEM_BPL's. | 80 * Allocate and Initialize FCP MEM_BPL table |
270 * This is for increased performance on sparc 271 */ | 81 * This is for increased performance on sparc 82 */ |
272 | |
273 bzero(buf_info, sizeof (MBUF_INFO)); | 83 bzero(buf_info, sizeof (MBUF_INFO)); |
274 buf_info->size = fcp_rp->max_iotag * sizeof (MATCHMAP); 275 buf_info->align = sizeof (void *); | 84 buf_info->size = hba->max_iotag * sizeof (MATCHMAP *); |
276 277 (void) emlxs_mem_alloc(hba, buf_info); 278 if (buf_info->virt == NULL) { | 85 86 (void) emlxs_mem_alloc(hba, buf_info); 87 if (buf_info->virt == NULL) { |
279 mutex_exit(&EMLXS_MEMGET_LOCK); | |
280 | 88 |
281 (void) emlxs_mem_free_buffer(hba); 282 | |
283 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 284 "FCP BPL table buffer."); 285 | 89 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 90 "FCP BPL table buffer."); 91 |
286 return (0); | 92 goto failed; |
287 } | 93 } |
288 hba->fcp_bpl_table = buf_info->virt; 289 bzero(hba->fcp_bpl_table, buf_info->size); | 94 hba->sli.sli3.fcp_bpl_table = buf_info->virt; 95 bzero(hba->sli.sli3.fcp_bpl_table, buf_info->size); |
290 | 96 |
291 bzero(buf_info, sizeof (MBUF_INFO)); 292 buf_info->size = (fcp_rp->max_iotag * (3 * sizeof (ULP_BDE64))); 293 buf_info->flags = FC_MBUF_DMA; 294 buf_info->align = 32; | 97 /* Allocate a pool of BPLs for the FCP MEM_BPL table */ 98 seg = &hba->sli.sli3.fcp_bpl_seg; 99 bzero(seg, sizeof (MEMSEG)); 100 (void) strcpy(seg->fc_label, "FCP BPL Pool"); 101 seg->fc_memtag = MEM_BPL; 102 seg->fc_memsize = (3 * sizeof (ULP_BDE64)); 103 seg->fc_numblks = hba->max_iotag; 104 seg->fc_reserved = 0; 105 seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 106 seg->fc_memalign = 32; |
295 | 107 |
296 (void) emlxs_mem_alloc(hba, buf_info); 297 if (buf_info->virt == NULL) { 298 mutex_exit(&EMLXS_MEMGET_LOCK); 299 300 (void) emlxs_mem_free_buffer(hba); 301 302 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 303 "FCP BPL DMA buffers."); 304 305 return (0); | 108 if (emlxs_mem_pool_alloc(hba, seg) == NULL) { 109 goto failed; |
306 } | 110 } |
307 bzero(buf_info->virt, buf_info->size); | |
308 | 111 |
309 hba->fcp_bpl_mp.size = buf_info->size; 310 hba->fcp_bpl_mp.virt = buf_info->virt; 311 hba->fcp_bpl_mp.phys = buf_info->phys; 312 hba->fcp_bpl_mp.data_handle = buf_info->data_handle; 313 hba->fcp_bpl_mp.dma_handle = buf_info->dma_handle; 314 hba->fcp_bpl_mp.tag = NULL; | 112 /* Initialize the FCP MEM_BPL table */ 113 fcp_bpl_table = (MATCHMAP**)hba->sli.sli3.fcp_bpl_table; 114 mp = (MATCHMAP*)seg->fc_memget_ptr; 115 for (i = 0; i < seg->fc_numblks; i++) { 116 mp->flag |= MAP_TABLE_ALLOCATED; 117 *fcp_bpl_table = mp; |
315 | 118 |
316 v_bpl = (ULP_BDE64 *)hba->fcp_bpl_mp.virt; 317 p_bpl = (ULP_BDE64 *)hba->fcp_bpl_mp.phys; 318 for (i = 0, j = 0; i < fcp_rp->max_iotag; i++, j += 3) { 319 matp = &hba->fcp_bpl_table[i]; 320 321 matp->fc_mptr = NULL; 322 matp->size = (3 * sizeof (ULP_BDE64)); 323 matp->virt = (uint8_t *)&v_bpl[j]; 324 matp->phys = (uint64_t)&p_bpl[j]; 325 matp->dma_handle = NULL; 326 matp->data_handle = NULL; 327 matp->tag = MEM_BPL; 328 matp->flag |= MAP_TABLE_ALLOCATED; | 119 mp = (MATCHMAP *)mp->fc_mptr; 120 fcp_bpl_table++; |
329 } | 121 } |
122 } |
|
330#endif /* EMLXS_SPARC */ 331 | 123#endif /* EMLXS_SPARC */ 124 |
332 /* 333 * Allocate and Initialize MEM_BPL (3) 334 */ | 125 /* Prepare the memory pools */ 126 for (i = 0; i < FC_MAX_SEG; i++) { 127 seg = &hba->memseg[i]; |
335 | 128 |
336 mp = &hba->memseg[MEM_BPL]; 337 mp->fc_memsize = hba->mem_bpl_size; /* Set during attach */ 338 mp->fc_numblks = (uint16_t)cfg[CFG_NUM_IOCBS].current; 339 mp->fc_memflag = FC_MEM_DMA; 340 mp->fc_lowmem = (mp->fc_numblks >> 4); 341 mp->fc_memstart_virt = 0; 342 mp->fc_memstart_phys = 0; 343 mp->fc_mem_dma_handle = 0; 344 mp->fc_mem_dat_handle = 0; 345 mp->fc_memget_ptr = 0; 346 mp->fc_memget_end = 0; 347 mp->fc_memput_ptr = 0; 348 mp->fc_memput_end = 0; 349 mp->fc_total_memsize = 0; 350 mp->fc_memget_cnt = mp->fc_numblks; 351 mp->fc_memput_cnt = 0; | 129 switch (i) { 130 case MEM_NLP: 131 (void) strcpy(seg->fc_label, "Node Pool"); 132 seg->fc_memtag = MEM_NLP; 133 seg->fc_memsize = sizeof (NODELIST); 134 seg->fc_numblks = (int16_t)hba->max_nodes + 2; 135 seg->fc_reserved = 0; 136 seg->fc_memflag = 0; 137 break; |
352 | 138 |
353 /* Allocate buffer pools for above buffer structures */ 354 for (i = 0; i < mp->fc_numblks; i++) { 355 /* 356 * If this is a DMA buffer we need alignment on a page 357 * so we don't want to worry about buffers spanning page 358 * boundries when mapping memory for the adapter. 359 */ 360 bzero(buf_info, sizeof (MBUF_INFO)); 361 buf_info->size = sizeof (MATCHMAP); 362 buf_info->align = sizeof (void *); | 139 case MEM_IOCB: 140 (void) strcpy(seg->fc_label, "IOCB Pool"); 141 seg->fc_memtag = MEM_IOCB; 142 seg->fc_memsize = sizeof (IOCBQ); 143 seg->fc_numblks = (uint16_t)cfg[CFG_NUM_IOCBS].current; 144 seg->fc_reserved = 0; 145 seg->fc_memflag = 0; 146 break; |
363 | 147 |
364 (void) emlxs_mem_alloc(hba, buf_info); 365 if (buf_info->virt == NULL) { 366 mutex_exit(&EMLXS_MEMGET_LOCK); | 148 case MEM_MBOX: 149 (void) strcpy(seg->fc_label, "MBOX Pool"); 150 seg->fc_memtag = MEM_MBOX; 151 seg->fc_memsize = sizeof (MAILBOXQ); 152 seg->fc_numblks = (int16_t)hba->max_nodes + 32; 153 seg->fc_reserved = 0; 154 seg->fc_memflag = 0; 155 break; |
367 | 156 |
368 (void) emlxs_mem_free_buffer(hba); | 157 case MEM_BPL: 158 if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) { 159 continue; 160 } 161 (void) strcpy(seg->fc_label, "BPL Pool"); 162 seg->fc_memtag = MEM_BPL; 163 seg->fc_memsize = hba->sli.sli3.mem_bpl_size; 164 seg->fc_numblks = (int16_t)hba->max_iotag + 2; 165 seg->fc_reserved = 0; 166 seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 167 seg->fc_memalign = 32; 168 break; |
369 | 169 |
370 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 371 "BPL segment buffer."); | 170 case MEM_BUF: 171 /* These are the unsolicited ELS buffers. */ 172 (void) strcpy(seg->fc_label, "BUF Pool"); 173 seg->fc_memtag = MEM_BUF; 174 seg->fc_memsize = MEM_BUF_SIZE; 175 seg->fc_numblks = MEM_ELSBUF_COUNT + MEM_BUF_COUNT; 176 seg->fc_reserved = 0; 177 seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 178 seg->fc_memalign = 32; 179 break; |
372 | 180 |
373 return (0); 374 } | 181 case MEM_IPBUF: 182 /* These are the unsolicited IP buffers. */ 183 if (cfg[CFG_NETWORK_ON].current == 0) { 184 continue; 185 } |
375 | 186 |
376 matp = (MATCHMAP *)buf_info->virt; 377 bzero(matp, sizeof (MATCHMAP)); | 187 (void) strcpy(seg->fc_label, "IPBUF Pool"); 188 seg->fc_memtag = MEM_IPBUF; 189 seg->fc_memsize = MEM_IPBUF_SIZE; 190 seg->fc_numblks = MEM_IPBUF_COUNT; 191 seg->fc_reserved = 0; 192 seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 193 seg->fc_memalign = 32; 194 break; |
378 | 195 |
379 bzero(buf_info, sizeof (MBUF_INFO)); 380 buf_info->size = mp->fc_memsize; 381 buf_info->flags = FC_MBUF_DMA; 382 buf_info->align = 32; | 196 case MEM_CTBUF: 197 /* These are the unsolicited CT buffers. */ 198 (void) strcpy(seg->fc_label, "CTBUF Pool"); 199 seg->fc_memtag = MEM_CTBUF; 200 seg->fc_memsize = MEM_CTBUF_SIZE; 201 seg->fc_numblks = MEM_CTBUF_COUNT; 202 seg->fc_reserved = 0; 203 seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 204 seg->fc_memalign = 32; 205 break; |
383 | 206 |
384 (void) emlxs_mem_alloc(hba, buf_info); 385 if (buf_info->virt == NULL) { 386 mutex_exit(&EMLXS_MEMGET_LOCK); | 207 case MEM_FCTBUF: 208#ifdef SFCT_SUPPORT 209 /* These are the unsolicited FCT buffers. */ 210 if (hba->tgt_mode == 0) { 211 continue; 212 } |
387 | 213 |
388 (void) emlxs_mem_free_buffer(hba); | 214 (void) strcpy(seg->fc_label, "FCTBUF Pool"); 215 seg->fc_memtag = MEM_FCTBUF; 216 seg->fc_memsize = MEM_FCTBUF_SIZE; 217 seg->fc_numblks = MEM_FCTBUF_COUNT; 218 seg->fc_reserved = 0; 219 seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 220 seg->fc_memalign = 32; 221#endif /* SFCT_SUPPORT */ 222 break; |
389 | 223 |
390 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 391 "BPL DMA buffer."); | 224 default: 225 continue; 226 } |
392 | 227 |
393 return (0); | 228 if (seg->fc_memsize == 0) { 229 continue; |
394 } | 230 } |
395 bp = (uint8_t *)buf_info->virt; 396 bzero(bp, mp->fc_memsize); | |
397 | 231 |
398 /* 399 * Link buffer into beginning of list. The first pointer 400 * in each buffer is a forward pointer to the next buffer. 401 */ 402 oldbp = mp->fc_memget_ptr; 403 404 if (oldbp == 0) { 405 mp->fc_memget_end = (uint8_t *)matp; | 232 if (emlxs_mem_pool_alloc(hba, seg) == NULL) { 233 goto failed; |
406 } 407 | 234 } 235 |
408 mp->fc_memget_ptr = (uint8_t *)matp; 409 matp->fc_mptr = oldbp; 410 matp->virt = buf_info->virt; 411 matp->phys = buf_info->phys; 412 matp->size = buf_info->size; 413 matp->dma_handle = buf_info->dma_handle; 414 matp->data_handle = buf_info->data_handle; 415 matp->tag = MEM_BPL; 416 matp->flag |= MAP_POOL_ALLOCATED; | 236 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg, 237 "%s: seg=%p size=%x count=%d flags=%x base=%p", 238 seg->fc_label, seg, seg->fc_memsize, seg->fc_numblks, 239 seg->fc_memflag, seg->fc_memget_ptr); |
417 } 418 | 240 } 241 |
242 return (1); |
|
419 | 243 |
420 /* 421 * These represent the unsolicited ELS buffers we preallocate. 422 */ | 244failed: |
423 | 245 |
424 mp = &hba->memseg[MEM_BUF]; 425 mp->fc_memsize = MEM_BUF_SIZE; 426 mp->fc_numblks = MEM_ELSBUF_COUNT + MEM_BUF_COUNT; 427 mp->fc_memflag = FC_MEM_DMA; 428 mp->fc_lowmem = 3; 429 mp->fc_memstart_virt = 0; 430 mp->fc_memstart_phys = 0; 431 mp->fc_mem_dma_handle = 0; 432 mp->fc_mem_dat_handle = 0; 433 mp->fc_memget_ptr = 0; 434 mp->fc_memget_end = 0; 435 mp->fc_memput_ptr = 0; 436 mp->fc_memput_end = 0; 437 mp->fc_total_memsize = 0; 438 mp->fc_memget_cnt = mp->fc_numblks; 439 mp->fc_memput_cnt = 0; | 246 (void) emlxs_mem_free_buffer(hba); 247 return (0); |
440 | 248 |
441 /* Allocate buffer pools for above buffer structures */ 442 for (i = 0; i < mp->fc_numblks; i++) { 443 /* 444 * If this is a DMA buffer we need alignment on a page 445 * so we don't want to worry about buffers spanning page 446 * boundries when mapping memory for the adapter. 447 */ 448 bzero(buf_info, sizeof (MBUF_INFO)); 449 buf_info->size = sizeof (MATCHMAP); 450 buf_info->align = sizeof (void *); | 249} /* emlxs_mem_alloc_buffer() */ |
451 | 250 |
452 (void) emlxs_mem_alloc(hba, buf_info); 453 if (buf_info->virt == NULL) { 454 mutex_exit(&EMLXS_MEMGET_LOCK); | |
455 | 251 |
456 (void) emlxs_mem_free_buffer(hba); | 252/* 253 * emlxs_mem_free_buffer 254 * 255 * This routine will free iocb/data buffer space 256 * and TGTM resource. 257 */ 258extern int 259emlxs_mem_free_buffer(emlxs_hba_t *hba) 260{ 261 emlxs_port_t *vport; 262 int32_t j; 263 MATCHMAP *mp; 264 CHANNEL *cp; 265 RING *rp; 266 MBUF_INFO *buf_info; 267 MBUF_INFO bufinfo; |
457 | 268 |
458 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 459 "MEM_BUF Segment buffer."); | 269 buf_info = &bufinfo; |
460 | 270 |
461 return (0); 462 } | 271 for (j = 0; j < hba->chan_count; j++) { 272 cp = &hba->chan[j]; |
463 | 273 |
464 matp = (MATCHMAP *)buf_info->virt; 465 bzero(matp, sizeof (MATCHMAP)); | 274 /* Flush the ring */ 275 (void) emlxs_tx_channel_flush(hba, cp, 0); 276 } |
466 | 277 |
467 bzero(buf_info, sizeof (MBUF_INFO)); 468 buf_info->size = mp->fc_memsize; 469 buf_info->flags = FC_MBUF_DMA; 470 buf_info->align = 32; | 278 if (!(hba->model_info.sli_mask & EMLXS_SLI4_MASK)) { 279 /* free the mapped address match area for each ring */ 280 for (j = 0; j < MAX_RINGS; j++) { 281 rp = &hba->sli.sli3.ring[j]; |
471 | 282 |
472 (void) emlxs_mem_alloc(hba, buf_info); 473 if (buf_info->virt == NULL) { 474 mutex_exit(&EMLXS_MEMGET_LOCK); | 283 while (rp->fc_mpoff) { 284 uint64_t addr; |
475 | 285 |
476 (void) emlxs_mem_free_buffer(hba); | 286 addr = 0; 287 mp = (MATCHMAP *)(rp->fc_mpoff); |
477 | 288 |
478 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 479 "MEM_BUF DMA buffer."); | 289 if ((j == hba->channel_els) || 290 (j == hba->channel_ct) || 291#ifdef SFCT_SUPPORT 292 (j == hba->CHANNEL_FCT) || 293#endif /* SFCT_SUPPORT */ 294 (j == hba->channel_ip)) { 295 addr = mp->phys; 296 } |
480 | 297 |
481 return (0); | 298 if ((mp = emlxs_mem_get_vaddr(hba, rp, addr))) { 299 if (j == hba->channel_els) { 300 (void) emlxs_mem_put(hba, 301 MEM_ELSBUF, (uint8_t *)mp); 302 } else if (j == hba->channel_ct) { 303 (void) emlxs_mem_put(hba, 304 MEM_CTBUF, (uint8_t *)mp); 305 } else if (j == hba->channel_ip) { 306 (void) emlxs_mem_put(hba, 307 MEM_IPBUF, (uint8_t *)mp); 308 } 309#ifdef SFCT_SUPPORT 310 else if (j == hba->CHANNEL_FCT) { 311 (void) emlxs_mem_put(hba, 312 MEM_FCTBUF, (uint8_t *)mp); 313 } 314#endif /* SFCT_SUPPORT */ 315 316 } 317 } |
482 } | 318 } |
483 bp = (uint8_t *)buf_info->virt; 484 bzero(bp, mp->fc_memsize); | 319 } |
485 | 320 |
486 /* 487 * Link buffer into beginning of list. The first pointer 488 * in each buffer is a forward pointer to the next buffer. 489 */ 490 oldbp = mp->fc_memget_ptr; | 321 if (hba->flag & FC_HBQ_ENABLED) { 322 emlxs_hbq_free_all(hba, EMLXS_ELS_HBQ_ID); 323 emlxs_hbq_free_all(hba, EMLXS_IP_HBQ_ID); 324 emlxs_hbq_free_all(hba, EMLXS_CT_HBQ_ID); |
491 | 325 |
492 if (oldbp == 0) { 493 mp->fc_memget_end = (uint8_t *)matp; | 326 if (hba->tgt_mode) { 327 emlxs_hbq_free_all(hba, EMLXS_FCT_HBQ_ID); |
494 } | 328 } |
329 } |
|
495 | 330 |
496 mp->fc_memget_ptr = (uint8_t *)matp; 497 matp->fc_mptr = oldbp; 498 matp->virt = buf_info->virt; 499 matp->phys = buf_info->phys; 500 matp->size = buf_info->size; 501 matp->dma_handle = buf_info->dma_handle; 502 matp->data_handle = buf_info->data_handle; 503 matp->tag = MEM_BUF; 504 matp->flag |= MAP_POOL_ALLOCATED; | 331 /* Free the nodes */ 332 for (j = 0; j < MAX_VPORTS; j++) { 333 vport = &VPORT(j); 334 if (vport->node_count) { 335 emlxs_node_destroy_all(vport); 336 } |
505 } 506 | 337 } 338 |
339 /* Make sure the mailbox queue is empty */ 340 emlxs_mb_flush(hba); |
|
507 | 341 |
508 /* 509 * These represent the unsolicited IP buffers we preallocate. 510 */ | 342 /* Free memory associated with all buffers on get buffer pool */ 343 if (hba->fc_table) { 344 bzero(buf_info, sizeof (MBUF_INFO)); 345 buf_info->size = hba->max_iotag * sizeof (emlxs_buf_t *); 346 buf_info->virt = hba->fc_table; 347 emlxs_mem_free(hba, buf_info); 348 hba->fc_table = NULL; 349 } |
511 | 350 |
512 mp = &hba->memseg[MEM_IPBUF]; 513 mp->fc_memsize = MEM_IPBUF_SIZE; 514 mp->fc_numblks = MEM_IPBUF_COUNT; 515 mp->fc_memflag = FC_MEM_DMA; 516 mp->fc_lowmem = 3; 517 mp->fc_memstart_virt = 0; 518 mp->fc_memstart_phys = 0; 519 mp->fc_mem_dma_handle = 0; 520 mp->fc_mem_dat_handle = 0; 521 mp->fc_memget_ptr = 0; 522 mp->fc_memget_end = 0; 523 mp->fc_memput_ptr = 0; 524 mp->fc_memput_end = 0; 525 mp->fc_total_memsize = 0; 526 mp->fc_memget_cnt = mp->fc_numblks; 527 mp->fc_memput_cnt = 0; 528 529 /* Allocate buffer pools for above buffer structures */ 530 for (i = 0; i < mp->fc_numblks; i++) { 531 /* 532 * If this is a DMA buffer we need alignment on a page 533 * so we don't want to worry about buffers spanning page 534 * boundries when mapping memory for the adapter. 535 */ | 351#ifdef EMLXS_SPARC 352 if (hba->sli.sli3.fcp_bpl_table) { |
536 bzero(buf_info, sizeof (MBUF_INFO)); | 353 bzero(buf_info, sizeof (MBUF_INFO)); |
537 buf_info->size = sizeof (MATCHMAP); 538 buf_info->align = sizeof (void *); | 354 buf_info->size = hba->max_iotag * sizeof (MATCHMAP *); 355 buf_info->virt = hba->sli.sli3.fcp_bpl_table; 356 emlxs_mem_free(hba, buf_info); 357 hba->sli.sli3.fcp_bpl_table = NULL; 358 } |
539 | 359 |
540 (void) emlxs_mem_alloc(hba, buf_info); 541 if (buf_info->virt == NULL) { 542 mutex_exit(&EMLXS_MEMGET_LOCK); | 360 if (hba->sli.sli3.fcp_bpl_seg.fc_memsize) { 361 emlxs_mem_pool_free(hba, &hba->sli.sli3.fcp_bpl_seg); 362 bzero(&hba->sli.sli3.fcp_bpl_seg, sizeof (MEMSEG)); 363 } 364#endif /* EMLXS_SPARC */ |
543 | 365 |
544 (void) emlxs_mem_free_buffer(hba); | 366 /* Free the memory segments */ 367 for (j = 0; j < FC_MAX_SEG; j++) { 368 emlxs_mem_pool_free(hba, &hba->memseg[j]); 369 } |
545 | 370 |
546 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 547 "IP_BUF Segment buffer."); | 371 return (0); |
548 | 372 |
549 return (0); 550 } | 373} /* emlxs_mem_free_buffer() */ |
551 | 374 |
552 matp = (MATCHMAP *)buf_info->virt; 553 bzero(matp, sizeof (MATCHMAP)); | |
554 | 375 |
555 bzero(buf_info, sizeof (MBUF_INFO)); 556 buf_info->size = mp->fc_memsize; 557 buf_info->flags = FC_MBUF_DMA; 558 buf_info->align = 32; | 376extern MEMSEG * 377emlxs_mem_pool_alloc(emlxs_hba_t *hba, MEMSEG *seg) 378{ 379 emlxs_port_t *port = &PPORT; 380 uint8_t *bp = NULL; 381 MATCHMAP *mp = NULL; 382 MBUF_INFO *buf_info; 383 MBUF_INFO local_buf_info; 384 uint32_t i; |
559 | 385 |
560 (void) emlxs_mem_alloc(hba, buf_info); 561 if (buf_info->virt == NULL) { 562 mutex_exit(&EMLXS_MEMGET_LOCK); | 386 buf_info = &local_buf_info; |
563 | 387 |
564 (void) emlxs_mem_free_buffer(hba); | 388 mutex_enter(&EMLXS_MEMGET_LOCK); 389 mutex_enter(&EMLXS_MEMPUT_LOCK); |
565 | 390 |
566 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 567 "IP_BUF DMA buffer."); | 391 /* Calculate total memory size */ 392 seg->fc_total_memsize = (seg->fc_memsize * seg->fc_numblks); |
568 | 393 |
569 return (0); 570 } 571 bp = (uint8_t *)buf_info->virt; 572 bzero(bp, mp->fc_memsize); | 394 if (seg->fc_total_memsize == 0) { 395 mutex_exit(&EMLXS_MEMPUT_LOCK); 396 mutex_exit(&EMLXS_MEMGET_LOCK); 397 return (NULL); 398 } |
573 | 399 |
574 /* 575 * Link buffer into beginning of list. The first pointer 576 * in each buffer is a forward pointer to the next buffer. 577 */ 578 oldbp = mp->fc_memget_ptr; 579 580 if (oldbp == 0) { 581 mp->fc_memget_end = (uint8_t *)matp; 582 } 583 584 mp->fc_memget_ptr = (uint8_t *)matp; 585 matp->fc_mptr = oldbp; 586 matp->virt = buf_info->virt; 587 matp->phys = buf_info->phys; 588 matp->size = buf_info->size; 589 matp->dma_handle = buf_info->dma_handle; 590 matp->data_handle = buf_info->data_handle; 591 matp->tag = MEM_IPBUF; 592 matp->flag |= MAP_POOL_ALLOCATED; | 400 if (!(seg->fc_memflag & FC_MBUF_DMA)) { 401 goto vmem_pool; |
593 } 594 | 402 } 403 |
595 /* 596 * These represent the unsolicited CT buffers we preallocate. 597 */ 598 mp = &hba->memseg[MEM_CTBUF]; 599 mp->fc_memsize = MEM_CTBUF_SIZE; 600 mp->fc_numblks = MEM_CTBUF_COUNT; 601 mp->fc_memflag = FC_MEM_DMA; 602 mp->fc_lowmem = 0; 603 mp->fc_memstart_virt = 0; 604 mp->fc_memstart_phys = 0; 605 mp->fc_mem_dma_handle = 0; 606 mp->fc_mem_dat_handle = 0; 607 mp->fc_memget_ptr = 0; 608 mp->fc_memget_end = 0; 609 mp->fc_memput_ptr = 0; 610 mp->fc_memput_end = 0; 611 mp->fc_total_memsize = 0; 612 mp->fc_memget_cnt = mp->fc_numblks; 613 mp->fc_memput_cnt = 0; | 404/* dma_pool */ |
614 | 405 |
615 /* Allocate buffer pools for above buffer structures */ 616 for (i = 0; i < mp->fc_numblks; i++) { 617 /* 618 * If this is a DMA buffer we need alignment on a page 619 * so we don't want to worry about buffers spanning page 620 * boundries when mapping memory for the adapter. 621 */ | 406 for (i = 0; i < seg->fc_numblks; i++) { |
622 bzero(buf_info, sizeof (MBUF_INFO)); 623 buf_info->size = sizeof (MATCHMAP); 624 buf_info->align = sizeof (void *); 625 626 (void) emlxs_mem_alloc(hba, buf_info); 627 if (buf_info->virt == NULL) { | 407 bzero(buf_info, sizeof (MBUF_INFO)); 408 buf_info->size = sizeof (MATCHMAP); 409 buf_info->align = sizeof (void *); 410 411 (void) emlxs_mem_alloc(hba, buf_info); 412 if (buf_info->virt == NULL) { |
628 mutex_exit(&EMLXS_MEMGET_LOCK); 629 630 (void) emlxs_mem_free_buffer(hba); 631 | |
632 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, | 413 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, |
633 "CT_BUF Segment buffer."); | 414 "%s desc[%d]. size=%d", seg->fc_label, i, 415 buf_info->size); |
634 | 416 |
635 return (0); | 417 goto failed; |
636 } 637 | 418 } 419 |
638 matp = (MATCHMAP *)buf_info->virt; 639 bzero(matp, sizeof (MATCHMAP)); | 420 mp = (MATCHMAP *)buf_info->virt; 421 bzero(mp, sizeof (MATCHMAP)); |
640 641 bzero(buf_info, sizeof (MBUF_INFO)); | 422 423 bzero(buf_info, sizeof (MBUF_INFO)); |
642 buf_info->size = mp->fc_memsize; 643 buf_info->flags = FC_MBUF_DMA; 644 buf_info->align = 32; | 424 buf_info->size = seg->fc_memsize; 425 buf_info->flags = seg->fc_memflag; 426 buf_info->align = seg->fc_memalign; |
645 646 (void) emlxs_mem_alloc(hba, buf_info); 647 if (buf_info->virt == NULL) { | 427 428 (void) emlxs_mem_alloc(hba, buf_info); 429 if (buf_info->virt == NULL) { |
648 mutex_exit(&EMLXS_MEMGET_LOCK); 649 650 (void) emlxs_mem_free_buffer(hba); 651 | |
652 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, | 430 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, |
653 "CT_BUF DMA buffer."); | 431 "%s buffer[%d]. size=%d", seg->fc_label, i, 432 buf_info->size); |
654 | 433 |
655 return (0); | 434 /* Free the mp object */ 435 bzero(buf_info, sizeof (MBUF_INFO)); 436 buf_info->size = sizeof (MATCHMAP); 437 buf_info->virt = (uint32_t *)mp; 438 emlxs_mem_free(hba, buf_info); 439 440 goto failed; |
656 } 657 bp = (uint8_t *)buf_info->virt; | 441 } 442 bp = (uint8_t *)buf_info->virt; |
658 bzero(bp, mp->fc_memsize); | 443 bzero(bp, seg->fc_memsize); |
659 | 444 |
660 /* 661 * Link buffer into beginning of list. The first pointer 662 * in each buffer is a forward pointer to the next buffer. 663 */ 664 oldbp = mp->fc_memget_ptr; | 445 mp->virt = buf_info->virt; 446 mp->phys = buf_info->phys; 447 mp->size = buf_info->size; 448 mp->dma_handle = buf_info->dma_handle; 449 mp->data_handle = buf_info->data_handle; 450 mp->tag = seg->fc_memtag; 451 mp->segment = seg; 452 mp->flag |= MAP_POOL_ALLOCATED; |
665 | 453 |
666 if (oldbp == 0) { 667 mp->fc_memget_end = (uint8_t *)matp; | 454 /* Add the buffer desc to the tail of the pool freelist */ 455 if (seg->fc_memget_end == NULL) { 456 seg->fc_memget_ptr = (uint8_t *)mp; 457 seg->fc_memget_cnt = 1; 458 } else { 459 *((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)mp; 460 seg->fc_memget_cnt++; |
668 } | 461 } |
669 670 mp->fc_memget_ptr = (uint8_t *)matp; 671 matp->fc_mptr = oldbp; 672 matp->virt = buf_info->virt; 673 matp->phys = buf_info->phys; 674 matp->size = buf_info->size; 675 matp->dma_handle = buf_info->dma_handle; 676 matp->data_handle = buf_info->data_handle; 677 matp->tag = MEM_CTBUF; 678 matp->flag |= MAP_POOL_ALLOCATED; | 462 seg->fc_memget_end = (uint8_t *)mp; |
679 } 680 | 463 } 464 |
681#ifdef SFCT_SUPPORT | 465 mutex_exit(&EMLXS_MEMPUT_LOCK); 466 mutex_exit(&EMLXS_MEMGET_LOCK); 467 return (seg); |
682 | 468 |
683 /* 684 * These represent the unsolicited FCT buffers we preallocate. 685 */ 686 mp = &hba->memseg[MEM_FCTBUF]; 687 mp->fc_memsize = MEM_FCTBUF_SIZE; 688 mp->fc_numblks = (hba->tgt_mode) ? MEM_FCTBUF_COUNT : 0; 689 mp->fc_memflag = FC_MEM_DMA; 690 mp->fc_lowmem = 0; 691 mp->fc_memstart_virt = 0; 692 mp->fc_memstart_phys = 0; 693 mp->fc_mem_dma_handle = 0; 694 mp->fc_mem_dat_handle = 0; 695 mp->fc_memget_ptr = 0; 696 mp->fc_memget_end = 0; 697 mp->fc_memput_ptr = 0; 698 mp->fc_memput_end = 0; 699 mp->fc_total_memsize = 0; 700 mp->fc_memget_cnt = mp->fc_numblks; 701 mp->fc_memput_cnt = 0; | 469vmem_pool: |
702 | 470 |
703 /* Allocate buffer pools for above buffer structures */ 704 for (i = 0; i < mp->fc_numblks; i++) { 705 /* 706 * If this is a DMA buffer we need alignment on a page 707 * so we don't want to worry about buffers spanning page 708 * boundries when mapping memory for the adapter. 709 */ 710 bzero(buf_info, sizeof (MBUF_INFO)); 711 buf_info->size = sizeof (MATCHMAP); 712 buf_info->align = sizeof (void *); | 471 mutex_exit(&EMLXS_MEMPUT_LOCK); 472 mutex_exit(&EMLXS_MEMGET_LOCK); |
713 | 473 |
714 (void) emlxs_mem_alloc(hba, buf_info); 715 if (buf_info->virt == NULL) { 716 mutex_exit(&EMLXS_MEMGET_LOCK); | 474 seg->fc_memstart_virt = kmem_zalloc(seg->fc_total_memsize, KM_SLEEP); |
717 | 475 |
718 (void) emlxs_mem_free_buffer(hba); | 476 mutex_enter(&EMLXS_MEMGET_LOCK); 477 mutex_enter(&EMLXS_MEMPUT_LOCK); |
719 | 478 |
720 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 721 "FCT_BUF Segment buffer."); | 479 if (seg->fc_memstart_virt == NULL) { 480 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 481 "%s base. size=%d", seg->fc_label, 482 seg->fc_total_memsize); |
722 | 483 |
723 return (0); 724 } | 484 goto failed; 485 } |
725 | 486 |
726 matp = (MATCHMAP *)buf_info->virt; 727 bzero(matp, sizeof (MATCHMAP)); | 487 bp = (uint8_t *)seg->fc_memstart_virt; 488 for (i = 0; i < seg->fc_numblks; i++) { |
728 | 489 |
729 bzero(buf_info, sizeof (MBUF_INFO)); 730 buf_info->size = mp->fc_memsize; 731 buf_info->flags = FC_MBUF_DMA; 732 buf_info->align = 32; | 490 /* Add the buffer to the tail of the pool freelist */ 491 if (seg->fc_memget_end == NULL) { 492 seg->fc_memget_ptr = (uint8_t *)bp; 493 seg->fc_memget_cnt = 1; 494 } else { 495 *((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)bp; 496 seg->fc_memget_cnt++; 497 } 498 seg->fc_memget_end = (uint8_t *)bp; |
733 | 499 |
734 (void) emlxs_mem_alloc(hba, buf_info); 735 if (buf_info->virt == NULL) { 736 mutex_exit(&EMLXS_MEMGET_LOCK); | 500 bp += seg->fc_memsize; 501 } |
737 | 502 |
738 (void) emlxs_mem_free_buffer(hba); | 503 mutex_exit(&EMLXS_MEMPUT_LOCK); 504 mutex_exit(&EMLXS_MEMGET_LOCK); 505 return (seg); |
739 | 506 |
740 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 741 "FCT_BUF DMA buffer."); | 507failed: |
742 | 508 |
743 return (0); 744 } 745 bp = (uint8_t *)buf_info->virt; 746 bzero(bp, mp->fc_memsize); | 509 mutex_exit(&EMLXS_MEMPUT_LOCK); 510 mutex_exit(&EMLXS_MEMGET_LOCK); 511 emlxs_mem_pool_free(hba, seg); 512 return (NULL); |
747 | 513 |
748 /* 749 * Link buffer into beginning of list. The first pointer 750 * in each buffer is a forward pointer to the next buffer. 751 */ 752 oldbp = mp->fc_memget_ptr; | 514} /* emlxs_mem_pool_alloc() */ |
753 | 515 |
754 if (oldbp == 0) { 755 mp->fc_memget_end = (uint8_t *)matp; 756 } | |
757 | 516 |
758 mp->fc_memget_ptr = (uint8_t *)matp; 759 matp->fc_mptr = oldbp; 760 matp->virt = buf_info->virt; 761 matp->phys = buf_info->phys; 762 matp->size = buf_info->size; 763 matp->dma_handle = buf_info->dma_handle; 764 matp->data_handle = buf_info->data_handle; 765 matp->tag = MEM_FCTBUF; 766 matp->flag |= MAP_POOL_ALLOCATED; 767 } 768#endif /* SFCT_SUPPORT */ | 517extern void 518emlxs_mem_pool_free(emlxs_hba_t *hba, MEMSEG *seg) 519{ 520 emlxs_port_t *port = &PPORT; 521 uint8_t *bp = NULL; 522 MATCHMAP *mp = NULL; 523 MBUF_INFO *buf_info; 524 MBUF_INFO local_buf_info; 525 MEMSEG segment; 526 uint32_t free; |
769 | 527 |
770 for (i = 0; i < FC_MAX_SEG; i++) { 771 char *seg; | 528 /* Save a local copy of the segment and */ 529 /* destroy the original outside of locks */ 530 mutex_enter(&EMLXS_MEMGET_LOCK); 531 mutex_enter(&EMLXS_MEMPUT_LOCK); |
772 | 532 |
773 switch (i) { 774 case MEM_NLP: 775 seg = "MEM_NLP"; 776 break; 777 case MEM_IOCB: 778 seg = "MEM_IOCB"; 779 break; 780 case MEM_MBOX: 781 seg = "MEM_MBOX"; 782 break; 783 case MEM_BPL: 784 seg = "MEM_BPL"; 785 break; 786 case MEM_BUF: 787 seg = "MEM_BUF"; 788 break; 789 case MEM_IPBUF: 790 seg = "MEM_IPBUF"; 791 break; 792 case MEM_CTBUF: 793 seg = "MEM_CTBUF"; 794 break; 795#ifdef SFCT_SUPPORT 796 case MEM_FCTBUF: 797 seg = "MEM_FCTBUF"; 798 break; 799#endif /* SFCT_SUPPORT */ 800 default: 801 break; 802 } 803 804 mp = &hba->memseg[i]; 805 806 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg, 807 "Segment: %s mp=%p size=%x count=%d flags=%x base=%p", 808 seg, mp, mp->fc_memsize, mp->fc_numblks, mp->fc_memflag, 809 mp->fc_memget_ptr); | 533 free = seg->fc_memget_cnt + seg->fc_memput_cnt; 534 if (free < seg->fc_numblks) { 535 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 536 "emlxs_mem_pool_free: %s not full. (%d < %d)", 537 seg->fc_label, free, seg->fc_numblks); |
810 } 811 | 538 } 539 |
540 bcopy(seg, &segment, sizeof (MEMSEG)); 541 bzero((char *)seg, sizeof (MEMSEG)); 542 seg = &segment; 543 544 mutex_exit(&EMLXS_MEMPUT_LOCK); |
|
812 mutex_exit(&EMLXS_MEMGET_LOCK); 813 | 545 mutex_exit(&EMLXS_MEMGET_LOCK); 546 |
814 return (1); | 547 /* Now free the memory */ |
815 | 548 |
816} /* emlxs_mem_alloc_buffer() */ | 549 if (!(seg->fc_memflag & FC_MBUF_DMA)) { 550 if (seg->fc_memstart_virt) { 551 kmem_free(seg->fc_memstart_virt, seg->fc_total_memsize); 552 } |
817 | 553 |
554 return; 555 } |
|
818 | 556 |
557 buf_info = &local_buf_info; |
|
819 | 558 |
820/* 821 * emlxs_mem_free_buffer 822 * 823 * This routine will free iocb/data buffer space 824 * and TGTM resource. 825 */ 826extern int 827emlxs_mem_free_buffer(emlxs_hba_t *hba) 828{ 829 emlxs_port_t *port = &PPORT; 830 emlxs_port_t *vport; 831 int32_t j; 832 uint8_t *bp; 833 MEMSEG *mp; 834 MATCHMAP *mm; 835 RING *rp; 836 IOCBQ *iocbq; 837 IOCB *iocb; 838 MAILBOXQ *mbox, *mbsave; 839 MBUF_INFO *buf_info; 840 MBUF_INFO bufinfo; 841 emlxs_buf_t *sbp; 842 fc_unsol_buf_t *ubp; 843 RING *fcp_rp; 844 RING *ip_rp; 845 RING *els_rp; 846 RING *ct_rp; 847 uint32_t total_iotags; 848 emlxs_ub_priv_t *ub_priv; | 559 /* Free memory associated with all buffers on get buffer pool */ 560 while ((bp = seg->fc_memget_ptr) != NULL) { 561 seg->fc_memget_ptr = *((uint8_t **)bp); 562 mp = (MATCHMAP *)bp; |
849 | 563 |
850 buf_info = &bufinfo; | 564 bzero(buf_info, sizeof (MBUF_INFO)); 565 buf_info->size = mp->size; 566 buf_info->virt = mp->virt; 567 buf_info->phys = mp->phys; 568 buf_info->dma_handle = mp->dma_handle; 569 buf_info->data_handle = mp->data_handle; 570 buf_info->flags = seg->fc_memflag; 571 emlxs_mem_free(hba, buf_info); |
851 | 572 |
852 /* Check for deferred pkt completion */ 853 if (hba->mbox_sbp) { 854 sbp = (emlxs_buf_t *)hba->mbox_sbp; 855 hba->mbox_sbp = 0; 856 857 emlxs_pkt_complete(sbp, -1, 0, 1); | 573 bzero(buf_info, sizeof (MBUF_INFO)); 574 buf_info->size = sizeof (MATCHMAP); 575 buf_info->virt = (uint32_t *)mp; 576 emlxs_mem_free(hba, buf_info); |
858 } 859 | 577 } 578 |
860 /* Check for deferred ub completion */ 861 if (hba->mbox_ubp) { 862 ubp = (fc_unsol_buf_t *)hba->mbox_ubp; 863 ub_priv = (emlxs_ub_priv_t *)ubp->ub_fca_private; 864 port = ub_priv->port; 865 hba->mbox_ubp = 0; | 579 /* Free memory associated with all buffers on put buffer pool */ 580 while ((bp = seg->fc_memput_ptr) != NULL) { 581 seg->fc_memput_ptr = *((uint8_t **)bp); 582 mp = (MATCHMAP *)bp; |
866 | 583 |
867 emlxs_ub_callback(port, ubp); 868 } | 584 bzero(buf_info, sizeof (MBUF_INFO)); 585 buf_info->size = mp->size; 586 buf_info->virt = mp->virt; 587 buf_info->phys = mp->phys; 588 buf_info->dma_handle = mp->dma_handle; 589 buf_info->data_handle = mp->data_handle; 590 buf_info->flags = seg->fc_memflag; 591 emlxs_mem_free(hba, buf_info); |
869 | 592 |
870#ifdef NPIV_SUPPORT 871 /* Special handle for vport PLOGI */ 872 if (hba->mbox_iocbq == (uint8_t *)1) { 873 hba->mbox_iocbq = NULL; | 593 bzero(buf_info, sizeof (MBUF_INFO)); 594 buf_info->size = sizeof (MATCHMAP); 595 buf_info->virt = (uint32_t *)mp; 596 emlxs_mem_free(hba, buf_info); |
874 } | 597 } |
875#endif /* NPIV_SUPPORT */ | |
876 | 598 |
877 /* Check for deferred iocb tx */ 878 if (hba->mbox_iocbq) { /* iocb */ 879 iocbq = (IOCBQ *)hba->mbox_iocbq; 880 hba->mbox_iocbq = 0; 881 iocb = &iocbq->iocb; | 599 return; |
882 | 600 |
883 /* Set the error status of the iocb */ 884 iocb->ulpStatus = IOSTAT_LOCAL_REJECT; 885 iocb->un.grsp.perr.statLocalError = IOERR_ABORT_REQUESTED; | 601} /* emlxs_mem_pool_free() */ |
886 | 602 |
887 switch (iocb->ulpCommand) { 888 case CMD_FCP_ICMND_CR: 889 case CMD_FCP_ICMND_CX: 890 case CMD_FCP_IREAD_CR: 891 case CMD_FCP_IREAD_CX: 892 case CMD_FCP_IWRITE_CR: 893 case CMD_FCP_IWRITE_CX: 894 case CMD_FCP_ICMND64_CR: 895 case CMD_FCP_ICMND64_CX: 896 case CMD_FCP_IREAD64_CR: 897 case CMD_FCP_IREAD64_CX: 898 case CMD_FCP_IWRITE64_CR: 899 case CMD_FCP_IWRITE64_CX: 900 rp = &hba->ring[FC_FCP_RING]; 901 emlxs_handle_fcp_event(hba, rp, iocbq); 902 break; | |
903 | 603 |
904 case CMD_ELS_REQUEST_CR: 905 case CMD_ELS_REQUEST_CX: 906 case CMD_XMIT_ELS_RSP_CX: 907 case CMD_ELS_REQUEST64_CR: /* This is the only one used */ 908 /* for deferred iocb tx */ 909 case CMD_ELS_REQUEST64_CX: 910 case CMD_XMIT_ELS_RSP64_CX: 911 rp = &hba->ring[FC_ELS_RING]; 912 (void) emlxs_els_handle_event(hba, rp, iocbq); 913 break; | 604extern uint8_t * 605emlxs_mem_pool_get(emlxs_hba_t *hba, MEMSEG *seg, uint32_t priority) 606{ 607 emlxs_port_t *port = &PPORT; 608 uint8_t *bp = NULL; 609 MATCHMAP *mp; 610 uint32_t free; |
914 | 611 |
915 case CMD_GEN_REQUEST64_CR: 916 case CMD_GEN_REQUEST64_CX: 917 rp = &hba->ring[FC_CT_RING]; 918 (void) emlxs_ct_handle_event(hba, rp, iocbq); 919 break; | 612 mutex_enter(&EMLXS_MEMGET_LOCK); |
920 | 613 |
921 default: 922 rp = (RING *)iocbq->ring; | 614 /* Check if memory segment destroyed! */ 615 if (seg->fc_total_memsize == 0) { 616 mutex_exit(&EMLXS_MEMGET_LOCK); 617 return (NULL); 618 } |
923 | 619 |
924 if (rp) { 925 if (rp->ringno == FC_ELS_RING) { 926 (void) emlxs_mem_put(hba, MEM_ELSBUF, 927 (uint8_t *)iocbq->bp); 928 } else if (rp->ringno == FC_CT_RING) { 929 (void) emlxs_mem_put(hba, MEM_CTBUF, 930 (uint8_t *)iocbq->bp); 931 } else if (rp->ringno == FC_IP_RING) { 932 (void) emlxs_mem_put(hba, MEM_IPBUF, 933 (uint8_t *)iocbq->bp); 934 } 935#ifdef SFCT_SUPPORT 936 else if (rp->ringno == FC_FCT_RING) { 937 (void) emlxs_mem_put(hba, MEM_FCTBUF, 938 (uint8_t *)iocbq->bp); 939 } 940#endif /* SFCT_SUPPORT */ | 620 /* Check priority and reserved status */ 621 if ((priority == 0) && seg->fc_reserved) { 622 free = seg->fc_memget_cnt + seg->fc_memput_cnt; 623 if (free <= seg->fc_reserved) { 624 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_alloc_failed_msg, 625 "%s low. (%d <= %d)", seg->fc_label, 626 free, seg->fc_reserved); |
941 | 627 |
942 } else if (iocbq->bp) { 943 (void) emlxs_mem_put(hba, MEM_BUF, 944 (uint8_t *)iocbq->bp); 945 } 946 947 if (!iocbq->sbp) { 948 (void) emlxs_mem_put(hba, MEM_IOCB, 949 (uint8_t *)iocbq); 950 } | 628 mutex_exit(&EMLXS_MEMGET_LOCK); 629 return (NULL); |
951 } 952 } 953 | 630 } 631 } 632 |
954 /* free the mapped address match area for each ring */ 955 for (j = 0; j < hba->ring_count; j++) { 956 rp = &hba->ring[j]; | 633top: |
957 | 634 |
958 /* Flush the ring */ 959 (void) emlxs_tx_ring_flush(hba, rp, 0); | 635 if (seg->fc_memget_ptr) { |
960 | 636 |
961 while (rp->fc_mpoff) { 962 uint64_t addr; | 637 bp = seg->fc_memget_ptr; |
963 | 638 |
964 addr = 0; 965 mm = (MATCHMAP *)(rp->fc_mpoff); | 639 /* Remove buffer from freelist */ 640 if (seg->fc_memget_end == bp) { 641 seg->fc_memget_ptr = NULL; 642 seg->fc_memget_end = NULL; 643 seg->fc_memget_cnt = 0; |
966 | 644 |
967 if ((j == FC_ELS_RING) || (j == FC_CT_RING) || 968#ifdef SFCT_SUPPORT 969 (j == FC_FCT_RING) || 970#endif /* SFCT_SUPPORT */ 971 (j == FC_IP_RING)) { 972 addr = mm->phys; 973 } | 645 } else { 646 seg->fc_memget_ptr = *((uint8_t **)bp); 647 seg->fc_memget_cnt--; 648 } |
974 | 649 |
975 if ((mm = emlxs_mem_get_vaddr(hba, rp, addr))) { 976 if (j == FC_ELS_RING) { 977 (void) emlxs_mem_put(hba, MEM_ELSBUF, 978 (uint8_t *)mm); 979 } else if (j == FC_CT_RING) { 980 (void) emlxs_mem_put(hba, MEM_CTBUF, 981 (uint8_t *)mm); 982 } else if (j == FC_IP_RING) { 983 (void) emlxs_mem_put(hba, MEM_IPBUF, 984 (uint8_t *)mm); 985 } 986#ifdef SFCT_SUPPORT 987 else if (j == FC_FCT_RING) { 988 (void) emlxs_mem_put(hba, MEM_FCTBUF, 989 (uint8_t *)mm); 990 } 991#endif /* SFCT_SUPPORT */ 992 993 } | 650 if (!(seg->fc_memflag & FC_MBUF_DMA)) { 651 bzero(bp, seg->fc_memsize); 652 } else { 653 mp = (MATCHMAP *)bp; 654 mp->fc_mptr = NULL; 655 mp->flag |= MAP_POOL_ALLOCATED; |
994 } | 656 } |
995 } | |
996 | 657 |
997#ifdef SLI3_SUPPORT 998 if (hba->flag & FC_HBQ_ENABLED) { 999 emlxs_hbq_free_all(hba, EMLXS_ELS_HBQ_ID); 1000 emlxs_hbq_free_all(hba, EMLXS_IP_HBQ_ID); 1001 emlxs_hbq_free_all(hba, EMLXS_CT_HBQ_ID); 1002#ifdef SFCT_SUPPORT 1003 if (hba->tgt_mode) { 1004 emlxs_hbq_free_all(hba, EMLXS_FCT_HBQ_ID); | 658 } else { 659 mutex_enter(&EMLXS_MEMPUT_LOCK); 660 if (seg->fc_memput_ptr) { 661 /* 662 * Move list from memput to memget 663 */ 664 seg->fc_memget_ptr = seg->fc_memput_ptr; 665 seg->fc_memget_end = seg->fc_memput_end; 666 seg->fc_memget_cnt = seg->fc_memput_cnt; 667 seg->fc_memput_ptr = NULL; 668 seg->fc_memput_end = NULL; 669 seg->fc_memput_cnt = 0; 670 mutex_exit(&EMLXS_MEMPUT_LOCK); 671 672 goto top; |
1005 } | 673 } |
1006#endif /* SFCT_SUPPORT */ | 674 mutex_exit(&EMLXS_MEMPUT_LOCK); |
1007 | 675 |
676 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_alloc_failed_msg, 677 "%s empty.", seg->fc_label); |
|
1008 } | 678 } |
1009#endif /* SLI3_SUPPORT */ | |
1010 | 679 |
1011 /* Free everything on mbox queue */ 1012 mbox = (MAILBOXQ *)(hba->mbox_queue.q_first); 1013 while (mbox) { 1014 mbsave = mbox; 1015 mbox = (MAILBOXQ *)mbox->next; 1016 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbsave); 1017 } 1018 hba->mbox_queue.q_first = NULL; 1019 hba->mbox_queue.q_last = NULL; 1020 hba->mbox_queue.q_cnt = 0; 1021 hba->mbox_queue_flag = 0; | 680 mutex_exit(&EMLXS_MEMGET_LOCK); |
1022 | 681 |
1023 /* Free the nodes */ 1024 for (j = 0; j < MAX_VPORTS; j++) { 1025 vport = &VPORT(j); 1026 if (vport->node_count) { 1027 emlxs_node_destroy_all(vport); 1028 } 1029 } | 682 return (bp); |
1030 | 683 |
1031 /* Free memory associated with all buffers on get buffer pool */ 1032 if (hba->iotag_table) { 1033 fcp_rp = &hba->ring[FC_FCP_RING]; 1034 ip_rp = &hba->ring[FC_IP_RING]; 1035 els_rp = &hba->ring[FC_ELS_RING]; 1036 ct_rp = &hba->ring[FC_CT_RING]; | 684} /* emlxs_mem_pool_get() */ |
1037 | 685 |
1038 total_iotags = fcp_rp->max_iotag + ip_rp->max_iotag + 1039 els_rp->max_iotag + ct_rp->max_iotag; | |
1040 | 686 |
1041 bzero(buf_info, sizeof (MBUF_INFO)); 1042 buf_info->size = total_iotags * sizeof (emlxs_buf_t *); 1043 buf_info->virt = hba->iotag_table; 1044 emlxs_mem_free(hba, buf_info); | 687extern MEMSEG * 688emlxs_mem_pool_put(emlxs_hba_t *hba, MEMSEG *seg, uint8_t *bp) 689{ 690 emlxs_port_t *port = &PPORT; 691 MATCHMAP *mp; 692 uint8_t *base; 693 uint8_t *end; |
1045 | 694 |
1046 hba->iotag_table = 0; 1047 } 1048#ifdef EMLXS_SPARC 1049 if (hba->fcp_bpl_table) { 1050 bzero(buf_info, sizeof (MBUF_INFO)); 1051 buf_info->size = fcp_rp->max_iotag * sizeof (MATCHMAP); 1052 buf_info->virt = hba->fcp_bpl_table; 1053 emlxs_mem_free(hba, buf_info); | 695 /* Free the pool object */ 696 mutex_enter(&EMLXS_MEMPUT_LOCK); |
1054 | 697 |
1055 hba->fcp_bpl_table = 0; | 698 /* Check if memory segment destroyed! */ 699 if (seg->fc_total_memsize == 0) { 700 mutex_exit(&EMLXS_MEMPUT_LOCK); 701 return (NULL); |
1056 } 1057 | 702 } 703 |
1058 if (hba->fcp_bpl_mp.virt) { 1059 bzero(buf_info, sizeof (MBUF_INFO)); 1060 buf_info->size = hba->fcp_bpl_mp.size; 1061 buf_info->virt = hba->fcp_bpl_mp.virt; 1062 buf_info->phys = hba->fcp_bpl_mp.phys; 1063 buf_info->dma_handle = hba->fcp_bpl_mp.dma_handle; 1064 buf_info->data_handle = hba->fcp_bpl_mp.data_handle; 1065 buf_info->flags = FC_MBUF_DMA; 1066 emlxs_mem_free(hba, buf_info); | 704 /* Check if buffer was just freed */ 705 if (seg->fc_memput_ptr == bp) { 706 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 707 "%s: Freeing free object: bp=%p", seg->fc_label, bp); |
1067 | 708 |
1068 bzero(&hba->fcp_bpl_mp, sizeof (MATCHMAP)); | 709 mutex_exit(&EMLXS_MEMPUT_LOCK); 710 return (NULL); |
1069 } | 711 } |
1070#endif /* EMLXS_SPARC */ | |
1071 | 712 |
1072 /* Free the memory segments */ 1073 for (j = 0; j < FC_MAX_SEG; j++) { 1074 mp = &hba->memseg[j]; | 713 /* Validate the buffer belongs to this pool */ 714 if (seg->fc_memflag & FC_MBUF_DMA) { 715 mp = (MATCHMAP *)bp; |
1075 | 716 |
1076 /* MEM_NLP, MEM_IOCB, MEM_MBOX */ 1077 if (j < MEM_BPL) { 1078 if (mp->fc_memstart_virt) { 1079 kmem_free(mp->fc_memstart_virt, 1080 mp->fc_total_memsize); 1081 bzero((char *)mp, sizeof (MEMSEG)); 1082 } | 717 if (!(mp->flag & MAP_POOL_ALLOCATED) || 718 (mp->segment != seg)) { 719 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 720 "emlxs_mem_pool_put: %s invalid: mp=%p " \ 721 "tag=0x%x flag=%x", seg->fc_label, 722 mp, mp->tag, mp->flag); |
1083 | 723 |
1084 continue; 1085 } | 724 EMLXS_STATE_CHANGE(hba, FC_ERROR); |
1086 | 725 |
1087 /* 1088 * MEM_BPL, MEM_BUF, MEM_ELSBUF, 1089 * MEM_IPBUF, MEM_CTBUF, MEM_FCTBUF 1090 */ | 726 mutex_exit(&EMLXS_MEMPUT_LOCK); |
1091 | 727 |
1092 /* Free memory associated with all buffers on get buffer pool */ 1093 mutex_enter(&EMLXS_MEMGET_LOCK); 1094 while ((bp = mp->fc_memget_ptr) != NULL) { 1095 mp->fc_memget_ptr = *((uint8_t **)bp); 1096 mm = (MATCHMAP *)bp; | 728 emlxs_thread_spawn(hba, emlxs_shutdown_thread, 729 NULL, NULL); |
1097 | 730 |
1098 bzero(buf_info, sizeof (MBUF_INFO)); 1099 buf_info->size = mm->size; 1100 buf_info->virt = mm->virt; 1101 buf_info->phys = mm->phys; 1102 buf_info->dma_handle = mm->dma_handle; 1103 buf_info->data_handle = mm->data_handle; 1104 buf_info->flags = FC_MBUF_DMA; 1105 emlxs_mem_free(hba, buf_info); 1106 1107 bzero(buf_info, sizeof (MBUF_INFO)); 1108 buf_info->size = sizeof (MATCHMAP); 1109 buf_info->virt = (uint32_t *)mm; 1110 emlxs_mem_free(hba, buf_info); | 731 return (NULL); |
1111 } | 732 } |
1112 mutex_exit(&EMLXS_MEMGET_LOCK); | |
1113 | 733 |
1114 /* Free memory associated with all buffers on put buffer pool */ 1115 mutex_enter(&EMLXS_MEMPUT_LOCK); 1116 while ((bp = mp->fc_memput_ptr) != NULL) { 1117 mp->fc_memput_ptr = *((uint8_t **)bp); 1118 mm = (MATCHMAP *)bp; | 734 } else { /* Vmem_pool */ 735 base = seg->fc_memstart_virt; 736 end = seg->fc_memstart_virt + seg->fc_total_memsize; |
1119 | 737 |
1120 bzero(buf_info, sizeof (MBUF_INFO)); 1121 buf_info->size = mm->size; 1122 buf_info->virt = mm->virt; 1123 buf_info->phys = mm->phys; 1124 buf_info->dma_handle = mm->dma_handle; 1125 buf_info->data_handle = mm->data_handle; 1126 buf_info->flags = FC_MBUF_DMA; 1127 emlxs_mem_free(hba, buf_info); | 738 if (bp < base || bp >= end) { 739 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 740 "emlxs_mem_pool_put: %s Invalid: bp=%p base=%p " \ 741 "end=%p", seg->fc_label, 742 bp, base, end); |
1128 | 743 |
1129 bzero(buf_info, sizeof (MBUF_INFO)); 1130 buf_info->size = sizeof (MATCHMAP); 1131 buf_info->virt = (uint32_t *)mm; 1132 emlxs_mem_free(hba, buf_info); | 744 EMLXS_STATE_CHANGE(hba, FC_ERROR); 745 746 mutex_exit(&EMLXS_MEMPUT_LOCK); 747 748 emlxs_thread_spawn(hba, emlxs_shutdown_thread, 749 NULL, NULL); 750 751 return (NULL); |
1133 } | 752 } |
1134 mutex_exit(&EMLXS_MEMPUT_LOCK); 1135 bzero((char *)mp, sizeof (MEMSEG)); | |
1136 } 1137 | 753 } 754 |
1138 return (0); | 755 /* Release buffer to the end of the freelist */ 756 if (seg->fc_memput_end == NULL) { 757 seg->fc_memput_ptr = bp; 758 seg->fc_memput_cnt = 1; 759 } else { 760 *((uint8_t **)(seg->fc_memput_end)) = bp; 761 seg->fc_memput_cnt++; 762 } 763 seg->fc_memput_end = bp; 764 *((uint8_t **)(bp)) = NULL; |
1139 | 765 |
1140} /* emlxs_mem_free_buffer() */ | 766 mutex_exit(&EMLXS_MEMPUT_LOCK); |
1141 | 767 |
768 return (seg); |
|
1142 | 769 |
1143extern uint8_t * 1144emlxs_mem_buf_alloc(emlxs_hba_t *hba) | 770} /* emlxs_mem_pool_put() */ 771 772 773extern MATCHMAP * 774emlxs_mem_buf_alloc(emlxs_hba_t *hba, uint32_t size) |
1145{ 1146 emlxs_port_t *port = &PPORT; 1147 uint8_t *bp = NULL; | 775{ 776 emlxs_port_t *port = &PPORT; 777 uint8_t *bp = NULL; |
1148 MATCHMAP *matp = NULL; | 778 MATCHMAP *mp = NULL; |
1149 MBUF_INFO *buf_info; 1150 MBUF_INFO bufinfo; 1151 1152 buf_info = &bufinfo; 1153 1154 bzero(buf_info, sizeof (MBUF_INFO)); 1155 buf_info->size = sizeof (MATCHMAP); 1156 buf_info->align = sizeof (void *); 1157 1158 (void) emlxs_mem_alloc(hba, buf_info); 1159 if (buf_info->virt == NULL) { 1160 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 1161 "MEM_BUF_ALLOC buffer."); 1162 | 779 MBUF_INFO *buf_info; 780 MBUF_INFO bufinfo; 781 782 buf_info = &bufinfo; 783 784 bzero(buf_info, sizeof (MBUF_INFO)); 785 buf_info->size = sizeof (MATCHMAP); 786 buf_info->align = sizeof (void *); 787 788 (void) emlxs_mem_alloc(hba, buf_info); 789 if (buf_info->virt == NULL) { 790 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 791 "MEM_BUF_ALLOC buffer."); 792 |
1163 return (0); | 793 return (NULL); |
1164 } 1165 | 794 } 795 |
1166 matp = (MATCHMAP *)buf_info->virt; 1167 bzero(matp, sizeof (MATCHMAP)); | 796 mp = (MATCHMAP *)buf_info->virt; 797 bzero(mp, sizeof (MATCHMAP)); |
1168 1169 bzero(buf_info, sizeof (MBUF_INFO)); | 798 799 bzero(buf_info, sizeof (MBUF_INFO)); |
1170 buf_info->size = MEM_BUF_SIZE; 1171 buf_info->flags = FC_MBUF_DMA; | 800 buf_info->size = size; 801 buf_info->flags = FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; |
1172 buf_info->align = 32; 1173 1174 (void) emlxs_mem_alloc(hba, buf_info); 1175 if (buf_info->virt == NULL) { 1176 1177 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 1178 "MEM_BUF_ALLOC DMA buffer."); 1179 | 802 buf_info->align = 32; 803 804 (void) emlxs_mem_alloc(hba, buf_info); 805 if (buf_info->virt == NULL) { 806 807 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 808 "MEM_BUF_ALLOC DMA buffer."); 809 |
1180 /* Free the matp object */ | 810 /* Free the mp object */ |
1181 bzero(buf_info, sizeof (MBUF_INFO)); 1182 buf_info->size = sizeof (MATCHMAP); | 811 bzero(buf_info, sizeof (MBUF_INFO)); 812 buf_info->size = sizeof (MATCHMAP); |
1183 buf_info->virt = (uint32_t *)matp; | 813 buf_info->virt = (uint32_t *)mp; |
1184 emlxs_mem_free(hba, buf_info); 1185 1186 return (0); 1187 } 1188 bp = (uint8_t *)buf_info->virt; 1189 bzero(bp, MEM_BUF_SIZE); 1190 | 814 emlxs_mem_free(hba, buf_info); 815 816 return (0); 817 } 818 bp = (uint8_t *)buf_info->virt; 819 bzero(bp, MEM_BUF_SIZE); 820 |
1191 matp->fc_mptr = NULL; 1192 matp->virt = buf_info->virt; 1193 matp->phys = buf_info->phys; 1194 matp->size = buf_info->size; 1195 matp->dma_handle = buf_info->dma_handle; 1196 matp->data_handle = buf_info->data_handle; 1197 matp->tag = MEM_BUF; 1198 matp->flag |= MAP_BUF_ALLOCATED; | 821 mp->virt = buf_info->virt; 822 mp->phys = buf_info->phys; 823 mp->size = buf_info->size; 824 mp->dma_handle = buf_info->dma_handle; 825 mp->data_handle = buf_info->data_handle; 826 mp->tag = MEM_BUF; 827 mp->flag |= MAP_BUF_ALLOCATED; |
1199 | 828 |
1200 return ((uint8_t *)matp); | 829 return (mp); |
1201 | 830 |
1202} /* emlxs_mem_buf_alloc() */ | 831} /* emlxs_mem_buf_alloc() */ |
1203 1204 | 832 833 |
1205extern uint8_t * 1206emlxs_mem_buf_free(emlxs_hba_t *hba, uint8_t *bp) | 834extern MATCHMAP * 835emlxs_mem_buf_free(emlxs_hba_t *hba, MATCHMAP *mp) |
1207{ | 836{ |
1208 MATCHMAP *matp; | |
1209 MBUF_INFO bufinfo; 1210 MBUF_INFO *buf_info; 1211 1212 buf_info = &bufinfo; 1213 | 837 MBUF_INFO bufinfo; 838 MBUF_INFO *buf_info; 839 840 buf_info = &bufinfo; 841 |
1214 matp = (MATCHMAP *)bp; 1215 1216 if (!(matp->flag & MAP_BUF_ALLOCATED)) { | 842 if (!(mp->flag & MAP_BUF_ALLOCATED)) { |
1217 return (NULL); 1218 } 1219 1220 bzero(buf_info, sizeof (MBUF_INFO)); | 843 return (NULL); 844 } 845 846 bzero(buf_info, sizeof (MBUF_INFO)); |
1221 buf_info->size = matp->size; 1222 buf_info->virt = matp->virt; 1223 buf_info->phys = matp->phys; 1224 buf_info->dma_handle = matp->dma_handle; 1225 buf_info->data_handle = matp->data_handle; | 847 buf_info->size = mp->size; 848 buf_info->virt = mp->virt; 849 buf_info->phys = mp->phys; 850 buf_info->dma_handle = mp->dma_handle; 851 buf_info->data_handle = mp->data_handle; |
1226 buf_info->flags = FC_MBUF_DMA; 1227 emlxs_mem_free(hba, buf_info); 1228 1229 bzero(buf_info, sizeof (MBUF_INFO)); 1230 buf_info->size = sizeof (MATCHMAP); | 852 buf_info->flags = FC_MBUF_DMA; 853 emlxs_mem_free(hba, buf_info); 854 855 bzero(buf_info, sizeof (MBUF_INFO)); 856 buf_info->size = sizeof (MATCHMAP); |
1231 buf_info->virt = (uint32_t *)matp; | 857 buf_info->virt = (uint32_t *)mp; |
1232 emlxs_mem_free(hba, buf_info); 1233 | 858 emlxs_mem_free(hba, buf_info); 859 |
1234 return (bp); | 860 return (mp); |
1235 | 861 |
1236} /* emlxs_mem_buf_free() */ | 862} /* emlxs_mem_buf_free() */ |
1237 1238 | 863 864 |
1239 1240/* 1241 * emlxs_mem_get 1242 * 1243 * This routine will get a free memory buffer. 1244 * seg identifies which buffer pool to use. 1245 * Returns the free buffer ptr or 0 for no buf 1246 */ | |
1247extern uint8_t * | 865extern uint8_t * |
1248emlxs_mem_get(emlxs_hba_t *hba, uint32_t arg) | 866emlxs_mem_get(emlxs_hba_t *hba, uint32_t seg_id, uint32_t priority) |
1249{ 1250 emlxs_port_t *port = &PPORT; | 867{ 868 emlxs_port_t *port = &PPORT; |
1251 MEMSEG *mp; 1252 uint8_t *bp = NULL; 1253 uint32_t seg = arg & MEM_SEG_MASK; | 869 uint8_t *bp; |
1254 MAILBOXQ *mbq; | 870 MAILBOXQ *mbq; |
1255 MATCHMAP *matp; | |
1256 IOCBQ *iocbq; 1257 NODELIST *node; | 871 IOCBQ *iocbq; 872 NODELIST *node; |
1258 uint8_t *base; 1259 uint8_t *end; | 873 MEMSEG *seg; |
1260 | 874 |
1261 /* range check on seg argument */ 1262 if (seg >= FC_MAX_SEG) { 1263 return (NULL); 1264 } | 875 if (seg_id >= FC_MAX_SEG) { |
1265 | 876 |
1266 mp = &hba->memseg[seg]; | 877 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 878 "emlxs_mem_get: Invalid segment id = %d", 879 seg_id); |
1267 | 880 |
1268 /* Check if memory segment destroyed! */ 1269 if (mp->fc_memsize == 0) { | |
1270 return (NULL); 1271 } | 881 return (NULL); 882 } |
883 seg = &hba->memseg[seg_id]; |
|
1272 | 884 |
1273 mutex_enter(&EMLXS_MEMGET_LOCK); | 885 /* Alloc a buffer from the pool */ 886 bp = emlxs_mem_pool_get(hba, seg, priority); |
1274 | 887 |
1275top: 1276 1277 if (mp->fc_memget_ptr) { 1278 bp = mp->fc_memget_ptr; 1279 1280 /* Checking if seg == MEM_MBOX, MEM_IOCB or MEM_NLP */ 1281 /* Verify buffer is in this memory region */ 1282 if (mp->fc_memstart_virt && mp->fc_total_memsize) { 1283 base = mp->fc_memstart_virt; 1284 end = mp->fc_memstart_virt + mp->fc_total_memsize; 1285 if (bp < base || bp >= end) { 1286 /* Invalidate the the get list */ 1287 mp->fc_memget_ptr = NULL; 1288 mp->fc_memget_end = NULL; 1289 mp->fc_memget_cnt = 0; 1290 1291 EMLXS_MSGF(EMLXS_CONTEXT, 1292 &emlxs_pool_error_msg, 1293 "Corruption detected: seg=%x bp=%p " 1294 "base=%p end=%p.", seg, bp, base, end); 1295 1296 emlxs_ffstate_change(hba, FC_ERROR); 1297 1298 mutex_exit(&EMLXS_MEMGET_LOCK); 1299 1300 emlxs_thread_spawn(hba, emlxs_shutdown_thread, 1301 NULL, NULL); 1302 1303 return (NULL); 1304 } 1305 } 1306 1307 /* 1308 * If a memory block exists, take it off freelist 1309 * and return it to the user. 1310 */ 1311 if (mp->fc_memget_end == bp) { 1312 mp->fc_memget_ptr = NULL; 1313 mp->fc_memget_end = NULL; 1314 mp->fc_memget_cnt = 0; 1315 1316 } else { 1317 /* 1318 * Pointer to the next free buffer 1319 */ 1320 mp->fc_memget_ptr = *((uint8_t **)bp); 1321 mp->fc_memget_cnt--; 1322 } 1323 1324 switch (seg) { | 888 if (bp) { 889 switch (seg_id) { |
1325 case MEM_MBOX: | 890 case MEM_MBOX: |
1326 bzero(bp, sizeof (MAILBOXQ)); 1327 | |
1328 mbq = (MAILBOXQ *)bp; 1329 mbq->flag |= MBQ_POOL_ALLOCATED; 1330 break; 1331 1332 case MEM_IOCB: | 891 mbq = (MAILBOXQ *)bp; 892 mbq->flag |= MBQ_POOL_ALLOCATED; 893 break; 894 895 case MEM_IOCB: |
1333 bzero(bp, sizeof (IOCBQ)); 1334 | |
1335 iocbq = (IOCBQ *)bp; 1336 iocbq->flag |= IOCB_POOL_ALLOCATED; 1337 break; 1338 1339 case MEM_NLP: | 896 iocbq = (IOCBQ *)bp; 897 iocbq->flag |= IOCB_POOL_ALLOCATED; 898 break; 899 900 case MEM_NLP: |
1340 bzero(bp, sizeof (NODELIST)); 1341 | |
1342 node = (NODELIST *)bp; 1343 node->flag |= NODE_POOL_ALLOCATED; 1344 break; | 901 node = (NODELIST *)bp; 902 node->flag |= NODE_POOL_ALLOCATED; 903 break; |
1345 1346 case MEM_BPL: 1347 case MEM_BUF: /* MEM_ELSBUF */ 1348 case MEM_IPBUF: 1349 case MEM_CTBUF: 1350#ifdef SFCT_SUPPORT 1351 case MEM_FCTBUF: 1352#endif /* SFCT_SUPPORT */ 1353 default: 1354 matp = (MATCHMAP *)bp; 1355 matp->fc_mptr = NULL; 1356 matp->flag |= MAP_POOL_ALLOCATED; 1357 break; | |
1358 } | 904 } |
1359 } else { 1360 mutex_enter(&EMLXS_MEMPUT_LOCK); 1361 if (mp->fc_memput_ptr) { 1362 /* 1363 * Move buffer from memput to memget 1364 */ 1365 mp->fc_memget_ptr = mp->fc_memput_ptr; 1366 mp->fc_memget_end = mp->fc_memput_end; 1367 mp->fc_memget_cnt = mp->fc_memput_cnt; 1368 mp->fc_memput_ptr = NULL; 1369 mp->fc_memput_end = NULL; 1370 mp->fc_memput_cnt = 0; 1371 mutex_exit(&EMLXS_MEMPUT_LOCK); 1372 1373 goto top; 1374 } 1375 mutex_exit(&EMLXS_MEMPUT_LOCK); 1376 1377 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_alloc_failed_msg, 1378 "Pool empty: seg=%x lowmem=%x free=%x", seg, 1379 mp->fc_lowmem, mp->fc_memget_cnt); 1380 1381 /* HBASTATS.memAllocErr++; */ | |
1382 } 1383 | 905 } 906 |
1384 mutex_exit(&EMLXS_MEMGET_LOCK); 1385 | |
1386 return (bp); 1387 | 907 return (bp); 908 |
1388} /* emlxs_mem_get() */ | 909} /* emlxs_mem_get() */ |
1389 1390 | 910 911 |
1391 | |
1392extern uint8_t * | 912extern uint8_t * |
1393emlxs_mem_put(emlxs_hba_t *hba, uint32_t seg, uint8_t *bp) | 913emlxs_mem_put(emlxs_hba_t *hba, uint32_t seg_id, uint8_t *bp) |
1394{ 1395 emlxs_port_t *port = &PPORT; | 914{ 915 emlxs_port_t *port = &PPORT; |
1396 MEMSEG *mp; 1397 uint8_t *oldbp; 1398 MATCHMAP *matp; 1399 IOCBQ *iocbq; | |
1400 MAILBOXQ *mbq; | 916 MAILBOXQ *mbq; |
917 IOCBQ *iocbq; |
|
1401 NODELIST *node; | 918 NODELIST *node; |
1402 uint8_t *base; 1403 uint8_t *end; | 919 MEMSEG *seg; 920 MATCHMAP *mp; |
1404 | 921 |
1405 if (!bp) { 1406 return (NULL); 1407 } | 922 if (seg_id >= FC_MAX_SEG) { |
1408 | 923 |
1409 /* Check on seg argument */ 1410 if (seg >= FC_MAX_SEG) { | 924 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 925 "emlxs_mem_put: Invalid segment id = %d: bp=%p", 926 seg_id, bp); 927 |
1411 return (NULL); 1412 } | 928 return (NULL); 929 } |
930 seg = &hba->memseg[seg_id]; |
|
1413 | 931 |
1414 mp = &hba->memseg[seg]; 1415 1416 switch (seg) { | 932 /* Verify buffer */ 933 switch (seg_id) { |
1417 case MEM_MBOX: 1418 mbq = (MAILBOXQ *)bp; 1419 1420 if (!(mbq->flag & MBQ_POOL_ALLOCATED)) { | 934 case MEM_MBOX: 935 mbq = (MAILBOXQ *)bp; 936 937 if (!(mbq->flag & MBQ_POOL_ALLOCATED)) { |
1421 return (bp); | 938 return (NULL); |
1422 } 1423 break; 1424 1425 case MEM_IOCB: 1426 iocbq = (IOCBQ *)bp; 1427 | 939 } 940 break; 941 942 case MEM_IOCB: 943 iocbq = (IOCBQ *)bp; 944 |
1428 /* Check to make sure the IOCB is pool allocated */ | |
1429 if (!(iocbq->flag & IOCB_POOL_ALLOCATED)) { | 945 if (!(iocbq->flag & IOCB_POOL_ALLOCATED)) { |
1430 return (bp); | 946 return (NULL); |
1431 } 1432 1433 /* Any IOCBQ with a packet attached did not come */ 1434 /* from our pool */ 1435 if (iocbq->sbp) { | 947 } 948 949 /* Any IOCBQ with a packet attached did not come */ 950 /* from our pool */ 951 if (iocbq->sbp) { |
1436 return (bp); | 952 return (NULL); |
1437 } 1438 break; 1439 1440 case MEM_NLP: 1441 node = (NODELIST *)bp; 1442 | 953 } 954 break; 955 956 case MEM_NLP: 957 node = (NODELIST *)bp; 958 |
1443 /* Check to make sure the NODE is pool allocated */ | |
1444 if (!(node->flag & NODE_POOL_ALLOCATED)) { | 959 if (!(node->flag & NODE_POOL_ALLOCATED)) { |
1445 return (bp); | 960 return (NULL); |
1446 } 1447 break; 1448 | 961 } 962 break; 963 |
1449 case MEM_BPL: 1450 case MEM_BUF: /* MEM_ELSBUF */ 1451 case MEM_IPBUF: 1452 case MEM_CTBUF: 1453#ifdef SFCT_SUPPORT 1454 case MEM_FCTBUF: 1455#endif /* SFCT_SUPPORT */ | |
1456 default: | 964 default: |
1457 matp = (MATCHMAP *)bp; | 965 mp = (MATCHMAP *)bp; |
1458 | 966 |
1459 if (matp->flag & MAP_BUF_ALLOCATED) { 1460 return (emlxs_mem_buf_free(hba, bp)); | 967 if (mp->flag & MAP_BUF_ALLOCATED) { 968 return ((uint8_t *)emlxs_mem_buf_free(hba, mp)); |
1461 } 1462 | 969 } 970 |
1463 if (matp->flag & MAP_TABLE_ALLOCATED) { | 971 if (mp->flag & MAP_TABLE_ALLOCATED) { |
1464 return (bp); 1465 } 1466 | 972 return (bp); 973 } 974 |
1467 /* Check to make sure the MATCHMAP is pool allocated */ 1468 if (!(matp->flag & MAP_POOL_ALLOCATED)) { 1469 return (bp); | 975 if (!(mp->flag & MAP_POOL_ALLOCATED)) { 976 return (NULL); |
1470 } 1471 break; 1472 } 1473 | 977 } 978 break; 979 } 980 |
1474 /* Free the pool object */ 1475 mutex_enter(&EMLXS_MEMPUT_LOCK); 1476 1477 /* Check if memory segment destroyed! */ 1478 if (mp->fc_memsize == 0) { 1479 mutex_exit(&EMLXS_MEMPUT_LOCK); | 981 /* Free a buffer to the pool */ 982 if (emlxs_mem_pool_put(hba, seg, bp) == NULL) { |
1480 return (NULL); 1481 } 1482 | 983 return (NULL); 984 } 985 |
1483 /* Check if buffer was just freed */ 1484 if (mp->fc_memput_ptr == bp) { 1485 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1486 "Freeing Free object: seg=%x bp=%p", seg, bp); 1487 1488 mutex_exit(&EMLXS_MEMPUT_LOCK); 1489 return (NULL); 1490 } 1491 1492 /* Validate the buffer */ 1493 1494 /* Checking if seg == MEM_BUF, MEM_BPL, MEM_CTBUF, */ 1495 /* MEM_IPBUF or MEM_FCTBUF */ 1496 if (mp->fc_memflag & FC_MEM_DMA) { 1497 if (matp->tag != seg) { 1498 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1499 "Corruption detected: seg=%x tag=%x bp=%p", seg, 1500 matp->tag, bp); 1501 1502 emlxs_ffstate_change(hba, FC_ERROR); 1503 1504 mutex_exit(&EMLXS_MEMPUT_LOCK); 1505 1506 emlxs_thread_spawn(hba, emlxs_shutdown_thread, 1507 NULL, NULL); 1508 1509 return (NULL); 1510 } 1511 } 1512 1513 /* Checking (seg == MEM_MBOX || seg == MEM_IOCB || seg == MEM_NLP) */ 1514 else if (mp->fc_memstart_virt && mp->fc_total_memsize) { 1515 base = mp->fc_memstart_virt; 1516 end = mp->fc_memstart_virt + mp->fc_total_memsize; 1517 if (bp < base || bp >= end) { 1518 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1519 "Corruption detected: seg=%x bp=%p base=%p end=%p", 1520 seg, bp, base, end); 1521 1522 emlxs_ffstate_change(hba, FC_ERROR); 1523 1524 mutex_exit(&EMLXS_MEMPUT_LOCK); 1525 1526 emlxs_thread_spawn(hba, emlxs_shutdown_thread, 1527 NULL, NULL); 1528 1529 return (NULL); 1530 } 1531 } 1532 1533 /* Release to the first place of the freelist */ 1534 oldbp = mp->fc_memput_ptr; 1535 mp->fc_memput_ptr = bp; 1536 *((uint8_t **)bp) = oldbp; 1537 1538 if (oldbp == NULL) { 1539 mp->fc_memput_end = bp; 1540 mp->fc_memput_cnt = 1; 1541 } else { 1542 mp->fc_memput_cnt++; 1543 } 1544 1545 mutex_exit(&EMLXS_MEMPUT_LOCK); 1546 | |
1547 return (bp); 1548 | 986 return (bp); 987 |
1549} /* emlxs_mem_put() */ | 988} /* emlxs_mem_put() */ |
1550 1551 | 989 990 |
1552 | |
1553/* 1554 * Look up the virtual address given a mapped address 1555 */ | 991/* 992 * Look up the virtual address given a mapped address 993 */ |
994/* SLI3 */ |
|
1556extern MATCHMAP * 1557emlxs_mem_get_vaddr(emlxs_hba_t *hba, RING *rp, uint64_t mapbp) 1558{ 1559 emlxs_port_t *port = &PPORT; 1560 MATCHMAP *prev; 1561 MATCHMAP *mp; 1562 | 995extern MATCHMAP * 996emlxs_mem_get_vaddr(emlxs_hba_t *hba, RING *rp, uint64_t mapbp) 997{ 998 emlxs_port_t *port = &PPORT; 999 MATCHMAP *prev; 1000 MATCHMAP *mp; 1001 |
1563 switch (rp->ringno) { 1564 case FC_ELS_RING: | 1002 if (rp->ringno == hba->channel_els) { |
1565 mp = (MATCHMAP *)rp->fc_mpoff; 1566 prev = 0; 1567 1568 while (mp) { 1569 if (mp->phys == mapbp) { 1570 if (prev == 0) { 1571 rp->fc_mpoff = mp->fc_mptr; 1572 } else { 1573 prev->fc_mptr = mp->fc_mptr; 1574 } 1575 1576 if (rp->fc_mpon == (uint8_t *)mp) { 1577 rp->fc_mpon = (uint8_t *)prev; 1578 } 1579 1580 mp->fc_mptr = 0; 1581 | 1003 mp = (MATCHMAP *)rp->fc_mpoff; 1004 prev = 0; 1005 1006 while (mp) { 1007 if (mp->phys == mapbp) { 1008 if (prev == 0) { 1009 rp->fc_mpoff = mp->fc_mptr; 1010 } else { 1011 prev->fc_mptr = mp->fc_mptr; 1012 } 1013 1014 if (rp->fc_mpon == (uint8_t *)mp) { 1015 rp->fc_mpon = (uint8_t *)prev; 1016 } 1017 1018 mp->fc_mptr = 0; 1019 |
1582 emlxs_mpdata_sync(mp->dma_handle, 0, mp->size, | 1020 EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, |
1583 DDI_DMA_SYNC_FORKERNEL); 1584 1585 HBASTATS.ElsUbPosted--; 1586 1587 return (mp); 1588 } 1589 1590 prev = mp; 1591 mp = (MATCHMAP *)mp->fc_mptr; 1592 } 1593 1594 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1595 "ELS Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1596 mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1597 | 1021 DDI_DMA_SYNC_FORKERNEL); 1022 1023 HBASTATS.ElsUbPosted--; 1024 1025 return (mp); 1026 } 1027 1028 prev = mp; 1029 mp = (MATCHMAP *)mp->fc_mptr; 1030 } 1031 1032 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1033 "ELS Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1034 mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1035 |
1598 break; | 1036 } else if (rp->ringno == hba->channel_ct) { |
1599 | 1037 |
1600 case FC_CT_RING: | |
1601 mp = (MATCHMAP *)rp->fc_mpoff; 1602 prev = 0; 1603 1604 while (mp) { 1605 if (mp->phys == mapbp) { 1606 if (prev == 0) { 1607 rp->fc_mpoff = mp->fc_mptr; 1608 } else { 1609 prev->fc_mptr = mp->fc_mptr; 1610 } 1611 1612 if (rp->fc_mpon == (uint8_t *)mp) { 1613 rp->fc_mpon = (uint8_t *)prev; 1614 } 1615 1616 mp->fc_mptr = 0; 1617 | 1038 mp = (MATCHMAP *)rp->fc_mpoff; 1039 prev = 0; 1040 1041 while (mp) { 1042 if (mp->phys == mapbp) { 1043 if (prev == 0) { 1044 rp->fc_mpoff = mp->fc_mptr; 1045 } else { 1046 prev->fc_mptr = mp->fc_mptr; 1047 } 1048 1049 if (rp->fc_mpon == (uint8_t *)mp) { 1050 rp->fc_mpon = (uint8_t *)prev; 1051 } 1052 1053 mp->fc_mptr = 0; 1054 |
1618 emlxs_mpdata_sync(mp->dma_handle, 0, mp->size, | 1055 EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, |
1619 DDI_DMA_SYNC_FORKERNEL); 1620 1621 HBASTATS.CtUbPosted--; 1622 1623 return (mp); 1624 } 1625 1626 prev = mp; 1627 mp = (MATCHMAP *)mp->fc_mptr; 1628 } 1629 1630 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1631 "CT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1632 mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1633 | 1056 DDI_DMA_SYNC_FORKERNEL); 1057 1058 HBASTATS.CtUbPosted--; 1059 1060 return (mp); 1061 } 1062 1063 prev = mp; 1064 mp = (MATCHMAP *)mp->fc_mptr; 1065 } 1066 1067 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1068 "CT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1069 mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1070 |
1634 break; | 1071 } else if (rp->ringno == hba->channel_ip) { |
1635 | 1072 |
1636 case FC_IP_RING: | |
1637 mp = (MATCHMAP *)rp->fc_mpoff; 1638 prev = 0; 1639 1640 while (mp) { 1641 if (mp->phys == mapbp) { 1642 if (prev == 0) { 1643 rp->fc_mpoff = mp->fc_mptr; 1644 } else { 1645 prev->fc_mptr = mp->fc_mptr; 1646 } 1647 1648 if (rp->fc_mpon == (uint8_t *)mp) { 1649 rp->fc_mpon = (uint8_t *)prev; 1650 } 1651 1652 mp->fc_mptr = 0; 1653 | 1073 mp = (MATCHMAP *)rp->fc_mpoff; 1074 prev = 0; 1075 1076 while (mp) { 1077 if (mp->phys == mapbp) { 1078 if (prev == 0) { 1079 rp->fc_mpoff = mp->fc_mptr; 1080 } else { 1081 prev->fc_mptr = mp->fc_mptr; 1082 } 1083 1084 if (rp->fc_mpon == (uint8_t *)mp) { 1085 rp->fc_mpon = (uint8_t *)prev; 1086 } 1087 1088 mp->fc_mptr = 0; 1089 |
1654 emlxs_mpdata_sync(mp->dma_handle, 0, mp->size, | 1090 EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, |
1655 DDI_DMA_SYNC_FORKERNEL); 1656 1657 HBASTATS.IpUbPosted--; 1658 1659 return (mp); 1660 } 1661 1662 prev = mp; 1663 mp = (MATCHMAP *)mp->fc_mptr; 1664 } 1665 1666 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1667 "IP Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1668 mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1669 | 1091 DDI_DMA_SYNC_FORKERNEL); 1092 1093 HBASTATS.IpUbPosted--; 1094 1095 return (mp); 1096 } 1097 1098 prev = mp; 1099 mp = (MATCHMAP *)mp->fc_mptr; 1100 } 1101 1102 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1103 "IP Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1104 mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1105 |
1670 break; 1671 | |
1672#ifdef SFCT_SUPPORT | 1106#ifdef SFCT_SUPPORT |
1673 case FC_FCT_RING: | 1107 } else if (rp->ringno == hba->CHANNEL_FCT) { |
1674 mp = (MATCHMAP *)rp->fc_mpoff; 1675 prev = 0; 1676 1677 while (mp) { 1678 if (mp->phys == mapbp) { 1679 if (prev == 0) { 1680 rp->fc_mpoff = mp->fc_mptr; 1681 } else { 1682 prev->fc_mptr = mp->fc_mptr; 1683 } 1684 1685 if (rp->fc_mpon == (uint8_t *)mp) { 1686 rp->fc_mpon = (uint8_t *)prev; 1687 } 1688 1689 mp->fc_mptr = 0; 1690 | 1108 mp = (MATCHMAP *)rp->fc_mpoff; 1109 prev = 0; 1110 1111 while (mp) { 1112 if (mp->phys == mapbp) { 1113 if (prev == 0) { 1114 rp->fc_mpoff = mp->fc_mptr; 1115 } else { 1116 prev->fc_mptr = mp->fc_mptr; 1117 } 1118 1119 if (rp->fc_mpon == (uint8_t *)mp) { 1120 rp->fc_mpon = (uint8_t *)prev; 1121 } 1122 1123 mp->fc_mptr = 0; 1124 |
1691 emlxs_mpdata_sync(mp->dma_handle, 0, mp->size, | 1125 EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, |
1692 DDI_DMA_SYNC_FORKERNEL); 1693 1694 HBASTATS.FctUbPosted--; 1695 1696 return (mp); 1697 } 1698 1699 prev = mp; 1700 mp = (MATCHMAP *)mp->fc_mptr; 1701 } 1702 1703 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1704 "FCT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1705 mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1706 | 1126 DDI_DMA_SYNC_FORKERNEL); 1127 1128 HBASTATS.FctUbPosted--; 1129 1130 return (mp); 1131 } 1132 1133 prev = mp; 1134 mp = (MATCHMAP *)mp->fc_mptr; 1135 } 1136 1137 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1138 "FCT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1139 mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1140 |
1707 break; | |
1708#endif /* SFCT_SUPPORT */ 1709 } 1710 1711 return (0); 1712 | 1141#endif /* SFCT_SUPPORT */ 1142 } 1143 1144 return (0); 1145 |
1713} /* emlxs_mem_get_vaddr() */ | 1146} /* emlxs_mem_get_vaddr() */ |
1714 1715 1716/* 1717 * Given a virtual address bp, generate the physical mapped address and 1718 * place it where addr points to. Save the address pair for lookup later. 1719 */ | 1147 1148 1149/* 1150 * Given a virtual address bp, generate the physical mapped address and 1151 * place it where addr points to. Save the address pair for lookup later. 1152 */ |
1153/* SLI3 */ |
|
1720extern void 1721emlxs_mem_map_vaddr(emlxs_hba_t *hba, RING *rp, MATCHMAP *mp, 1722 uint32_t *haddr, uint32_t *laddr) 1723{ | 1154extern void 1155emlxs_mem_map_vaddr(emlxs_hba_t *hba, RING *rp, MATCHMAP *mp, 1156 uint32_t *haddr, uint32_t *laddr) 1157{ |
1724 switch (rp->ringno) { 1725 case FC_ELS_RING: | 1158 if (rp->ringno == hba->channel_els) { |
1726 /* 1727 * Update slot fc_mpon points to then bump it 1728 * fc_mpoff is pointer head of the list. 1729 * fc_mpon is pointer tail of the list. 1730 */ 1731 mp->fc_mptr = 0; 1732 if (rp->fc_mpoff == 0) { 1733 rp->fc_mpoff = (uint8_t *)mp; 1734 rp->fc_mpon = (uint8_t *)mp; 1735 } else { 1736 ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1737 (uint8_t *)mp; 1738 rp->fc_mpon = (uint8_t *)mp; 1739 } 1740 1741 if (hba->flag & FC_SLIM2_MODE) { 1742 1743 /* return mapped address */ | 1159 /* 1160 * Update slot fc_mpon points to then bump it 1161 * fc_mpoff is pointer head of the list. 1162 * fc_mpon is pointer tail of the list. 1163 */ 1164 mp->fc_mptr = 0; 1165 if (rp->fc_mpoff == 0) { 1166 rp->fc_mpoff = (uint8_t *)mp; 1167 rp->fc_mpon = (uint8_t *)mp; 1168 } else { 1169 ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1170 (uint8_t *)mp; 1171 rp->fc_mpon = (uint8_t *)mp; 1172 } 1173 1174 if (hba->flag & FC_SLIM2_MODE) { 1175 1176 /* return mapped address */ |
1744 *haddr = putPaddrHigh(mp->phys); | 1177 *haddr = PADDR_HI(mp->phys); |
1745 /* return mapped address */ | 1178 /* return mapped address */ |
1746 *laddr = putPaddrLow(mp->phys); | 1179 *laddr = PADDR_LO(mp->phys); |
1747 } else { 1748 /* return mapped address */ | 1180 } else { 1181 /* return mapped address */ |
1749 *laddr = putPaddrLow(mp->phys); | 1182 *laddr = PADDR_LO(mp->phys); |
1750 } 1751 1752 HBASTATS.ElsUbPosted++; 1753 | 1183 } 1184 1185 HBASTATS.ElsUbPosted++; 1186 |
1754 break; 1755 1756 case FC_CT_RING: | 1187 } else if (rp->ringno == hba->channel_ct) { |
1757 /* 1758 * Update slot fc_mpon points to then bump it 1759 * fc_mpoff is pointer head of the list. 1760 * fc_mpon is pointer tail of the list. 1761 */ 1762 mp->fc_mptr = 0; 1763 if (rp->fc_mpoff == 0) { 1764 rp->fc_mpoff = (uint8_t *)mp; 1765 rp->fc_mpon = (uint8_t *)mp; 1766 } else { 1767 ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1768 (uint8_t *)mp; 1769 rp->fc_mpon = (uint8_t *)mp; 1770 } 1771 1772 if (hba->flag & FC_SLIM2_MODE) { 1773 /* return mapped address */ | 1188 /* 1189 * Update slot fc_mpon points to then bump it 1190 * fc_mpoff is pointer head of the list. 1191 * fc_mpon is pointer tail of the list. 1192 */ 1193 mp->fc_mptr = 0; 1194 if (rp->fc_mpoff == 0) { 1195 rp->fc_mpoff = (uint8_t *)mp; 1196 rp->fc_mpon = (uint8_t *)mp; 1197 } else { 1198 ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1199 (uint8_t *)mp; 1200 rp->fc_mpon = (uint8_t *)mp; 1201 } 1202 1203 if (hba->flag & FC_SLIM2_MODE) { 1204 /* return mapped address */ |
1774 *haddr = putPaddrHigh(mp->phys); | 1205 *haddr = PADDR_HI(mp->phys); |
1775 /* return mapped address */ | 1206 /* return mapped address */ |
1776 *laddr = putPaddrLow(mp->phys); | 1207 *laddr = PADDR_LO(mp->phys); |
1777 } else { 1778 /* return mapped address */ | 1208 } else { 1209 /* return mapped address */ |
1779 *laddr = putPaddrLow(mp->phys); | 1210 *laddr = PADDR_LO(mp->phys); |
1780 } 1781 1782 HBASTATS.CtUbPosted++; 1783 | 1211 } 1212 1213 HBASTATS.CtUbPosted++; 1214 |
1784 break; | |
1785 | 1215 |
1786 1787 case FC_IP_RING: | 1216 } else if (rp->ringno == hba->channel_ip) { |
1788 /* 1789 * Update slot fc_mpon points to then bump it 1790 * fc_mpoff is pointer head of the list. 1791 * fc_mpon is pointer tail of the list. 1792 */ 1793 mp->fc_mptr = 0; 1794 if (rp->fc_mpoff == 0) { 1795 rp->fc_mpoff = (uint8_t *)mp; 1796 rp->fc_mpon = (uint8_t *)mp; 1797 } else { 1798 ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1799 (uint8_t *)mp; 1800 rp->fc_mpon = (uint8_t *)mp; 1801 } 1802 1803 if (hba->flag & FC_SLIM2_MODE) { 1804 /* return mapped address */ | 1217 /* 1218 * Update slot fc_mpon points to then bump it 1219 * fc_mpoff is pointer head of the list. 1220 * fc_mpon is pointer tail of the list. 1221 */ 1222 mp->fc_mptr = 0; 1223 if (rp->fc_mpoff == 0) { 1224 rp->fc_mpoff = (uint8_t *)mp; 1225 rp->fc_mpon = (uint8_t *)mp; 1226 } else { 1227 ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1228 (uint8_t *)mp; 1229 rp->fc_mpon = (uint8_t *)mp; 1230 } 1231 1232 if (hba->flag & FC_SLIM2_MODE) { 1233 /* return mapped address */ |
1805 *haddr = putPaddrHigh(mp->phys); 1806 *laddr = putPaddrLow(mp->phys); | 1234 *haddr = PADDR_HI(mp->phys); 1235 *laddr = PADDR_LO(mp->phys); |
1807 } else { | 1236 } else { |
1808 *laddr = putPaddrLow(mp->phys); | 1237 *laddr = PADDR_LO(mp->phys); |
1809 } 1810 1811 HBASTATS.IpUbPosted++; | 1238 } 1239 1240 HBASTATS.IpUbPosted++; |
1812 break; | |
1813 1814 1815#ifdef SFCT_SUPPORT | 1241 1242 1243#ifdef SFCT_SUPPORT |
1816 case FC_FCT_RING: | 1244 } else if (rp->ringno == hba->CHANNEL_FCT) { |
1817 /* 1818 * Update slot fc_mpon points to then bump it 1819 * fc_mpoff is pointer head of the list. 1820 * fc_mpon is pointer tail of the list. 1821 */ 1822 mp->fc_mptr = 0; 1823 if (rp->fc_mpoff == 0) { 1824 rp->fc_mpoff = (uint8_t *)mp; 1825 rp->fc_mpon = (uint8_t *)mp; 1826 } else { 1827 ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1828 (uint8_t *)mp; 1829 rp->fc_mpon = (uint8_t *)mp; 1830 } 1831 1832 if (hba->flag & FC_SLIM2_MODE) { 1833 /* return mapped address */ | 1245 /* 1246 * Update slot fc_mpon points to then bump it 1247 * fc_mpoff is pointer head of the list. 1248 * fc_mpon is pointer tail of the list. 1249 */ 1250 mp->fc_mptr = 0; 1251 if (rp->fc_mpoff == 0) { 1252 rp->fc_mpoff = (uint8_t *)mp; 1253 rp->fc_mpon = (uint8_t *)mp; 1254 } else { 1255 ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1256 (uint8_t *)mp; 1257 rp->fc_mpon = (uint8_t *)mp; 1258 } 1259 1260 if (hba->flag & FC_SLIM2_MODE) { 1261 /* return mapped address */ |
1834 *haddr = putPaddrHigh(mp->phys); | 1262 *haddr = PADDR_HI(mp->phys); |
1835 /* return mapped address */ | 1263 /* return mapped address */ |
1836 *laddr = putPaddrLow(mp->phys); | 1264 *laddr = PADDR_LO(mp->phys); |
1837 } else { 1838 /* return mapped address */ | 1265 } else { 1266 /* return mapped address */ |
1839 *laddr = putPaddrLow(mp->phys); | 1267 *laddr = PADDR_LO(mp->phys); |
1840 } 1841 1842 HBASTATS.FctUbPosted++; | 1268 } 1269 1270 HBASTATS.FctUbPosted++; |
1843 break; | 1271 |
1844#endif /* SFCT_SUPPORT */ 1845 } | 1272#endif /* SFCT_SUPPORT */ 1273 } |
1846} /* emlxs_mem_map_vaddr() */ | 1274} /* emlxs_mem_map_vaddr() */ |
1847 1848 | 1275 1276 |
1849#ifdef SLI3_SUPPORT 1850 | 1277/* SLI3 */ |
1851uint32_t 1852emlxs_hbq_alloc(emlxs_hba_t *hba, uint32_t hbq_id) 1853{ 1854 emlxs_port_t *port = &PPORT; 1855 HBQ_INIT_t *hbq; 1856 MBUF_INFO *buf_info; 1857 MBUF_INFO bufinfo; 1858 | 1278uint32_t 1279emlxs_hbq_alloc(emlxs_hba_t *hba, uint32_t hbq_id) 1280{ 1281 emlxs_port_t *port = &PPORT; 1282 HBQ_INIT_t *hbq; 1283 MBUF_INFO *buf_info; 1284 MBUF_INFO bufinfo; 1285 |
1859 hbq = &hba->hbq_table[hbq_id]; | 1286 hbq = &hba->sli.sli3.hbq_table[hbq_id]; |
1860 1861 if (hbq->HBQ_host_buf.virt == 0) { 1862 buf_info = &bufinfo; 1863 1864 /* Get the system's page size in a DDI-compliant way. */ 1865 bzero(buf_info, sizeof (MBUF_INFO)); 1866 buf_info->size = hbq->HBQ_numEntries * sizeof (HBQE_t); 1867 buf_info->flags = FC_MBUF_DMA; --- 14 unchanged lines hidden (view full) --- 1882 hbq->HBQ_host_buf.size = buf_info->size; 1883 hbq->HBQ_host_buf.tag = hbq_id; 1884 1885 bzero((char *)hbq->HBQ_host_buf.virt, buf_info->size); 1886 } 1887 1888 return (0); 1889 | 1287 1288 if (hbq->HBQ_host_buf.virt == 0) { 1289 buf_info = &bufinfo; 1290 1291 /* Get the system's page size in a DDI-compliant way. */ 1292 bzero(buf_info, sizeof (MBUF_INFO)); 1293 buf_info->size = hbq->HBQ_numEntries * sizeof (HBQE_t); 1294 buf_info->flags = FC_MBUF_DMA; --- 14 unchanged lines hidden (view full) --- 1309 hbq->HBQ_host_buf.size = buf_info->size; 1310 hbq->HBQ_host_buf.tag = hbq_id; 1311 1312 bzero((char *)hbq->HBQ_host_buf.virt, buf_info->size); 1313 } 1314 1315 return (0); 1316 |
1890} /* emlxs_hbq_alloc() */ 1891 1892 1893#endif /* SLI3_SUPPORT */ | 1317} /* emlxs_hbq_alloc() */ |