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