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 *
88f23e9faSHans Rosenfeld * You can obtain a copy of the license at
98f23e9faSHans Rosenfeld * http://www.opensource.org/licenses/cddl1.txt.
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 /*
238f23e9faSHans Rosenfeld * Copyright (c) 2004-2011 Emulex. All rights reserved.
2482527734SSukumar Swaminathan * Use is subject to license terms.
25a3170057SPaul Winder * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
26a3170057SPaul Winder * Copyright 2020 RackTop Systems, Inc.
27fcf3ce44SJohn Forte */
28fcf3ce44SJohn Forte
29291a2b48SSukumar Swaminathan #include <emlxs.h>
30fcf3ce44SJohn Forte
318f23e9faSHans Rosenfeld /* #define EMLXS_POOL_DEBUG */
328f23e9faSHans Rosenfeld
33fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_MEM_C);
34fcf3ce44SJohn Forte
35fcf3ce44SJohn Forte
368f23e9faSHans Rosenfeld static uint32_t emlxs_mem_pool_alloc(emlxs_hba_t *hba, MEMSEG *seg,
378f23e9faSHans Rosenfeld uint32_t count);
388f23e9faSHans Rosenfeld static void emlxs_mem_pool_free(emlxs_hba_t *hba, MEMSEG *seg, uint32_t count);
398f23e9faSHans Rosenfeld
408f23e9faSHans Rosenfeld
41fcf3ce44SJohn Forte extern int32_t
emlxs_mem_alloc_buffer(emlxs_hba_t * hba)42fcf3ce44SJohn Forte emlxs_mem_alloc_buffer(emlxs_hba_t *hba)
43fcf3ce44SJohn Forte {
44fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT;
45fcf3ce44SJohn Forte emlxs_config_t *cfg;
46fcf3ce44SJohn Forte MBUF_INFO *buf_info;
4782527734SSukumar Swaminathan MEMSEG *seg;
48fcf3ce44SJohn Forte MBUF_INFO bufinfo;
49fcf3ce44SJohn Forte int32_t i;
5082527734SSukumar Swaminathan MATCHMAP *mp;
518f23e9faSHans Rosenfeld MATCHMAP **bpl_table;
52fcf3ce44SJohn Forte
53fcf3ce44SJohn Forte buf_info = &bufinfo;
54fcf3ce44SJohn Forte cfg = &CFG;
55fcf3ce44SJohn Forte
5682527734SSukumar Swaminathan bzero(hba->memseg, sizeof (hba->memseg));
57fcf3ce44SJohn Forte
58fcf3ce44SJohn Forte /* Allocate the fc_table */
59fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO));
6082527734SSukumar Swaminathan buf_info->size = (hba->max_iotag * sizeof (emlxs_buf_t *));
61fcf3ce44SJohn Forte
62fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info);
63fcf3ce44SJohn Forte if (buf_info->virt == NULL) {
64fcf3ce44SJohn Forte
65fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
66fcf3ce44SJohn Forte "fc_table buffer.");
67fcf3ce44SJohn Forte
6882527734SSukumar Swaminathan goto failed;
69fcf3ce44SJohn Forte }
7082527734SSukumar Swaminathan hba->fc_table = buf_info->virt;
7182527734SSukumar Swaminathan bzero(hba->fc_table, buf_info->size);
72fcf3ce44SJohn Forte
7382527734SSukumar Swaminathan /* Prepare the memory pools */
7482527734SSukumar Swaminathan for (i = 0; i < FC_MAX_SEG; i++) {
7582527734SSukumar Swaminathan seg = &hba->memseg[i];
76fcf3ce44SJohn Forte
7782527734SSukumar Swaminathan switch (i) {
7882527734SSukumar Swaminathan case MEM_NLP:
798f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "Node Pool",
808f23e9faSHans Rosenfeld sizeof (seg->fc_label));
8182527734SSukumar Swaminathan seg->fc_memtag = MEM_NLP;
8282527734SSukumar Swaminathan seg->fc_memsize = sizeof (NODELIST);
838f23e9faSHans Rosenfeld seg->fc_hi_water = hba->max_nodes + 2;
848f23e9faSHans Rosenfeld seg->fc_lo_water = 2;
858f23e9faSHans Rosenfeld seg->fc_step = 1;
8682527734SSukumar Swaminathan break;
87fcf3ce44SJohn Forte
8882527734SSukumar Swaminathan case MEM_IOCB:
898f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "IOCB Pool",
908f23e9faSHans Rosenfeld sizeof (seg->fc_label));
9182527734SSukumar Swaminathan seg->fc_memtag = MEM_IOCB;
9282527734SSukumar Swaminathan seg->fc_memsize = sizeof (IOCBQ);
938f23e9faSHans Rosenfeld seg->fc_hi_water = cfg[CFG_NUM_IOCBS].current;
948f23e9faSHans Rosenfeld seg->fc_lo_water = cfg[CFG_NUM_IOCBS].low;
958f23e9faSHans Rosenfeld seg->fc_step = cfg[CFG_NUM_IOCBS].low;
9682527734SSukumar Swaminathan break;
97fcf3ce44SJohn Forte
9882527734SSukumar Swaminathan case MEM_MBOX:
998f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "MBOX Pool",
1008f23e9faSHans Rosenfeld sizeof (seg->fc_label));
10182527734SSukumar Swaminathan seg->fc_memtag = MEM_MBOX;
10282527734SSukumar Swaminathan seg->fc_memsize = sizeof (MAILBOXQ);
1038f23e9faSHans Rosenfeld seg->fc_hi_water = hba->max_nodes + 32;
1048f23e9faSHans Rosenfeld seg->fc_lo_water = 32;
1058f23e9faSHans Rosenfeld seg->fc_step = 1;
10682527734SSukumar Swaminathan break;
107fcf3ce44SJohn Forte
10882527734SSukumar Swaminathan case MEM_BPL:
10982527734SSukumar Swaminathan if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) {
11082527734SSukumar Swaminathan continue;
11182527734SSukumar Swaminathan }
1128f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "BPL Pool",
1138f23e9faSHans Rosenfeld sizeof (seg->fc_label));
11482527734SSukumar Swaminathan seg->fc_memtag = MEM_BPL;
11582527734SSukumar Swaminathan seg->fc_memsize = hba->sli.sli3.mem_bpl_size;
11682527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG;
11782527734SSukumar Swaminathan seg->fc_memalign = 32;
1188f23e9faSHans Rosenfeld seg->fc_hi_water = hba->max_iotag;
1198f23e9faSHans Rosenfeld seg->fc_lo_water = cfg[CFG_NUM_IOCBS].low;
1208f23e9faSHans Rosenfeld seg->fc_step = cfg[CFG_NUM_IOCBS].low;
12182527734SSukumar Swaminathan break;
122fcf3ce44SJohn Forte
12382527734SSukumar Swaminathan case MEM_BUF:
12482527734SSukumar Swaminathan /* These are the unsolicited ELS buffers. */
1258f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "BUF Pool",
1268f23e9faSHans Rosenfeld sizeof (seg->fc_label));
12782527734SSukumar Swaminathan seg->fc_memtag = MEM_BUF;
12882527734SSukumar Swaminathan seg->fc_memsize = MEM_BUF_SIZE;
12982527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG;
13082527734SSukumar Swaminathan seg->fc_memalign = 32;
1318f23e9faSHans Rosenfeld seg->fc_hi_water = MEM_ELSBUF_COUNT + MEM_BUF_COUNT;
1328f23e9faSHans Rosenfeld seg->fc_lo_water = MEM_ELSBUF_COUNT;
1338f23e9faSHans Rosenfeld seg->fc_step = 1;
13482527734SSukumar Swaminathan break;
135291a2b48SSukumar Swaminathan
13682527734SSukumar Swaminathan case MEM_IPBUF:
13782527734SSukumar Swaminathan /* These are the unsolicited IP buffers. */
13882527734SSukumar Swaminathan if (cfg[CFG_NETWORK_ON].current == 0) {
13982527734SSukumar Swaminathan continue;
14082527734SSukumar Swaminathan }
141fcf3ce44SJohn Forte
1428f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "IPBUF Pool",
1438f23e9faSHans Rosenfeld sizeof (seg->fc_label));
14482527734SSukumar Swaminathan seg->fc_memtag = MEM_IPBUF;
14582527734SSukumar Swaminathan seg->fc_memsize = MEM_IPBUF_SIZE;
14682527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG;
14782527734SSukumar Swaminathan seg->fc_memalign = 32;
1488f23e9faSHans Rosenfeld seg->fc_hi_water = MEM_IPBUF_COUNT;
1498f23e9faSHans Rosenfeld seg->fc_lo_water = 0;
1508f23e9faSHans Rosenfeld seg->fc_step = 4;
15182527734SSukumar Swaminathan break;
152fcf3ce44SJohn Forte
15382527734SSukumar Swaminathan case MEM_CTBUF:
15482527734SSukumar Swaminathan /* These are the unsolicited CT buffers. */
1558f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "CTBUF Pool",
1568f23e9faSHans Rosenfeld sizeof (seg->fc_label));
15782527734SSukumar Swaminathan seg->fc_memtag = MEM_CTBUF;
15882527734SSukumar Swaminathan seg->fc_memsize = MEM_CTBUF_SIZE;
15982527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG;
16082527734SSukumar Swaminathan seg->fc_memalign = 32;
1618f23e9faSHans Rosenfeld seg->fc_hi_water = MEM_CTBUF_COUNT;
1628f23e9faSHans Rosenfeld seg->fc_lo_water = MEM_CTBUF_COUNT;
1638f23e9faSHans Rosenfeld seg->fc_step = 1;
16482527734SSukumar Swaminathan break;
165fcf3ce44SJohn Forte
166a3170057SPaul Winder case MEM_SGL1K:
167a3170057SPaul Winder (void) strlcpy(seg->fc_label, "1K SGL Pool",
168a3170057SPaul Winder sizeof (seg->fc_label));
169a3170057SPaul Winder seg->fc_memtag = MEM_SGL1K;
170a3170057SPaul Winder seg->fc_memsize = 0x400;
171a3170057SPaul Winder seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG;
172a3170057SPaul Winder seg->fc_memalign = 32;
173a3170057SPaul Winder seg->fc_hi_water = 0x5000;
174a3170057SPaul Winder seg->fc_lo_water = 0;
175a3170057SPaul Winder seg->fc_step = 0x100;
176a3170057SPaul Winder break;
177a3170057SPaul Winder
178a3170057SPaul Winder case MEM_SGL2K:
179a3170057SPaul Winder (void) strlcpy(seg->fc_label, "2K SGL Pool",
180a3170057SPaul Winder sizeof (seg->fc_label));
181a3170057SPaul Winder seg->fc_memtag = MEM_SGL2K;
182a3170057SPaul Winder seg->fc_memsize = 0x800;
183a3170057SPaul Winder seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG;
184a3170057SPaul Winder seg->fc_memalign = 32;
185a3170057SPaul Winder seg->fc_hi_water = 0x5000;
186a3170057SPaul Winder seg->fc_lo_water = 0;
187a3170057SPaul Winder seg->fc_step = 0x100;
188a3170057SPaul Winder break;
189a3170057SPaul Winder
190a3170057SPaul Winder case MEM_SGL4K:
191a3170057SPaul Winder (void) strlcpy(seg->fc_label, "4K SGL Pool",
192a3170057SPaul Winder sizeof (seg->fc_label));
193a3170057SPaul Winder seg->fc_memtag = MEM_SGL4K;
194a3170057SPaul Winder seg->fc_memsize = 0x1000;
195a3170057SPaul Winder seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG;
196a3170057SPaul Winder seg->fc_memalign = 32;
197a3170057SPaul Winder seg->fc_hi_water = 0x5000;
198a3170057SPaul Winder seg->fc_lo_water = 0;
199a3170057SPaul Winder seg->fc_step = 0x100;
200a3170057SPaul Winder break;
201a3170057SPaul Winder
20282527734SSukumar Swaminathan #ifdef SFCT_SUPPORT
2038f23e9faSHans Rosenfeld case MEM_FCTBUF:
20482527734SSukumar Swaminathan /* These are the unsolicited FCT buffers. */
2058f23e9faSHans Rosenfeld if (!(port->flag & EMLXS_TGT_ENABLED)) {
20682527734SSukumar Swaminathan continue;
20782527734SSukumar Swaminathan }
208fcf3ce44SJohn Forte
2098f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "FCTBUF Pool",
2108f23e9faSHans Rosenfeld sizeof (seg->fc_label));
21182527734SSukumar Swaminathan seg->fc_memtag = MEM_FCTBUF;
21282527734SSukumar Swaminathan seg->fc_memsize = MEM_FCTBUF_SIZE;
21382527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG;
21482527734SSukumar Swaminathan seg->fc_memalign = 32;
2158f23e9faSHans Rosenfeld seg->fc_hi_water = MEM_FCTBUF_COUNT;
2168f23e9faSHans Rosenfeld seg->fc_lo_water = 0;
2178f23e9faSHans Rosenfeld seg->fc_step = 8;
21882527734SSukumar Swaminathan break;
2198f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */
220fcf3ce44SJohn Forte
22182527734SSukumar Swaminathan default:
22282527734SSukumar Swaminathan continue;
223fcf3ce44SJohn Forte }
224fcf3ce44SJohn Forte
22582527734SSukumar Swaminathan if (seg->fc_memsize == 0) {
22682527734SSukumar Swaminathan continue;
22782527734SSukumar Swaminathan }
228fcf3ce44SJohn Forte
2298f23e9faSHans Rosenfeld (void) emlxs_mem_pool_create(hba, seg);
2308f23e9faSHans Rosenfeld
2318f23e9faSHans Rosenfeld if (seg->fc_numblks < seg->fc_lo_water) {
2328f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
2338f23e9faSHans Rosenfeld "%s: count=%d size=%d flags=%x lo=%d hi=%d",
2348f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks,
2358f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water,
2368f23e9faSHans Rosenfeld seg->fc_hi_water);
2378f23e9faSHans Rosenfeld
2388f23e9faSHans Rosenfeld goto failed;
2398f23e9faSHans Rosenfeld }
2408f23e9faSHans Rosenfeld }
2418f23e9faSHans Rosenfeld
2428f23e9faSHans Rosenfeld hba->sli.sli3.bpl_table = NULL;
2438f23e9faSHans Rosenfeld seg = &hba->memseg[MEM_BPL];
2448f23e9faSHans Rosenfeld
2458f23e9faSHans Rosenfeld /* If SLI3 and MEM_BPL pool is static */
2468f23e9faSHans Rosenfeld if (!(hba->model_info.sli_mask & EMLXS_SLI4_MASK) &&
2478f23e9faSHans Rosenfeld !(seg->fc_memflag & FC_MEMSEG_DYNAMIC)) {
2488f23e9faSHans Rosenfeld /*
2498f23e9faSHans Rosenfeld * Allocate and Initialize bpl_table
2508f23e9faSHans Rosenfeld * This is for increased performance.
2518f23e9faSHans Rosenfeld */
2528f23e9faSHans Rosenfeld bzero(buf_info, sizeof (MBUF_INFO));
2538f23e9faSHans Rosenfeld buf_info->size = hba->max_iotag * sizeof (MATCHMAP *);
2548f23e9faSHans Rosenfeld
2558f23e9faSHans Rosenfeld (void) emlxs_mem_alloc(hba, buf_info);
2568f23e9faSHans Rosenfeld if (buf_info->virt == NULL) {
2578f23e9faSHans Rosenfeld
2588f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT,
2598f23e9faSHans Rosenfeld &emlxs_mem_alloc_failed_msg,
2608f23e9faSHans Rosenfeld "BPL table buffer.");
2618f23e9faSHans Rosenfeld
26282527734SSukumar Swaminathan goto failed;
263fcf3ce44SJohn Forte }
2648f23e9faSHans Rosenfeld hba->sli.sli3.bpl_table = buf_info->virt;
265291a2b48SSukumar Swaminathan
2668f23e9faSHans Rosenfeld bpl_table = (MATCHMAP**)hba->sli.sli3.bpl_table;
2678f23e9faSHans Rosenfeld for (i = 0; i < hba->max_iotag; i++) {
2688f23e9faSHans Rosenfeld mp = (MATCHMAP *) emlxs_mem_get(hba, MEM_BPL);
2698f23e9faSHans Rosenfeld mp->flag |= MAP_TABLE_ALLOCATED;
2708f23e9faSHans Rosenfeld bpl_table[i] = mp;
2718f23e9faSHans Rosenfeld }
272fcf3ce44SJohn Forte }
273fcf3ce44SJohn Forte
27482527734SSukumar Swaminathan return (1);
275fcf3ce44SJohn Forte
27682527734SSukumar Swaminathan failed:
277fcf3ce44SJohn Forte
27882527734SSukumar Swaminathan (void) emlxs_mem_free_buffer(hba);
27982527734SSukumar Swaminathan return (0);
280fcf3ce44SJohn Forte
28182527734SSukumar Swaminathan } /* emlxs_mem_alloc_buffer() */
282fcf3ce44SJohn Forte
283fcf3ce44SJohn Forte
28482527734SSukumar Swaminathan /*
28582527734SSukumar Swaminathan * emlxs_mem_free_buffer
28682527734SSukumar Swaminathan *
28782527734SSukumar Swaminathan * This routine will free iocb/data buffer space
28882527734SSukumar Swaminathan * and TGTM resource.
28982527734SSukumar Swaminathan */
29082527734SSukumar Swaminathan extern int
emlxs_mem_free_buffer(emlxs_hba_t * hba)29182527734SSukumar Swaminathan emlxs_mem_free_buffer(emlxs_hba_t *hba)
29282527734SSukumar Swaminathan {
2938f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT;
29482527734SSukumar Swaminathan emlxs_port_t *vport;
29582527734SSukumar Swaminathan int32_t j;
29682527734SSukumar Swaminathan MATCHMAP *mp;
29782527734SSukumar Swaminathan CHANNEL *cp;
29882527734SSukumar Swaminathan RING *rp;
29982527734SSukumar Swaminathan MBUF_INFO *buf_info;
30082527734SSukumar Swaminathan MBUF_INFO bufinfo;
3018f23e9faSHans Rosenfeld MATCHMAP **bpl_table;
302fcf3ce44SJohn Forte
30382527734SSukumar Swaminathan buf_info = &bufinfo;
304291a2b48SSukumar Swaminathan
30582527734SSukumar Swaminathan for (j = 0; j < hba->chan_count; j++) {
30682527734SSukumar Swaminathan cp = &hba->chan[j];
307fcf3ce44SJohn Forte
30882527734SSukumar Swaminathan /* Flush the ring */
30982527734SSukumar Swaminathan (void) emlxs_tx_channel_flush(hba, cp, 0);
31082527734SSukumar Swaminathan }
311fcf3ce44SJohn Forte
31282527734SSukumar Swaminathan if (!(hba->model_info.sli_mask & EMLXS_SLI4_MASK)) {
31382527734SSukumar Swaminathan /* free the mapped address match area for each ring */
31482527734SSukumar Swaminathan for (j = 0; j < MAX_RINGS; j++) {
31582527734SSukumar Swaminathan rp = &hba->sli.sli3.ring[j];
316fcf3ce44SJohn Forte
31782527734SSukumar Swaminathan while (rp->fc_mpoff) {
31882527734SSukumar Swaminathan uint64_t addr;
319fcf3ce44SJohn Forte
32082527734SSukumar Swaminathan addr = 0;
32182527734SSukumar Swaminathan mp = (MATCHMAP *)(rp->fc_mpoff);
322fcf3ce44SJohn Forte
32382527734SSukumar Swaminathan if ((j == hba->channel_els) ||
32482527734SSukumar Swaminathan (j == hba->channel_ct) ||
32582527734SSukumar Swaminathan #ifdef SFCT_SUPPORT
32682527734SSukumar Swaminathan (j == hba->CHANNEL_FCT) ||
32782527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */
32882527734SSukumar Swaminathan (j == hba->channel_ip)) {
32982527734SSukumar Swaminathan addr = mp->phys;
33082527734SSukumar Swaminathan }
331fcf3ce44SJohn Forte
33282527734SSukumar Swaminathan if ((mp = emlxs_mem_get_vaddr(hba, rp, addr))) {
33382527734SSukumar Swaminathan if (j == hba->channel_els) {
334a9800bebSGarrett D'Amore emlxs_mem_put(hba,
335a9800bebSGarrett D'Amore MEM_ELSBUF, (void *)mp);
33682527734SSukumar Swaminathan } else if (j == hba->channel_ct) {
337a9800bebSGarrett D'Amore emlxs_mem_put(hba,
338a9800bebSGarrett D'Amore MEM_CTBUF, (void *)mp);
33982527734SSukumar Swaminathan } else if (j == hba->channel_ip) {
340a9800bebSGarrett D'Amore emlxs_mem_put(hba,
341a9800bebSGarrett D'Amore MEM_IPBUF, (void *)mp);
34282527734SSukumar Swaminathan }
34382527734SSukumar Swaminathan #ifdef SFCT_SUPPORT
34482527734SSukumar Swaminathan else if (j == hba->CHANNEL_FCT) {
345a9800bebSGarrett D'Amore emlxs_mem_put(hba,
346a9800bebSGarrett D'Amore MEM_FCTBUF, (void *)mp);
34782527734SSukumar Swaminathan }
34882527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */
349fcf3ce44SJohn Forte
35082527734SSukumar Swaminathan }
35182527734SSukumar Swaminathan }
352fcf3ce44SJohn Forte }
35382527734SSukumar Swaminathan }
35482527734SSukumar Swaminathan
35582527734SSukumar Swaminathan if (hba->flag & FC_HBQ_ENABLED) {
35682527734SSukumar Swaminathan emlxs_hbq_free_all(hba, EMLXS_ELS_HBQ_ID);
35782527734SSukumar Swaminathan emlxs_hbq_free_all(hba, EMLXS_IP_HBQ_ID);
35882527734SSukumar Swaminathan emlxs_hbq_free_all(hba, EMLXS_CT_HBQ_ID);
359291a2b48SSukumar Swaminathan
3608f23e9faSHans Rosenfeld if (port->flag & EMLXS_TGT_ENABLED) {
36182527734SSukumar Swaminathan emlxs_hbq_free_all(hba, EMLXS_FCT_HBQ_ID);
36282527734SSukumar Swaminathan }
363fcf3ce44SJohn Forte }
364fcf3ce44SJohn Forte
36582527734SSukumar Swaminathan /* Free the nodes */
36682527734SSukumar Swaminathan for (j = 0; j < MAX_VPORTS; j++) {
36782527734SSukumar Swaminathan vport = &VPORT(j);
36882527734SSukumar Swaminathan if (vport->node_count) {
36982527734SSukumar Swaminathan emlxs_node_destroy_all(vport);
37082527734SSukumar Swaminathan }
37182527734SSukumar Swaminathan }
372fcf3ce44SJohn Forte
37382527734SSukumar Swaminathan /* Make sure the mailbox queue is empty */
37482527734SSukumar Swaminathan emlxs_mb_flush(hba);
375fcf3ce44SJohn Forte
37682527734SSukumar Swaminathan if (hba->fc_table) {
377fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO));
37882527734SSukumar Swaminathan buf_info->size = hba->max_iotag * sizeof (emlxs_buf_t *);
37982527734SSukumar Swaminathan buf_info->virt = hba->fc_table;
38082527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info);
38182527734SSukumar Swaminathan hba->fc_table = NULL;
38282527734SSukumar Swaminathan }
383fcf3ce44SJohn Forte
3848f23e9faSHans Rosenfeld if (hba->sli.sli3.bpl_table) {
3858f23e9faSHans Rosenfeld /* Return MEM_BPLs to their pool */
3868f23e9faSHans Rosenfeld bpl_table = (MATCHMAP**)hba->sli.sli3.bpl_table;
3878f23e9faSHans Rosenfeld for (j = 0; j < hba->max_iotag; j++) {
3888f23e9faSHans Rosenfeld mp = bpl_table[j];
3898f23e9faSHans Rosenfeld mp->flag &= ~MAP_TABLE_ALLOCATED;
3908f23e9faSHans Rosenfeld emlxs_mem_put(hba, MEM_BPL, (void*)mp);
3918f23e9faSHans Rosenfeld }
3928f23e9faSHans Rosenfeld
39382527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO));
39482527734SSukumar Swaminathan buf_info->size = hba->max_iotag * sizeof (MATCHMAP *);
3958f23e9faSHans Rosenfeld buf_info->virt = hba->sli.sli3.bpl_table;
39682527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info);
3978f23e9faSHans Rosenfeld hba->sli.sli3.bpl_table = NULL;
39882527734SSukumar Swaminathan }
399fcf3ce44SJohn Forte
40082527734SSukumar Swaminathan /* Free the memory segments */
40182527734SSukumar Swaminathan for (j = 0; j < FC_MAX_SEG; j++) {
4028f23e9faSHans Rosenfeld emlxs_mem_pool_destroy(hba, &hba->memseg[j]);
40382527734SSukumar Swaminathan }
404291a2b48SSukumar Swaminathan
40582527734SSukumar Swaminathan return (0);
406fcf3ce44SJohn Forte
40782527734SSukumar Swaminathan } /* emlxs_mem_free_buffer() */
408fcf3ce44SJohn Forte
409fcf3ce44SJohn Forte
4108f23e9faSHans Rosenfeld /* Must hold EMLXS_MEMGET_LOCK when calling */
4118f23e9faSHans Rosenfeld static uint32_t
emlxs_mem_pool_alloc(emlxs_hba_t * hba,MEMSEG * seg,uint32_t count)4128f23e9faSHans Rosenfeld emlxs_mem_pool_alloc(emlxs_hba_t *hba, MEMSEG *seg, uint32_t count)
41382527734SSukumar Swaminathan {
41482527734SSukumar Swaminathan emlxs_port_t *port = &PPORT;
41582527734SSukumar Swaminathan uint8_t *bp = NULL;
41682527734SSukumar Swaminathan MATCHMAP *mp = NULL;
41782527734SSukumar Swaminathan MBUF_INFO *buf_info;
41882527734SSukumar Swaminathan MBUF_INFO local_buf_info;
41982527734SSukumar Swaminathan uint32_t i;
4208f23e9faSHans Rosenfeld uint32_t fc_numblks;
421fcf3ce44SJohn Forte
4228f23e9faSHans Rosenfeld if (seg->fc_memsize == 0) {
4238f23e9faSHans Rosenfeld return (0);
4248f23e9faSHans Rosenfeld }
425fcf3ce44SJohn Forte
4268f23e9faSHans Rosenfeld if (seg->fc_numblks >= seg->fc_hi_water) {
4278f23e9faSHans Rosenfeld return (0);
4288f23e9faSHans Rosenfeld }
4298f23e9faSHans Rosenfeld
4308f23e9faSHans Rosenfeld if (count == 0) {
4318f23e9faSHans Rosenfeld return (0);
4328f23e9faSHans Rosenfeld }
433fcf3ce44SJohn Forte
4348f23e9faSHans Rosenfeld if (count > (seg->fc_hi_water - seg->fc_numblks)) {
4358f23e9faSHans Rosenfeld count = (seg->fc_hi_water - seg->fc_numblks);
4368f23e9faSHans Rosenfeld }
437fcf3ce44SJohn Forte
4388f23e9faSHans Rosenfeld buf_info = &local_buf_info;
4398f23e9faSHans Rosenfeld fc_numblks = seg->fc_numblks;
4408f23e9faSHans Rosenfeld
4418f23e9faSHans Rosenfeld /* Check for initial allocation */
4428f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_PUT_ENABLED)) {
4438f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg,
444*e2d1a434SCarsten Grzemba "%s alloc:%d n=%d s=%d f=%x l=%d,%d,%d f=%d:%d",
4458f23e9faSHans Rosenfeld seg->fc_label, count, seg->fc_numblks,
446*e2d1a434SCarsten Grzemba seg->fc_memsize, seg->fc_memflag,
447*e2d1a434SCarsten Grzemba seg->fc_lo_water, seg->fc_hi_water, seg->fc_step,
448*e2d1a434SCarsten Grzemba seg->fc_memget_cnt, seg->fc_low);
44982527734SSukumar Swaminathan }
450291a2b48SSukumar Swaminathan
45182527734SSukumar Swaminathan if (!(seg->fc_memflag & FC_MBUF_DMA)) {
45282527734SSukumar Swaminathan goto vmem_pool;
453fcf3ce44SJohn Forte }
454fcf3ce44SJohn Forte
45582527734SSukumar Swaminathan /* dma_pool */
45682527734SSukumar Swaminathan
4578f23e9faSHans Rosenfeld for (i = 0; i < count; i++) {
458fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO));
459fcf3ce44SJohn Forte buf_info->size = sizeof (MATCHMAP);
460fcf3ce44SJohn Forte buf_info->align = sizeof (void *);
461fcf3ce44SJohn Forte
462fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info);
463fcf3ce44SJohn Forte if (buf_info->virt == NULL) {
464fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
4658f23e9faSHans Rosenfeld "%s: count=%d size=%d",
4668f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, seg->fc_memsize);
467fcf3ce44SJohn Forte
4688f23e9faSHans Rosenfeld goto done;
469fcf3ce44SJohn Forte }
470291a2b48SSukumar Swaminathan
47182527734SSukumar Swaminathan mp = (MATCHMAP *)buf_info->virt;
47282527734SSukumar Swaminathan bzero(mp, sizeof (MATCHMAP));
473fcf3ce44SJohn Forte
474fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO));
47582527734SSukumar Swaminathan buf_info->size = seg->fc_memsize;
47682527734SSukumar Swaminathan buf_info->flags = seg->fc_memflag;
47782527734SSukumar Swaminathan buf_info->align = seg->fc_memalign;
478fcf3ce44SJohn Forte
479fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info);
480fcf3ce44SJohn Forte if (buf_info->virt == NULL) {
481fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
4828f23e9faSHans Rosenfeld "%s: count=%d size=%d",
4838f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, seg->fc_memsize);
484fcf3ce44SJohn Forte
48582527734SSukumar Swaminathan /* Free the mp object */
48682527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO));
48782527734SSukumar Swaminathan buf_info->size = sizeof (MATCHMAP);
488a9800bebSGarrett D'Amore buf_info->virt = (void *)mp;
48982527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info);
49082527734SSukumar Swaminathan
4918f23e9faSHans Rosenfeld goto done;
492fcf3ce44SJohn Forte }
493fcf3ce44SJohn Forte bp = (uint8_t *)buf_info->virt;
49482527734SSukumar Swaminathan bzero(bp, seg->fc_memsize);
49582527734SSukumar Swaminathan
49682527734SSukumar Swaminathan mp->virt = buf_info->virt;
49782527734SSukumar Swaminathan mp->phys = buf_info->phys;
49882527734SSukumar Swaminathan mp->size = buf_info->size;
49982527734SSukumar Swaminathan mp->dma_handle = buf_info->dma_handle;
50082527734SSukumar Swaminathan mp->data_handle = buf_info->data_handle;
50182527734SSukumar Swaminathan mp->tag = seg->fc_memtag;
50282527734SSukumar Swaminathan mp->segment = seg;
50382527734SSukumar Swaminathan mp->flag |= MAP_POOL_ALLOCATED;
50482527734SSukumar Swaminathan
5058f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT
5068f23e9faSHans Rosenfeld if (mp->tag >= MEM_FCTSEG) {
5078f23e9faSHans Rosenfeld if (emlxs_fct_stmf_alloc(hba, mp)) {
5088f23e9faSHans Rosenfeld /* Free the DMA memory itself */
5098f23e9faSHans Rosenfeld emlxs_mem_free(hba, buf_info);
5108f23e9faSHans Rosenfeld
5118f23e9faSHans Rosenfeld /* Free the mp object */
5128f23e9faSHans Rosenfeld bzero(buf_info, sizeof (MBUF_INFO));
5138f23e9faSHans Rosenfeld buf_info->size = sizeof (MATCHMAP);
5148f23e9faSHans Rosenfeld buf_info->virt = (void *)mp;
5158f23e9faSHans Rosenfeld emlxs_mem_free(hba, buf_info);
5168f23e9faSHans Rosenfeld
5178f23e9faSHans Rosenfeld goto done;
5188f23e9faSHans Rosenfeld }
5198f23e9faSHans Rosenfeld }
5208f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */
5218f23e9faSHans Rosenfeld
52282527734SSukumar Swaminathan /* Add the buffer desc to the tail of the pool freelist */
52382527734SSukumar Swaminathan if (seg->fc_memget_end == NULL) {
52482527734SSukumar Swaminathan seg->fc_memget_ptr = (uint8_t *)mp;
52582527734SSukumar Swaminathan seg->fc_memget_cnt = 1;
52682527734SSukumar Swaminathan } else {
52782527734SSukumar Swaminathan *((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)mp;
52882527734SSukumar Swaminathan seg->fc_memget_cnt++;
529fcf3ce44SJohn Forte }
53082527734SSukumar Swaminathan seg->fc_memget_end = (uint8_t *)mp;
5318f23e9faSHans Rosenfeld
5328f23e9faSHans Rosenfeld seg->fc_numblks++;
5338f23e9faSHans Rosenfeld seg->fc_total_memsize += (seg->fc_memsize + sizeof (MATCHMAP));
534fcf3ce44SJohn Forte }
535fcf3ce44SJohn Forte
5368f23e9faSHans Rosenfeld goto done;
537fcf3ce44SJohn Forte
53882527734SSukumar Swaminathan vmem_pool:
539fcf3ce44SJohn Forte
5408f23e9faSHans Rosenfeld for (i = 0; i < count; i++) {
5418f23e9faSHans Rosenfeld bzero(buf_info, sizeof (MBUF_INFO));
5428f23e9faSHans Rosenfeld buf_info->size = seg->fc_memsize;
543fcf3ce44SJohn Forte
5448f23e9faSHans Rosenfeld (void) emlxs_mem_alloc(hba, buf_info);
5458f23e9faSHans Rosenfeld if (buf_info->virt == NULL) {
5468f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
5478f23e9faSHans Rosenfeld "%s: count=%d size=%d",
5488f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, seg->fc_memsize);
549fcf3ce44SJohn Forte
5508f23e9faSHans Rosenfeld goto done;
5518f23e9faSHans Rosenfeld }
5528f23e9faSHans Rosenfeld bp = (uint8_t *)buf_info->virt;
553fcf3ce44SJohn Forte
55482527734SSukumar Swaminathan /* Add the buffer to the tail of the pool freelist */
55582527734SSukumar Swaminathan if (seg->fc_memget_end == NULL) {
55682527734SSukumar Swaminathan seg->fc_memget_ptr = (uint8_t *)bp;
55782527734SSukumar Swaminathan seg->fc_memget_cnt = 1;
55882527734SSukumar Swaminathan } else {
55982527734SSukumar Swaminathan *((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)bp;
56082527734SSukumar Swaminathan seg->fc_memget_cnt++;
56182527734SSukumar Swaminathan }
56282527734SSukumar Swaminathan seg->fc_memget_end = (uint8_t *)bp;
563fcf3ce44SJohn Forte
5648f23e9faSHans Rosenfeld seg->fc_numblks++;
5658f23e9faSHans Rosenfeld seg->fc_total_memsize += seg->fc_memsize;
56682527734SSukumar Swaminathan }
567fcf3ce44SJohn Forte
5688f23e9faSHans Rosenfeld done:
569fcf3ce44SJohn Forte
5708f23e9faSHans Rosenfeld return ((seg->fc_numblks - fc_numblks));
571291a2b48SSukumar Swaminathan
57282527734SSukumar Swaminathan } /* emlxs_mem_pool_alloc() */
573fcf3ce44SJohn Forte
574fcf3ce44SJohn Forte
5758f23e9faSHans Rosenfeld /* Must hold EMLXS_MEMGET_LOCK & EMLXS_MEMPUT_LOCK when calling */
5768f23e9faSHans Rosenfeld static void
emlxs_mem_pool_free(emlxs_hba_t * hba,MEMSEG * seg,uint32_t count)5778f23e9faSHans Rosenfeld emlxs_mem_pool_free(emlxs_hba_t *hba, MEMSEG *seg, uint32_t count)
57882527734SSukumar Swaminathan {
57982527734SSukumar Swaminathan emlxs_port_t *port = &PPORT;
58082527734SSukumar Swaminathan uint8_t *bp = NULL;
58182527734SSukumar Swaminathan MATCHMAP *mp = NULL;
58282527734SSukumar Swaminathan MBUF_INFO *buf_info;
58382527734SSukumar Swaminathan MBUF_INFO local_buf_info;
584fcf3ce44SJohn Forte
5858f23e9faSHans Rosenfeld if ((seg->fc_memsize == 0) ||
5868f23e9faSHans Rosenfeld (seg->fc_numblks == 0) ||
5878f23e9faSHans Rosenfeld (count == 0)) {
5888f23e9faSHans Rosenfeld return;
5898f23e9faSHans Rosenfeld }
590fcf3ce44SJohn Forte
5918f23e9faSHans Rosenfeld /* Check max count */
5928f23e9faSHans Rosenfeld if (count > seg->fc_numblks) {
5938f23e9faSHans Rosenfeld count = seg->fc_numblks;
594fcf3ce44SJohn Forte }
595fcf3ce44SJohn Forte
5968f23e9faSHans Rosenfeld /* Move memput list to memget list */
5978f23e9faSHans Rosenfeld if (seg->fc_memput_ptr) {
5988f23e9faSHans Rosenfeld if (seg->fc_memget_end == NULL) {
5998f23e9faSHans Rosenfeld seg->fc_memget_ptr = seg->fc_memput_ptr;
6008f23e9faSHans Rosenfeld } else {
6018f23e9faSHans Rosenfeld *((uint8_t **)(seg->fc_memget_end)) =\
6028f23e9faSHans Rosenfeld seg->fc_memput_ptr;
6038f23e9faSHans Rosenfeld }
6048f23e9faSHans Rosenfeld seg->fc_memget_end = seg->fc_memput_end;
6058f23e9faSHans Rosenfeld seg->fc_memget_cnt += seg->fc_memput_cnt;
606fcf3ce44SJohn Forte
6078f23e9faSHans Rosenfeld seg->fc_memput_ptr = NULL;
6088f23e9faSHans Rosenfeld seg->fc_memput_end = NULL;
6098f23e9faSHans Rosenfeld seg->fc_memput_cnt = 0;
6108f23e9faSHans Rosenfeld }
611fcf3ce44SJohn Forte
6128f23e9faSHans Rosenfeld buf_info = &local_buf_info;
613fcf3ce44SJohn Forte
6148f23e9faSHans Rosenfeld /* Check for final deallocation */
6158f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) {
6168f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg,
6178f23e9faSHans Rosenfeld "%s free:%d n=%d s=%d f=%x l=%d,%d,%d "
6188f23e9faSHans Rosenfeld "f=%d:%d",
6198f23e9faSHans Rosenfeld seg->fc_label, count, seg->fc_numblks,
6208f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water,
6218f23e9faSHans Rosenfeld seg->fc_hi_water, seg->fc_step, seg->fc_memget_cnt,
6228f23e9faSHans Rosenfeld seg->fc_low);
6238f23e9faSHans Rosenfeld }
624fcf3ce44SJohn Forte
6258f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MBUF_DMA)) {
6268f23e9faSHans Rosenfeld goto vmem_pool;
62782527734SSukumar Swaminathan }
628fcf3ce44SJohn Forte
6298f23e9faSHans Rosenfeld dma_pool:
630fcf3ce44SJohn Forte
63182527734SSukumar Swaminathan /* Free memory associated with all buffers on get buffer pool */
6328f23e9faSHans Rosenfeld while (count && ((bp = seg->fc_memget_ptr) != NULL)) {
6338f23e9faSHans Rosenfeld /* Remove buffer from list */
6348f23e9faSHans Rosenfeld if (seg->fc_memget_end == bp) {
6358f23e9faSHans Rosenfeld seg->fc_memget_ptr = NULL;
6368f23e9faSHans Rosenfeld seg->fc_memget_end = NULL;
6378f23e9faSHans Rosenfeld seg->fc_memget_cnt = 0;
6388f23e9faSHans Rosenfeld
6398f23e9faSHans Rosenfeld } else {
6408f23e9faSHans Rosenfeld seg->fc_memget_ptr = *((uint8_t **)bp);
6418f23e9faSHans Rosenfeld seg->fc_memget_cnt--;
6428f23e9faSHans Rosenfeld }
64382527734SSukumar Swaminathan mp = (MATCHMAP *)bp;
644fcf3ce44SJohn Forte
6458f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT
6468f23e9faSHans Rosenfeld if (mp->tag >= MEM_FCTSEG) {
6478f23e9faSHans Rosenfeld emlxs_fct_stmf_free(hba, mp);
6488f23e9faSHans Rosenfeld }
6498f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */
6508f23e9faSHans Rosenfeld
6518f23e9faSHans Rosenfeld /* Free the DMA memory itself */
65282527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO));
65382527734SSukumar Swaminathan buf_info->size = mp->size;
65482527734SSukumar Swaminathan buf_info->virt = mp->virt;
65582527734SSukumar Swaminathan buf_info->phys = mp->phys;
65682527734SSukumar Swaminathan buf_info->dma_handle = mp->dma_handle;
65782527734SSukumar Swaminathan buf_info->data_handle = mp->data_handle;
65882527734SSukumar Swaminathan buf_info->flags = seg->fc_memflag;
65982527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info);
660fcf3ce44SJohn Forte
6618f23e9faSHans Rosenfeld /* Free the handle */
66282527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO));
66382527734SSukumar Swaminathan buf_info->size = sizeof (MATCHMAP);
664a9800bebSGarrett D'Amore buf_info->virt = (void *)mp;
66582527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info);
6668f23e9faSHans Rosenfeld
6678f23e9faSHans Rosenfeld seg->fc_numblks--;
6688f23e9faSHans Rosenfeld seg->fc_total_memsize -= (seg->fc_memsize + sizeof (MATCHMAP));
6698f23e9faSHans Rosenfeld
6708f23e9faSHans Rosenfeld count--;
671fcf3ce44SJohn Forte }
672291a2b48SSukumar Swaminathan
6738f23e9faSHans Rosenfeld return;
674fcf3ce44SJohn Forte
6758f23e9faSHans Rosenfeld vmem_pool:
676291a2b48SSukumar Swaminathan
6778f23e9faSHans Rosenfeld /* Free memory associated with all buffers on get buffer pool */
6788f23e9faSHans Rosenfeld while (count && ((bp = seg->fc_memget_ptr) != NULL)) {
6798f23e9faSHans Rosenfeld /* Remove buffer from list */
6808f23e9faSHans Rosenfeld if (seg->fc_memget_end == bp) {
6818f23e9faSHans Rosenfeld seg->fc_memget_ptr = NULL;
6828f23e9faSHans Rosenfeld seg->fc_memget_end = NULL;
6838f23e9faSHans Rosenfeld seg->fc_memget_cnt = 0;
6848f23e9faSHans Rosenfeld
6858f23e9faSHans Rosenfeld } else {
6868f23e9faSHans Rosenfeld seg->fc_memget_ptr = *((uint8_t **)bp);
6878f23e9faSHans Rosenfeld seg->fc_memget_cnt--;
6888f23e9faSHans Rosenfeld }
6898f23e9faSHans Rosenfeld
6908f23e9faSHans Rosenfeld /* Free the Virtual memory itself */
69182527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO));
6928f23e9faSHans Rosenfeld buf_info->size = seg->fc_memsize;
6938f23e9faSHans Rosenfeld buf_info->virt = bp;
69482527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info);
6958f23e9faSHans Rosenfeld
6968f23e9faSHans Rosenfeld seg->fc_numblks--;
6978f23e9faSHans Rosenfeld seg->fc_total_memsize -= seg->fc_memsize;
6988f23e9faSHans Rosenfeld
6998f23e9faSHans Rosenfeld count--;
700291a2b48SSukumar Swaminathan }
701fcf3ce44SJohn Forte
70282527734SSukumar Swaminathan return;
703fcf3ce44SJohn Forte
70482527734SSukumar Swaminathan } /* emlxs_mem_pool_free() */
705fcf3ce44SJohn Forte
706fcf3ce44SJohn Forte
7078f23e9faSHans Rosenfeld extern uint32_t
emlxs_mem_pool_create(emlxs_hba_t * hba,MEMSEG * seg)7088f23e9faSHans Rosenfeld emlxs_mem_pool_create(emlxs_hba_t *hba, MEMSEG *seg)
70982527734SSukumar Swaminathan {
7108f23e9faSHans Rosenfeld emlxs_config_t *cfg = &CFG;
711291a2b48SSukumar Swaminathan
71282527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMGET_LOCK);
7138f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMPUT_LOCK);
71482527734SSukumar Swaminathan
7158f23e9faSHans Rosenfeld if (seg->fc_memsize == 0) {
7168f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK);
71782527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK);
7188f23e9faSHans Rosenfeld
7198f23e9faSHans Rosenfeld return (0);
7208f23e9faSHans Rosenfeld }
7218f23e9faSHans Rosenfeld
7228f23e9faSHans Rosenfeld /* Sanity check hi > lo */
7238f23e9faSHans Rosenfeld if (seg->fc_lo_water > seg->fc_hi_water) {
7248f23e9faSHans Rosenfeld seg->fc_hi_water = seg->fc_lo_water;
7258f23e9faSHans Rosenfeld }
7268f23e9faSHans Rosenfeld
7278f23e9faSHans Rosenfeld /* If dynamic pools are disabled, then force pool to max level */
7288f23e9faSHans Rosenfeld if (cfg[CFG_MEM_DYNAMIC].current == 0) {
7298f23e9faSHans Rosenfeld seg->fc_lo_water = seg->fc_hi_water;
730fcf3ce44SJohn Forte }
731291a2b48SSukumar Swaminathan
7328f23e9faSHans Rosenfeld /* If pool is dynamic, then fc_step must be >0 */
7338f23e9faSHans Rosenfeld /* Otherwise, fc_step must be 0 */
7348f23e9faSHans Rosenfeld if (seg->fc_lo_water != seg->fc_hi_water) {
7358f23e9faSHans Rosenfeld seg->fc_memflag |= FC_MEMSEG_DYNAMIC;
736fcf3ce44SJohn Forte
7378f23e9faSHans Rosenfeld if (seg->fc_step == 0) {
7388f23e9faSHans Rosenfeld seg->fc_step = 1;
73982527734SSukumar Swaminathan }
7408f23e9faSHans Rosenfeld } else {
7418f23e9faSHans Rosenfeld seg->fc_step = 0;
74282527734SSukumar Swaminathan }
743fcf3ce44SJohn Forte
7448f23e9faSHans Rosenfeld seg->fc_numblks = 0;
7458f23e9faSHans Rosenfeld seg->fc_total_memsize = 0;
7468f23e9faSHans Rosenfeld seg->fc_low = 0;
747fcf3ce44SJohn Forte
748a3170057SPaul Winder (void) emlxs_mem_pool_alloc(hba, seg, seg->fc_lo_water);
749fcf3ce44SJohn Forte
7508f23e9faSHans Rosenfeld seg->fc_memflag |= (FC_MEMSEG_PUT_ENABLED|FC_MEMSEG_GET_ENABLED);
751291a2b48SSukumar Swaminathan
7528f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK);
7538f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK);
754fcf3ce44SJohn Forte
7558f23e9faSHans Rosenfeld return (seg->fc_numblks);
7568f23e9faSHans Rosenfeld
7578f23e9faSHans Rosenfeld } /* emlxs_mem_pool_create() */
758fcf3ce44SJohn Forte
759fcf3ce44SJohn Forte
7608f23e9faSHans Rosenfeld extern void
emlxs_mem_pool_destroy(emlxs_hba_t * hba,MEMSEG * seg)7618f23e9faSHans Rosenfeld emlxs_mem_pool_destroy(emlxs_hba_t *hba, MEMSEG *seg)
7628f23e9faSHans Rosenfeld {
7638f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT;
7648f23e9faSHans Rosenfeld
7658f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMGET_LOCK);
7668f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMPUT_LOCK);
7678f23e9faSHans Rosenfeld
7688f23e9faSHans Rosenfeld if (seg->fc_memsize == 0) {
7698f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK);
7708f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK);
7718f23e9faSHans Rosenfeld return;
7728f23e9faSHans Rosenfeld }
7738f23e9faSHans Rosenfeld
7748f23e9faSHans Rosenfeld /* Leave FC_MEMSEG_PUT_ENABLED set for now */
7758f23e9faSHans Rosenfeld seg->fc_memflag &= ~FC_MEMSEG_GET_ENABLED;
7768f23e9faSHans Rosenfeld
7778f23e9faSHans Rosenfeld /* Try to free all objects */
7788f23e9faSHans Rosenfeld emlxs_mem_pool_free(hba, seg, seg->fc_numblks);
7798f23e9faSHans Rosenfeld
7808f23e9faSHans Rosenfeld if (seg->fc_numblks) {
7818f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg,
7828f23e9faSHans Rosenfeld "mem_pool_destroy: %s leak detected: "
7838f23e9faSHans Rosenfeld "%d objects still allocated.",
7848f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks);
78582527734SSukumar Swaminathan } else {
7868f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg,
7878f23e9faSHans Rosenfeld "mem_pool_destroy: %s destroyed.",
7888f23e9faSHans Rosenfeld seg->fc_label);
7898f23e9faSHans Rosenfeld
7908f23e9faSHans Rosenfeld /* Clear all */
7918f23e9faSHans Rosenfeld bzero(seg, sizeof (MEMSEG));
7928f23e9faSHans Rosenfeld }
7938f23e9faSHans Rosenfeld
7948f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK);
7958f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK);
7968f23e9faSHans Rosenfeld
7978f23e9faSHans Rosenfeld return;
7988f23e9faSHans Rosenfeld
7998f23e9faSHans Rosenfeld } /* emlxs_mem_pool_destroy() */
8008f23e9faSHans Rosenfeld
8018f23e9faSHans Rosenfeld
8028f23e9faSHans Rosenfeld extern void
emlxs_mem_pool_clean(emlxs_hba_t * hba,MEMSEG * seg)8038f23e9faSHans Rosenfeld emlxs_mem_pool_clean(emlxs_hba_t *hba, MEMSEG *seg)
8048f23e9faSHans Rosenfeld {
8058f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT;
8068f23e9faSHans Rosenfeld uint32_t clean_count;
8078f23e9faSHans Rosenfeld uint32_t free_count;
8088f23e9faSHans Rosenfeld uint32_t free_pad;
8098f23e9faSHans Rosenfeld
8108f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMGET_LOCK);
8118f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMPUT_LOCK);
8128f23e9faSHans Rosenfeld
8138f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_DYNAMIC)) {
8148f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK);
8158f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK);
8168f23e9faSHans Rosenfeld return;
8178f23e9faSHans Rosenfeld }
8188f23e9faSHans Rosenfeld
8198f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) {
8208f23e9faSHans Rosenfeld goto done;
8218f23e9faSHans Rosenfeld }
8228f23e9faSHans Rosenfeld
8238f23e9faSHans Rosenfeld #ifdef EMLXS_POOL_DEBUG
8248f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg,
8258f23e9faSHans Rosenfeld "%s clean: n=%d s=%d f=%x l=%d,%d,%d "
8268f23e9faSHans Rosenfeld "f=%d:%d",
8278f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks,
8288f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water,
8298f23e9faSHans Rosenfeld seg->fc_hi_water, seg->fc_step, seg->fc_memget_cnt,
8308f23e9faSHans Rosenfeld seg->fc_low);
8318f23e9faSHans Rosenfeld #endif /* EMLXS_POOL_DEBUG */
8328f23e9faSHans Rosenfeld
8338f23e9faSHans Rosenfeld /* Calculatge current free count */
8348f23e9faSHans Rosenfeld free_count = (seg->fc_memget_cnt + seg->fc_memput_cnt);
8358f23e9faSHans Rosenfeld
8368f23e9faSHans Rosenfeld /* Reset fc_low value to current free count */
8378f23e9faSHans Rosenfeld clean_count = seg->fc_low;
8388f23e9faSHans Rosenfeld seg->fc_low = free_count;
8398f23e9faSHans Rosenfeld
8408f23e9faSHans Rosenfeld /* Return if pool is already at lo water mark */
8418f23e9faSHans Rosenfeld if (seg->fc_numblks <= seg->fc_lo_water) {
8428f23e9faSHans Rosenfeld goto done;
8438f23e9faSHans Rosenfeld }
8448f23e9faSHans Rosenfeld
8458f23e9faSHans Rosenfeld /* Return if there is nothing to clean */
8468f23e9faSHans Rosenfeld if ((free_count == 0) ||
8478f23e9faSHans Rosenfeld (clean_count <= 1)) {
8488f23e9faSHans Rosenfeld goto done;
8498f23e9faSHans Rosenfeld }
8508f23e9faSHans Rosenfeld
8518f23e9faSHans Rosenfeld /* Calculate a 3 percent free pad count (1 being minimum) */
8528f23e9faSHans Rosenfeld if (seg->fc_numblks > 66) {
8538f23e9faSHans Rosenfeld free_pad = ((seg->fc_numblks * 3)/100);
8548f23e9faSHans Rosenfeld } else {
8558f23e9faSHans Rosenfeld free_pad = 1;
8568f23e9faSHans Rosenfeld }
8578f23e9faSHans Rosenfeld
8588f23e9faSHans Rosenfeld /* Return if fc_low is below pool free pad */
8598f23e9faSHans Rosenfeld if (clean_count <= free_pad) {
8608f23e9faSHans Rosenfeld goto done;
8618f23e9faSHans Rosenfeld }
8628f23e9faSHans Rosenfeld
8638f23e9faSHans Rosenfeld clean_count -= free_pad;
8648f23e9faSHans Rosenfeld
8658f23e9faSHans Rosenfeld /* clean_count can't exceed minimum pool levels */
8668f23e9faSHans Rosenfeld if (clean_count > (seg->fc_numblks - seg->fc_lo_water)) {
8678f23e9faSHans Rosenfeld clean_count = (seg->fc_numblks - seg->fc_lo_water);
8688f23e9faSHans Rosenfeld }
8698f23e9faSHans Rosenfeld
8708f23e9faSHans Rosenfeld emlxs_mem_pool_free(hba, seg, clean_count);
8718f23e9faSHans Rosenfeld
8728f23e9faSHans Rosenfeld done:
8738f23e9faSHans Rosenfeld if (seg->fc_last != seg->fc_numblks) {
8748f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg,
8758f23e9faSHans Rosenfeld "%s update: n=%d->%d s=%d f=%x l=%d,%d,%d "
8768f23e9faSHans Rosenfeld "f=%d:%d",
8778f23e9faSHans Rosenfeld seg->fc_label, seg->fc_last, seg->fc_numblks,
8788f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water,
8798f23e9faSHans Rosenfeld seg->fc_hi_water, seg->fc_step, seg->fc_memget_cnt,
8808f23e9faSHans Rosenfeld seg->fc_low);
8818f23e9faSHans Rosenfeld
8828f23e9faSHans Rosenfeld seg->fc_last = seg->fc_numblks;
8838f23e9faSHans Rosenfeld }
8848f23e9faSHans Rosenfeld
8858f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK);
8868f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK);
8878f23e9faSHans Rosenfeld return;
8888f23e9faSHans Rosenfeld
8898f23e9faSHans Rosenfeld } /* emlxs_mem_pool_clean() */
8908f23e9faSHans Rosenfeld
8918f23e9faSHans Rosenfeld
8928f23e9faSHans Rosenfeld extern void *
emlxs_mem_pool_get(emlxs_hba_t * hba,MEMSEG * seg)8938f23e9faSHans Rosenfeld emlxs_mem_pool_get(emlxs_hba_t *hba, MEMSEG *seg)
8948f23e9faSHans Rosenfeld {
8958f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT;
8968f23e9faSHans Rosenfeld void *bp = NULL;
8978f23e9faSHans Rosenfeld MATCHMAP *mp;
8988f23e9faSHans Rosenfeld uint32_t free_count;
8998f23e9faSHans Rosenfeld
9008f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMGET_LOCK);
9018f23e9faSHans Rosenfeld
9028f23e9faSHans Rosenfeld /* Check if memory pool is GET enabled */
9038f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) {
9048f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK);
9058f23e9faSHans Rosenfeld return (NULL);
9068f23e9faSHans Rosenfeld }
9078f23e9faSHans Rosenfeld
9088f23e9faSHans Rosenfeld /* If no entries on memget list, then check memput list */
9098f23e9faSHans Rosenfeld if (!seg->fc_memget_ptr) {
91082527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMPUT_LOCK);
91182527734SSukumar Swaminathan if (seg->fc_memput_ptr) {
91282527734SSukumar Swaminathan /*
91382527734SSukumar Swaminathan * Move list from memput to memget
91482527734SSukumar Swaminathan */
91582527734SSukumar Swaminathan seg->fc_memget_ptr = seg->fc_memput_ptr;
91682527734SSukumar Swaminathan seg->fc_memget_end = seg->fc_memput_end;
91782527734SSukumar Swaminathan seg->fc_memget_cnt = seg->fc_memput_cnt;
91882527734SSukumar Swaminathan seg->fc_memput_ptr = NULL;
91982527734SSukumar Swaminathan seg->fc_memput_end = NULL;
92082527734SSukumar Swaminathan seg->fc_memput_cnt = 0;
921fcf3ce44SJohn Forte }
92282527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK);
9238f23e9faSHans Rosenfeld }
9248f23e9faSHans Rosenfeld
9258f23e9faSHans Rosenfeld /* If no entries on memget list, then pool is empty */
9268f23e9faSHans Rosenfeld /* Try to allocate more if pool is dynamic */
9278f23e9faSHans Rosenfeld if (!seg->fc_memget_ptr &&
9288f23e9faSHans Rosenfeld (seg->fc_memflag & FC_MEMSEG_DYNAMIC)) {
9298f23e9faSHans Rosenfeld (void) emlxs_mem_pool_alloc(hba, seg, seg->fc_step);
9308f23e9faSHans Rosenfeld seg->fc_low = 0;
9318f23e9faSHans Rosenfeld }
93282527734SSukumar Swaminathan
9338f23e9faSHans Rosenfeld /* If no entries on memget list, then pool is empty */
9348f23e9faSHans Rosenfeld if (!seg->fc_memget_ptr) {
93582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_alloc_failed_msg,
93682527734SSukumar Swaminathan "%s empty.", seg->fc_label);
9378f23e9faSHans Rosenfeld
9388f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK);
9398f23e9faSHans Rosenfeld return (NULL);
9408f23e9faSHans Rosenfeld }
9418f23e9faSHans Rosenfeld
9428f23e9faSHans Rosenfeld /* Remove an entry from the get list */
9438f23e9faSHans Rosenfeld bp = seg->fc_memget_ptr;
9448f23e9faSHans Rosenfeld
9458f23e9faSHans Rosenfeld if (seg->fc_memget_end == bp) {
9468f23e9faSHans Rosenfeld seg->fc_memget_ptr = NULL;
9478f23e9faSHans Rosenfeld seg->fc_memget_end = NULL;
9488f23e9faSHans Rosenfeld seg->fc_memget_cnt = 0;
9498f23e9faSHans Rosenfeld
9508f23e9faSHans Rosenfeld } else {
9518f23e9faSHans Rosenfeld seg->fc_memget_ptr = *((uint8_t **)bp);
9528f23e9faSHans Rosenfeld seg->fc_memget_cnt--;
9538f23e9faSHans Rosenfeld }
9548f23e9faSHans Rosenfeld
9558f23e9faSHans Rosenfeld /* Initialize buffer */
9568f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MBUF_DMA)) {
9578f23e9faSHans Rosenfeld bzero(bp, seg->fc_memsize);
9588f23e9faSHans Rosenfeld } else {
9598f23e9faSHans Rosenfeld mp = (MATCHMAP *)bp;
9608f23e9faSHans Rosenfeld mp->fc_mptr = NULL;
9618f23e9faSHans Rosenfeld mp->flag |= MAP_POOL_ALLOCATED;
9628f23e9faSHans Rosenfeld }
9638f23e9faSHans Rosenfeld
9648f23e9faSHans Rosenfeld /* Set fc_low if pool is dynamic */
9658f23e9faSHans Rosenfeld if (seg->fc_memflag & FC_MEMSEG_DYNAMIC) {
9668f23e9faSHans Rosenfeld free_count = (seg->fc_memget_cnt + seg->fc_memput_cnt);
9678f23e9faSHans Rosenfeld if (free_count < seg->fc_low) {
9688f23e9faSHans Rosenfeld seg->fc_low = free_count;
9698f23e9faSHans Rosenfeld }
970fcf3ce44SJohn Forte }
971fcf3ce44SJohn Forte
97282527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK);
97382527734SSukumar Swaminathan
97482527734SSukumar Swaminathan return (bp);
975fcf3ce44SJohn Forte
97682527734SSukumar Swaminathan } /* emlxs_mem_pool_get() */
977fcf3ce44SJohn Forte
978fcf3ce44SJohn Forte
979a9800bebSGarrett D'Amore extern void
emlxs_mem_pool_put(emlxs_hba_t * hba,MEMSEG * seg,void * bp)980a9800bebSGarrett D'Amore emlxs_mem_pool_put(emlxs_hba_t *hba, MEMSEG *seg, void *bp)
98182527734SSukumar Swaminathan {
982a9800bebSGarrett D'Amore emlxs_port_t *port = &PPORT;
983a9800bebSGarrett D'Amore MATCHMAP *mp;
984fcf3ce44SJohn Forte
98582527734SSukumar Swaminathan /* Free the pool object */
98682527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMPUT_LOCK);
98782527734SSukumar Swaminathan
9888f23e9faSHans Rosenfeld /* Check if memory pool is PUT enabled */
9898f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_PUT_ENABLED)) {
99082527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK);
991a9800bebSGarrett D'Amore return;
992fcf3ce44SJohn Forte }
993291a2b48SSukumar Swaminathan
99482527734SSukumar Swaminathan /* Check if buffer was just freed */
9958f23e9faSHans Rosenfeld if ((seg->fc_memput_end == bp) || (seg->fc_memget_end == bp)) {
99682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
99782527734SSukumar Swaminathan "%s: Freeing free object: bp=%p", seg->fc_label, bp);
998fcf3ce44SJohn Forte
99982527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK);
1000a9800bebSGarrett D'Amore return;
1001fcf3ce44SJohn Forte }
1002fcf3ce44SJohn Forte
10038f23e9faSHans Rosenfeld /* Validate DMA buffer */
100482527734SSukumar Swaminathan if (seg->fc_memflag & FC_MBUF_DMA) {
100582527734SSukumar Swaminathan mp = (MATCHMAP *)bp;
1006291a2b48SSukumar Swaminathan
100782527734SSukumar Swaminathan if (!(mp->flag & MAP_POOL_ALLOCATED) ||
100882527734SSukumar Swaminathan (mp->segment != seg)) {
100982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
10108f23e9faSHans Rosenfeld "mem_pool_put: %s invalid: mp=%p " \
101182527734SSukumar Swaminathan "tag=0x%x flag=%x", seg->fc_label,
101282527734SSukumar Swaminathan mp, mp->tag, mp->flag);
1013291a2b48SSukumar Swaminathan
101482527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR);
1015fcf3ce44SJohn Forte
101682527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK);
1017fcf3ce44SJohn Forte
101882527734SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_shutdown_thread,
101982527734SSukumar Swaminathan NULL, NULL);
102082527734SSukumar Swaminathan
1021a9800bebSGarrett D'Amore return;
1022fcf3ce44SJohn Forte }
1023fcf3ce44SJohn Forte }
1024fcf3ce44SJohn Forte
10258f23e9faSHans Rosenfeld /* Release buffer to the end of the memput list */
102682527734SSukumar Swaminathan if (seg->fc_memput_end == NULL) {
102782527734SSukumar Swaminathan seg->fc_memput_ptr = bp;
102882527734SSukumar Swaminathan seg->fc_memput_cnt = 1;
102982527734SSukumar Swaminathan } else {
1030a9800bebSGarrett D'Amore *((void **)(seg->fc_memput_end)) = bp;
103182527734SSukumar Swaminathan seg->fc_memput_cnt++;
103282527734SSukumar Swaminathan }
103382527734SSukumar Swaminathan seg->fc_memput_end = bp;
1034a9800bebSGarrett D'Amore *((void **)(bp)) = NULL;
103582527734SSukumar Swaminathan
103682527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK);
1037fcf3ce44SJohn Forte
10388f23e9faSHans Rosenfeld /* This is for late PUT's after an initial */
10398f23e9faSHans Rosenfeld /* emlxs_mem_pool_destroy call */
10408f23e9faSHans Rosenfeld if ((seg->fc_memflag & FC_MEMSEG_PUT_ENABLED) &&
10418f23e9faSHans Rosenfeld !(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) {
10428f23e9faSHans Rosenfeld emlxs_mem_pool_destroy(hba, seg);
10438f23e9faSHans Rosenfeld }
10448f23e9faSHans Rosenfeld
1045a9800bebSGarrett D'Amore return;
1046fcf3ce44SJohn Forte
104782527734SSukumar Swaminathan } /* emlxs_mem_pool_put() */
1048fcf3ce44SJohn Forte
104982527734SSukumar Swaminathan
105082527734SSukumar Swaminathan extern MATCHMAP *
emlxs_mem_buf_alloc(emlxs_hba_t * hba,uint32_t size)105182527734SSukumar Swaminathan emlxs_mem_buf_alloc(emlxs_hba_t *hba, uint32_t size)
1052fcf3ce44SJohn Forte {
1053fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT;
1054fcf3ce44SJohn Forte uint8_t *bp = NULL;
105582527734SSukumar Swaminathan MATCHMAP *mp = NULL;
1056fcf3ce44SJohn Forte MBUF_INFO *buf_info;
1057fcf3ce44SJohn Forte MBUF_INFO bufinfo;
1058fcf3ce44SJohn Forte
1059fcf3ce44SJohn Forte buf_info = &bufinfo;
1060fcf3ce44SJohn Forte
1061fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO));
1062fcf3ce44SJohn Forte buf_info->size = sizeof (MATCHMAP);
1063fcf3ce44SJohn Forte buf_info->align = sizeof (void *);
1064fcf3ce44SJohn Forte
1065fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info);
1066fcf3ce44SJohn Forte if (buf_info->virt == NULL) {
1067fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
1068fcf3ce44SJohn Forte "MEM_BUF_ALLOC buffer.");
1069fcf3ce44SJohn Forte
107082527734SSukumar Swaminathan return (NULL);
1071fcf3ce44SJohn Forte }
1072291a2b48SSukumar Swaminathan
107382527734SSukumar Swaminathan mp = (MATCHMAP *)buf_info->virt;
107482527734SSukumar Swaminathan bzero(mp, sizeof (MATCHMAP));
1075fcf3ce44SJohn Forte
1076fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO));
107782527734SSukumar Swaminathan buf_info->size = size;
1078a3170057SPaul Winder buf_info->flags = FC_MBUF_DMA | FC_MBUF_SNGLSG;
1079fcf3ce44SJohn Forte buf_info->align = 32;
1080fcf3ce44SJohn Forte
1081fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info);
1082fcf3ce44SJohn Forte if (buf_info->virt == NULL) {
1083fcf3ce44SJohn Forte
1084fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
1085fcf3ce44SJohn Forte "MEM_BUF_ALLOC DMA buffer.");
1086fcf3ce44SJohn Forte
108782527734SSukumar Swaminathan /* Free the mp object */
1088728bdc9bSSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO));
1089728bdc9bSSukumar Swaminathan buf_info->size = sizeof (MATCHMAP);
1090a9800bebSGarrett D'Amore buf_info->virt = (void *)mp;
1091728bdc9bSSukumar Swaminathan emlxs_mem_free(hba, buf_info);
1092728bdc9bSSukumar Swaminathan
1093a3170057SPaul Winder return (NULL);
1094fcf3ce44SJohn Forte }
1095fcf3ce44SJohn Forte bp = (uint8_t *)buf_info->virt;
10968f23e9faSHans Rosenfeld bzero(bp, buf_info->size);
1097fcf3ce44SJohn Forte
109882527734SSukumar Swaminathan mp->virt = buf_info->virt;
109982527734SSukumar Swaminathan mp->phys = buf_info->phys;
110082527734SSukumar Swaminathan mp->size = buf_info->size;
110182527734SSukumar Swaminathan mp->dma_handle = buf_info->dma_handle;
110282527734SSukumar Swaminathan mp->data_handle = buf_info->data_handle;
110382527734SSukumar Swaminathan mp->tag = MEM_BUF;
110482527734SSukumar Swaminathan mp->flag |= MAP_BUF_ALLOCATED;
1105fcf3ce44SJohn Forte
110682527734SSukumar Swaminathan return (mp);
1107fcf3ce44SJohn Forte
110882527734SSukumar Swaminathan } /* emlxs_mem_buf_alloc() */
1109fcf3ce44SJohn Forte
1110fcf3ce44SJohn Forte
1111a9800bebSGarrett D'Amore extern void
emlxs_mem_buf_free(emlxs_hba_t * hba,MATCHMAP * mp)111282527734SSukumar Swaminathan emlxs_mem_buf_free(emlxs_hba_t *hba, MATCHMAP *mp)
1113fcf3ce44SJohn Forte {
1114fcf3ce44SJohn Forte MBUF_INFO bufinfo;
1115fcf3ce44SJohn Forte MBUF_INFO *buf_info;
1116fcf3ce44SJohn Forte
1117fcf3ce44SJohn Forte buf_info = &bufinfo;
1118fcf3ce44SJohn Forte
111982527734SSukumar Swaminathan if (!(mp->flag & MAP_BUF_ALLOCATED)) {
1120a9800bebSGarrett D'Amore return;
1121fcf3ce44SJohn Forte }
1122fcf3ce44SJohn Forte
1123fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO));
112482527734SSukumar Swaminathan buf_info->size = mp->size;
112582527734SSukumar Swaminathan buf_info->virt = mp->virt;
112682527734SSukumar Swaminathan buf_info->phys = mp->phys;
112782527734SSukumar Swaminathan buf_info->dma_handle = mp->dma_handle;
112882527734SSukumar Swaminathan buf_info->data_handle = mp->data_handle;
1129fcf3ce44SJohn Forte buf_info->flags = FC_MBUF_DMA;
1130fcf3ce44SJohn Forte emlxs_mem_free(hba, buf_info);
1131fcf3ce44SJohn Forte
1132fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO));
1133fcf3ce44SJohn Forte buf_info->size = sizeof (MATCHMAP);
1134a9800bebSGarrett D'Amore buf_info->virt = (void *)mp;
1135fcf3ce44SJohn Forte emlxs_mem_free(hba, buf_info);
1136fcf3ce44SJohn Forte
1137a9800bebSGarrett D'Amore return;
1138fcf3ce44SJohn Forte
113982527734SSukumar Swaminathan } /* emlxs_mem_buf_free() */
1140fcf3ce44SJohn Forte
1141fcf3ce44SJohn Forte
1142a9800bebSGarrett D'Amore extern void *
emlxs_mem_get(emlxs_hba_t * hba,uint32_t seg_id)11438f23e9faSHans Rosenfeld emlxs_mem_get(emlxs_hba_t *hba, uint32_t seg_id)
1144fcf3ce44SJohn Forte {
1145a9800bebSGarrett D'Amore emlxs_port_t *port = &PPORT;
1146a9800bebSGarrett D'Amore void *bp;
1147a9800bebSGarrett D'Amore MAILBOXQ *mbq;
1148a9800bebSGarrett D'Amore IOCBQ *iocbq;
1149a9800bebSGarrett D'Amore NODELIST *node;
1150a9800bebSGarrett D'Amore MEMSEG *seg;
1151fcf3ce44SJohn Forte
115282527734SSukumar Swaminathan if (seg_id >= FC_MAX_SEG) {
1153291a2b48SSukumar Swaminathan
115482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
11558f23e9faSHans Rosenfeld "mem_get: Invalid segment id = %d",
115682527734SSukumar Swaminathan seg_id);
1157fcf3ce44SJohn Forte
1158fcf3ce44SJohn Forte return (NULL);
1159fcf3ce44SJohn Forte }
116082527734SSukumar Swaminathan seg = &hba->memseg[seg_id];
1161fcf3ce44SJohn Forte
116282527734SSukumar Swaminathan /* Alloc a buffer from the pool */
11638f23e9faSHans Rosenfeld bp = emlxs_mem_pool_get(hba, seg);
1164fcf3ce44SJohn Forte
116582527734SSukumar Swaminathan if (bp) {
116682527734SSukumar Swaminathan switch (seg_id) {
1167fcf3ce44SJohn Forte case MEM_MBOX:
1168291a2b48SSukumar Swaminathan mbq = (MAILBOXQ *)bp;
1169fcf3ce44SJohn Forte mbq->flag |= MBQ_POOL_ALLOCATED;
1170fcf3ce44SJohn Forte break;
1171fcf3ce44SJohn Forte
1172fcf3ce44SJohn Forte case MEM_IOCB:
1173291a2b48SSukumar Swaminathan iocbq = (IOCBQ *)bp;
1174fcf3ce44SJohn Forte iocbq->flag |= IOCB_POOL_ALLOCATED;
1175fcf3ce44SJohn Forte break;
1176fcf3ce44SJohn Forte
1177fcf3ce44SJohn Forte case MEM_NLP:
1178291a2b48SSukumar Swaminathan node = (NODELIST *)bp;
1179fcf3ce44SJohn Forte node->flag |= NODE_POOL_ALLOCATED;
1180fcf3ce44SJohn Forte break;
1181fcf3ce44SJohn Forte }
1182fcf3ce44SJohn Forte }
1183fcf3ce44SJohn Forte
1184fcf3ce44SJohn Forte return (bp);
1185fcf3ce44SJohn Forte
118682527734SSukumar Swaminathan } /* emlxs_mem_get() */
1187fcf3ce44SJohn Forte
1188fcf3ce44SJohn Forte
1189a9800bebSGarrett D'Amore extern void
emlxs_mem_put(emlxs_hba_t * hba,uint32_t seg_id,void * bp)1190a9800bebSGarrett D'Amore emlxs_mem_put(emlxs_hba_t *hba, uint32_t seg_id, void *bp)
1191fcf3ce44SJohn Forte {
1192a9800bebSGarrett D'Amore emlxs_port_t *port = &PPORT;
1193a9800bebSGarrett D'Amore MAILBOXQ *mbq;
1194a9800bebSGarrett D'Amore IOCBQ *iocbq;
1195a9800bebSGarrett D'Amore NODELIST *node;
1196a9800bebSGarrett D'Amore MEMSEG *seg;
1197a9800bebSGarrett D'Amore MATCHMAP *mp;
1198fcf3ce44SJohn Forte
119982527734SSukumar Swaminathan if (seg_id >= FC_MAX_SEG) {
120082527734SSukumar Swaminathan
120182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
12028f23e9faSHans Rosenfeld "mem_put: Invalid segment id = %d: bp=%p",
120382527734SSukumar Swaminathan seg_id, bp);
1204291a2b48SSukumar Swaminathan
1205a9800bebSGarrett D'Amore return;
1206fcf3ce44SJohn Forte }
120782527734SSukumar Swaminathan seg = &hba->memseg[seg_id];
1208291a2b48SSukumar Swaminathan
120982527734SSukumar Swaminathan /* Verify buffer */
121082527734SSukumar Swaminathan switch (seg_id) {
1211fcf3ce44SJohn Forte case MEM_MBOX:
1212291a2b48SSukumar Swaminathan mbq = (MAILBOXQ *)bp;
1213fcf3ce44SJohn Forte
1214fcf3ce44SJohn Forte if (!(mbq->flag & MBQ_POOL_ALLOCATED)) {
1215a9800bebSGarrett D'Amore return;
1216fcf3ce44SJohn Forte }
1217fcf3ce44SJohn Forte break;
1218fcf3ce44SJohn Forte
1219fcf3ce44SJohn Forte case MEM_IOCB:
1220291a2b48SSukumar Swaminathan iocbq = (IOCBQ *)bp;
1221fcf3ce44SJohn Forte
1222fcf3ce44SJohn Forte if (!(iocbq->flag & IOCB_POOL_ALLOCATED)) {
1223a9800bebSGarrett D'Amore return;
1224fcf3ce44SJohn Forte }
1225291a2b48SSukumar Swaminathan
1226291a2b48SSukumar Swaminathan /* Any IOCBQ with a packet attached did not come */
1227291a2b48SSukumar Swaminathan /* from our pool */
1228fcf3ce44SJohn Forte if (iocbq->sbp) {
1229a9800bebSGarrett D'Amore return;
1230fcf3ce44SJohn Forte }
1231fcf3ce44SJohn Forte break;
1232fcf3ce44SJohn Forte
1233fcf3ce44SJohn Forte case MEM_NLP:
1234291a2b48SSukumar Swaminathan node = (NODELIST *)bp;
1235fcf3ce44SJohn Forte
1236fcf3ce44SJohn Forte if (!(node->flag & NODE_POOL_ALLOCATED)) {
1237a9800bebSGarrett D'Amore return;
1238fcf3ce44SJohn Forte }
1239fcf3ce44SJohn Forte break;
1240fcf3ce44SJohn Forte
1241fcf3ce44SJohn Forte default:
124282527734SSukumar Swaminathan mp = (MATCHMAP *)bp;
1243fcf3ce44SJohn Forte
124482527734SSukumar Swaminathan if (mp->flag & MAP_BUF_ALLOCATED) {
1245a9800bebSGarrett D'Amore emlxs_mem_buf_free(hba, mp);
1246a9800bebSGarrett D'Amore return;
1247fcf3ce44SJohn Forte }
1248291a2b48SSukumar Swaminathan
124982527734SSukumar Swaminathan if (mp->flag & MAP_TABLE_ALLOCATED) {
1250a9800bebSGarrett D'Amore return;
1251fcf3ce44SJohn Forte }
1252291a2b48SSukumar Swaminathan
125382527734SSukumar Swaminathan if (!(mp->flag & MAP_POOL_ALLOCATED)) {
1254a9800bebSGarrett D'Amore return;
1255fcf3ce44SJohn Forte }
1256fcf3ce44SJohn Forte break;
1257fcf3ce44SJohn Forte }
1258fcf3ce44SJohn Forte
125982527734SSukumar Swaminathan /* Free a buffer to the pool */
1260a9800bebSGarrett D'Amore emlxs_mem_pool_put(hba, seg, bp);
1261291a2b48SSukumar Swaminathan
1262a9800bebSGarrett D'Amore return;
1263fcf3ce44SJohn Forte
126482527734SSukumar Swaminathan } /* emlxs_mem_put() */
1265fcf3ce44SJohn Forte
1266fcf3ce44SJohn Forte
1267fcf3ce44SJohn Forte /*
1268fcf3ce44SJohn Forte * Look up the virtual address given a mapped address
1269fcf3ce44SJohn Forte */
127082527734SSukumar Swaminathan /* SLI3 */
1271fcf3ce44SJohn Forte extern MATCHMAP *
emlxs_mem_get_vaddr(emlxs_hba_t * hba,RING * rp,uint64_t mapbp)1272fcf3ce44SJohn Forte emlxs_mem_get_vaddr(emlxs_hba_t *hba, RING *rp, uint64_t mapbp)
1273fcf3ce44SJohn Forte {
1274fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT;
1275fcf3ce44SJohn Forte MATCHMAP *prev;
1276fcf3ce44SJohn Forte MATCHMAP *mp;
1277fcf3ce44SJohn Forte
127882527734SSukumar Swaminathan if (rp->ringno == hba->channel_els) {
1279291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff;
1280fcf3ce44SJohn Forte prev = 0;
1281fcf3ce44SJohn Forte
1282fcf3ce44SJohn Forte while (mp) {
1283fcf3ce44SJohn Forte if (mp->phys == mapbp) {
1284fcf3ce44SJohn Forte if (prev == 0) {
1285fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr;
1286fcf3ce44SJohn Forte } else {
1287fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr;
1288fcf3ce44SJohn Forte }
1289fcf3ce44SJohn Forte
1290a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) {
1291a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev;
1292fcf3ce44SJohn Forte }
1293291a2b48SSukumar Swaminathan
1294a9800bebSGarrett D'Amore mp->fc_mptr = NULL;
1295fcf3ce44SJohn Forte
129682527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
1297fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL);
1298fcf3ce44SJohn Forte
1299fcf3ce44SJohn Forte HBASTATS.ElsUbPosted--;
1300fcf3ce44SJohn Forte
1301fcf3ce44SJohn Forte return (mp);
1302fcf3ce44SJohn Forte }
1303291a2b48SSukumar Swaminathan
1304fcf3ce44SJohn Forte prev = mp;
1305291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr;
1306fcf3ce44SJohn Forte }
1307fcf3ce44SJohn Forte
1308fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
1309fcf3ce44SJohn Forte "ELS Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p",
1310fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon);
1311fcf3ce44SJohn Forte
131282527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ct) {
1313fcf3ce44SJohn Forte
1314291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff;
1315fcf3ce44SJohn Forte prev = 0;
1316fcf3ce44SJohn Forte
1317fcf3ce44SJohn Forte while (mp) {
1318fcf3ce44SJohn Forte if (mp->phys == mapbp) {
1319fcf3ce44SJohn Forte if (prev == 0) {
1320fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr;
1321fcf3ce44SJohn Forte } else {
1322fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr;
1323fcf3ce44SJohn Forte }
1324fcf3ce44SJohn Forte
1325a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) {
1326a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev;
1327fcf3ce44SJohn Forte }
1328291a2b48SSukumar Swaminathan
1329a9800bebSGarrett D'Amore mp->fc_mptr = NULL;
1330fcf3ce44SJohn Forte
133182527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
1332fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL);
1333fcf3ce44SJohn Forte
1334fcf3ce44SJohn Forte HBASTATS.CtUbPosted--;
1335fcf3ce44SJohn Forte
1336fcf3ce44SJohn Forte return (mp);
1337fcf3ce44SJohn Forte }
1338291a2b48SSukumar Swaminathan
1339fcf3ce44SJohn Forte prev = mp;
1340291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr;
1341fcf3ce44SJohn Forte }
1342fcf3ce44SJohn Forte
1343fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
1344fcf3ce44SJohn Forte "CT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p",
1345fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon);
1346fcf3ce44SJohn Forte
134782527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ip) {
1348fcf3ce44SJohn Forte
1349291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff;
1350fcf3ce44SJohn Forte prev = 0;
1351fcf3ce44SJohn Forte
1352fcf3ce44SJohn Forte while (mp) {
1353fcf3ce44SJohn Forte if (mp->phys == mapbp) {
1354fcf3ce44SJohn Forte if (prev == 0) {
1355fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr;
1356fcf3ce44SJohn Forte } else {
1357fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr;
1358fcf3ce44SJohn Forte }
1359fcf3ce44SJohn Forte
1360a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) {
1361a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev;
1362fcf3ce44SJohn Forte }
1363291a2b48SSukumar Swaminathan
1364a9800bebSGarrett D'Amore mp->fc_mptr = NULL;
1365fcf3ce44SJohn Forte
136682527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
1367fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL);
1368fcf3ce44SJohn Forte
1369fcf3ce44SJohn Forte HBASTATS.IpUbPosted--;
1370fcf3ce44SJohn Forte
1371fcf3ce44SJohn Forte return (mp);
1372fcf3ce44SJohn Forte }
1373291a2b48SSukumar Swaminathan
1374fcf3ce44SJohn Forte prev = mp;
1375291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr;
1376fcf3ce44SJohn Forte }
1377fcf3ce44SJohn Forte
1378fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
1379fcf3ce44SJohn Forte "IP Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p",
1380fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon);
1381fcf3ce44SJohn Forte
1382fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT
138382527734SSukumar Swaminathan } else if (rp->ringno == hba->CHANNEL_FCT) {
1384291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff;
1385fcf3ce44SJohn Forte prev = 0;
1386fcf3ce44SJohn Forte
1387fcf3ce44SJohn Forte while (mp) {
1388fcf3ce44SJohn Forte if (mp->phys == mapbp) {
1389fcf3ce44SJohn Forte if (prev == 0) {
1390fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr;
1391fcf3ce44SJohn Forte } else {
1392fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr;
1393fcf3ce44SJohn Forte }
1394fcf3ce44SJohn Forte
1395a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) {
1396a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev;
1397fcf3ce44SJohn Forte }
1398291a2b48SSukumar Swaminathan
1399a9800bebSGarrett D'Amore mp->fc_mptr = NULL;
1400fcf3ce44SJohn Forte
140182527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
1402fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL);
1403fcf3ce44SJohn Forte
1404fcf3ce44SJohn Forte HBASTATS.FctUbPosted--;
1405fcf3ce44SJohn Forte
1406fcf3ce44SJohn Forte return (mp);
1407fcf3ce44SJohn Forte }
1408291a2b48SSukumar Swaminathan
1409fcf3ce44SJohn Forte prev = mp;
1410291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr;
1411fcf3ce44SJohn Forte }
1412fcf3ce44SJohn Forte
1413fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg,
1414fcf3ce44SJohn Forte "FCT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p",
1415fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon);
1416fcf3ce44SJohn Forte
1417291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */
1418fcf3ce44SJohn Forte }
1419fcf3ce44SJohn Forte
1420fcf3ce44SJohn Forte return (0);
1421fcf3ce44SJohn Forte
142282527734SSukumar Swaminathan } /* emlxs_mem_get_vaddr() */
1423fcf3ce44SJohn Forte
1424fcf3ce44SJohn Forte
1425fcf3ce44SJohn Forte /*
1426291a2b48SSukumar Swaminathan * Given a virtual address bp, generate the physical mapped address and
1427291a2b48SSukumar Swaminathan * place it where addr points to. Save the address pair for lookup later.
1428fcf3ce44SJohn Forte */
142982527734SSukumar Swaminathan /* SLI3 */
1430fcf3ce44SJohn Forte extern void
emlxs_mem_map_vaddr(emlxs_hba_t * hba,RING * rp,MATCHMAP * mp,uint32_t * haddr,uint32_t * laddr)1431291a2b48SSukumar Swaminathan emlxs_mem_map_vaddr(emlxs_hba_t *hba, RING *rp, MATCHMAP *mp,
1432291a2b48SSukumar Swaminathan uint32_t *haddr, uint32_t *laddr)
1433fcf3ce44SJohn Forte {
143482527734SSukumar Swaminathan if (rp->ringno == hba->channel_els) {
1435fcf3ce44SJohn Forte /*
1436291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it
1437291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list.
1438291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list.
1439fcf3ce44SJohn Forte */
1440a9800bebSGarrett D'Amore mp->fc_mptr = NULL;
1441fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) {
1442a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp;
1443a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp;
1444fcf3ce44SJohn Forte } else {
1445291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr =
1446a9800bebSGarrett D'Amore (void *)mp;
1447a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp;
1448fcf3ce44SJohn Forte }
1449fcf3ce44SJohn Forte
1450fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) {
1451291a2b48SSukumar Swaminathan
1452291a2b48SSukumar Swaminathan /* return mapped address */
145382527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys);
1454fcf3ce44SJohn Forte /* return mapped address */
145582527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys);
1456fcf3ce44SJohn Forte } else {
1457fcf3ce44SJohn Forte /* return mapped address */
145882527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys);
1459fcf3ce44SJohn Forte }
1460fcf3ce44SJohn Forte
1461fcf3ce44SJohn Forte HBASTATS.ElsUbPosted++;
1462fcf3ce44SJohn Forte
146382527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ct) {
1464fcf3ce44SJohn Forte /*
1465291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it
1466291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list.
1467291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list.
1468fcf3ce44SJohn Forte */
1469a9800bebSGarrett D'Amore mp->fc_mptr = NULL;
1470fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) {
1471a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp;
1472a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp;
1473fcf3ce44SJohn Forte } else {
1474291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr =
1475a9800bebSGarrett D'Amore (void *)mp;
1476a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp;
1477fcf3ce44SJohn Forte }
1478fcf3ce44SJohn Forte
1479fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) {
1480fcf3ce44SJohn Forte /* return mapped address */
148182527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys);
1482291a2b48SSukumar Swaminathan /* return mapped address */
148382527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys);
1484fcf3ce44SJohn Forte } else {
1485fcf3ce44SJohn Forte /* return mapped address */
148682527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys);
1487fcf3ce44SJohn Forte }
1488fcf3ce44SJohn Forte
1489fcf3ce44SJohn Forte HBASTATS.CtUbPosted++;
1490fcf3ce44SJohn Forte
1491fcf3ce44SJohn Forte
149282527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ip) {
1493fcf3ce44SJohn Forte /*
1494291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it
1495291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list.
1496291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list.
1497fcf3ce44SJohn Forte */
1498a9800bebSGarrett D'Amore mp->fc_mptr = NULL;
1499fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) {
1500a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp;
1501a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp;
1502fcf3ce44SJohn Forte } else {
1503291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr =
1504a9800bebSGarrett D'Amore (void *)mp;
1505a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp;
1506fcf3ce44SJohn Forte }
1507fcf3ce44SJohn Forte
1508fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) {
1509fcf3ce44SJohn Forte /* return mapped address */
151082527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys);
151182527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys);
1512fcf3ce44SJohn Forte } else {
151382527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys);
1514fcf3ce44SJohn Forte }
1515fcf3ce44SJohn Forte
1516fcf3ce44SJohn Forte HBASTATS.IpUbPosted++;
1517fcf3ce44SJohn Forte
1518fcf3ce44SJohn Forte
1519fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT
152082527734SSukumar Swaminathan } else if (rp->ringno == hba->CHANNEL_FCT) {
1521fcf3ce44SJohn Forte /*
1522291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it
1523291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list.
1524291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list.
1525fcf3ce44SJohn Forte */
1526a9800bebSGarrett D'Amore mp->fc_mptr = NULL;
1527fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) {
1528a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp;
1529a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp;
1530fcf3ce44SJohn Forte } else {
1531291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr =
1532a9800bebSGarrett D'Amore (void *)mp;
1533a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp;
1534fcf3ce44SJohn Forte }
1535fcf3ce44SJohn Forte
1536fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) {
1537fcf3ce44SJohn Forte /* return mapped address */
153882527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys);
1539291a2b48SSukumar Swaminathan /* return mapped address */
154082527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys);
1541fcf3ce44SJohn Forte } else {
1542fcf3ce44SJohn Forte /* return mapped address */
154382527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys);
1544fcf3ce44SJohn Forte }
1545fcf3ce44SJohn Forte
1546fcf3ce44SJohn Forte HBASTATS.FctUbPosted++;
154782527734SSukumar Swaminathan
1548291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */
1549fcf3ce44SJohn Forte }
155082527734SSukumar Swaminathan } /* emlxs_mem_map_vaddr() */
1551fcf3ce44SJohn Forte
1552fcf3ce44SJohn Forte
155382527734SSukumar Swaminathan /* SLI3 */
1554291a2b48SSukumar Swaminathan uint32_t
emlxs_hbq_alloc(emlxs_hba_t * hba,uint32_t hbq_id)1555fcf3ce44SJohn Forte emlxs_hbq_alloc(emlxs_hba_t *hba, uint32_t hbq_id)
1556fcf3ce44SJohn Forte {
1557fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT;
1558fcf3ce44SJohn Forte HBQ_INIT_t *hbq;
1559fcf3ce44SJohn Forte MBUF_INFO *buf_info;
1560fcf3ce44SJohn Forte MBUF_INFO bufinfo;
1561fcf3ce44SJohn Forte
156282527734SSukumar Swaminathan hbq = &hba->sli.sli3.hbq_table[hbq_id];
1563fcf3ce44SJohn Forte
1564fcf3ce44SJohn Forte if (hbq->HBQ_host_buf.virt == 0) {
1565fcf3ce44SJohn Forte buf_info = &bufinfo;
1566fcf3ce44SJohn Forte
1567fcf3ce44SJohn Forte /* Get the system's page size in a DDI-compliant way. */
1568fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO));
1569fcf3ce44SJohn Forte buf_info->size = hbq->HBQ_numEntries * sizeof (HBQE_t);
1570fcf3ce44SJohn Forte buf_info->flags = FC_MBUF_DMA;
1571fcf3ce44SJohn Forte buf_info->align = 4096;
1572fcf3ce44SJohn Forte
1573fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info);
1574fcf3ce44SJohn Forte
1575fcf3ce44SJohn Forte if (buf_info->virt == NULL) {
1576fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg,
1577fcf3ce44SJohn Forte "Unable to alloc HBQ.");
1578fcf3ce44SJohn Forte return (ENOMEM);
1579fcf3ce44SJohn Forte }
1580291a2b48SSukumar Swaminathan
1581a9800bebSGarrett D'Amore hbq->HBQ_host_buf.virt = buf_info->virt;
1582fcf3ce44SJohn Forte hbq->HBQ_host_buf.phys = buf_info->phys;
1583fcf3ce44SJohn Forte hbq->HBQ_host_buf.data_handle = buf_info->data_handle;
1584fcf3ce44SJohn Forte hbq->HBQ_host_buf.dma_handle = buf_info->dma_handle;
1585fcf3ce44SJohn Forte hbq->HBQ_host_buf.size = buf_info->size;
1586fcf3ce44SJohn Forte hbq->HBQ_host_buf.tag = hbq_id;
1587fcf3ce44SJohn Forte
1588fcf3ce44SJohn Forte bzero((char *)hbq->HBQ_host_buf.virt, buf_info->size);
1589fcf3ce44SJohn Forte }
1590fcf3ce44SJohn Forte
1591fcf3ce44SJohn Forte return (0);
1592fcf3ce44SJohn Forte
159382527734SSukumar Swaminathan } /* emlxs_hbq_alloc() */
1594