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