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