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. 25*a3170057SPaul Winder * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. 26*a3170057SPaul 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 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 166*a3170057SPaul Winder case MEM_SGL1K: 167*a3170057SPaul Winder (void) strlcpy(seg->fc_label, "1K SGL Pool", 168*a3170057SPaul Winder sizeof (seg->fc_label)); 169*a3170057SPaul Winder seg->fc_memtag = MEM_SGL1K; 170*a3170057SPaul Winder seg->fc_memsize = 0x400; 171*a3170057SPaul Winder seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 172*a3170057SPaul Winder seg->fc_memalign = 32; 173*a3170057SPaul Winder seg->fc_hi_water = 0x5000; 174*a3170057SPaul Winder seg->fc_lo_water = 0; 175*a3170057SPaul Winder seg->fc_step = 0x100; 176*a3170057SPaul Winder break; 177*a3170057SPaul Winder 178*a3170057SPaul Winder case MEM_SGL2K: 179*a3170057SPaul Winder (void) strlcpy(seg->fc_label, "2K SGL Pool", 180*a3170057SPaul Winder sizeof (seg->fc_label)); 181*a3170057SPaul Winder seg->fc_memtag = MEM_SGL2K; 182*a3170057SPaul Winder seg->fc_memsize = 0x800; 183*a3170057SPaul Winder seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 184*a3170057SPaul Winder seg->fc_memalign = 32; 185*a3170057SPaul Winder seg->fc_hi_water = 0x5000; 186*a3170057SPaul Winder seg->fc_lo_water = 0; 187*a3170057SPaul Winder seg->fc_step = 0x100; 188*a3170057SPaul Winder break; 189*a3170057SPaul Winder 190*a3170057SPaul Winder case MEM_SGL4K: 191*a3170057SPaul Winder (void) strlcpy(seg->fc_label, "4K SGL Pool", 192*a3170057SPaul Winder sizeof (seg->fc_label)); 193*a3170057SPaul Winder seg->fc_memtag = MEM_SGL4K; 194*a3170057SPaul Winder seg->fc_memsize = 0x1000; 195*a3170057SPaul Winder seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 196*a3170057SPaul Winder seg->fc_memalign = 32; 197*a3170057SPaul Winder seg->fc_hi_water = 0x5000; 198*a3170057SPaul Winder seg->fc_lo_water = 0; 199*a3170057SPaul Winder seg->fc_step = 0x100; 200*a3170057SPaul Winder break; 201*a3170057SPaul 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 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 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, 4448f23e9faSHans Rosenfeld "%s alloc:%d n=%d s=%d f=%x l=%d,%d,%d " 4458f23e9faSHans Rosenfeld "f=%d:%d", 4468f23e9faSHans Rosenfeld seg->fc_label, count, seg->fc_numblks, 4478f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water, 4488f23e9faSHans Rosenfeld seg->fc_hi_water, seg->fc_step, seg->fc_memget_cnt, 4498f23e9faSHans Rosenfeld seg->fc_low); 45082527734SSukumar Swaminathan } 451291a2b48SSukumar Swaminathan 45282527734SSukumar Swaminathan if (!(seg->fc_memflag & FC_MBUF_DMA)) { 45382527734SSukumar Swaminathan goto vmem_pool; 454fcf3ce44SJohn Forte } 455fcf3ce44SJohn Forte 45682527734SSukumar Swaminathan /* dma_pool */ 45782527734SSukumar Swaminathan 4588f23e9faSHans Rosenfeld for (i = 0; i < count; i++) { 459fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 460fcf3ce44SJohn Forte buf_info->size = sizeof (MATCHMAP); 461fcf3ce44SJohn Forte buf_info->align = sizeof (void *); 462fcf3ce44SJohn Forte 463fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 464fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 465fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 4668f23e9faSHans Rosenfeld "%s: count=%d size=%d", 4678f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, seg->fc_memsize); 468fcf3ce44SJohn Forte 4698f23e9faSHans Rosenfeld goto done; 470fcf3ce44SJohn Forte } 471291a2b48SSukumar Swaminathan 47282527734SSukumar Swaminathan mp = (MATCHMAP *)buf_info->virt; 47382527734SSukumar Swaminathan bzero(mp, sizeof (MATCHMAP)); 474fcf3ce44SJohn Forte 475fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 47682527734SSukumar Swaminathan buf_info->size = seg->fc_memsize; 47782527734SSukumar Swaminathan buf_info->flags = seg->fc_memflag; 47882527734SSukumar Swaminathan buf_info->align = seg->fc_memalign; 479fcf3ce44SJohn Forte 480fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 481fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 482fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 4838f23e9faSHans Rosenfeld "%s: count=%d size=%d", 4848f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, seg->fc_memsize); 485fcf3ce44SJohn Forte 48682527734SSukumar Swaminathan /* Free the mp object */ 48782527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 48882527734SSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 489a9800bebSGarrett D'Amore buf_info->virt = (void *)mp; 49082527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 49182527734SSukumar Swaminathan 4928f23e9faSHans Rosenfeld goto done; 493fcf3ce44SJohn Forte } 494fcf3ce44SJohn Forte bp = (uint8_t *)buf_info->virt; 49582527734SSukumar Swaminathan bzero(bp, seg->fc_memsize); 49682527734SSukumar Swaminathan 49782527734SSukumar Swaminathan mp->virt = buf_info->virt; 49882527734SSukumar Swaminathan mp->phys = buf_info->phys; 49982527734SSukumar Swaminathan mp->size = buf_info->size; 50082527734SSukumar Swaminathan mp->dma_handle = buf_info->dma_handle; 50182527734SSukumar Swaminathan mp->data_handle = buf_info->data_handle; 50282527734SSukumar Swaminathan mp->tag = seg->fc_memtag; 50382527734SSukumar Swaminathan mp->segment = seg; 50482527734SSukumar Swaminathan mp->flag |= MAP_POOL_ALLOCATED; 50582527734SSukumar Swaminathan 5068f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 5078f23e9faSHans Rosenfeld if (mp->tag >= MEM_FCTSEG) { 5088f23e9faSHans Rosenfeld if (emlxs_fct_stmf_alloc(hba, mp)) { 5098f23e9faSHans Rosenfeld /* Free the DMA memory itself */ 5108f23e9faSHans Rosenfeld emlxs_mem_free(hba, buf_info); 5118f23e9faSHans Rosenfeld 5128f23e9faSHans Rosenfeld /* Free the mp object */ 5138f23e9faSHans Rosenfeld bzero(buf_info, sizeof (MBUF_INFO)); 5148f23e9faSHans Rosenfeld buf_info->size = sizeof (MATCHMAP); 5158f23e9faSHans Rosenfeld buf_info->virt = (void *)mp; 5168f23e9faSHans Rosenfeld emlxs_mem_free(hba, buf_info); 5178f23e9faSHans Rosenfeld 5188f23e9faSHans Rosenfeld goto done; 5198f23e9faSHans Rosenfeld } 5208f23e9faSHans Rosenfeld } 5218f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 5228f23e9faSHans Rosenfeld 52382527734SSukumar Swaminathan /* Add the buffer desc to the tail of the pool freelist */ 52482527734SSukumar Swaminathan if (seg->fc_memget_end == NULL) { 52582527734SSukumar Swaminathan seg->fc_memget_ptr = (uint8_t *)mp; 52682527734SSukumar Swaminathan seg->fc_memget_cnt = 1; 52782527734SSukumar Swaminathan } else { 52882527734SSukumar Swaminathan *((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)mp; 52982527734SSukumar Swaminathan seg->fc_memget_cnt++; 530fcf3ce44SJohn Forte } 53182527734SSukumar Swaminathan seg->fc_memget_end = (uint8_t *)mp; 5328f23e9faSHans Rosenfeld 5338f23e9faSHans Rosenfeld seg->fc_numblks++; 5348f23e9faSHans Rosenfeld seg->fc_total_memsize += (seg->fc_memsize + sizeof (MATCHMAP)); 535fcf3ce44SJohn Forte } 536fcf3ce44SJohn Forte 5378f23e9faSHans Rosenfeld goto done; 538fcf3ce44SJohn Forte 53982527734SSukumar Swaminathan vmem_pool: 540fcf3ce44SJohn Forte 5418f23e9faSHans Rosenfeld for (i = 0; i < count; i++) { 5428f23e9faSHans Rosenfeld bzero(buf_info, sizeof (MBUF_INFO)); 5438f23e9faSHans Rosenfeld buf_info->size = seg->fc_memsize; 544fcf3ce44SJohn Forte 5458f23e9faSHans Rosenfeld (void) emlxs_mem_alloc(hba, buf_info); 5468f23e9faSHans Rosenfeld if (buf_info->virt == NULL) { 5478f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 5488f23e9faSHans Rosenfeld "%s: count=%d size=%d", 5498f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, seg->fc_memsize); 550fcf3ce44SJohn Forte 5518f23e9faSHans Rosenfeld goto done; 5528f23e9faSHans Rosenfeld } 5538f23e9faSHans Rosenfeld bp = (uint8_t *)buf_info->virt; 554fcf3ce44SJohn Forte 55582527734SSukumar Swaminathan /* Add the buffer to the tail of the pool freelist */ 55682527734SSukumar Swaminathan if (seg->fc_memget_end == NULL) { 55782527734SSukumar Swaminathan seg->fc_memget_ptr = (uint8_t *)bp; 55882527734SSukumar Swaminathan seg->fc_memget_cnt = 1; 55982527734SSukumar Swaminathan } else { 56082527734SSukumar Swaminathan *((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)bp; 56182527734SSukumar Swaminathan seg->fc_memget_cnt++; 56282527734SSukumar Swaminathan } 56382527734SSukumar Swaminathan seg->fc_memget_end = (uint8_t *)bp; 564fcf3ce44SJohn Forte 5658f23e9faSHans Rosenfeld seg->fc_numblks++; 5668f23e9faSHans Rosenfeld seg->fc_total_memsize += seg->fc_memsize; 56782527734SSukumar Swaminathan } 568fcf3ce44SJohn Forte 5698f23e9faSHans Rosenfeld done: 570fcf3ce44SJohn Forte 5718f23e9faSHans Rosenfeld return ((seg->fc_numblks - fc_numblks)); 572291a2b48SSukumar Swaminathan 57382527734SSukumar Swaminathan } /* emlxs_mem_pool_alloc() */ 574fcf3ce44SJohn Forte 575fcf3ce44SJohn Forte 5768f23e9faSHans Rosenfeld /* Must hold EMLXS_MEMGET_LOCK & EMLXS_MEMPUT_LOCK when calling */ 5778f23e9faSHans Rosenfeld static void 5788f23e9faSHans Rosenfeld emlxs_mem_pool_free(emlxs_hba_t *hba, MEMSEG *seg, uint32_t count) 57982527734SSukumar Swaminathan { 58082527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 58182527734SSukumar Swaminathan uint8_t *bp = NULL; 58282527734SSukumar Swaminathan MATCHMAP *mp = NULL; 58382527734SSukumar Swaminathan MBUF_INFO *buf_info; 58482527734SSukumar Swaminathan MBUF_INFO local_buf_info; 585fcf3ce44SJohn Forte 5868f23e9faSHans Rosenfeld if ((seg->fc_memsize == 0) || 5878f23e9faSHans Rosenfeld (seg->fc_numblks == 0) || 5888f23e9faSHans Rosenfeld (count == 0)) { 5898f23e9faSHans Rosenfeld return; 5908f23e9faSHans Rosenfeld } 591fcf3ce44SJohn Forte 5928f23e9faSHans Rosenfeld /* Check max count */ 5938f23e9faSHans Rosenfeld if (count > seg->fc_numblks) { 5948f23e9faSHans Rosenfeld count = seg->fc_numblks; 595fcf3ce44SJohn Forte } 596fcf3ce44SJohn Forte 5978f23e9faSHans Rosenfeld /* Move memput list to memget list */ 5988f23e9faSHans Rosenfeld if (seg->fc_memput_ptr) { 5998f23e9faSHans Rosenfeld if (seg->fc_memget_end == NULL) { 6008f23e9faSHans Rosenfeld seg->fc_memget_ptr = seg->fc_memput_ptr; 6018f23e9faSHans Rosenfeld } else { 6028f23e9faSHans Rosenfeld *((uint8_t **)(seg->fc_memget_end)) =\ 6038f23e9faSHans Rosenfeld seg->fc_memput_ptr; 6048f23e9faSHans Rosenfeld } 6058f23e9faSHans Rosenfeld seg->fc_memget_end = seg->fc_memput_end; 6068f23e9faSHans Rosenfeld seg->fc_memget_cnt += seg->fc_memput_cnt; 607fcf3ce44SJohn Forte 6088f23e9faSHans Rosenfeld seg->fc_memput_ptr = NULL; 6098f23e9faSHans Rosenfeld seg->fc_memput_end = NULL; 6108f23e9faSHans Rosenfeld seg->fc_memput_cnt = 0; 6118f23e9faSHans Rosenfeld } 612fcf3ce44SJohn Forte 6138f23e9faSHans Rosenfeld buf_info = &local_buf_info; 614fcf3ce44SJohn Forte 6158f23e9faSHans Rosenfeld /* Check for final deallocation */ 6168f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) { 6178f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 6188f23e9faSHans Rosenfeld "%s free:%d n=%d s=%d f=%x l=%d,%d,%d " 6198f23e9faSHans Rosenfeld "f=%d:%d", 6208f23e9faSHans Rosenfeld seg->fc_label, count, seg->fc_numblks, 6218f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water, 6228f23e9faSHans Rosenfeld seg->fc_hi_water, seg->fc_step, seg->fc_memget_cnt, 6238f23e9faSHans Rosenfeld seg->fc_low); 6248f23e9faSHans Rosenfeld } 625fcf3ce44SJohn Forte 6268f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MBUF_DMA)) { 6278f23e9faSHans Rosenfeld goto vmem_pool; 62882527734SSukumar Swaminathan } 629fcf3ce44SJohn Forte 6308f23e9faSHans Rosenfeld dma_pool: 631fcf3ce44SJohn Forte 63282527734SSukumar Swaminathan /* Free memory associated with all buffers on get buffer pool */ 6338f23e9faSHans Rosenfeld while (count && ((bp = seg->fc_memget_ptr) != NULL)) { 6348f23e9faSHans Rosenfeld /* Remove buffer from list */ 6358f23e9faSHans Rosenfeld if (seg->fc_memget_end == bp) { 6368f23e9faSHans Rosenfeld seg->fc_memget_ptr = NULL; 6378f23e9faSHans Rosenfeld seg->fc_memget_end = NULL; 6388f23e9faSHans Rosenfeld seg->fc_memget_cnt = 0; 6398f23e9faSHans Rosenfeld 6408f23e9faSHans Rosenfeld } else { 6418f23e9faSHans Rosenfeld seg->fc_memget_ptr = *((uint8_t **)bp); 6428f23e9faSHans Rosenfeld seg->fc_memget_cnt--; 6438f23e9faSHans Rosenfeld } 64482527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 645fcf3ce44SJohn Forte 6468f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 6478f23e9faSHans Rosenfeld if (mp->tag >= MEM_FCTSEG) { 6488f23e9faSHans Rosenfeld emlxs_fct_stmf_free(hba, mp); 6498f23e9faSHans Rosenfeld } 6508f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 6518f23e9faSHans Rosenfeld 6528f23e9faSHans Rosenfeld /* Free the DMA memory itself */ 65382527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 65482527734SSukumar Swaminathan buf_info->size = mp->size; 65582527734SSukumar Swaminathan buf_info->virt = mp->virt; 65682527734SSukumar Swaminathan buf_info->phys = mp->phys; 65782527734SSukumar Swaminathan buf_info->dma_handle = mp->dma_handle; 65882527734SSukumar Swaminathan buf_info->data_handle = mp->data_handle; 65982527734SSukumar Swaminathan buf_info->flags = seg->fc_memflag; 66082527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 661fcf3ce44SJohn Forte 6628f23e9faSHans Rosenfeld /* Free the handle */ 66382527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 66482527734SSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 665a9800bebSGarrett D'Amore buf_info->virt = (void *)mp; 66682527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 6678f23e9faSHans Rosenfeld 6688f23e9faSHans Rosenfeld seg->fc_numblks--; 6698f23e9faSHans Rosenfeld seg->fc_total_memsize -= (seg->fc_memsize + sizeof (MATCHMAP)); 6708f23e9faSHans Rosenfeld 6718f23e9faSHans Rosenfeld count--; 672fcf3ce44SJohn Forte } 673291a2b48SSukumar Swaminathan 6748f23e9faSHans Rosenfeld return; 675fcf3ce44SJohn Forte 6768f23e9faSHans Rosenfeld vmem_pool: 677291a2b48SSukumar Swaminathan 6788f23e9faSHans Rosenfeld /* Free memory associated with all buffers on get buffer pool */ 6798f23e9faSHans Rosenfeld while (count && ((bp = seg->fc_memget_ptr) != NULL)) { 6808f23e9faSHans Rosenfeld /* Remove buffer from list */ 6818f23e9faSHans Rosenfeld if (seg->fc_memget_end == bp) { 6828f23e9faSHans Rosenfeld seg->fc_memget_ptr = NULL; 6838f23e9faSHans Rosenfeld seg->fc_memget_end = NULL; 6848f23e9faSHans Rosenfeld seg->fc_memget_cnt = 0; 6858f23e9faSHans Rosenfeld 6868f23e9faSHans Rosenfeld } else { 6878f23e9faSHans Rosenfeld seg->fc_memget_ptr = *((uint8_t **)bp); 6888f23e9faSHans Rosenfeld seg->fc_memget_cnt--; 6898f23e9faSHans Rosenfeld } 6908f23e9faSHans Rosenfeld 6918f23e9faSHans Rosenfeld /* Free the Virtual memory itself */ 69282527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 6938f23e9faSHans Rosenfeld buf_info->size = seg->fc_memsize; 6948f23e9faSHans Rosenfeld buf_info->virt = bp; 69582527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 6968f23e9faSHans Rosenfeld 6978f23e9faSHans Rosenfeld seg->fc_numblks--; 6988f23e9faSHans Rosenfeld seg->fc_total_memsize -= seg->fc_memsize; 6998f23e9faSHans Rosenfeld 7008f23e9faSHans Rosenfeld count--; 701291a2b48SSukumar Swaminathan } 702fcf3ce44SJohn Forte 70382527734SSukumar Swaminathan return; 704fcf3ce44SJohn Forte 70582527734SSukumar Swaminathan } /* emlxs_mem_pool_free() */ 706fcf3ce44SJohn Forte 707fcf3ce44SJohn Forte 7088f23e9faSHans Rosenfeld extern uint32_t 7098f23e9faSHans Rosenfeld emlxs_mem_pool_create(emlxs_hba_t *hba, MEMSEG *seg) 71082527734SSukumar Swaminathan { 7118f23e9faSHans Rosenfeld emlxs_config_t *cfg = &CFG; 712291a2b48SSukumar Swaminathan 71382527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMGET_LOCK); 7148f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMPUT_LOCK); 71582527734SSukumar Swaminathan 7168f23e9faSHans Rosenfeld if (seg->fc_memsize == 0) { 7178f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 71882527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 7198f23e9faSHans Rosenfeld 7208f23e9faSHans Rosenfeld return (0); 7218f23e9faSHans Rosenfeld } 7228f23e9faSHans Rosenfeld 7238f23e9faSHans Rosenfeld /* Sanity check hi > lo */ 7248f23e9faSHans Rosenfeld if (seg->fc_lo_water > seg->fc_hi_water) { 7258f23e9faSHans Rosenfeld seg->fc_hi_water = seg->fc_lo_water; 7268f23e9faSHans Rosenfeld } 7278f23e9faSHans Rosenfeld 7288f23e9faSHans Rosenfeld /* If dynamic pools are disabled, then force pool to max level */ 7298f23e9faSHans Rosenfeld if (cfg[CFG_MEM_DYNAMIC].current == 0) { 7308f23e9faSHans Rosenfeld seg->fc_lo_water = seg->fc_hi_water; 731fcf3ce44SJohn Forte } 732291a2b48SSukumar Swaminathan 7338f23e9faSHans Rosenfeld /* If pool is dynamic, then fc_step must be >0 */ 7348f23e9faSHans Rosenfeld /* Otherwise, fc_step must be 0 */ 7358f23e9faSHans Rosenfeld if (seg->fc_lo_water != seg->fc_hi_water) { 7368f23e9faSHans Rosenfeld seg->fc_memflag |= FC_MEMSEG_DYNAMIC; 737fcf3ce44SJohn Forte 7388f23e9faSHans Rosenfeld if (seg->fc_step == 0) { 7398f23e9faSHans Rosenfeld seg->fc_step = 1; 74082527734SSukumar Swaminathan } 7418f23e9faSHans Rosenfeld } else { 7428f23e9faSHans Rosenfeld seg->fc_step = 0; 74382527734SSukumar Swaminathan } 744fcf3ce44SJohn Forte 7458f23e9faSHans Rosenfeld seg->fc_numblks = 0; 7468f23e9faSHans Rosenfeld seg->fc_total_memsize = 0; 7478f23e9faSHans Rosenfeld seg->fc_low = 0; 748fcf3ce44SJohn Forte 749*a3170057SPaul Winder (void) emlxs_mem_pool_alloc(hba, seg, seg->fc_lo_water); 750fcf3ce44SJohn Forte 7518f23e9faSHans Rosenfeld seg->fc_memflag |= (FC_MEMSEG_PUT_ENABLED|FC_MEMSEG_GET_ENABLED); 752291a2b48SSukumar Swaminathan 7538f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 7548f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 755fcf3ce44SJohn Forte 7568f23e9faSHans Rosenfeld return (seg->fc_numblks); 7578f23e9faSHans Rosenfeld 7588f23e9faSHans Rosenfeld } /* emlxs_mem_pool_create() */ 759fcf3ce44SJohn Forte 760fcf3ce44SJohn Forte 7618f23e9faSHans Rosenfeld extern void 7628f23e9faSHans Rosenfeld emlxs_mem_pool_destroy(emlxs_hba_t *hba, MEMSEG *seg) 7638f23e9faSHans Rosenfeld { 7648f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 7658f23e9faSHans Rosenfeld 7668f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMGET_LOCK); 7678f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMPUT_LOCK); 7688f23e9faSHans Rosenfeld 7698f23e9faSHans Rosenfeld if (seg->fc_memsize == 0) { 7708f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 7718f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 7728f23e9faSHans Rosenfeld return; 7738f23e9faSHans Rosenfeld } 7748f23e9faSHans Rosenfeld 7758f23e9faSHans Rosenfeld /* Leave FC_MEMSEG_PUT_ENABLED set for now */ 7768f23e9faSHans Rosenfeld seg->fc_memflag &= ~FC_MEMSEG_GET_ENABLED; 7778f23e9faSHans Rosenfeld 7788f23e9faSHans Rosenfeld /* Try to free all objects */ 7798f23e9faSHans Rosenfeld emlxs_mem_pool_free(hba, seg, seg->fc_numblks); 7808f23e9faSHans Rosenfeld 7818f23e9faSHans Rosenfeld if (seg->fc_numblks) { 7828f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 7838f23e9faSHans Rosenfeld "mem_pool_destroy: %s leak detected: " 7848f23e9faSHans Rosenfeld "%d objects still allocated.", 7858f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks); 78682527734SSukumar Swaminathan } else { 7878f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 7888f23e9faSHans Rosenfeld "mem_pool_destroy: %s destroyed.", 7898f23e9faSHans Rosenfeld seg->fc_label); 7908f23e9faSHans Rosenfeld 7918f23e9faSHans Rosenfeld /* Clear all */ 7928f23e9faSHans Rosenfeld bzero(seg, sizeof (MEMSEG)); 7938f23e9faSHans Rosenfeld } 7948f23e9faSHans Rosenfeld 7958f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 7968f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 7978f23e9faSHans Rosenfeld 7988f23e9faSHans Rosenfeld return; 7998f23e9faSHans Rosenfeld 8008f23e9faSHans Rosenfeld } /* emlxs_mem_pool_destroy() */ 8018f23e9faSHans Rosenfeld 8028f23e9faSHans Rosenfeld 8038f23e9faSHans Rosenfeld extern void 8048f23e9faSHans Rosenfeld emlxs_mem_pool_clean(emlxs_hba_t *hba, MEMSEG *seg) 8058f23e9faSHans Rosenfeld { 8068f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 8078f23e9faSHans Rosenfeld uint32_t clean_count; 8088f23e9faSHans Rosenfeld uint32_t free_count; 8098f23e9faSHans Rosenfeld uint32_t free_pad; 8108f23e9faSHans Rosenfeld 8118f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMGET_LOCK); 8128f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMPUT_LOCK); 8138f23e9faSHans Rosenfeld 8148f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_DYNAMIC)) { 8158f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 8168f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 8178f23e9faSHans Rosenfeld return; 8188f23e9faSHans Rosenfeld } 8198f23e9faSHans Rosenfeld 8208f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) { 8218f23e9faSHans Rosenfeld goto done; 8228f23e9faSHans Rosenfeld } 8238f23e9faSHans Rosenfeld 8248f23e9faSHans Rosenfeld #ifdef EMLXS_POOL_DEBUG 8258f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 8268f23e9faSHans Rosenfeld "%s clean: n=%d s=%d f=%x l=%d,%d,%d " 8278f23e9faSHans Rosenfeld "f=%d:%d", 8288f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, 8298f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water, 8308f23e9faSHans Rosenfeld seg->fc_hi_water, seg->fc_step, seg->fc_memget_cnt, 8318f23e9faSHans Rosenfeld seg->fc_low); 8328f23e9faSHans Rosenfeld #endif /* EMLXS_POOL_DEBUG */ 8338f23e9faSHans Rosenfeld 8348f23e9faSHans Rosenfeld /* Calculatge current free count */ 8358f23e9faSHans Rosenfeld free_count = (seg->fc_memget_cnt + seg->fc_memput_cnt); 8368f23e9faSHans Rosenfeld 8378f23e9faSHans Rosenfeld /* Reset fc_low value to current free count */ 8388f23e9faSHans Rosenfeld clean_count = seg->fc_low; 8398f23e9faSHans Rosenfeld seg->fc_low = free_count; 8408f23e9faSHans Rosenfeld 8418f23e9faSHans Rosenfeld /* Return if pool is already at lo water mark */ 8428f23e9faSHans Rosenfeld if (seg->fc_numblks <= seg->fc_lo_water) { 8438f23e9faSHans Rosenfeld goto done; 8448f23e9faSHans Rosenfeld } 8458f23e9faSHans Rosenfeld 8468f23e9faSHans Rosenfeld /* Return if there is nothing to clean */ 8478f23e9faSHans Rosenfeld if ((free_count == 0) || 8488f23e9faSHans Rosenfeld (clean_count <= 1)) { 8498f23e9faSHans Rosenfeld goto done; 8508f23e9faSHans Rosenfeld } 8518f23e9faSHans Rosenfeld 8528f23e9faSHans Rosenfeld /* Calculate a 3 percent free pad count (1 being minimum) */ 8538f23e9faSHans Rosenfeld if (seg->fc_numblks > 66) { 8548f23e9faSHans Rosenfeld free_pad = ((seg->fc_numblks * 3)/100); 8558f23e9faSHans Rosenfeld } else { 8568f23e9faSHans Rosenfeld free_pad = 1; 8578f23e9faSHans Rosenfeld } 8588f23e9faSHans Rosenfeld 8598f23e9faSHans Rosenfeld /* Return if fc_low is below pool free pad */ 8608f23e9faSHans Rosenfeld if (clean_count <= free_pad) { 8618f23e9faSHans Rosenfeld goto done; 8628f23e9faSHans Rosenfeld } 8638f23e9faSHans Rosenfeld 8648f23e9faSHans Rosenfeld clean_count -= free_pad; 8658f23e9faSHans Rosenfeld 8668f23e9faSHans Rosenfeld /* clean_count can't exceed minimum pool levels */ 8678f23e9faSHans Rosenfeld if (clean_count > (seg->fc_numblks - seg->fc_lo_water)) { 8688f23e9faSHans Rosenfeld clean_count = (seg->fc_numblks - seg->fc_lo_water); 8698f23e9faSHans Rosenfeld } 8708f23e9faSHans Rosenfeld 8718f23e9faSHans Rosenfeld emlxs_mem_pool_free(hba, seg, clean_count); 8728f23e9faSHans Rosenfeld 8738f23e9faSHans Rosenfeld done: 8748f23e9faSHans Rosenfeld if (seg->fc_last != seg->fc_numblks) { 8758f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 8768f23e9faSHans Rosenfeld "%s update: n=%d->%d s=%d f=%x l=%d,%d,%d " 8778f23e9faSHans Rosenfeld "f=%d:%d", 8788f23e9faSHans Rosenfeld seg->fc_label, seg->fc_last, seg->fc_numblks, 8798f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water, 8808f23e9faSHans Rosenfeld seg->fc_hi_water, seg->fc_step, seg->fc_memget_cnt, 8818f23e9faSHans Rosenfeld seg->fc_low); 8828f23e9faSHans Rosenfeld 8838f23e9faSHans Rosenfeld seg->fc_last = seg->fc_numblks; 8848f23e9faSHans Rosenfeld } 8858f23e9faSHans Rosenfeld 8868f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 8878f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 8888f23e9faSHans Rosenfeld return; 8898f23e9faSHans Rosenfeld 8908f23e9faSHans Rosenfeld } /* emlxs_mem_pool_clean() */ 8918f23e9faSHans Rosenfeld 8928f23e9faSHans Rosenfeld 8938f23e9faSHans Rosenfeld extern void * 8948f23e9faSHans Rosenfeld emlxs_mem_pool_get(emlxs_hba_t *hba, MEMSEG *seg) 8958f23e9faSHans Rosenfeld { 8968f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 8978f23e9faSHans Rosenfeld void *bp = NULL; 8988f23e9faSHans Rosenfeld MATCHMAP *mp; 8998f23e9faSHans Rosenfeld uint32_t free_count; 9008f23e9faSHans Rosenfeld 9018f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMGET_LOCK); 9028f23e9faSHans Rosenfeld 9038f23e9faSHans Rosenfeld /* Check if memory pool is GET enabled */ 9048f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) { 9058f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 9068f23e9faSHans Rosenfeld return (NULL); 9078f23e9faSHans Rosenfeld } 9088f23e9faSHans Rosenfeld 9098f23e9faSHans Rosenfeld /* If no entries on memget list, then check memput list */ 9108f23e9faSHans Rosenfeld if (!seg->fc_memget_ptr) { 91182527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMPUT_LOCK); 91282527734SSukumar Swaminathan if (seg->fc_memput_ptr) { 91382527734SSukumar Swaminathan /* 91482527734SSukumar Swaminathan * Move list from memput to memget 91582527734SSukumar Swaminathan */ 91682527734SSukumar Swaminathan seg->fc_memget_ptr = seg->fc_memput_ptr; 91782527734SSukumar Swaminathan seg->fc_memget_end = seg->fc_memput_end; 91882527734SSukumar Swaminathan seg->fc_memget_cnt = seg->fc_memput_cnt; 91982527734SSukumar Swaminathan seg->fc_memput_ptr = NULL; 92082527734SSukumar Swaminathan seg->fc_memput_end = NULL; 92182527734SSukumar Swaminathan seg->fc_memput_cnt = 0; 922fcf3ce44SJohn Forte } 92382527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 9248f23e9faSHans Rosenfeld } 9258f23e9faSHans Rosenfeld 9268f23e9faSHans Rosenfeld /* If no entries on memget list, then pool is empty */ 9278f23e9faSHans Rosenfeld /* Try to allocate more if pool is dynamic */ 9288f23e9faSHans Rosenfeld if (!seg->fc_memget_ptr && 9298f23e9faSHans Rosenfeld (seg->fc_memflag & FC_MEMSEG_DYNAMIC)) { 9308f23e9faSHans Rosenfeld (void) emlxs_mem_pool_alloc(hba, seg, seg->fc_step); 9318f23e9faSHans Rosenfeld seg->fc_low = 0; 9328f23e9faSHans Rosenfeld } 93382527734SSukumar Swaminathan 9348f23e9faSHans Rosenfeld /* If no entries on memget list, then pool is empty */ 9358f23e9faSHans Rosenfeld if (!seg->fc_memget_ptr) { 93682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_alloc_failed_msg, 93782527734SSukumar Swaminathan "%s empty.", seg->fc_label); 9388f23e9faSHans Rosenfeld 9398f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 9408f23e9faSHans Rosenfeld return (NULL); 9418f23e9faSHans Rosenfeld } 9428f23e9faSHans Rosenfeld 9438f23e9faSHans Rosenfeld /* Remove an entry from the get list */ 9448f23e9faSHans Rosenfeld bp = seg->fc_memget_ptr; 9458f23e9faSHans Rosenfeld 9468f23e9faSHans Rosenfeld if (seg->fc_memget_end == bp) { 9478f23e9faSHans Rosenfeld seg->fc_memget_ptr = NULL; 9488f23e9faSHans Rosenfeld seg->fc_memget_end = NULL; 9498f23e9faSHans Rosenfeld seg->fc_memget_cnt = 0; 9508f23e9faSHans Rosenfeld 9518f23e9faSHans Rosenfeld } else { 9528f23e9faSHans Rosenfeld seg->fc_memget_ptr = *((uint8_t **)bp); 9538f23e9faSHans Rosenfeld seg->fc_memget_cnt--; 9548f23e9faSHans Rosenfeld } 9558f23e9faSHans Rosenfeld 9568f23e9faSHans Rosenfeld /* Initialize buffer */ 9578f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MBUF_DMA)) { 9588f23e9faSHans Rosenfeld bzero(bp, seg->fc_memsize); 9598f23e9faSHans Rosenfeld } else { 9608f23e9faSHans Rosenfeld mp = (MATCHMAP *)bp; 9618f23e9faSHans Rosenfeld mp->fc_mptr = NULL; 9628f23e9faSHans Rosenfeld mp->flag |= MAP_POOL_ALLOCATED; 9638f23e9faSHans Rosenfeld } 9648f23e9faSHans Rosenfeld 9658f23e9faSHans Rosenfeld /* Set fc_low if pool is dynamic */ 9668f23e9faSHans Rosenfeld if (seg->fc_memflag & FC_MEMSEG_DYNAMIC) { 9678f23e9faSHans Rosenfeld free_count = (seg->fc_memget_cnt + seg->fc_memput_cnt); 9688f23e9faSHans Rosenfeld if (free_count < seg->fc_low) { 9698f23e9faSHans Rosenfeld seg->fc_low = free_count; 9708f23e9faSHans Rosenfeld } 971fcf3ce44SJohn Forte } 972fcf3ce44SJohn Forte 97382527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 97482527734SSukumar Swaminathan 97582527734SSukumar Swaminathan return (bp); 976fcf3ce44SJohn Forte 97782527734SSukumar Swaminathan } /* emlxs_mem_pool_get() */ 978fcf3ce44SJohn Forte 979fcf3ce44SJohn Forte 980a9800bebSGarrett D'Amore extern void 981a9800bebSGarrett D'Amore emlxs_mem_pool_put(emlxs_hba_t *hba, MEMSEG *seg, void *bp) 98282527734SSukumar Swaminathan { 983a9800bebSGarrett D'Amore emlxs_port_t *port = &PPORT; 984a9800bebSGarrett D'Amore MATCHMAP *mp; 985fcf3ce44SJohn Forte 98682527734SSukumar Swaminathan /* Free the pool object */ 98782527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMPUT_LOCK); 98882527734SSukumar Swaminathan 9898f23e9faSHans Rosenfeld /* Check if memory pool is PUT enabled */ 9908f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_PUT_ENABLED)) { 99182527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 992a9800bebSGarrett D'Amore return; 993fcf3ce44SJohn Forte } 994291a2b48SSukumar Swaminathan 99582527734SSukumar Swaminathan /* Check if buffer was just freed */ 9968f23e9faSHans Rosenfeld if ((seg->fc_memput_end == bp) || (seg->fc_memget_end == bp)) { 99782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 99882527734SSukumar Swaminathan "%s: Freeing free object: bp=%p", seg->fc_label, bp); 999fcf3ce44SJohn Forte 100082527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 1001a9800bebSGarrett D'Amore return; 1002fcf3ce44SJohn Forte } 1003fcf3ce44SJohn Forte 10048f23e9faSHans Rosenfeld /* Validate DMA buffer */ 100582527734SSukumar Swaminathan if (seg->fc_memflag & FC_MBUF_DMA) { 100682527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 1007291a2b48SSukumar Swaminathan 100882527734SSukumar Swaminathan if (!(mp->flag & MAP_POOL_ALLOCATED) || 100982527734SSukumar Swaminathan (mp->segment != seg)) { 101082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 10118f23e9faSHans Rosenfeld "mem_pool_put: %s invalid: mp=%p " \ 101282527734SSukumar Swaminathan "tag=0x%x flag=%x", seg->fc_label, 101382527734SSukumar Swaminathan mp, mp->tag, mp->flag); 1014291a2b48SSukumar Swaminathan 101582527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 1016fcf3ce44SJohn Forte 101782527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 1018fcf3ce44SJohn Forte 101982527734SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_shutdown_thread, 102082527734SSukumar Swaminathan NULL, NULL); 102182527734SSukumar Swaminathan 1022a9800bebSGarrett D'Amore return; 1023fcf3ce44SJohn Forte } 1024fcf3ce44SJohn Forte } 1025fcf3ce44SJohn Forte 10268f23e9faSHans Rosenfeld /* Release buffer to the end of the memput list */ 102782527734SSukumar Swaminathan if (seg->fc_memput_end == NULL) { 102882527734SSukumar Swaminathan seg->fc_memput_ptr = bp; 102982527734SSukumar Swaminathan seg->fc_memput_cnt = 1; 103082527734SSukumar Swaminathan } else { 1031a9800bebSGarrett D'Amore *((void **)(seg->fc_memput_end)) = bp; 103282527734SSukumar Swaminathan seg->fc_memput_cnt++; 103382527734SSukumar Swaminathan } 103482527734SSukumar Swaminathan seg->fc_memput_end = bp; 1035a9800bebSGarrett D'Amore *((void **)(bp)) = NULL; 103682527734SSukumar Swaminathan 103782527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 1038fcf3ce44SJohn Forte 10398f23e9faSHans Rosenfeld /* This is for late PUT's after an initial */ 10408f23e9faSHans Rosenfeld /* emlxs_mem_pool_destroy call */ 10418f23e9faSHans Rosenfeld if ((seg->fc_memflag & FC_MEMSEG_PUT_ENABLED) && 10428f23e9faSHans Rosenfeld !(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) { 10438f23e9faSHans Rosenfeld emlxs_mem_pool_destroy(hba, seg); 10448f23e9faSHans Rosenfeld } 10458f23e9faSHans Rosenfeld 1046a9800bebSGarrett D'Amore return; 1047fcf3ce44SJohn Forte 104882527734SSukumar Swaminathan } /* emlxs_mem_pool_put() */ 1049fcf3ce44SJohn Forte 105082527734SSukumar Swaminathan 105182527734SSukumar Swaminathan extern MATCHMAP * 105282527734SSukumar Swaminathan emlxs_mem_buf_alloc(emlxs_hba_t *hba, uint32_t size) 1053fcf3ce44SJohn Forte { 1054fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1055fcf3ce44SJohn Forte uint8_t *bp = NULL; 105682527734SSukumar Swaminathan MATCHMAP *mp = NULL; 1057fcf3ce44SJohn Forte MBUF_INFO *buf_info; 1058fcf3ce44SJohn Forte MBUF_INFO bufinfo; 1059fcf3ce44SJohn Forte 1060fcf3ce44SJohn Forte buf_info = &bufinfo; 1061fcf3ce44SJohn Forte 1062fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 1063fcf3ce44SJohn Forte buf_info->size = sizeof (MATCHMAP); 1064fcf3ce44SJohn Forte buf_info->align = sizeof (void *); 1065fcf3ce44SJohn Forte 1066fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 1067fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 1068fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 1069fcf3ce44SJohn Forte "MEM_BUF_ALLOC buffer."); 1070fcf3ce44SJohn Forte 107182527734SSukumar Swaminathan return (NULL); 1072fcf3ce44SJohn Forte } 1073291a2b48SSukumar Swaminathan 107482527734SSukumar Swaminathan mp = (MATCHMAP *)buf_info->virt; 107582527734SSukumar Swaminathan bzero(mp, sizeof (MATCHMAP)); 1076fcf3ce44SJohn Forte 1077fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 107882527734SSukumar Swaminathan buf_info->size = size; 1079*a3170057SPaul Winder buf_info->flags = FC_MBUF_DMA | FC_MBUF_SNGLSG; 1080fcf3ce44SJohn Forte buf_info->align = 32; 1081fcf3ce44SJohn Forte 1082fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 1083fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 1084fcf3ce44SJohn Forte 1085fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 1086fcf3ce44SJohn Forte "MEM_BUF_ALLOC DMA buffer."); 1087fcf3ce44SJohn Forte 108882527734SSukumar Swaminathan /* Free the mp object */ 1089728bdc9bSSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 1090728bdc9bSSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 1091a9800bebSGarrett D'Amore buf_info->virt = (void *)mp; 1092728bdc9bSSukumar Swaminathan emlxs_mem_free(hba, buf_info); 1093728bdc9bSSukumar Swaminathan 1094*a3170057SPaul Winder return (NULL); 1095fcf3ce44SJohn Forte } 1096fcf3ce44SJohn Forte bp = (uint8_t *)buf_info->virt; 10978f23e9faSHans Rosenfeld bzero(bp, buf_info->size); 1098fcf3ce44SJohn Forte 109982527734SSukumar Swaminathan mp->virt = buf_info->virt; 110082527734SSukumar Swaminathan mp->phys = buf_info->phys; 110182527734SSukumar Swaminathan mp->size = buf_info->size; 110282527734SSukumar Swaminathan mp->dma_handle = buf_info->dma_handle; 110382527734SSukumar Swaminathan mp->data_handle = buf_info->data_handle; 110482527734SSukumar Swaminathan mp->tag = MEM_BUF; 110582527734SSukumar Swaminathan mp->flag |= MAP_BUF_ALLOCATED; 1106fcf3ce44SJohn Forte 110782527734SSukumar Swaminathan return (mp); 1108fcf3ce44SJohn Forte 110982527734SSukumar Swaminathan } /* emlxs_mem_buf_alloc() */ 1110fcf3ce44SJohn Forte 1111fcf3ce44SJohn Forte 1112a9800bebSGarrett D'Amore extern void 111382527734SSukumar Swaminathan emlxs_mem_buf_free(emlxs_hba_t *hba, MATCHMAP *mp) 1114fcf3ce44SJohn Forte { 1115fcf3ce44SJohn Forte MBUF_INFO bufinfo; 1116fcf3ce44SJohn Forte MBUF_INFO *buf_info; 1117fcf3ce44SJohn Forte 1118fcf3ce44SJohn Forte buf_info = &bufinfo; 1119fcf3ce44SJohn Forte 112082527734SSukumar Swaminathan if (!(mp->flag & MAP_BUF_ALLOCATED)) { 1121a9800bebSGarrett D'Amore return; 1122fcf3ce44SJohn Forte } 1123fcf3ce44SJohn Forte 1124fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 112582527734SSukumar Swaminathan buf_info->size = mp->size; 112682527734SSukumar Swaminathan buf_info->virt = mp->virt; 112782527734SSukumar Swaminathan buf_info->phys = mp->phys; 112882527734SSukumar Swaminathan buf_info->dma_handle = mp->dma_handle; 112982527734SSukumar Swaminathan buf_info->data_handle = mp->data_handle; 1130fcf3ce44SJohn Forte buf_info->flags = FC_MBUF_DMA; 1131fcf3ce44SJohn Forte emlxs_mem_free(hba, buf_info); 1132fcf3ce44SJohn Forte 1133fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 1134fcf3ce44SJohn Forte buf_info->size = sizeof (MATCHMAP); 1135a9800bebSGarrett D'Amore buf_info->virt = (void *)mp; 1136fcf3ce44SJohn Forte emlxs_mem_free(hba, buf_info); 1137fcf3ce44SJohn Forte 1138a9800bebSGarrett D'Amore return; 1139fcf3ce44SJohn Forte 114082527734SSukumar Swaminathan } /* emlxs_mem_buf_free() */ 1141fcf3ce44SJohn Forte 1142fcf3ce44SJohn Forte 1143a9800bebSGarrett D'Amore extern void * 11448f23e9faSHans Rosenfeld emlxs_mem_get(emlxs_hba_t *hba, uint32_t seg_id) 1145fcf3ce44SJohn Forte { 1146a9800bebSGarrett D'Amore emlxs_port_t *port = &PPORT; 1147a9800bebSGarrett D'Amore void *bp; 1148a9800bebSGarrett D'Amore MAILBOXQ *mbq; 1149a9800bebSGarrett D'Amore IOCBQ *iocbq; 1150a9800bebSGarrett D'Amore NODELIST *node; 1151a9800bebSGarrett D'Amore MEMSEG *seg; 1152fcf3ce44SJohn Forte 115382527734SSukumar Swaminathan if (seg_id >= FC_MAX_SEG) { 1154291a2b48SSukumar Swaminathan 115582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 11568f23e9faSHans Rosenfeld "mem_get: Invalid segment id = %d", 115782527734SSukumar Swaminathan seg_id); 1158fcf3ce44SJohn Forte 1159fcf3ce44SJohn Forte return (NULL); 1160fcf3ce44SJohn Forte } 116182527734SSukumar Swaminathan seg = &hba->memseg[seg_id]; 1162fcf3ce44SJohn Forte 116382527734SSukumar Swaminathan /* Alloc a buffer from the pool */ 11648f23e9faSHans Rosenfeld bp = emlxs_mem_pool_get(hba, seg); 1165fcf3ce44SJohn Forte 116682527734SSukumar Swaminathan if (bp) { 116782527734SSukumar Swaminathan switch (seg_id) { 1168fcf3ce44SJohn Forte case MEM_MBOX: 1169291a2b48SSukumar Swaminathan mbq = (MAILBOXQ *)bp; 1170fcf3ce44SJohn Forte mbq->flag |= MBQ_POOL_ALLOCATED; 1171fcf3ce44SJohn Forte break; 1172fcf3ce44SJohn Forte 1173fcf3ce44SJohn Forte case MEM_IOCB: 1174291a2b48SSukumar Swaminathan iocbq = (IOCBQ *)bp; 1175fcf3ce44SJohn Forte iocbq->flag |= IOCB_POOL_ALLOCATED; 1176fcf3ce44SJohn Forte break; 1177fcf3ce44SJohn Forte 1178fcf3ce44SJohn Forte case MEM_NLP: 1179291a2b48SSukumar Swaminathan node = (NODELIST *)bp; 1180fcf3ce44SJohn Forte node->flag |= NODE_POOL_ALLOCATED; 1181fcf3ce44SJohn Forte break; 1182fcf3ce44SJohn Forte } 1183fcf3ce44SJohn Forte } 1184fcf3ce44SJohn Forte 1185fcf3ce44SJohn Forte return (bp); 1186fcf3ce44SJohn Forte 118782527734SSukumar Swaminathan } /* emlxs_mem_get() */ 1188fcf3ce44SJohn Forte 1189fcf3ce44SJohn Forte 1190a9800bebSGarrett D'Amore extern void 1191a9800bebSGarrett D'Amore emlxs_mem_put(emlxs_hba_t *hba, uint32_t seg_id, void *bp) 1192fcf3ce44SJohn Forte { 1193a9800bebSGarrett D'Amore emlxs_port_t *port = &PPORT; 1194a9800bebSGarrett D'Amore MAILBOXQ *mbq; 1195a9800bebSGarrett D'Amore IOCBQ *iocbq; 1196a9800bebSGarrett D'Amore NODELIST *node; 1197a9800bebSGarrett D'Amore MEMSEG *seg; 1198a9800bebSGarrett D'Amore MATCHMAP *mp; 1199fcf3ce44SJohn Forte 120082527734SSukumar Swaminathan if (seg_id >= FC_MAX_SEG) { 120182527734SSukumar Swaminathan 120282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 12038f23e9faSHans Rosenfeld "mem_put: Invalid segment id = %d: bp=%p", 120482527734SSukumar Swaminathan seg_id, bp); 1205291a2b48SSukumar Swaminathan 1206a9800bebSGarrett D'Amore return; 1207fcf3ce44SJohn Forte } 120882527734SSukumar Swaminathan seg = &hba->memseg[seg_id]; 1209291a2b48SSukumar Swaminathan 121082527734SSukumar Swaminathan /* Verify buffer */ 121182527734SSukumar Swaminathan switch (seg_id) { 1212fcf3ce44SJohn Forte case MEM_MBOX: 1213291a2b48SSukumar Swaminathan mbq = (MAILBOXQ *)bp; 1214fcf3ce44SJohn Forte 1215fcf3ce44SJohn Forte if (!(mbq->flag & MBQ_POOL_ALLOCATED)) { 1216a9800bebSGarrett D'Amore return; 1217fcf3ce44SJohn Forte } 1218fcf3ce44SJohn Forte break; 1219fcf3ce44SJohn Forte 1220fcf3ce44SJohn Forte case MEM_IOCB: 1221291a2b48SSukumar Swaminathan iocbq = (IOCBQ *)bp; 1222fcf3ce44SJohn Forte 1223fcf3ce44SJohn Forte if (!(iocbq->flag & IOCB_POOL_ALLOCATED)) { 1224a9800bebSGarrett D'Amore return; 1225fcf3ce44SJohn Forte } 1226291a2b48SSukumar Swaminathan 1227291a2b48SSukumar Swaminathan /* Any IOCBQ with a packet attached did not come */ 1228291a2b48SSukumar Swaminathan /* from our pool */ 1229fcf3ce44SJohn Forte if (iocbq->sbp) { 1230a9800bebSGarrett D'Amore return; 1231fcf3ce44SJohn Forte } 1232fcf3ce44SJohn Forte break; 1233fcf3ce44SJohn Forte 1234fcf3ce44SJohn Forte case MEM_NLP: 1235291a2b48SSukumar Swaminathan node = (NODELIST *)bp; 1236fcf3ce44SJohn Forte 1237fcf3ce44SJohn Forte if (!(node->flag & NODE_POOL_ALLOCATED)) { 1238a9800bebSGarrett D'Amore return; 1239fcf3ce44SJohn Forte } 1240fcf3ce44SJohn Forte break; 1241fcf3ce44SJohn Forte 1242fcf3ce44SJohn Forte default: 124382527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 1244fcf3ce44SJohn Forte 124582527734SSukumar Swaminathan if (mp->flag & MAP_BUF_ALLOCATED) { 1246a9800bebSGarrett D'Amore emlxs_mem_buf_free(hba, mp); 1247a9800bebSGarrett D'Amore return; 1248fcf3ce44SJohn Forte } 1249291a2b48SSukumar Swaminathan 125082527734SSukumar Swaminathan if (mp->flag & MAP_TABLE_ALLOCATED) { 1251a9800bebSGarrett D'Amore return; 1252fcf3ce44SJohn Forte } 1253291a2b48SSukumar Swaminathan 125482527734SSukumar Swaminathan if (!(mp->flag & MAP_POOL_ALLOCATED)) { 1255a9800bebSGarrett D'Amore return; 1256fcf3ce44SJohn Forte } 1257fcf3ce44SJohn Forte break; 1258fcf3ce44SJohn Forte } 1259fcf3ce44SJohn Forte 126082527734SSukumar Swaminathan /* Free a buffer to the pool */ 1261a9800bebSGarrett D'Amore emlxs_mem_pool_put(hba, seg, bp); 1262291a2b48SSukumar Swaminathan 1263a9800bebSGarrett D'Amore return; 1264fcf3ce44SJohn Forte 126582527734SSukumar Swaminathan } /* emlxs_mem_put() */ 1266fcf3ce44SJohn Forte 1267fcf3ce44SJohn Forte 1268fcf3ce44SJohn Forte /* 1269fcf3ce44SJohn Forte * Look up the virtual address given a mapped address 1270fcf3ce44SJohn Forte */ 127182527734SSukumar Swaminathan /* SLI3 */ 1272fcf3ce44SJohn Forte extern MATCHMAP * 1273fcf3ce44SJohn Forte emlxs_mem_get_vaddr(emlxs_hba_t *hba, RING *rp, uint64_t mapbp) 1274fcf3ce44SJohn Forte { 1275fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1276fcf3ce44SJohn Forte MATCHMAP *prev; 1277fcf3ce44SJohn Forte MATCHMAP *mp; 1278fcf3ce44SJohn Forte 127982527734SSukumar Swaminathan if (rp->ringno == hba->channel_els) { 1280291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff; 1281fcf3ce44SJohn Forte prev = 0; 1282fcf3ce44SJohn Forte 1283fcf3ce44SJohn Forte while (mp) { 1284fcf3ce44SJohn Forte if (mp->phys == mapbp) { 1285fcf3ce44SJohn Forte if (prev == 0) { 1286fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr; 1287fcf3ce44SJohn Forte } else { 1288fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr; 1289fcf3ce44SJohn Forte } 1290fcf3ce44SJohn Forte 1291a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) { 1292a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev; 1293fcf3ce44SJohn Forte } 1294291a2b48SSukumar Swaminathan 1295a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1296fcf3ce44SJohn Forte 129782527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 1298fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 1299fcf3ce44SJohn Forte 1300fcf3ce44SJohn Forte HBASTATS.ElsUbPosted--; 1301fcf3ce44SJohn Forte 1302fcf3ce44SJohn Forte return (mp); 1303fcf3ce44SJohn Forte } 1304291a2b48SSukumar Swaminathan 1305fcf3ce44SJohn Forte prev = mp; 1306291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr; 1307fcf3ce44SJohn Forte } 1308fcf3ce44SJohn Forte 1309fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1310fcf3ce44SJohn Forte "ELS Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1311fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1312fcf3ce44SJohn Forte 131382527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ct) { 1314fcf3ce44SJohn Forte 1315291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff; 1316fcf3ce44SJohn Forte prev = 0; 1317fcf3ce44SJohn Forte 1318fcf3ce44SJohn Forte while (mp) { 1319fcf3ce44SJohn Forte if (mp->phys == mapbp) { 1320fcf3ce44SJohn Forte if (prev == 0) { 1321fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr; 1322fcf3ce44SJohn Forte } else { 1323fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr; 1324fcf3ce44SJohn Forte } 1325fcf3ce44SJohn Forte 1326a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) { 1327a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev; 1328fcf3ce44SJohn Forte } 1329291a2b48SSukumar Swaminathan 1330a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1331fcf3ce44SJohn Forte 133282527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 1333fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 1334fcf3ce44SJohn Forte 1335fcf3ce44SJohn Forte HBASTATS.CtUbPosted--; 1336fcf3ce44SJohn Forte 1337fcf3ce44SJohn Forte return (mp); 1338fcf3ce44SJohn Forte } 1339291a2b48SSukumar Swaminathan 1340fcf3ce44SJohn Forte prev = mp; 1341291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr; 1342fcf3ce44SJohn Forte } 1343fcf3ce44SJohn Forte 1344fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1345fcf3ce44SJohn Forte "CT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1346fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1347fcf3ce44SJohn Forte 134882527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ip) { 1349fcf3ce44SJohn Forte 1350291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff; 1351fcf3ce44SJohn Forte prev = 0; 1352fcf3ce44SJohn Forte 1353fcf3ce44SJohn Forte while (mp) { 1354fcf3ce44SJohn Forte if (mp->phys == mapbp) { 1355fcf3ce44SJohn Forte if (prev == 0) { 1356fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr; 1357fcf3ce44SJohn Forte } else { 1358fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr; 1359fcf3ce44SJohn Forte } 1360fcf3ce44SJohn Forte 1361a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) { 1362a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev; 1363fcf3ce44SJohn Forte } 1364291a2b48SSukumar Swaminathan 1365a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1366fcf3ce44SJohn Forte 136782527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 1368fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 1369fcf3ce44SJohn Forte 1370fcf3ce44SJohn Forte HBASTATS.IpUbPosted--; 1371fcf3ce44SJohn Forte 1372fcf3ce44SJohn Forte return (mp); 1373fcf3ce44SJohn Forte } 1374291a2b48SSukumar Swaminathan 1375fcf3ce44SJohn Forte prev = mp; 1376291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr; 1377fcf3ce44SJohn Forte } 1378fcf3ce44SJohn Forte 1379fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1380fcf3ce44SJohn Forte "IP Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1381fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1382fcf3ce44SJohn Forte 1383fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 138482527734SSukumar Swaminathan } else if (rp->ringno == hba->CHANNEL_FCT) { 1385291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff; 1386fcf3ce44SJohn Forte prev = 0; 1387fcf3ce44SJohn Forte 1388fcf3ce44SJohn Forte while (mp) { 1389fcf3ce44SJohn Forte if (mp->phys == mapbp) { 1390fcf3ce44SJohn Forte if (prev == 0) { 1391fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr; 1392fcf3ce44SJohn Forte } else { 1393fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr; 1394fcf3ce44SJohn Forte } 1395fcf3ce44SJohn Forte 1396a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) { 1397a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev; 1398fcf3ce44SJohn Forte } 1399291a2b48SSukumar Swaminathan 1400a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1401fcf3ce44SJohn Forte 140282527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 1403fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 1404fcf3ce44SJohn Forte 1405fcf3ce44SJohn Forte HBASTATS.FctUbPosted--; 1406fcf3ce44SJohn Forte 1407fcf3ce44SJohn Forte return (mp); 1408fcf3ce44SJohn Forte } 1409291a2b48SSukumar Swaminathan 1410fcf3ce44SJohn Forte prev = mp; 1411291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr; 1412fcf3ce44SJohn Forte } 1413fcf3ce44SJohn Forte 1414fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1415fcf3ce44SJohn Forte "FCT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1416fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1417fcf3ce44SJohn Forte 1418291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 1419fcf3ce44SJohn Forte } 1420fcf3ce44SJohn Forte 1421fcf3ce44SJohn Forte return (0); 1422fcf3ce44SJohn Forte 142382527734SSukumar Swaminathan } /* emlxs_mem_get_vaddr() */ 1424fcf3ce44SJohn Forte 1425fcf3ce44SJohn Forte 1426fcf3ce44SJohn Forte /* 1427291a2b48SSukumar Swaminathan * Given a virtual address bp, generate the physical mapped address and 1428291a2b48SSukumar Swaminathan * place it where addr points to. Save the address pair for lookup later. 1429fcf3ce44SJohn Forte */ 143082527734SSukumar Swaminathan /* SLI3 */ 1431fcf3ce44SJohn Forte extern void 1432291a2b48SSukumar Swaminathan emlxs_mem_map_vaddr(emlxs_hba_t *hba, RING *rp, MATCHMAP *mp, 1433291a2b48SSukumar Swaminathan uint32_t *haddr, uint32_t *laddr) 1434fcf3ce44SJohn Forte { 143582527734SSukumar Swaminathan if (rp->ringno == hba->channel_els) { 1436fcf3ce44SJohn Forte /* 1437291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it 1438291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list. 1439291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list. 1440fcf3ce44SJohn Forte */ 1441a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1442fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1443a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp; 1444a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1445fcf3ce44SJohn Forte } else { 1446291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1447a9800bebSGarrett D'Amore (void *)mp; 1448a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1449fcf3ce44SJohn Forte } 1450fcf3ce44SJohn Forte 1451fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1452291a2b48SSukumar Swaminathan 1453291a2b48SSukumar Swaminathan /* return mapped address */ 145482527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 1455fcf3ce44SJohn Forte /* return mapped address */ 145682527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1457fcf3ce44SJohn Forte } else { 1458fcf3ce44SJohn Forte /* return mapped address */ 145982527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1460fcf3ce44SJohn Forte } 1461fcf3ce44SJohn Forte 1462fcf3ce44SJohn Forte HBASTATS.ElsUbPosted++; 1463fcf3ce44SJohn Forte 146482527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ct) { 1465fcf3ce44SJohn Forte /* 1466291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it 1467291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list. 1468291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list. 1469fcf3ce44SJohn Forte */ 1470a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1471fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1472a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp; 1473a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1474fcf3ce44SJohn Forte } else { 1475291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1476a9800bebSGarrett D'Amore (void *)mp; 1477a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1478fcf3ce44SJohn Forte } 1479fcf3ce44SJohn Forte 1480fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1481fcf3ce44SJohn Forte /* return mapped address */ 148282527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 1483291a2b48SSukumar Swaminathan /* return mapped address */ 148482527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1485fcf3ce44SJohn Forte } else { 1486fcf3ce44SJohn Forte /* return mapped address */ 148782527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1488fcf3ce44SJohn Forte } 1489fcf3ce44SJohn Forte 1490fcf3ce44SJohn Forte HBASTATS.CtUbPosted++; 1491fcf3ce44SJohn Forte 1492fcf3ce44SJohn Forte 149382527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ip) { 1494fcf3ce44SJohn Forte /* 1495291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it 1496291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list. 1497291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list. 1498fcf3ce44SJohn Forte */ 1499a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1500fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1501a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp; 1502a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1503fcf3ce44SJohn Forte } else { 1504291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1505a9800bebSGarrett D'Amore (void *)mp; 1506a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1507fcf3ce44SJohn Forte } 1508fcf3ce44SJohn Forte 1509fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1510fcf3ce44SJohn Forte /* return mapped address */ 151182527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 151282527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1513fcf3ce44SJohn Forte } else { 151482527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1515fcf3ce44SJohn Forte } 1516fcf3ce44SJohn Forte 1517fcf3ce44SJohn Forte HBASTATS.IpUbPosted++; 1518fcf3ce44SJohn Forte 1519fcf3ce44SJohn Forte 1520fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 152182527734SSukumar Swaminathan } else if (rp->ringno == hba->CHANNEL_FCT) { 1522fcf3ce44SJohn Forte /* 1523291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it 1524291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list. 1525291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list. 1526fcf3ce44SJohn Forte */ 1527a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1528fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1529a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp; 1530a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1531fcf3ce44SJohn Forte } else { 1532291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1533a9800bebSGarrett D'Amore (void *)mp; 1534a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1535fcf3ce44SJohn Forte } 1536fcf3ce44SJohn Forte 1537fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1538fcf3ce44SJohn Forte /* return mapped address */ 153982527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 1540291a2b48SSukumar Swaminathan /* return mapped address */ 154182527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1542fcf3ce44SJohn Forte } else { 1543fcf3ce44SJohn Forte /* return mapped address */ 154482527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1545fcf3ce44SJohn Forte } 1546fcf3ce44SJohn Forte 1547fcf3ce44SJohn Forte HBASTATS.FctUbPosted++; 154882527734SSukumar Swaminathan 1549291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 1550fcf3ce44SJohn Forte } 155182527734SSukumar Swaminathan } /* emlxs_mem_map_vaddr() */ 1552fcf3ce44SJohn Forte 1553fcf3ce44SJohn Forte 155482527734SSukumar Swaminathan /* SLI3 */ 1555291a2b48SSukumar Swaminathan uint32_t 1556fcf3ce44SJohn Forte emlxs_hbq_alloc(emlxs_hba_t *hba, uint32_t hbq_id) 1557fcf3ce44SJohn Forte { 1558fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1559fcf3ce44SJohn Forte HBQ_INIT_t *hbq; 1560fcf3ce44SJohn Forte MBUF_INFO *buf_info; 1561fcf3ce44SJohn Forte MBUF_INFO bufinfo; 1562fcf3ce44SJohn Forte 156382527734SSukumar Swaminathan hbq = &hba->sli.sli3.hbq_table[hbq_id]; 1564fcf3ce44SJohn Forte 1565fcf3ce44SJohn Forte if (hbq->HBQ_host_buf.virt == 0) { 1566fcf3ce44SJohn Forte buf_info = &bufinfo; 1567fcf3ce44SJohn Forte 1568fcf3ce44SJohn Forte /* Get the system's page size in a DDI-compliant way. */ 1569fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 1570fcf3ce44SJohn Forte buf_info->size = hbq->HBQ_numEntries * sizeof (HBQE_t); 1571fcf3ce44SJohn Forte buf_info->flags = FC_MBUF_DMA; 1572fcf3ce44SJohn Forte buf_info->align = 4096; 1573fcf3ce44SJohn Forte 1574fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 1575fcf3ce44SJohn Forte 1576fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 1577fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg, 1578fcf3ce44SJohn Forte "Unable to alloc HBQ."); 1579fcf3ce44SJohn Forte return (ENOMEM); 1580fcf3ce44SJohn Forte } 1581291a2b48SSukumar Swaminathan 1582a9800bebSGarrett D'Amore hbq->HBQ_host_buf.virt = buf_info->virt; 1583fcf3ce44SJohn Forte hbq->HBQ_host_buf.phys = buf_info->phys; 1584fcf3ce44SJohn Forte hbq->HBQ_host_buf.data_handle = buf_info->data_handle; 1585fcf3ce44SJohn Forte hbq->HBQ_host_buf.dma_handle = buf_info->dma_handle; 1586fcf3ce44SJohn Forte hbq->HBQ_host_buf.size = buf_info->size; 1587fcf3ce44SJohn Forte hbq->HBQ_host_buf.tag = hbq_id; 1588fcf3ce44SJohn Forte 1589fcf3ce44SJohn Forte bzero((char *)hbq->HBQ_host_buf.virt, buf_info->size); 1590fcf3ce44SJohn Forte } 1591fcf3ce44SJohn Forte 1592fcf3ce44SJohn Forte return (0); 1593fcf3ce44SJohn Forte 159482527734SSukumar Swaminathan } /* emlxs_hbq_alloc() */ 1595