1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte 
22fcf3ce44SJohn Forte /*
23*a9800bebSGarrett D'Amore  * Copyright 2010 Emulex.  All rights reserved.
2482527734SSukumar Swaminathan  * Use is subject to license terms.
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
2782527734SSukumar Swaminathan 
28291a2b48SSukumar Swaminathan #include <emlxs.h>
29fcf3ce44SJohn Forte 
30fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_MEM_C);
31fcf3ce44SJohn Forte 
32fcf3ce44SJohn Forte 
33fcf3ce44SJohn Forte extern int32_t
34fcf3ce44SJohn Forte emlxs_mem_alloc_buffer(emlxs_hba_t *hba)
35fcf3ce44SJohn Forte {
36fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
37fcf3ce44SJohn Forte 	emlxs_config_t *cfg;
38fcf3ce44SJohn Forte 	MBUF_INFO *buf_info;
3982527734SSukumar Swaminathan 	MEMSEG *seg;
40fcf3ce44SJohn Forte 	MBUF_INFO bufinfo;
41fcf3ce44SJohn Forte 	int32_t i;
4282527734SSukumar Swaminathan 	int32_t cnt;
43fcf3ce44SJohn Forte #ifdef EMLXS_SPARC
4482527734SSukumar Swaminathan 	MATCHMAP *mp;
4582527734SSukumar Swaminathan 	MATCHMAP **fcp_bpl_table;
46fcf3ce44SJohn Forte #endif	/* EMLXS_SPARC */
47fcf3ce44SJohn Forte 
48fcf3ce44SJohn Forte 	buf_info = &bufinfo;
49fcf3ce44SJohn Forte 	cfg = &CFG;
50fcf3ce44SJohn Forte 
5182527734SSukumar Swaminathan 	bzero(hba->memseg, sizeof (hba->memseg));
52fcf3ce44SJohn Forte 
53fcf3ce44SJohn Forte 	/*
54fcf3ce44SJohn Forte 	 * Initialize fc_table
55fcf3ce44SJohn Forte 	 */
5682527734SSukumar Swaminathan 	cnt = cfg[CFG_NUM_IOTAGS].current;
5782527734SSukumar Swaminathan 	if (cnt) {
58*a9800bebSGarrett D'Amore 		hba->max_iotag = (uint16_t)cnt;
5982527734SSukumar Swaminathan 	}
6082527734SSukumar Swaminathan 	/* ioatg 0 is not used, iotags 1 thru max_iotag-1 are used */
61fcf3ce44SJohn Forte 
62fcf3ce44SJohn Forte 	/* Allocate the fc_table */
63fcf3ce44SJohn Forte 	bzero(buf_info, sizeof (MBUF_INFO));
6482527734SSukumar Swaminathan 	buf_info->size = (hba->max_iotag * sizeof (emlxs_buf_t *));
65fcf3ce44SJohn Forte 
66fcf3ce44SJohn Forte 	(void) emlxs_mem_alloc(hba, buf_info);
67fcf3ce44SJohn Forte 	if (buf_info->virt == NULL) {
68fcf3ce44SJohn Forte 
69fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
70fcf3ce44SJohn Forte 		    "fc_table buffer.");
71fcf3ce44SJohn Forte 
7282527734SSukumar Swaminathan 		goto failed;
73fcf3ce44SJohn Forte 	}
7482527734SSukumar Swaminathan 	hba->fc_table = buf_info->virt;
7582527734SSukumar Swaminathan 	bzero(hba->fc_table, buf_info->size);
76fcf3ce44SJohn Forte 
77fcf3ce44SJohn Forte #ifdef EMLXS_SPARC
7882527734SSukumar Swaminathan 	if (!(hba->model_info.sli_mask & EMLXS_SLI4_MASK)) {
79fcf3ce44SJohn Forte 	/*
8082527734SSukumar Swaminathan 	 * Allocate and Initialize FCP MEM_BPL table
81291a2b48SSukumar Swaminathan 	 * This is for increased performance on sparc
82fcf3ce44SJohn Forte 	 */
83fcf3ce44SJohn Forte 	bzero(buf_info, sizeof (MBUF_INFO));
8482527734SSukumar Swaminathan 	buf_info->size = hba->max_iotag * sizeof (MATCHMAP *);
85fcf3ce44SJohn Forte 
86fcf3ce44SJohn Forte 	(void) emlxs_mem_alloc(hba, buf_info);
87fcf3ce44SJohn Forte 	if (buf_info->virt == NULL) {
88fcf3ce44SJohn Forte 
89fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
90fcf3ce44SJohn Forte 		    "FCP BPL table buffer.");
91fcf3ce44SJohn Forte 
9282527734SSukumar Swaminathan 		goto failed;
9382527734SSukumar Swaminathan 	}
9482527734SSukumar Swaminathan 	hba->sli.sli3.fcp_bpl_table = buf_info->virt;
9582527734SSukumar Swaminathan 	bzero(hba->sli.sli3.fcp_bpl_table, buf_info->size);
9682527734SSukumar Swaminathan 
9782527734SSukumar Swaminathan 	/* Allocate a pool of BPLs for the FCP MEM_BPL table */
9882527734SSukumar Swaminathan 	seg = &hba->sli.sli3.fcp_bpl_seg;
9982527734SSukumar Swaminathan 	bzero(seg, sizeof (MEMSEG));
10082527734SSukumar Swaminathan 	(void) strcpy(seg->fc_label, "FCP BPL Pool");
10182527734SSukumar Swaminathan 	seg->fc_memtag	= MEM_BPL;
10282527734SSukumar Swaminathan 	seg->fc_memsize	= (3 * sizeof (ULP_BDE64));
10382527734SSukumar Swaminathan 	seg->fc_numblks	= hba->max_iotag;
10482527734SSukumar Swaminathan 	seg->fc_reserved = 0;
10582527734SSukumar Swaminathan 	seg->fc_memflag	= FC_MBUF_DMA | FC_MBUF_SNGLSG;
10682527734SSukumar Swaminathan 	seg->fc_memalign = 32;
10782527734SSukumar Swaminathan 
10882527734SSukumar Swaminathan 	if (emlxs_mem_pool_alloc(hba, seg) == NULL) {
10982527734SSukumar Swaminathan 		goto failed;
110fcf3ce44SJohn Forte 	}
111fcf3ce44SJohn Forte 
11282527734SSukumar Swaminathan 	/* Initialize the FCP MEM_BPL table */
11382527734SSukumar Swaminathan 	fcp_bpl_table = (MATCHMAP**)hba->sli.sli3.fcp_bpl_table;
11482527734SSukumar Swaminathan 	mp = (MATCHMAP*)seg->fc_memget_ptr;
11582527734SSukumar Swaminathan 	for (i = 0; i < seg->fc_numblks; i++) {
11682527734SSukumar Swaminathan 		mp->flag |= MAP_TABLE_ALLOCATED;
11782527734SSukumar Swaminathan 		*fcp_bpl_table = mp;
118fcf3ce44SJohn Forte 
11982527734SSukumar Swaminathan 		mp = (MATCHMAP *)mp->fc_mptr;
12082527734SSukumar Swaminathan 		fcp_bpl_table++;
121fcf3ce44SJohn Forte 	}
122fcf3ce44SJohn Forte 	}
123291a2b48SSukumar Swaminathan #endif /* EMLXS_SPARC */
124fcf3ce44SJohn Forte 
12582527734SSukumar Swaminathan 	/* Prepare the memory pools */
12682527734SSukumar Swaminathan 	for (i = 0; i < FC_MAX_SEG; i++) {
12782527734SSukumar Swaminathan 		seg = &hba->memseg[i];
128fcf3ce44SJohn Forte 
12982527734SSukumar Swaminathan 		switch (i) {
13082527734SSukumar Swaminathan 		case MEM_NLP:
13182527734SSukumar Swaminathan 			(void) strcpy(seg->fc_label, "Node Pool");
13282527734SSukumar Swaminathan 			seg->fc_memtag	= MEM_NLP;
13382527734SSukumar Swaminathan 			seg->fc_memsize	= sizeof (NODELIST);
13482527734SSukumar Swaminathan 			seg->fc_numblks	= (int16_t)hba->max_nodes + 2;
13582527734SSukumar Swaminathan 			seg->fc_reserved = 0;
13682527734SSukumar Swaminathan 			seg->fc_memflag	= 0;
13782527734SSukumar Swaminathan 			break;
138fcf3ce44SJohn Forte 
13982527734SSukumar Swaminathan 		case MEM_IOCB:
14082527734SSukumar Swaminathan 			(void) strcpy(seg->fc_label, "IOCB Pool");
14182527734SSukumar Swaminathan 			seg->fc_memtag	= MEM_IOCB;
14282527734SSukumar Swaminathan 			seg->fc_memsize	= sizeof (IOCBQ);
14382527734SSukumar Swaminathan 			seg->fc_numblks	= (uint16_t)cfg[CFG_NUM_IOCBS].current;
14482527734SSukumar Swaminathan 			seg->fc_reserved = 0;
14582527734SSukumar Swaminathan 			seg->fc_memflag	= 0;
14682527734SSukumar Swaminathan 			break;
147fcf3ce44SJohn Forte 
14882527734SSukumar Swaminathan 		case MEM_MBOX:
14982527734SSukumar Swaminathan 			(void) strcpy(seg->fc_label, "MBOX Pool");
15082527734SSukumar Swaminathan 			seg->fc_memtag	= MEM_MBOX;
15182527734SSukumar Swaminathan 			seg->fc_memsize	= sizeof (MAILBOXQ);
15282527734SSukumar Swaminathan 			seg->fc_numblks	= (int16_t)hba->max_nodes + 32;
15382527734SSukumar Swaminathan 			seg->fc_reserved = 0;
15482527734SSukumar Swaminathan 			seg->fc_memflag	= 0;
15582527734SSukumar Swaminathan 			break;
156fcf3ce44SJohn Forte 
15782527734SSukumar Swaminathan 		case MEM_BPL:
15882527734SSukumar Swaminathan 			if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) {
15982527734SSukumar Swaminathan 				continue;
16082527734SSukumar Swaminathan 			}
16182527734SSukumar Swaminathan 			(void) strcpy(seg->fc_label, "BPL Pool");
16282527734SSukumar Swaminathan 			seg->fc_memtag	= MEM_BPL;
16382527734SSukumar Swaminathan 			seg->fc_memsize	= hba->sli.sli3.mem_bpl_size;
16482527734SSukumar Swaminathan 			seg->fc_numblks	= (int16_t)hba->max_iotag + 2;
16582527734SSukumar Swaminathan 			seg->fc_reserved = 0;
16682527734SSukumar Swaminathan 			seg->fc_memflag	= FC_MBUF_DMA | FC_MBUF_SNGLSG;
16782527734SSukumar Swaminathan 			seg->fc_memalign = 32;
16882527734SSukumar Swaminathan 			break;
169fcf3ce44SJohn Forte 
17082527734SSukumar Swaminathan 		case MEM_BUF:
17182527734SSukumar Swaminathan 			/* These are the unsolicited ELS buffers. */
17282527734SSukumar Swaminathan 			(void) strcpy(seg->fc_label, "BUF Pool");
17382527734SSukumar Swaminathan 			seg->fc_memtag	= MEM_BUF;
17482527734SSukumar Swaminathan 			seg->fc_memsize	= MEM_BUF_SIZE;
17582527734SSukumar Swaminathan 			seg->fc_numblks	= MEM_ELSBUF_COUNT + MEM_BUF_COUNT;
17682527734SSukumar Swaminathan 			seg->fc_reserved = 0;
17782527734SSukumar Swaminathan 			seg->fc_memflag	= FC_MBUF_DMA | FC_MBUF_SNGLSG;
17882527734SSukumar Swaminathan 			seg->fc_memalign = 32;
17982527734SSukumar Swaminathan 			break;
180291a2b48SSukumar Swaminathan 
18182527734SSukumar Swaminathan 		case MEM_IPBUF:
18282527734SSukumar Swaminathan 			/* These are the unsolicited IP buffers. */
18382527734SSukumar Swaminathan 			if (cfg[CFG_NETWORK_ON].current == 0) {
18482527734SSukumar Swaminathan 				continue;
18582527734SSukumar Swaminathan 			}
186fcf3ce44SJohn Forte 
18782527734SSukumar Swaminathan 			(void) strcpy(seg->fc_label, "IPBUF Pool");
18882527734SSukumar Swaminathan 			seg->fc_memtag	= MEM_IPBUF;
18982527734SSukumar Swaminathan 			seg->fc_memsize	= MEM_IPBUF_SIZE;
19082527734SSukumar Swaminathan 			seg->fc_numblks	= MEM_IPBUF_COUNT;
19182527734SSukumar Swaminathan 			seg->fc_reserved = 0;
19282527734SSukumar Swaminathan 			seg->fc_memflag	= FC_MBUF_DMA | FC_MBUF_SNGLSG;
19382527734SSukumar Swaminathan 			seg->fc_memalign = 32;
19482527734SSukumar Swaminathan 			break;
195fcf3ce44SJohn Forte 
19682527734SSukumar Swaminathan 		case MEM_CTBUF:
19782527734SSukumar Swaminathan 			/* These are the unsolicited CT buffers. */
19882527734SSukumar Swaminathan 			(void) strcpy(seg->fc_label, "CTBUF Pool");
19982527734SSukumar Swaminathan 			seg->fc_memtag	= MEM_CTBUF;
20082527734SSukumar Swaminathan 			seg->fc_memsize	= MEM_CTBUF_SIZE;
20182527734SSukumar Swaminathan 			seg->fc_numblks	= MEM_CTBUF_COUNT;
20282527734SSukumar Swaminathan 			seg->fc_reserved = 0;
20382527734SSukumar Swaminathan 			seg->fc_memflag	= FC_MBUF_DMA | FC_MBUF_SNGLSG;
20482527734SSukumar Swaminathan 			seg->fc_memalign = 32;
20582527734SSukumar Swaminathan 			break;
206fcf3ce44SJohn Forte 
20782527734SSukumar Swaminathan 		case MEM_FCTBUF:
20882527734SSukumar Swaminathan #ifdef SFCT_SUPPORT
20982527734SSukumar Swaminathan 			/* These are the unsolicited FCT buffers. */
21082527734SSukumar Swaminathan 			if (hba->tgt_mode == 0) {
21182527734SSukumar Swaminathan 				continue;
21282527734SSukumar Swaminathan 			}
213fcf3ce44SJohn Forte 
21482527734SSukumar Swaminathan 			(void) strcpy(seg->fc_label, "FCTBUF Pool");
21582527734SSukumar Swaminathan 			seg->fc_memtag	= MEM_FCTBUF;
21682527734SSukumar Swaminathan 			seg->fc_memsize	= MEM_FCTBUF_SIZE;
21782527734SSukumar Swaminathan 			seg->fc_numblks	= MEM_FCTBUF_COUNT;
21882527734SSukumar Swaminathan 			seg->fc_reserved = 0;
21982527734SSukumar Swaminathan 			seg->fc_memflag	= FC_MBUF_DMA | FC_MBUF_SNGLSG;
22082527734SSukumar Swaminathan 			seg->fc_memalign = 32;
22182527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */
22282527734SSukumar Swaminathan 			break;
223fcf3ce44SJohn Forte 
22482527734SSukumar Swaminathan 		default:
22582527734SSukumar Swaminathan 			continue;
226fcf3ce44SJohn Forte 		}
227fcf3ce44SJohn Forte 
22882527734SSukumar Swaminathan 		if (seg->fc_memsize == 0) {
22982527734SSukumar Swaminathan 			continue;
23082527734SSukumar Swaminathan 		}
231fcf3ce44SJohn Forte 
23282527734SSukumar Swaminathan 		if (emlxs_mem_pool_alloc(hba, seg) == NULL) {
23382527734SSukumar Swaminathan 			goto failed;
234fcf3ce44SJohn Forte 		}
235291a2b48SSukumar Swaminathan 
23682527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg,
23782527734SSukumar Swaminathan 		    "%s: seg=%p size=%x count=%d flags=%x base=%p",
23882527734SSukumar Swaminathan 		    seg->fc_label, seg, seg->fc_memsize, seg->fc_numblks,
23982527734SSukumar Swaminathan 		    seg->fc_memflag, seg->fc_memget_ptr);
240fcf3ce44SJohn Forte 	}
241fcf3ce44SJohn Forte 
24282527734SSukumar Swaminathan 	return (1);
243fcf3ce44SJohn Forte 
24482527734SSukumar Swaminathan failed:
245fcf3ce44SJohn Forte 
24682527734SSukumar Swaminathan 	(void) emlxs_mem_free_buffer(hba);
24782527734SSukumar Swaminathan 	return (0);
248fcf3ce44SJohn Forte 
24982527734SSukumar Swaminathan } /* emlxs_mem_alloc_buffer() */
250fcf3ce44SJohn Forte 
251fcf3ce44SJohn Forte 
25282527734SSukumar Swaminathan /*
25382527734SSukumar Swaminathan  * emlxs_mem_free_buffer
25482527734SSukumar Swaminathan  *
25582527734SSukumar Swaminathan  * This routine will free iocb/data buffer space
25682527734SSukumar Swaminathan  * and TGTM resource.
25782527734SSukumar Swaminathan  */
25882527734SSukumar Swaminathan extern int
25982527734SSukumar Swaminathan emlxs_mem_free_buffer(emlxs_hba_t *hba)
26082527734SSukumar Swaminathan {
26182527734SSukumar Swaminathan 	emlxs_port_t *vport;
26282527734SSukumar Swaminathan 	int32_t j;
26382527734SSukumar Swaminathan 	MATCHMAP *mp;
26482527734SSukumar Swaminathan 	CHANNEL *cp;
26582527734SSukumar Swaminathan 	RING *rp;
26682527734SSukumar Swaminathan 	MBUF_INFO *buf_info;
26782527734SSukumar Swaminathan 	MBUF_INFO bufinfo;
268fcf3ce44SJohn Forte 
26982527734SSukumar Swaminathan 	buf_info = &bufinfo;
270291a2b48SSukumar Swaminathan 
27182527734SSukumar Swaminathan 	for (j = 0; j < hba->chan_count; j++) {
27282527734SSukumar Swaminathan 		cp = &hba->chan[j];
273fcf3ce44SJohn Forte 
27482527734SSukumar Swaminathan 		/* Flush the ring */
27582527734SSukumar Swaminathan 		(void) emlxs_tx_channel_flush(hba, cp, 0);
27682527734SSukumar Swaminathan 	}
277fcf3ce44SJohn Forte 
27882527734SSukumar Swaminathan 	if (!(hba->model_info.sli_mask & EMLXS_SLI4_MASK)) {
27982527734SSukumar Swaminathan 		/* free the mapped address match area for each ring */
28082527734SSukumar Swaminathan 		for (j = 0; j < MAX_RINGS; j++) {
28182527734SSukumar Swaminathan 			rp = &hba->sli.sli3.ring[j];
282fcf3ce44SJohn Forte 
28382527734SSukumar Swaminathan 			while (rp->fc_mpoff) {
28482527734SSukumar Swaminathan 				uint64_t addr;
285fcf3ce44SJohn Forte 
28682527734SSukumar Swaminathan 				addr = 0;
28782527734SSukumar Swaminathan 				mp = (MATCHMAP *)(rp->fc_mpoff);
288fcf3ce44SJohn Forte 
28982527734SSukumar Swaminathan 				if ((j == hba->channel_els) ||
29082527734SSukumar Swaminathan 				    (j == hba->channel_ct) ||
29182527734SSukumar Swaminathan #ifdef SFCT_SUPPORT
29282527734SSukumar Swaminathan 				    (j == hba->CHANNEL_FCT) ||
29382527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */
29482527734SSukumar Swaminathan 				    (j == hba->channel_ip)) {
29582527734SSukumar Swaminathan 					addr = mp->phys;
29682527734SSukumar Swaminathan 				}
297fcf3ce44SJohn Forte 
29882527734SSukumar Swaminathan 				if ((mp = emlxs_mem_get_vaddr(hba, rp, addr))) {
29982527734SSukumar Swaminathan 					if (j == hba->channel_els) {
300*a9800bebSGarrett D'Amore 						emlxs_mem_put(hba,
301*a9800bebSGarrett D'Amore 						    MEM_ELSBUF, (void *)mp);
30282527734SSukumar Swaminathan 					} else if (j == hba->channel_ct) {
303*a9800bebSGarrett D'Amore 						emlxs_mem_put(hba,
304*a9800bebSGarrett D'Amore 						    MEM_CTBUF, (void *)mp);
30582527734SSukumar Swaminathan 					} else if (j == hba->channel_ip) {
306*a9800bebSGarrett D'Amore 						emlxs_mem_put(hba,
307*a9800bebSGarrett D'Amore 						    MEM_IPBUF, (void *)mp);
30882527734SSukumar Swaminathan 					}
30982527734SSukumar Swaminathan #ifdef SFCT_SUPPORT
31082527734SSukumar Swaminathan 					else if (j == hba->CHANNEL_FCT) {
311*a9800bebSGarrett D'Amore 						emlxs_mem_put(hba,
312*a9800bebSGarrett D'Amore 						    MEM_FCTBUF, (void *)mp);
31382527734SSukumar Swaminathan 					}
31482527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */
315fcf3ce44SJohn Forte 
31682527734SSukumar Swaminathan 				}
31782527734SSukumar Swaminathan 			}
318fcf3ce44SJohn Forte 		}
31982527734SSukumar Swaminathan 	}
32082527734SSukumar Swaminathan 
32182527734SSukumar Swaminathan 	if (hba->flag & FC_HBQ_ENABLED) {
32282527734SSukumar Swaminathan 		emlxs_hbq_free_all(hba, EMLXS_ELS_HBQ_ID);
32382527734SSukumar Swaminathan 		emlxs_hbq_free_all(hba, EMLXS_IP_HBQ_ID);
32482527734SSukumar Swaminathan 		emlxs_hbq_free_all(hba, EMLXS_CT_HBQ_ID);
325291a2b48SSukumar Swaminathan 
32682527734SSukumar Swaminathan 		if (hba->tgt_mode) {
32782527734SSukumar Swaminathan 			emlxs_hbq_free_all(hba, EMLXS_FCT_HBQ_ID);
32882527734SSukumar Swaminathan 		}
329fcf3ce44SJohn Forte 	}
330fcf3ce44SJohn Forte 
33182527734SSukumar Swaminathan 	/* Free the nodes */
33282527734SSukumar Swaminathan 	for (j = 0; j < MAX_VPORTS; j++) {
33382527734SSukumar Swaminathan 		vport = &VPORT(j);
33482527734SSukumar Swaminathan 		if (vport->node_count) {
33582527734SSukumar Swaminathan 			emlxs_node_destroy_all(vport);
33682527734SSukumar Swaminathan 		}
33782527734SSukumar Swaminathan 	}
338fcf3ce44SJohn Forte 
33982527734SSukumar Swaminathan 	/* Make sure the mailbox queue is empty */
34082527734SSukumar Swaminathan 	emlxs_mb_flush(hba);
341fcf3ce44SJohn Forte 
34282527734SSukumar Swaminathan 	/* Free memory associated with all buffers on get buffer pool */
34382527734SSukumar Swaminathan 	if (hba->fc_table) {
344fcf3ce44SJohn Forte 		bzero(buf_info, sizeof (MBUF_INFO));
34582527734SSukumar Swaminathan 		buf_info->size = hba->max_iotag * sizeof (emlxs_buf_t *);
34682527734SSukumar Swaminathan 		buf_info->virt = hba->fc_table;
34782527734SSukumar Swaminathan 		emlxs_mem_free(hba, buf_info);
34882527734SSukumar Swaminathan 		hba->fc_table = NULL;
34982527734SSukumar Swaminathan 	}
350fcf3ce44SJohn Forte 
35182527734SSukumar Swaminathan #ifdef EMLXS_SPARC
35282527734SSukumar Swaminathan 	if (hba->sli.sli3.fcp_bpl_table) {
35382527734SSukumar Swaminathan 		bzero(buf_info, sizeof (MBUF_INFO));
35482527734SSukumar Swaminathan 		buf_info->size = hba->max_iotag * sizeof (MATCHMAP *);
35582527734SSukumar Swaminathan 		buf_info->virt = hba->sli.sli3.fcp_bpl_table;
35682527734SSukumar Swaminathan 		emlxs_mem_free(hba, buf_info);
35782527734SSukumar Swaminathan 		hba->sli.sli3.fcp_bpl_table = NULL;
35882527734SSukumar Swaminathan 	}
359fcf3ce44SJohn Forte 
36082527734SSukumar Swaminathan 	if (hba->sli.sli3.fcp_bpl_seg.fc_memsize) {
36182527734SSukumar Swaminathan 		emlxs_mem_pool_free(hba, &hba->sli.sli3.fcp_bpl_seg);
36282527734SSukumar Swaminathan 		bzero(&hba->sli.sli3.fcp_bpl_seg, sizeof (MEMSEG));
36382527734SSukumar Swaminathan 	}
36482527734SSukumar Swaminathan #endif /* EMLXS_SPARC */
365fcf3ce44SJohn Forte 
36682527734SSukumar Swaminathan 	/* Free the memory segments */
36782527734SSukumar Swaminathan 	for (j = 0; j < FC_MAX_SEG; j++) {
36882527734SSukumar Swaminathan 		emlxs_mem_pool_free(hba, &hba->memseg[j]);
36982527734SSukumar Swaminathan 	}
370291a2b48SSukumar Swaminathan 
37182527734SSukumar Swaminathan 	return (0);
372fcf3ce44SJohn Forte 
37382527734SSukumar Swaminathan } /* emlxs_mem_free_buffer() */
374fcf3ce44SJohn Forte 
375fcf3ce44SJohn Forte 
37682527734SSukumar Swaminathan extern MEMSEG *
37782527734SSukumar Swaminathan emlxs_mem_pool_alloc(emlxs_hba_t *hba, MEMSEG *seg)
37882527734SSukumar Swaminathan {
37982527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
38082527734SSukumar Swaminathan 	uint8_t *bp = NULL;
38182527734SSukumar Swaminathan 	MATCHMAP *mp = NULL;
38282527734SSukumar Swaminathan 	MBUF_INFO *buf_info;
38382527734SSukumar Swaminathan 	MBUF_INFO local_buf_info;
38482527734SSukumar Swaminathan 	uint32_t i;
385fcf3ce44SJohn Forte 
38682527734SSukumar Swaminathan 	buf_info = &local_buf_info;
387fcf3ce44SJohn Forte 
38882527734SSukumar Swaminathan 	mutex_enter(&EMLXS_MEMGET_LOCK);
38982527734SSukumar Swaminathan 	mutex_enter(&EMLXS_MEMPUT_LOCK);
390fcf3ce44SJohn Forte 
39182527734SSukumar Swaminathan 	/* Calculate total memory size */
39282527734SSukumar Swaminathan 	seg->fc_total_memsize = (seg->fc_memsize * seg->fc_numblks);
393fcf3ce44SJohn Forte 
39482527734SSukumar Swaminathan 	if (seg->fc_total_memsize == 0) {
39582527734SSukumar Swaminathan 		mutex_exit(&EMLXS_MEMPUT_LOCK);
39682527734SSukumar Swaminathan 		mutex_exit(&EMLXS_MEMGET_LOCK);
39782527734SSukumar Swaminathan 		return (NULL);
39882527734SSukumar Swaminathan 	}
399291a2b48SSukumar Swaminathan 
40082527734SSukumar Swaminathan 	if (!(seg->fc_memflag & FC_MBUF_DMA)) {
40182527734SSukumar Swaminathan 		goto vmem_pool;
402fcf3ce44SJohn Forte 	}
403fcf3ce44SJohn Forte 
40482527734SSukumar Swaminathan /* dma_pool */
40582527734SSukumar Swaminathan 
40682527734SSukumar Swaminathan 	for (i = 0; i < seg->fc_numblks; i++) {
407fcf3ce44SJohn Forte 		bzero(buf_info, sizeof (MBUF_INFO));
408fcf3ce44SJohn Forte 		buf_info->size = sizeof (MATCHMAP);
409fcf3ce44SJohn Forte 		buf_info->align = sizeof (void *);
410fcf3ce44SJohn Forte 
411fcf3ce44SJohn Forte 		(void) emlxs_mem_alloc(hba, buf_info);
412fcf3ce44SJohn Forte 		if (buf_info->virt == NULL) {
413fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
41482527734SSukumar Swaminathan 			    "%s desc[%d]. size=%d", seg->fc_label, i,
41582527734SSukumar Swaminathan 			    buf_info->size);
416fcf3ce44SJohn Forte 
41782527734SSukumar Swaminathan 			goto failed;
418fcf3ce44SJohn Forte 		}
419291a2b48SSukumar Swaminathan 
42082527734SSukumar Swaminathan 		mp = (MATCHMAP *)buf_info->virt;
42182527734SSukumar Swaminathan 		bzero(mp, sizeof (MATCHMAP));
422fcf3ce44SJohn Forte 
423fcf3ce44SJohn Forte 		bzero(buf_info, sizeof (MBUF_INFO));
42482527734SSukumar Swaminathan 		buf_info->size  = seg->fc_memsize;
42582527734SSukumar Swaminathan 		buf_info->flags = seg->fc_memflag;
42682527734SSukumar Swaminathan 		buf_info->align = seg->fc_memalign;
427fcf3ce44SJohn Forte 
428fcf3ce44SJohn Forte 		(void) emlxs_mem_alloc(hba, buf_info);
429fcf3ce44SJohn Forte 		if (buf_info->virt == NULL) {
430fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
43182527734SSukumar Swaminathan 			    "%s buffer[%d]. size=%d", seg->fc_label, i,
43282527734SSukumar Swaminathan 			    buf_info->size);
433fcf3ce44SJohn Forte 
43482527734SSukumar Swaminathan 			/* Free the mp object */
43582527734SSukumar Swaminathan 			bzero(buf_info, sizeof (MBUF_INFO));
43682527734SSukumar Swaminathan 			buf_info->size = sizeof (MATCHMAP);
437*a9800bebSGarrett D'Amore 			buf_info->virt = (void *)mp;
43882527734SSukumar Swaminathan 			emlxs_mem_free(hba, buf_info);
43982527734SSukumar Swaminathan 
44082527734SSukumar Swaminathan 			goto failed;
441fcf3ce44SJohn Forte 		}
442fcf3ce44SJohn Forte 		bp = (uint8_t *)buf_info->virt;
44382527734SSukumar Swaminathan 		bzero(bp, seg->fc_memsize);
44482527734SSukumar Swaminathan 
44582527734SSukumar Swaminathan 		mp->virt = buf_info->virt;
44682527734SSukumar Swaminathan 		mp->phys = buf_info->phys;
44782527734SSukumar Swaminathan 		mp->size = buf_info->size;
44882527734SSukumar Swaminathan 		mp->dma_handle = buf_info->dma_handle;
44982527734SSukumar Swaminathan 		mp->data_handle = buf_info->data_handle;
45082527734SSukumar Swaminathan 		mp->tag = seg->fc_memtag;
45182527734SSukumar Swaminathan 		mp->segment = seg;
45282527734SSukumar Swaminathan 		mp->flag |= MAP_POOL_ALLOCATED;
45382527734SSukumar Swaminathan 
45482527734SSukumar Swaminathan 		/* Add the buffer desc to the tail of the pool freelist */
45582527734SSukumar Swaminathan 		if (seg->fc_memget_end == NULL) {
45682527734SSukumar Swaminathan 			seg->fc_memget_ptr = (uint8_t *)mp;
45782527734SSukumar Swaminathan 			seg->fc_memget_cnt = 1;
45882527734SSukumar Swaminathan 		} else {
45982527734SSukumar Swaminathan 			*((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)mp;
46082527734SSukumar Swaminathan 			seg->fc_memget_cnt++;
461fcf3ce44SJohn Forte 		}
46282527734SSukumar Swaminathan 		seg->fc_memget_end = (uint8_t *)mp;
463fcf3ce44SJohn Forte 	}
464fcf3ce44SJohn Forte 
46582527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMPUT_LOCK);
46682527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMGET_LOCK);
46782527734SSukumar Swaminathan 	return (seg);
468fcf3ce44SJohn Forte 
46982527734SSukumar Swaminathan vmem_pool:
470fcf3ce44SJohn Forte 
47182527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMPUT_LOCK);
47282527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMGET_LOCK);
473fcf3ce44SJohn Forte 
47482527734SSukumar Swaminathan 	seg->fc_memstart_virt = kmem_zalloc(seg->fc_total_memsize, KM_SLEEP);
475fcf3ce44SJohn Forte 
47682527734SSukumar Swaminathan 	mutex_enter(&EMLXS_MEMGET_LOCK);
47782527734SSukumar Swaminathan 	mutex_enter(&EMLXS_MEMPUT_LOCK);
478291a2b48SSukumar Swaminathan 
47982527734SSukumar Swaminathan 	if (seg->fc_memstart_virt == NULL) {
48082527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
48182527734SSukumar Swaminathan 		    "%s base. size=%d", seg->fc_label,
48282527734SSukumar Swaminathan 		    seg->fc_total_memsize);
483fcf3ce44SJohn Forte 
48482527734SSukumar Swaminathan 		goto failed;
48582527734SSukumar Swaminathan 	}
486fcf3ce44SJohn Forte 
48782527734SSukumar Swaminathan 	bp = (uint8_t *)seg->fc_memstart_virt;
48882527734SSukumar Swaminathan 	for (i = 0; i < seg->fc_numblks; i++) {
489fcf3ce44SJohn Forte 
49082527734SSukumar Swaminathan 		/* Add the buffer to the tail of the pool freelist */
49182527734SSukumar Swaminathan 		if (seg->fc_memget_end == NULL) {
49282527734SSukumar Swaminathan 			seg->fc_memget_ptr = (uint8_t *)bp;
49382527734SSukumar Swaminathan 			seg->fc_memget_cnt = 1;
49482527734SSukumar Swaminathan 		} else {
49582527734SSukumar Swaminathan 			*((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)bp;
49682527734SSukumar Swaminathan 			seg->fc_memget_cnt++;
49782527734SSukumar Swaminathan 		}
49882527734SSukumar Swaminathan 		seg->fc_memget_end = (uint8_t *)bp;
499fcf3ce44SJohn Forte 
50082527734SSukumar Swaminathan 		bp += seg->fc_memsize;
50182527734SSukumar Swaminathan 	}
502fcf3ce44SJohn Forte 
50382527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMPUT_LOCK);
50482527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMGET_LOCK);
50582527734SSukumar Swaminathan 	return (seg);
506fcf3ce44SJohn Forte 
50782527734SSukumar Swaminathan failed:
508fcf3ce44SJohn Forte 
50982527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMPUT_LOCK);
51082527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMGET_LOCK);
51182527734SSukumar Swaminathan 	emlxs_mem_pool_free(hba, seg);
51282527734SSukumar Swaminathan 	return (NULL);
513291a2b48SSukumar Swaminathan 
51482527734SSukumar Swaminathan } /* emlxs_mem_pool_alloc() */
515fcf3ce44SJohn Forte 
516fcf3ce44SJohn Forte 
51782527734SSukumar Swaminathan extern void
51882527734SSukumar Swaminathan emlxs_mem_pool_free(emlxs_hba_t *hba, MEMSEG *seg)
51982527734SSukumar Swaminathan {
52082527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
52182527734SSukumar Swaminathan 	uint8_t *bp = NULL;
52282527734SSukumar Swaminathan 	MATCHMAP *mp = NULL;
52382527734SSukumar Swaminathan 	MBUF_INFO *buf_info;
52482527734SSukumar Swaminathan 	MBUF_INFO local_buf_info;
52582527734SSukumar Swaminathan 	MEMSEG segment;
52682527734SSukumar Swaminathan 	uint32_t free;
527fcf3ce44SJohn Forte 
52882527734SSukumar Swaminathan 	/* Save a local copy of the segment and */
52982527734SSukumar Swaminathan 	/* destroy the original outside of locks */
53082527734SSukumar Swaminathan 	mutex_enter(&EMLXS_MEMGET_LOCK);
53182527734SSukumar Swaminathan 	mutex_enter(&EMLXS_MEMPUT_LOCK);
532fcf3ce44SJohn Forte 
53382527734SSukumar Swaminathan 	free = seg->fc_memget_cnt + seg->fc_memput_cnt;
53482527734SSukumar Swaminathan 	if (free < seg->fc_numblks) {
53582527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg,
53682527734SSukumar Swaminathan 		    "emlxs_mem_pool_free: %s not full. (%d < %d)",
53782527734SSukumar Swaminathan 		    seg->fc_label, free, seg->fc_numblks);
538fcf3ce44SJohn Forte 	}
539fcf3ce44SJohn Forte 
54082527734SSukumar Swaminathan 	bcopy(seg, &segment, sizeof (MEMSEG));
54182527734SSukumar Swaminathan 	bzero((char *)seg, sizeof (MEMSEG));
54282527734SSukumar Swaminathan 	seg = &segment;
543fcf3ce44SJohn Forte 
54482527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMPUT_LOCK);
54582527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMGET_LOCK);
546fcf3ce44SJohn Forte 
54782527734SSukumar Swaminathan 	/* Now free the memory  */
548fcf3ce44SJohn Forte 
54982527734SSukumar Swaminathan 	if (!(seg->fc_memflag & FC_MBUF_DMA)) {
55082527734SSukumar Swaminathan 		if (seg->fc_memstart_virt) {
55182527734SSukumar Swaminathan 			kmem_free(seg->fc_memstart_virt, seg->fc_total_memsize);
55282527734SSukumar Swaminathan 		}
553fcf3ce44SJohn Forte 
55482527734SSukumar Swaminathan 		return;
55582527734SSukumar Swaminathan 	}
556fcf3ce44SJohn Forte 
55782527734SSukumar Swaminathan 	buf_info = &local_buf_info;
558fcf3ce44SJohn Forte 
55982527734SSukumar Swaminathan 	/* Free memory associated with all buffers on get buffer pool */
56082527734SSukumar Swaminathan 	while ((bp = seg->fc_memget_ptr) != NULL) {
56182527734SSukumar Swaminathan 		seg->fc_memget_ptr = *((uint8_t **)bp);
56282527734SSukumar Swaminathan 		mp = (MATCHMAP *)bp;
563fcf3ce44SJohn Forte 
56482527734SSukumar Swaminathan 		bzero(buf_info, sizeof (MBUF_INFO));
56582527734SSukumar Swaminathan 		buf_info->size = mp->size;
56682527734SSukumar Swaminathan 		buf_info->virt = mp->virt;
56782527734SSukumar Swaminathan 		buf_info->phys = mp->phys;
56882527734SSukumar Swaminathan 		buf_info->dma_handle = mp->dma_handle;
56982527734SSukumar Swaminathan 		buf_info->data_handle = mp->data_handle;
57082527734SSukumar Swaminathan 		buf_info->flags = seg->fc_memflag;
57182527734SSukumar Swaminathan 		emlxs_mem_free(hba, buf_info);
572fcf3ce44SJohn Forte 
57382527734SSukumar Swaminathan 		bzero(buf_info, sizeof (MBUF_INFO));
57482527734SSukumar Swaminathan 		buf_info->size = sizeof (MATCHMAP);
575*a9800bebSGarrett D'Amore 		buf_info->virt = (void *)mp;
57682527734SSukumar Swaminathan 		emlxs_mem_free(hba, buf_info);
577fcf3ce44SJohn Forte 	}
578291a2b48SSukumar Swaminathan 
57982527734SSukumar Swaminathan 	/* Free memory associated with all buffers on put buffer pool */
58082527734SSukumar Swaminathan 	while ((bp = seg->fc_memput_ptr) != NULL) {
58182527734SSukumar Swaminathan 		seg->fc_memput_ptr = *((uint8_t **)bp);
58282527734SSukumar Swaminathan 		mp = (MATCHMAP *)bp;
583fcf3ce44SJohn Forte 
58482527734SSukumar Swaminathan 		bzero(buf_info, sizeof (MBUF_INFO));
58582527734SSukumar Swaminathan 		buf_info->size = mp->size;
58682527734SSukumar Swaminathan 		buf_info->virt = mp->virt;
58782527734SSukumar Swaminathan 		buf_info->phys = mp->phys;
58882527734SSukumar Swaminathan 		buf_info->dma_handle = mp->dma_handle;
58982527734SSukumar Swaminathan 		buf_info->data_handle = mp->data_handle;
59082527734SSukumar Swaminathan 		buf_info->flags = seg->fc_memflag;
59182527734SSukumar Swaminathan 		emlxs_mem_free(hba, buf_info);
592291a2b48SSukumar Swaminathan 
59382527734SSukumar Swaminathan 		bzero(buf_info, sizeof (MBUF_INFO));
59482527734SSukumar Swaminathan 		buf_info->size = sizeof (MATCHMAP);
595*a9800bebSGarrett D'Amore 		buf_info->virt = (void *)mp;
59682527734SSukumar Swaminathan 		emlxs_mem_free(hba, buf_info);
597291a2b48SSukumar Swaminathan 	}
598fcf3ce44SJohn Forte 
59982527734SSukumar Swaminathan 	return;
600fcf3ce44SJohn Forte 
60182527734SSukumar Swaminathan } /* emlxs_mem_pool_free() */
602fcf3ce44SJohn Forte 
603fcf3ce44SJohn Forte 
604*a9800bebSGarrett D'Amore extern void *
60582527734SSukumar Swaminathan emlxs_mem_pool_get(emlxs_hba_t *hba, MEMSEG *seg, uint32_t priority)
60682527734SSukumar Swaminathan {
607*a9800bebSGarrett D'Amore 	emlxs_port_t	*port = &PPORT;
608*a9800bebSGarrett D'Amore 	void		*bp = NULL;
609*a9800bebSGarrett D'Amore 	MATCHMAP	*mp;
610*a9800bebSGarrett D'Amore 	uint32_t	free;
611291a2b48SSukumar Swaminathan 
61282527734SSukumar Swaminathan 	mutex_enter(&EMLXS_MEMGET_LOCK);
61382527734SSukumar Swaminathan 
61482527734SSukumar Swaminathan 	/* Check if memory segment destroyed! */
61582527734SSukumar Swaminathan 	if (seg->fc_total_memsize == 0) {
61682527734SSukumar Swaminathan 		mutex_exit(&EMLXS_MEMGET_LOCK);
61782527734SSukumar Swaminathan 		return (NULL);
618fcf3ce44SJohn Forte 	}
619291a2b48SSukumar Swaminathan 
62082527734SSukumar Swaminathan 	/* Check priority and reserved status */
62182527734SSukumar Swaminathan 	if ((priority == 0) && seg->fc_reserved) {
62282527734SSukumar Swaminathan 		free = seg->fc_memget_cnt + seg->fc_memput_cnt;
62382527734SSukumar Swaminathan 		if (free <= seg->fc_reserved) {
62482527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_alloc_failed_msg,
62582527734SSukumar Swaminathan 			    "%s low. (%d <= %d)", seg->fc_label,
62682527734SSukumar Swaminathan 			    free, seg->fc_reserved);
627fcf3ce44SJohn Forte 
62882527734SSukumar Swaminathan 			mutex_exit(&EMLXS_MEMGET_LOCK);
62982527734SSukumar Swaminathan 			return (NULL);
63082527734SSukumar Swaminathan 		}
63182527734SSukumar Swaminathan 	}
632fcf3ce44SJohn Forte 
63382527734SSukumar Swaminathan top:
634fcf3ce44SJohn Forte 
63582527734SSukumar Swaminathan 	if (seg->fc_memget_ptr) {
636fcf3ce44SJohn Forte 
63782527734SSukumar Swaminathan 		bp = seg->fc_memget_ptr;
638291a2b48SSukumar Swaminathan 
63982527734SSukumar Swaminathan 		/* Remove buffer from freelist */
64082527734SSukumar Swaminathan 		if (seg->fc_memget_end == bp) {
64182527734SSukumar Swaminathan 			seg->fc_memget_ptr = NULL;
64282527734SSukumar Swaminathan 			seg->fc_memget_end = NULL;
64382527734SSukumar Swaminathan 			seg->fc_memget_cnt = 0;
644fcf3ce44SJohn Forte 
64582527734SSukumar Swaminathan 		} else {
64682527734SSukumar Swaminathan 			seg->fc_memget_ptr = *((uint8_t **)bp);
64782527734SSukumar Swaminathan 			seg->fc_memget_cnt--;
648fcf3ce44SJohn Forte 		}
649fcf3ce44SJohn Forte 
65082527734SSukumar Swaminathan 		if (!(seg->fc_memflag & FC_MBUF_DMA)) {
65182527734SSukumar Swaminathan 			bzero(bp, seg->fc_memsize);
65282527734SSukumar Swaminathan 		} else {
65382527734SSukumar Swaminathan 			mp = (MATCHMAP *)bp;
65482527734SSukumar Swaminathan 			mp->fc_mptr = NULL;
65582527734SSukumar Swaminathan 			mp->flag |= MAP_POOL_ALLOCATED;
656fcf3ce44SJohn Forte 		}
657fcf3ce44SJohn Forte 
65882527734SSukumar Swaminathan 	} else {
65982527734SSukumar Swaminathan 		mutex_enter(&EMLXS_MEMPUT_LOCK);
66082527734SSukumar Swaminathan 		if (seg->fc_memput_ptr) {
66182527734SSukumar Swaminathan 			/*
66282527734SSukumar Swaminathan 			 * Move list from memput to memget
66382527734SSukumar Swaminathan 			 */
66482527734SSukumar Swaminathan 			seg->fc_memget_ptr = seg->fc_memput_ptr;
66582527734SSukumar Swaminathan 			seg->fc_memget_end = seg->fc_memput_end;
66682527734SSukumar Swaminathan 			seg->fc_memget_cnt = seg->fc_memput_cnt;
66782527734SSukumar Swaminathan 			seg->fc_memput_ptr = NULL;
66882527734SSukumar Swaminathan 			seg->fc_memput_end = NULL;
66982527734SSukumar Swaminathan 			seg->fc_memput_cnt = 0;
67082527734SSukumar Swaminathan 			mutex_exit(&EMLXS_MEMPUT_LOCK);
671fcf3ce44SJohn Forte 
67282527734SSukumar Swaminathan 			goto top;
673fcf3ce44SJohn Forte 		}
67482527734SSukumar Swaminathan 		mutex_exit(&EMLXS_MEMPUT_LOCK);
67582527734SSukumar Swaminathan 
67682527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_alloc_failed_msg,
67782527734SSukumar Swaminathan 		    "%s empty.", seg->fc_label);
678fcf3ce44SJohn Forte 	}
679fcf3ce44SJohn Forte 
68082527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMGET_LOCK);
68182527734SSukumar Swaminathan 
68282527734SSukumar Swaminathan 	return (bp);
683fcf3ce44SJohn Forte 
68482527734SSukumar Swaminathan } /* emlxs_mem_pool_get() */
685fcf3ce44SJohn Forte 
686fcf3ce44SJohn Forte 
687*a9800bebSGarrett D'Amore extern void
688*a9800bebSGarrett D'Amore emlxs_mem_pool_put(emlxs_hba_t *hba, MEMSEG *seg, void *bp)
68982527734SSukumar Swaminathan {
690*a9800bebSGarrett D'Amore 	emlxs_port_t	*port = &PPORT;
691*a9800bebSGarrett D'Amore 	MATCHMAP	*mp;
692*a9800bebSGarrett D'Amore 	void		*base;
693*a9800bebSGarrett D'Amore 	void		*end;
694fcf3ce44SJohn Forte 
69582527734SSukumar Swaminathan 	/* Free the pool object */
69682527734SSukumar Swaminathan 	mutex_enter(&EMLXS_MEMPUT_LOCK);
69782527734SSukumar Swaminathan 
69882527734SSukumar Swaminathan 	/* Check if memory segment destroyed! */
69982527734SSukumar Swaminathan 	if (seg->fc_total_memsize == 0) {
70082527734SSukumar Swaminathan 		mutex_exit(&EMLXS_MEMPUT_LOCK);
701*a9800bebSGarrett D'Amore 		return;
702fcf3ce44SJohn Forte 	}
703291a2b48SSukumar Swaminathan 
70482527734SSukumar Swaminathan 	/* Check if buffer was just freed */
70582527734SSukumar Swaminathan 	if (seg->fc_memput_ptr == bp) {
70682527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
70782527734SSukumar Swaminathan 		    "%s: Freeing free object: bp=%p", seg->fc_label, bp);
708fcf3ce44SJohn Forte 
70982527734SSukumar Swaminathan 		mutex_exit(&EMLXS_MEMPUT_LOCK);
710*a9800bebSGarrett D'Amore 		return;
711fcf3ce44SJohn Forte 	}
712fcf3ce44SJohn Forte 
71382527734SSukumar Swaminathan 	/* Validate the buffer belongs to this pool */
71482527734SSukumar Swaminathan 	if (seg->fc_memflag & FC_MBUF_DMA) {
71582527734SSukumar Swaminathan 		mp = (MATCHMAP *)bp;
716291a2b48SSukumar Swaminathan 
71782527734SSukumar Swaminathan 		if (!(mp->flag & MAP_POOL_ALLOCATED) ||
71882527734SSukumar Swaminathan 		    (mp->segment != seg)) {
71982527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
72082527734SSukumar Swaminathan 			    "emlxs_mem_pool_put: %s invalid: mp=%p " \
72182527734SSukumar Swaminathan 			    "tag=0x%x flag=%x", seg->fc_label,
72282527734SSukumar Swaminathan 			    mp, mp->tag, mp->flag);
723291a2b48SSukumar Swaminathan 
72482527734SSukumar Swaminathan 			EMLXS_STATE_CHANGE(hba, FC_ERROR);
725fcf3ce44SJohn Forte 
72682527734SSukumar Swaminathan 			mutex_exit(&EMLXS_MEMPUT_LOCK);
727fcf3ce44SJohn Forte 
72882527734SSukumar Swaminathan 			emlxs_thread_spawn(hba, emlxs_shutdown_thread,
72982527734SSukumar Swaminathan 			    NULL, NULL);
730fcf3ce44SJohn Forte 
731*a9800bebSGarrett D'Amore 			return;
732fcf3ce44SJohn Forte 		}
733fcf3ce44SJohn Forte 
73482527734SSukumar Swaminathan 	} else { /* Vmem_pool */
73582527734SSukumar Swaminathan 		base = seg->fc_memstart_virt;
736*a9800bebSGarrett D'Amore 		end = (void *)((uint8_t *)seg->fc_memstart_virt +
737*a9800bebSGarrett D'Amore 		    seg->fc_total_memsize);
738fcf3ce44SJohn Forte 
73982527734SSukumar Swaminathan 		if (bp < base || bp >= end) {
74082527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
74182527734SSukumar Swaminathan 			    "emlxs_mem_pool_put: %s Invalid: bp=%p base=%p " \
74282527734SSukumar Swaminathan 			    "end=%p", seg->fc_label,
74382527734SSukumar Swaminathan 			    bp, base, end);
744fcf3ce44SJohn Forte 
74582527734SSukumar Swaminathan 			EMLXS_STATE_CHANGE(hba, FC_ERROR);
74682527734SSukumar Swaminathan 
74782527734SSukumar Swaminathan 			mutex_exit(&EMLXS_MEMPUT_LOCK);
74882527734SSukumar Swaminathan 
74982527734SSukumar Swaminathan 			emlxs_thread_spawn(hba, emlxs_shutdown_thread,
75082527734SSukumar Swaminathan 			    NULL, NULL);
75182527734SSukumar Swaminathan 
752*a9800bebSGarrett D'Amore 			return;
753fcf3ce44SJohn Forte 		}
754fcf3ce44SJohn Forte 	}
755fcf3ce44SJohn Forte 
75682527734SSukumar Swaminathan 	/* Release buffer to the end of the freelist */
75782527734SSukumar Swaminathan 	if (seg->fc_memput_end == NULL) {
75882527734SSukumar Swaminathan 		seg->fc_memput_ptr = bp;
75982527734SSukumar Swaminathan 		seg->fc_memput_cnt = 1;
76082527734SSukumar Swaminathan 	} else {
761*a9800bebSGarrett D'Amore 		*((void **)(seg->fc_memput_end)) = bp;
76282527734SSukumar Swaminathan 		seg->fc_memput_cnt++;
76382527734SSukumar Swaminathan 	}
76482527734SSukumar Swaminathan 	seg->fc_memput_end = bp;
765*a9800bebSGarrett D'Amore 	*((void **)(bp)) = NULL;
76682527734SSukumar Swaminathan 
76782527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MEMPUT_LOCK);
768fcf3ce44SJohn Forte 
769*a9800bebSGarrett D'Amore 	return;
770fcf3ce44SJohn Forte 
77182527734SSukumar Swaminathan } /* emlxs_mem_pool_put() */
772fcf3ce44SJohn Forte 
77382527734SSukumar Swaminathan 
77482527734SSukumar Swaminathan extern MATCHMAP *
77582527734SSukumar Swaminathan emlxs_mem_buf_alloc(emlxs_hba_t *hba, uint32_t size)
776fcf3ce44SJohn Forte {
777fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
778fcf3ce44SJohn Forte 	uint8_t *bp = NULL;
77982527734SSukumar Swaminathan 	MATCHMAP *mp = NULL;
780fcf3ce44SJohn Forte 	MBUF_INFO *buf_info;
781fcf3ce44SJohn Forte 	MBUF_INFO bufinfo;
782fcf3ce44SJohn Forte 
783fcf3ce44SJohn Forte 	buf_info = &bufinfo;
784fcf3ce44SJohn Forte 
785fcf3ce44SJohn Forte 	bzero(buf_info, sizeof (MBUF_INFO));
786fcf3ce44SJohn Forte 	buf_info->size = sizeof (MATCHMAP);
787fcf3ce44SJohn Forte 	buf_info->align = sizeof (void *);
788fcf3ce44SJohn Forte 
789fcf3ce44SJohn Forte 	(void) emlxs_mem_alloc(hba, buf_info);
790fcf3ce44SJohn Forte 	if (buf_info->virt == NULL) {
791fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
792fcf3ce44SJohn Forte 		    "MEM_BUF_ALLOC buffer.");
793fcf3ce44SJohn Forte 
79482527734SSukumar Swaminathan 		return (NULL);
795fcf3ce44SJohn Forte 	}
796291a2b48SSukumar Swaminathan 
79782527734SSukumar Swaminathan 	mp = (MATCHMAP *)buf_info->virt;
79882527734SSukumar Swaminathan 	bzero(mp, sizeof (MATCHMAP));
799fcf3ce44SJohn Forte 
800fcf3ce44SJohn Forte 	bzero(buf_info, sizeof (MBUF_INFO));
80182527734SSukumar Swaminathan 	buf_info->size = size;
80282527734SSukumar Swaminathan 	buf_info->flags = FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
803fcf3ce44SJohn Forte 	buf_info->align = 32;
804fcf3ce44SJohn Forte 
805fcf3ce44SJohn Forte 	(void) emlxs_mem_alloc(hba, buf_info);
806fcf3ce44SJohn Forte 	if (buf_info->virt == NULL) {
807fcf3ce44SJohn Forte 
808fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
809fcf3ce44SJohn Forte 		    "MEM_BUF_ALLOC DMA buffer.");
810fcf3ce44SJohn Forte 
81182527734SSukumar Swaminathan 		/* Free the mp object */
812728bdc9bSSukumar Swaminathan 		bzero(buf_info, sizeof (MBUF_INFO));
813728bdc9bSSukumar Swaminathan 		buf_info->size = sizeof (MATCHMAP);
814*a9800bebSGarrett D'Amore 		buf_info->virt = (void *)mp;
815728bdc9bSSukumar Swaminathan 		emlxs_mem_free(hba, buf_info);
816728bdc9bSSukumar Swaminathan 
817fcf3ce44SJohn Forte 		return (0);
818fcf3ce44SJohn Forte 	}
819fcf3ce44SJohn Forte 	bp = (uint8_t *)buf_info->virt;
820fcf3ce44SJohn Forte 	bzero(bp, MEM_BUF_SIZE);
821fcf3ce44SJohn Forte 
82282527734SSukumar Swaminathan 	mp->virt = buf_info->virt;
82382527734SSukumar Swaminathan 	mp->phys = buf_info->phys;
82482527734SSukumar Swaminathan 	mp->size = buf_info->size;
82582527734SSukumar Swaminathan 	mp->dma_handle = buf_info->dma_handle;
82682527734SSukumar Swaminathan 	mp->data_handle = buf_info->data_handle;
82782527734SSukumar Swaminathan 	mp->tag = MEM_BUF;
82882527734SSukumar Swaminathan 	mp->flag |= MAP_BUF_ALLOCATED;
829fcf3ce44SJohn Forte 
83082527734SSukumar Swaminathan 	return (mp);
831fcf3ce44SJohn Forte 
83282527734SSukumar Swaminathan } /* emlxs_mem_buf_alloc() */
833fcf3ce44SJohn Forte 
834fcf3ce44SJohn Forte 
835*a9800bebSGarrett D'Amore extern void
83682527734SSukumar Swaminathan emlxs_mem_buf_free(emlxs_hba_t *hba, MATCHMAP *mp)
837fcf3ce44SJohn Forte {
838fcf3ce44SJohn Forte 	MBUF_INFO bufinfo;
839fcf3ce44SJohn Forte 	MBUF_INFO *buf_info;
840fcf3ce44SJohn Forte 
841fcf3ce44SJohn Forte 	buf_info = &bufinfo;
842fcf3ce44SJohn Forte 
84382527734SSukumar Swaminathan 	if (!(mp->flag & MAP_BUF_ALLOCATED)) {
844*a9800bebSGarrett D'Amore 		return;
845fcf3ce44SJohn Forte 	}
846fcf3ce44SJohn Forte 
847fcf3ce44SJohn Forte 	bzero(buf_info, sizeof (MBUF_INFO));
84882527734SSukumar Swaminathan 	buf_info->size = mp->size;
84982527734SSukumar Swaminathan 	buf_info->virt = mp->virt;
85082527734SSukumar Swaminathan 	buf_info->phys = mp->phys;
85182527734SSukumar Swaminathan 	buf_info->dma_handle = mp->dma_handle;
85282527734SSukumar Swaminathan 	buf_info->data_handle = mp->data_handle;
853fcf3ce44SJohn Forte 	buf_info->flags = FC_MBUF_DMA;
854fcf3ce44SJohn Forte 	emlxs_mem_free(hba, buf_info);
855fcf3ce44SJohn Forte 
856fcf3ce44SJohn Forte 	bzero(buf_info, sizeof (MBUF_INFO));
857fcf3ce44SJohn Forte 	buf_info->size = sizeof (MATCHMAP);
858*a9800bebSGarrett D'Amore 	buf_info->virt = (void *)mp;
859fcf3ce44SJohn Forte 	emlxs_mem_free(hba, buf_info);
860fcf3ce44SJohn Forte 
861*a9800bebSGarrett D'Amore 	return;
862fcf3ce44SJohn Forte 
86382527734SSukumar Swaminathan } /* emlxs_mem_buf_free() */
864fcf3ce44SJohn Forte 
865fcf3ce44SJohn Forte 
866*a9800bebSGarrett D'Amore extern void *
86782527734SSukumar Swaminathan emlxs_mem_get(emlxs_hba_t *hba, uint32_t seg_id, uint32_t priority)
868fcf3ce44SJohn Forte {
869*a9800bebSGarrett D'Amore 	emlxs_port_t	*port = &PPORT;
870*a9800bebSGarrett D'Amore 	void		*bp;
871*a9800bebSGarrett D'Amore 	MAILBOXQ	*mbq;
872*a9800bebSGarrett D'Amore 	IOCBQ		*iocbq;
873*a9800bebSGarrett D'Amore 	NODELIST	*node;
874*a9800bebSGarrett D'Amore 	MEMSEG		*seg;
875fcf3ce44SJohn Forte 
87682527734SSukumar Swaminathan 	if (seg_id >= FC_MAX_SEG) {
877291a2b48SSukumar Swaminathan 
87882527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
87982527734SSukumar Swaminathan 		    "emlxs_mem_get: Invalid segment id = %d",
88082527734SSukumar Swaminathan 		    seg_id);
881fcf3ce44SJohn Forte 
882fcf3ce44SJohn Forte 		return (NULL);
883fcf3ce44SJohn Forte 	}
88482527734SSukumar Swaminathan 	seg = &hba->memseg[seg_id];
885fcf3ce44SJohn Forte 
88682527734SSukumar Swaminathan 	/* Alloc a buffer from the pool */
88782527734SSukumar Swaminathan 	bp = emlxs_mem_pool_get(hba, seg, priority);
888fcf3ce44SJohn Forte 
88982527734SSukumar Swaminathan 	if (bp) {
89082527734SSukumar Swaminathan 		switch (seg_id) {
891fcf3ce44SJohn Forte 		case MEM_MBOX:
892291a2b48SSukumar Swaminathan 			mbq = (MAILBOXQ *)bp;
893fcf3ce44SJohn Forte 			mbq->flag |= MBQ_POOL_ALLOCATED;
894fcf3ce44SJohn Forte 			break;
895fcf3ce44SJohn Forte 
896fcf3ce44SJohn Forte 		case MEM_IOCB:
897291a2b48SSukumar Swaminathan 			iocbq = (IOCBQ *)bp;
898fcf3ce44SJohn Forte 			iocbq->flag |= IOCB_POOL_ALLOCATED;
899fcf3ce44SJohn Forte 			break;
900fcf3ce44SJohn Forte 
901fcf3ce44SJohn Forte 		case MEM_NLP:
902291a2b48SSukumar Swaminathan 			node = (NODELIST *)bp;
903fcf3ce44SJohn Forte 			node->flag |= NODE_POOL_ALLOCATED;
904fcf3ce44SJohn Forte 			break;
905fcf3ce44SJohn Forte 		}
906fcf3ce44SJohn Forte 	}
907fcf3ce44SJohn Forte 
908fcf3ce44SJohn Forte 	return (bp);
909fcf3ce44SJohn Forte 
91082527734SSukumar Swaminathan } /* emlxs_mem_get() */
911fcf3ce44SJohn Forte 
912fcf3ce44SJohn Forte 
913*a9800bebSGarrett D'Amore extern void
914*a9800bebSGarrett D'Amore emlxs_mem_put(emlxs_hba_t *hba, uint32_t seg_id, void *bp)
915fcf3ce44SJohn Forte {
916*a9800bebSGarrett D'Amore 	emlxs_port_t	*port = &PPORT;
917*a9800bebSGarrett D'Amore 	MAILBOXQ	*mbq;
918*a9800bebSGarrett D'Amore 	IOCBQ		*iocbq;
919*a9800bebSGarrett D'Amore 	NODELIST	*node;
920*a9800bebSGarrett D'Amore 	MEMSEG		*seg;
921*a9800bebSGarrett D'Amore 	MATCHMAP	*mp;
922fcf3ce44SJohn Forte 
92382527734SSukumar Swaminathan 	if (seg_id >= FC_MAX_SEG) {
92482527734SSukumar Swaminathan 
92582527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
92682527734SSukumar Swaminathan 		    "emlxs_mem_put: Invalid segment id = %d: bp=%p",
92782527734SSukumar Swaminathan 		    seg_id, bp);
928291a2b48SSukumar Swaminathan 
929*a9800bebSGarrett D'Amore 		return;
930fcf3ce44SJohn Forte 	}
93182527734SSukumar Swaminathan 	seg = &hba->memseg[seg_id];
932291a2b48SSukumar Swaminathan 
93382527734SSukumar Swaminathan 	/* Verify buffer */
93482527734SSukumar Swaminathan 	switch (seg_id) {
935fcf3ce44SJohn Forte 	case MEM_MBOX:
936291a2b48SSukumar Swaminathan 		mbq = (MAILBOXQ *)bp;
937fcf3ce44SJohn Forte 
938fcf3ce44SJohn Forte 		if (!(mbq->flag & MBQ_POOL_ALLOCATED)) {
939*a9800bebSGarrett D'Amore 			return;
940fcf3ce44SJohn Forte 		}
941fcf3ce44SJohn Forte 		break;
942fcf3ce44SJohn Forte 
943fcf3ce44SJohn Forte 	case MEM_IOCB:
944291a2b48SSukumar Swaminathan 		iocbq = (IOCBQ *)bp;
945fcf3ce44SJohn Forte 
946fcf3ce44SJohn Forte 		if (!(iocbq->flag & IOCB_POOL_ALLOCATED)) {
947*a9800bebSGarrett D'Amore 			return;
948fcf3ce44SJohn Forte 		}
949291a2b48SSukumar Swaminathan 
950291a2b48SSukumar Swaminathan 		/* Any IOCBQ with a packet attached did not come */
951291a2b48SSukumar Swaminathan 		/* from our pool */
952fcf3ce44SJohn Forte 		if (iocbq->sbp) {
953*a9800bebSGarrett D'Amore 			return;
954fcf3ce44SJohn Forte 		}
955fcf3ce44SJohn Forte 		break;
956fcf3ce44SJohn Forte 
957fcf3ce44SJohn Forte 	case MEM_NLP:
958291a2b48SSukumar Swaminathan 		node = (NODELIST *)bp;
959fcf3ce44SJohn Forte 
960fcf3ce44SJohn Forte 		if (!(node->flag & NODE_POOL_ALLOCATED)) {
961*a9800bebSGarrett D'Amore 			return;
962fcf3ce44SJohn Forte 		}
963fcf3ce44SJohn Forte 		break;
964fcf3ce44SJohn Forte 
965fcf3ce44SJohn Forte 	default:
96682527734SSukumar Swaminathan 		mp = (MATCHMAP *)bp;
967fcf3ce44SJohn Forte 
96882527734SSukumar Swaminathan 		if (mp->flag & MAP_BUF_ALLOCATED) {
969*a9800bebSGarrett D'Amore 			emlxs_mem_buf_free(hba, mp);
970*a9800bebSGarrett D'Amore 			return;
971fcf3ce44SJohn Forte 		}
972291a2b48SSukumar Swaminathan 
97382527734SSukumar Swaminathan 		if (mp->flag & MAP_TABLE_ALLOCATED) {
974*a9800bebSGarrett D'Amore 			return;
975fcf3ce44SJohn Forte 		}
976291a2b48SSukumar Swaminathan 
97782527734SSukumar Swaminathan 		if (!(mp->flag & MAP_POOL_ALLOCATED)) {
978*a9800bebSGarrett D'Amore 			return;
979fcf3ce44SJohn Forte 		}
980fcf3ce44SJohn Forte 		break;
981fcf3ce44SJohn Forte 	}
982fcf3ce44SJohn Forte 
98382527734SSukumar Swaminathan 	/* Free a buffer to the pool */
984*a9800bebSGarrett D'Amore 	emlxs_mem_pool_put(hba, seg, bp);
985291a2b48SSukumar Swaminathan 
986*a9800bebSGarrett D'Amore 	return;
987fcf3ce44SJohn Forte 
98882527734SSukumar Swaminathan } /* emlxs_mem_put() */
989fcf3ce44SJohn Forte 
990fcf3ce44SJohn Forte 
991fcf3ce44SJohn Forte /*
992fcf3ce44SJohn Forte  * Look up the virtual address given a mapped address
993fcf3ce44SJohn Forte  */
99482527734SSukumar Swaminathan /* SLI3 */
995fcf3ce44SJohn Forte extern MATCHMAP *
996fcf3ce44SJohn Forte emlxs_mem_get_vaddr(emlxs_hba_t *hba, RING *rp, uint64_t mapbp)
997fcf3ce44SJohn Forte {
998fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
999fcf3ce44SJohn Forte 	MATCHMAP *prev;
1000fcf3ce44SJohn Forte 	MATCHMAP *mp;
1001fcf3ce44SJohn Forte 
100282527734SSukumar Swaminathan 	if (rp->ringno == hba->channel_els) {
1003291a2b48SSukumar Swaminathan 		mp = (MATCHMAP *)rp->fc_mpoff;
1004fcf3ce44SJohn Forte 		prev = 0;
1005fcf3ce44SJohn Forte 
1006fcf3ce44SJohn Forte 		while (mp) {
1007fcf3ce44SJohn Forte 			if (mp->phys == mapbp) {
1008fcf3ce44SJohn Forte 				if (prev == 0) {
1009fcf3ce44SJohn Forte 					rp->fc_mpoff = mp->fc_mptr;
1010fcf3ce44SJohn Forte 				} else {
1011fcf3ce44SJohn Forte 					prev->fc_mptr = mp->fc_mptr;
1012fcf3ce44SJohn Forte 				}
1013fcf3ce44SJohn Forte 
1014*a9800bebSGarrett D'Amore 				if (rp->fc_mpon == mp) {
1015*a9800bebSGarrett D'Amore 					rp->fc_mpon = (void *)prev;
1016fcf3ce44SJohn Forte 				}
1017291a2b48SSukumar Swaminathan 
1018*a9800bebSGarrett D'Amore 				mp->fc_mptr = NULL;
1019fcf3ce44SJohn Forte 
102082527734SSukumar Swaminathan 				EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
1021fcf3ce44SJohn Forte 				    DDI_DMA_SYNC_FORKERNEL);
1022fcf3ce44SJohn Forte 
1023fcf3ce44SJohn Forte 				HBASTATS.ElsUbPosted--;
1024fcf3ce44SJohn Forte 
1025fcf3ce44SJohn Forte 				return (mp);
1026fcf3ce44SJohn Forte 			}
1027291a2b48SSukumar Swaminathan 
1028fcf3ce44SJohn Forte 			prev = mp;
1029291a2b48SSukumar Swaminathan 			mp = (MATCHMAP *)mp->fc_mptr;
1030fcf3ce44SJohn Forte 		}
1031fcf3ce44SJohn Forte 
1032fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
1033fcf3ce44SJohn Forte 		    "ELS Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p",
1034fcf3ce44SJohn Forte 		    mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon);
1035fcf3ce44SJohn Forte 
103682527734SSukumar Swaminathan 	} else if (rp->ringno == hba->channel_ct) {
1037fcf3ce44SJohn Forte 
1038291a2b48SSukumar Swaminathan 		mp = (MATCHMAP *)rp->fc_mpoff;
1039fcf3ce44SJohn Forte 		prev = 0;
1040fcf3ce44SJohn Forte 
1041fcf3ce44SJohn Forte 		while (mp) {
1042fcf3ce44SJohn Forte 			if (mp->phys == mapbp) {
1043fcf3ce44SJohn Forte 				if (prev == 0) {
1044fcf3ce44SJohn Forte 					rp->fc_mpoff = mp->fc_mptr;
1045fcf3ce44SJohn Forte 				} else {
1046fcf3ce44SJohn Forte 					prev->fc_mptr = mp->fc_mptr;
1047fcf3ce44SJohn Forte 				}
1048fcf3ce44SJohn Forte 
1049*a9800bebSGarrett D'Amore 				if (rp->fc_mpon == mp) {
1050*a9800bebSGarrett D'Amore 					rp->fc_mpon = (void *)prev;
1051fcf3ce44SJohn Forte 				}
1052291a2b48SSukumar Swaminathan 
1053*a9800bebSGarrett D'Amore 				mp->fc_mptr = NULL;
1054fcf3ce44SJohn Forte 
105582527734SSukumar Swaminathan 				EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
1056fcf3ce44SJohn Forte 				    DDI_DMA_SYNC_FORKERNEL);
1057fcf3ce44SJohn Forte 
1058fcf3ce44SJohn Forte 				HBASTATS.CtUbPosted--;
1059fcf3ce44SJohn Forte 
1060fcf3ce44SJohn Forte 				return (mp);
1061fcf3ce44SJohn Forte 			}
1062291a2b48SSukumar Swaminathan 
1063fcf3ce44SJohn Forte 			prev = mp;
1064291a2b48SSukumar Swaminathan 			mp = (MATCHMAP *)mp->fc_mptr;
1065fcf3ce44SJohn Forte 		}
1066fcf3ce44SJohn Forte 
1067fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
1068fcf3ce44SJohn Forte 		    "CT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p",
1069fcf3ce44SJohn Forte 		    mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon);
1070fcf3ce44SJohn Forte 
107182527734SSukumar Swaminathan 	} else if (rp->ringno == hba->channel_ip) {
1072fcf3ce44SJohn Forte 
1073291a2b48SSukumar Swaminathan 		mp = (MATCHMAP *)rp->fc_mpoff;
1074fcf3ce44SJohn Forte 		prev = 0;
1075fcf3ce44SJohn Forte 
1076fcf3ce44SJohn Forte 		while (mp) {
1077fcf3ce44SJohn Forte 			if (mp->phys == mapbp) {
1078fcf3ce44SJohn Forte 				if (prev == 0) {
1079fcf3ce44SJohn Forte 					rp->fc_mpoff = mp->fc_mptr;
1080fcf3ce44SJohn Forte 				} else {
1081fcf3ce44SJohn Forte 					prev->fc_mptr = mp->fc_mptr;
1082fcf3ce44SJohn Forte 				}
1083fcf3ce44SJohn Forte 
1084*a9800bebSGarrett D'Amore 				if (rp->fc_mpon == mp) {
1085*a9800bebSGarrett D'Amore 					rp->fc_mpon = (void *)prev;
1086fcf3ce44SJohn Forte 				}
1087291a2b48SSukumar Swaminathan 
1088*a9800bebSGarrett D'Amore 				mp->fc_mptr = NULL;
1089fcf3ce44SJohn Forte 
109082527734SSukumar Swaminathan 				EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
1091fcf3ce44SJohn Forte 				    DDI_DMA_SYNC_FORKERNEL);
1092fcf3ce44SJohn Forte 
1093fcf3ce44SJohn Forte 				HBASTATS.IpUbPosted--;
1094fcf3ce44SJohn Forte 
1095fcf3ce44SJohn Forte 				return (mp);
1096fcf3ce44SJohn Forte 			}
1097291a2b48SSukumar Swaminathan 
1098fcf3ce44SJohn Forte 			prev = mp;
1099291a2b48SSukumar Swaminathan 			mp = (MATCHMAP *)mp->fc_mptr;
1100fcf3ce44SJohn Forte 		}
1101fcf3ce44SJohn Forte 
1102fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
1103fcf3ce44SJohn Forte 		    "IP Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p",
1104fcf3ce44SJohn Forte 		    mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon);
1105fcf3ce44SJohn Forte 
1106fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT
110782527734SSukumar Swaminathan 	} else if (rp->ringno == hba->CHANNEL_FCT) {
1108291a2b48SSukumar Swaminathan 		mp = (MATCHMAP *)rp->fc_mpoff;
1109fcf3ce44SJohn Forte 		prev = 0;
1110fcf3ce44SJohn Forte 
1111fcf3ce44SJohn Forte 		while (mp) {
1112fcf3ce44SJohn Forte 			if (mp->phys == mapbp) {
1113fcf3ce44SJohn Forte 				if (prev == 0) {
1114fcf3ce44SJohn Forte 					rp->fc_mpoff = mp->fc_mptr;
1115fcf3ce44SJohn Forte 				} else {
1116fcf3ce44SJohn Forte 					prev->fc_mptr = mp->fc_mptr;
1117fcf3ce44SJohn Forte 				}
1118fcf3ce44SJohn Forte 
1119*a9800bebSGarrett D'Amore 				if (rp->fc_mpon == mp) {
1120*a9800bebSGarrett D'Amore 					rp->fc_mpon = (void *)prev;
1121fcf3ce44SJohn Forte 				}
1122291a2b48SSukumar Swaminathan 
1123*a9800bebSGarrett D'Amore 				mp->fc_mptr = NULL;
1124fcf3ce44SJohn Forte 
112582527734SSukumar Swaminathan 				EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
1126fcf3ce44SJohn Forte 				    DDI_DMA_SYNC_FORKERNEL);
1127fcf3ce44SJohn Forte 
1128fcf3ce44SJohn Forte 				HBASTATS.FctUbPosted--;
1129fcf3ce44SJohn Forte 
1130fcf3ce44SJohn Forte 				return (mp);
1131fcf3ce44SJohn Forte 			}
1132291a2b48SSukumar Swaminathan 
1133fcf3ce44SJohn Forte 			prev = mp;
1134291a2b48SSukumar Swaminathan 			mp = (MATCHMAP *)mp->fc_mptr;
1135fcf3ce44SJohn Forte 		}
1136fcf3ce44SJohn Forte 
1137fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
1138fcf3ce44SJohn Forte 		    "FCT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p",
1139fcf3ce44SJohn Forte 		    mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon);
1140fcf3ce44SJohn Forte 
1141291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */
1142fcf3ce44SJohn Forte 	}
1143fcf3ce44SJohn Forte 
1144fcf3ce44SJohn Forte 	return (0);
1145fcf3ce44SJohn Forte 
114682527734SSukumar Swaminathan } /* emlxs_mem_get_vaddr() */
1147fcf3ce44SJohn Forte 
1148fcf3ce44SJohn Forte 
1149fcf3ce44SJohn Forte /*
1150291a2b48SSukumar Swaminathan  * Given a virtual address bp, generate the physical mapped address and
1151291a2b48SSukumar Swaminathan  * place it where addr points to. Save the address pair for lookup later.
1152fcf3ce44SJohn Forte  */
115382527734SSukumar Swaminathan /* SLI3 */
1154fcf3ce44SJohn Forte extern void
1155291a2b48SSukumar Swaminathan emlxs_mem_map_vaddr(emlxs_hba_t *hba, RING *rp, MATCHMAP *mp,
1156291a2b48SSukumar Swaminathan     uint32_t *haddr, uint32_t *laddr)
1157fcf3ce44SJohn Forte {
115882527734SSukumar Swaminathan 	if (rp->ringno == hba->channel_els) {
1159fcf3ce44SJohn Forte 		/*
1160291a2b48SSukumar Swaminathan 		 * Update slot fc_mpon points to then bump it
1161291a2b48SSukumar Swaminathan 		 * fc_mpoff is pointer head of the list.
1162291a2b48SSukumar Swaminathan 		 * fc_mpon is pointer tail of the list.
1163fcf3ce44SJohn Forte 		 */
1164*a9800bebSGarrett D'Amore 		mp->fc_mptr = NULL;
1165fcf3ce44SJohn Forte 		if (rp->fc_mpoff == 0) {
1166*a9800bebSGarrett D'Amore 			rp->fc_mpoff = (void *)mp;
1167*a9800bebSGarrett D'Amore 			rp->fc_mpon = (void *)mp;
1168fcf3ce44SJohn Forte 		} else {
1169291a2b48SSukumar Swaminathan 			((MATCHMAP *)(rp->fc_mpon))->fc_mptr =
1170*a9800bebSGarrett D'Amore 			    (void *)mp;
1171*a9800bebSGarrett D'Amore 			rp->fc_mpon = (void *)mp;
1172fcf3ce44SJohn Forte 		}
1173fcf3ce44SJohn Forte 
1174fcf3ce44SJohn Forte 		if (hba->flag & FC_SLIM2_MODE) {
1175291a2b48SSukumar Swaminathan 
1176291a2b48SSukumar Swaminathan 			/* return mapped address */
117782527734SSukumar Swaminathan 			*haddr = PADDR_HI(mp->phys);
1178fcf3ce44SJohn Forte 			/* return mapped address */
117982527734SSukumar Swaminathan 			*laddr = PADDR_LO(mp->phys);
1180fcf3ce44SJohn Forte 		} else {
1181fcf3ce44SJohn Forte 			/* return mapped address */
118282527734SSukumar Swaminathan 			*laddr = PADDR_LO(mp->phys);
1183fcf3ce44SJohn Forte 		}
1184fcf3ce44SJohn Forte 
1185fcf3ce44SJohn Forte 		HBASTATS.ElsUbPosted++;
1186fcf3ce44SJohn Forte 
118782527734SSukumar Swaminathan 	} else if (rp->ringno == hba->channel_ct) {
1188fcf3ce44SJohn Forte 		/*
1189291a2b48SSukumar Swaminathan 		 * Update slot fc_mpon points to then bump it
1190291a2b48SSukumar Swaminathan 		 * fc_mpoff is pointer head of the list.
1191291a2b48SSukumar Swaminathan 		 * fc_mpon is pointer tail of the list.
1192fcf3ce44SJohn Forte 		 */
1193*a9800bebSGarrett D'Amore 		mp->fc_mptr = NULL;
1194fcf3ce44SJohn Forte 		if (rp->fc_mpoff == 0) {
1195*a9800bebSGarrett D'Amore 			rp->fc_mpoff = (void *)mp;
1196*a9800bebSGarrett D'Amore 			rp->fc_mpon = (void *)mp;
1197fcf3ce44SJohn Forte 		} else {
1198291a2b48SSukumar Swaminathan 			((MATCHMAP *)(rp->fc_mpon))->fc_mptr =
1199*a9800bebSGarrett D'Amore 			    (void *)mp;
1200*a9800bebSGarrett D'Amore 			rp->fc_mpon = (void *)mp;
1201fcf3ce44SJohn Forte 		}
1202fcf3ce44SJohn Forte 
1203fcf3ce44SJohn Forte 		if (hba->flag & FC_SLIM2_MODE) {
1204fcf3ce44SJohn Forte 			/* return mapped address */
120582527734SSukumar Swaminathan 			*haddr = PADDR_HI(mp->phys);
1206291a2b48SSukumar Swaminathan 			/* return mapped address */
120782527734SSukumar Swaminathan 			*laddr = PADDR_LO(mp->phys);
1208fcf3ce44SJohn Forte 		} else {
1209fcf3ce44SJohn Forte 			/* return mapped address */
121082527734SSukumar Swaminathan 			*laddr = PADDR_LO(mp->phys);
1211fcf3ce44SJohn Forte 		}
1212fcf3ce44SJohn Forte 
1213fcf3ce44SJohn Forte 		HBASTATS.CtUbPosted++;
1214fcf3ce44SJohn Forte 
1215fcf3ce44SJohn Forte 
121682527734SSukumar Swaminathan 	} else if (rp->ringno == hba->channel_ip) {
1217fcf3ce44SJohn Forte 		/*
1218291a2b48SSukumar Swaminathan 		 * Update slot fc_mpon points to then bump it
1219291a2b48SSukumar Swaminathan 		 * fc_mpoff is pointer head of the list.
1220291a2b48SSukumar Swaminathan 		 * fc_mpon is pointer tail of the list.
1221fcf3ce44SJohn Forte 		 */
1222*a9800bebSGarrett D'Amore 		mp->fc_mptr = NULL;
1223fcf3ce44SJohn Forte 		if (rp->fc_mpoff == 0) {
1224*a9800bebSGarrett D'Amore 			rp->fc_mpoff = (void *)mp;
1225*a9800bebSGarrett D'Amore 			rp->fc_mpon = (void *)mp;
1226fcf3ce44SJohn Forte 		} else {
1227291a2b48SSukumar Swaminathan 			((MATCHMAP *)(rp->fc_mpon))->fc_mptr =
1228*a9800bebSGarrett D'Amore 			    (void *)mp;
1229*a9800bebSGarrett D'Amore 			rp->fc_mpon = (void *)mp;
1230fcf3ce44SJohn Forte 		}
1231fcf3ce44SJohn Forte 
1232fcf3ce44SJohn Forte 		if (hba->flag & FC_SLIM2_MODE) {
1233fcf3ce44SJohn Forte 			/* return mapped address */
123482527734SSukumar Swaminathan 			*haddr = PADDR_HI(mp->phys);
123582527734SSukumar Swaminathan 			*laddr = PADDR_LO(mp->phys);
1236fcf3ce44SJohn Forte 		} else {
123782527734SSukumar Swaminathan 			*laddr = PADDR_LO(mp->phys);
1238fcf3ce44SJohn Forte 		}
1239fcf3ce44SJohn Forte 
1240fcf3ce44SJohn Forte 		HBASTATS.IpUbPosted++;
1241fcf3ce44SJohn Forte 
1242fcf3ce44SJohn Forte 
1243fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT
124482527734SSukumar Swaminathan 	} else if (rp->ringno == hba->CHANNEL_FCT) {
1245fcf3ce44SJohn Forte 		/*
1246291a2b48SSukumar Swaminathan 		 * Update slot fc_mpon points to then bump it
1247291a2b48SSukumar Swaminathan 		 * fc_mpoff is pointer head of the list.
1248291a2b48SSukumar Swaminathan 		 * fc_mpon is pointer tail of the list.
1249fcf3ce44SJohn Forte 		 */
1250*a9800bebSGarrett D'Amore 		mp->fc_mptr = NULL;
1251fcf3ce44SJohn Forte 		if (rp->fc_mpoff == 0) {
1252*a9800bebSGarrett D'Amore 			rp->fc_mpoff = (void *)mp;
1253*a9800bebSGarrett D'Amore 			rp->fc_mpon = (void *)mp;
1254fcf3ce44SJohn Forte 		} else {
1255291a2b48SSukumar Swaminathan 			((MATCHMAP *)(rp->fc_mpon))->fc_mptr =
1256*a9800bebSGarrett D'Amore 			    (void *)mp;
1257*a9800bebSGarrett D'Amore 			rp->fc_mpon = (void *)mp;
1258fcf3ce44SJohn Forte 		}
1259fcf3ce44SJohn Forte 
1260fcf3ce44SJohn Forte 		if (hba->flag & FC_SLIM2_MODE) {
1261fcf3ce44SJohn Forte 			/* return mapped address */
126282527734SSukumar Swaminathan 			*haddr = PADDR_HI(mp->phys);
1263291a2b48SSukumar Swaminathan 			/* return mapped address */
126482527734SSukumar Swaminathan 			*laddr = PADDR_LO(mp->phys);
1265fcf3ce44SJohn Forte 		} else {
1266fcf3ce44SJohn Forte 			/* return mapped address */
126782527734SSukumar Swaminathan 			*laddr = PADDR_LO(mp->phys);
1268fcf3ce44SJohn Forte 		}
1269fcf3ce44SJohn Forte 
1270fcf3ce44SJohn Forte 		HBASTATS.FctUbPosted++;
127182527734SSukumar Swaminathan 
1272291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */
1273fcf3ce44SJohn Forte 	}
127482527734SSukumar Swaminathan } /* emlxs_mem_map_vaddr() */
1275fcf3ce44SJohn Forte 
1276fcf3ce44SJohn Forte 
127782527734SSukumar Swaminathan /* SLI3 */
1278291a2b48SSukumar Swaminathan uint32_t
1279fcf3ce44SJohn Forte emlxs_hbq_alloc(emlxs_hba_t *hba, uint32_t hbq_id)
1280fcf3ce44SJohn Forte {
1281fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
1282fcf3ce44SJohn Forte 	HBQ_INIT_t *hbq;
1283fcf3ce44SJohn Forte 	MBUF_INFO *buf_info;
1284fcf3ce44SJohn Forte 	MBUF_INFO bufinfo;
1285fcf3ce44SJohn Forte 
128682527734SSukumar Swaminathan 	hbq = &hba->sli.sli3.hbq_table[hbq_id];
1287fcf3ce44SJohn Forte 
1288fcf3ce44SJohn Forte 	if (hbq->HBQ_host_buf.virt == 0) {
1289fcf3ce44SJohn Forte 		buf_info = &bufinfo;
1290fcf3ce44SJohn Forte 
1291fcf3ce44SJohn Forte 		/* Get the system's page size in a DDI-compliant way. */
1292fcf3ce44SJohn Forte 		bzero(buf_info, sizeof (MBUF_INFO));
1293fcf3ce44SJohn Forte 		buf_info->size = hbq->HBQ_numEntries * sizeof (HBQE_t);
1294fcf3ce44SJohn Forte 		buf_info->flags = FC_MBUF_DMA;
1295fcf3ce44SJohn Forte 		buf_info->align = 4096;
1296fcf3ce44SJohn Forte 
1297fcf3ce44SJohn Forte 		(void) emlxs_mem_alloc(hba, buf_info);
1298fcf3ce44SJohn Forte 
1299fcf3ce44SJohn Forte 		if (buf_info->virt == NULL) {
1300fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg,
1301fcf3ce44SJohn Forte 			    "Unable to alloc HBQ.");
1302fcf3ce44SJohn Forte 			return (ENOMEM);
1303fcf3ce44SJohn Forte 		}
1304291a2b48SSukumar Swaminathan 
1305*a9800bebSGarrett D'Amore 		hbq->HBQ_host_buf.virt = buf_info->virt;
1306fcf3ce44SJohn Forte 		hbq->HBQ_host_buf.phys = buf_info->phys;
1307fcf3ce44SJohn Forte 		hbq->HBQ_host_buf.data_handle = buf_info->data_handle;
1308fcf3ce44SJohn Forte 		hbq->HBQ_host_buf.dma_handle = buf_info->dma_handle;
1309fcf3ce44SJohn Forte 		hbq->HBQ_host_buf.size = buf_info->size;
1310fcf3ce44SJohn Forte 		hbq->HBQ_host_buf.tag = hbq_id;
1311fcf3ce44SJohn Forte 
1312fcf3ce44SJohn Forte 		bzero((char *)hbq->HBQ_host_buf.virt, buf_info->size);
1313fcf3ce44SJohn Forte 	}
1314fcf3ce44SJohn Forte 
1315fcf3ce44SJohn Forte 	return (0);
1316fcf3ce44SJohn Forte 
131782527734SSukumar Swaminathan } /* emlxs_hbq_alloc() */
1318