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() */