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 */ 74fcf3ce44SJohn Forte for (i = 0; i < FC_MAX_SEG; i++) { 7582527734SSukumar Swaminathan seg = &hba->memseg[i]; 76fcf3ce44SJohn Forte 77fcf3ce44SJohn Forte switch (i) { 78fcf3ce44SJohn Forte 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; 86fcf3ce44SJohn Forte break; 8782527734SSukumar Swaminathan 88fcf3ce44SJohn Forte 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; 96fcf3ce44SJohn Forte break; 9782527734SSukumar Swaminathan 98fcf3ce44SJohn Forte 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; 106fcf3ce44SJohn Forte break; 10782527734SSukumar Swaminathan 108fcf3ce44SJohn Forte 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; 121fcf3ce44SJohn Forte break; 12282527734SSukumar Swaminathan 123fcf3ce44SJohn Forte 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; 134fcf3ce44SJohn Forte break; 13582527734SSukumar Swaminathan 136fcf3ce44SJohn Forte case MEM_IPBUF: 13782527734SSukumar Swaminathan /* These are the unsolicited IP buffers. */ 13882527734SSukumar Swaminathan if (cfg[CFG_NETWORK_ON].current == 0) { 13982527734SSukumar Swaminathan continue; 140fcf3ce44SJohn Forte } 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; 15282527734SSukumar Swaminathan 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; 16582527734SSukumar Swaminathan 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 } 20882527734SSukumar Swaminathan 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 */ 22082527734SSukumar Swaminathan 22182527734SSukumar Swaminathan default: 22282527734SSukumar Swaminathan continue; 22382527734SSukumar Swaminathan } 22482527734SSukumar Swaminathan 22582527734SSukumar Swaminathan if (seg->fc_memsize == 0) { 22682527734SSukumar Swaminathan continue; 22782527734SSukumar Swaminathan } 22882527734SSukumar Swaminathan 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 23882527734SSukumar Swaminathan goto failed; 23982527734SSukumar Swaminathan } 2408f23e9faSHans Rosenfeld } 241fcf3ce44SJohn Forte 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 2628f23e9faSHans Rosenfeld goto failed; 2638f23e9faSHans Rosenfeld } 2648f23e9faSHans Rosenfeld hba->sli.sli3.bpl_table = buf_info->virt; 2658f23e9faSHans Rosenfeld 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 274fcf3ce44SJohn Forte return (1); 275fcf3ce44SJohn Forte 27682527734SSukumar Swaminathan failed: 277fcf3ce44SJohn Forte 27882527734SSukumar Swaminathan (void) emlxs_mem_free_buffer(hba); 27982527734SSukumar Swaminathan return (0); 28082527734SSukumar Swaminathan 28182527734SSukumar Swaminathan } /* emlxs_mem_alloc_buffer() */ 282fcf3ce44SJohn Forte 283fcf3ce44SJohn Forte 284fcf3ce44SJohn Forte /* 285fcf3ce44SJohn Forte * emlxs_mem_free_buffer 286fcf3ce44SJohn Forte * 287fcf3ce44SJohn Forte * This routine will free iocb/data buffer space 288fcf3ce44SJohn Forte * and TGTM resource. 289fcf3ce44SJohn Forte */ 290fcf3ce44SJohn Forte extern int 291fcf3ce44SJohn Forte emlxs_mem_free_buffer(emlxs_hba_t *hba) 292fcf3ce44SJohn Forte { 2938f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 294fcf3ce44SJohn Forte emlxs_port_t *vport; 295fcf3ce44SJohn Forte int32_t j; 29682527734SSukumar Swaminathan MATCHMAP *mp; 29782527734SSukumar Swaminathan CHANNEL *cp; 298fcf3ce44SJohn Forte RING *rp; 299fcf3ce44SJohn Forte MBUF_INFO *buf_info; 300fcf3ce44SJohn Forte MBUF_INFO bufinfo; 3018f23e9faSHans Rosenfeld MATCHMAP **bpl_table; 302fcf3ce44SJohn Forte 303fcf3ce44SJohn Forte buf_info = &bufinfo; 304fcf3ce44SJohn Forte 30582527734SSukumar Swaminathan for (j = 0; j < hba->chan_count; j++) { 30682527734SSukumar Swaminathan cp = &hba->chan[j]; 307fcf3ce44SJohn Forte 308fcf3ce44SJohn Forte /* Flush the ring */ 30982527734SSukumar Swaminathan (void) emlxs_tx_channel_flush(hba, cp, 0); 31082527734SSukumar Swaminathan } 31182527734SSukumar Swaminathan 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 317fcf3ce44SJohn Forte while (rp->fc_mpoff) { 318fcf3ce44SJohn Forte uint64_t addr; 319fcf3ce44SJohn Forte 320fcf3ce44SJohn Forte addr = 0; 32182527734SSukumar Swaminathan mp = (MATCHMAP *)(rp->fc_mpoff); 322fcf3ce44SJohn Forte 32382527734SSukumar Swaminathan if ((j == hba->channel_els) || 32482527734SSukumar Swaminathan (j == hba->channel_ct) || 325fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 32682527734SSukumar Swaminathan (j == hba->CHANNEL_FCT) || 327fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 32882527734SSukumar Swaminathan (j == hba->channel_ip)) { 32982527734SSukumar Swaminathan addr = mp->phys; 330fcf3ce44SJohn Forte } 331291a2b48SSukumar Swaminathan 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); 342fcf3ce44SJohn Forte } 343fcf3ce44SJohn Forte #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); 347fcf3ce44SJohn Forte } 348fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 349fcf3ce44SJohn Forte 350fcf3ce44SJohn Forte } 351fcf3ce44SJohn Forte } 352fcf3ce44SJohn Forte } 35382527734SSukumar Swaminathan } 354fcf3ce44SJohn Forte 355fcf3ce44SJohn Forte if (hba->flag & FC_HBQ_ENABLED) { 356fcf3ce44SJohn Forte emlxs_hbq_free_all(hba, EMLXS_ELS_HBQ_ID); 357fcf3ce44SJohn Forte emlxs_hbq_free_all(hba, EMLXS_IP_HBQ_ID); 358fcf3ce44SJohn Forte emlxs_hbq_free_all(hba, EMLXS_CT_HBQ_ID); 35982527734SSukumar Swaminathan 3608f23e9faSHans Rosenfeld if (port->flag & EMLXS_TGT_ENABLED) { 361fcf3ce44SJohn Forte emlxs_hbq_free_all(hba, EMLXS_FCT_HBQ_ID); 362fcf3ce44SJohn Forte } 363fcf3ce44SJohn Forte } 364fcf3ce44SJohn Forte 365fcf3ce44SJohn Forte /* Free the nodes */ 366fcf3ce44SJohn Forte for (j = 0; j < MAX_VPORTS; j++) { 367fcf3ce44SJohn Forte vport = &VPORT(j); 368fcf3ce44SJohn Forte if (vport->node_count) { 369fcf3ce44SJohn Forte emlxs_node_destroy_all(vport); 370fcf3ce44SJohn Forte } 371fcf3ce44SJohn Forte } 372fcf3ce44SJohn Forte 37382527734SSukumar Swaminathan /* Make sure the mailbox queue is empty */ 37482527734SSukumar Swaminathan emlxs_mb_flush(hba); 37582527734SSukumar Swaminathan 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; 380fcf3ce44SJohn Forte emlxs_mem_free(hba, buf_info); 38182527734SSukumar Swaminathan hba->fc_table = NULL; 382fcf3ce44SJohn Forte } 38382527734SSukumar Swaminathan 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); 391fcf3ce44SJohn Forte } 392291a2b48SSukumar Swaminathan 3938f23e9faSHans Rosenfeld bzero(buf_info, sizeof (MBUF_INFO)); 3948f23e9faSHans Rosenfeld buf_info->size = hba->max_iotag * sizeof (MATCHMAP *); 3958f23e9faSHans Rosenfeld buf_info->virt = hba->sli.sli3.bpl_table; 3968f23e9faSHans Rosenfeld emlxs_mem_free(hba, buf_info); 3978f23e9faSHans Rosenfeld hba->sli.sli3.bpl_table = NULL; 398fcf3ce44SJohn Forte } 399fcf3ce44SJohn Forte 400fcf3ce44SJohn Forte /* Free the memory segments */ 401fcf3ce44SJohn Forte for (j = 0; j < FC_MAX_SEG; j++) { 4028f23e9faSHans Rosenfeld emlxs_mem_pool_destroy(hba, &hba->memseg[j]); 403fcf3ce44SJohn Forte } 404fcf3ce44SJohn Forte 405fcf3ce44SJohn Forte return (0); 406fcf3ce44SJohn Forte 407fcf3ce44SJohn Forte } /* 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) 413fcf3ce44SJohn Forte { 414fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 415fcf3ce44SJohn Forte 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; 4218f23e9faSHans Rosenfeld 4228f23e9faSHans Rosenfeld if (seg->fc_memsize == 0) { 4238f23e9faSHans Rosenfeld return (0); 4248f23e9faSHans Rosenfeld } 4258f23e9faSHans Rosenfeld 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 } 4338f23e9faSHans Rosenfeld 4348f23e9faSHans Rosenfeld if (count > (seg->fc_hi_water - seg->fc_numblks)) { 4358f23e9faSHans Rosenfeld count = (seg->fc_hi_water - seg->fc_numblks); 4368f23e9faSHans Rosenfeld } 43782527734SSukumar Swaminathan 43882527734SSukumar Swaminathan buf_info = &local_buf_info; 4398f23e9faSHans Rosenfeld fc_numblks = seg->fc_numblks; 44082527734SSukumar Swaminathan 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 } 45182527734SSukumar Swaminathan 45282527734SSukumar Swaminathan if (!(seg->fc_memflag & FC_MBUF_DMA)) { 45382527734SSukumar Swaminathan goto vmem_pool; 45482527734SSukumar Swaminathan } 45582527734SSukumar Swaminathan 45682527734SSukumar Swaminathan /* dma_pool */ 45782527734SSukumar Swaminathan 4588f23e9faSHans Rosenfeld for (i = 0; i < count; i++) { 45982527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 46082527734SSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 46182527734SSukumar Swaminathan buf_info->align = sizeof (void *); 46282527734SSukumar Swaminathan 46382527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 46482527734SSukumar Swaminathan if (buf_info->virt == NULL) { 46582527734SSukumar Swaminathan 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); 46882527734SSukumar Swaminathan 4698f23e9faSHans Rosenfeld goto done; 47082527734SSukumar Swaminathan } 47182527734SSukumar Swaminathan 47282527734SSukumar Swaminathan mp = (MATCHMAP *)buf_info->virt; 47382527734SSukumar Swaminathan bzero(mp, sizeof (MATCHMAP)); 47482527734SSukumar Swaminathan 47582527734SSukumar Swaminathan 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; 47982527734SSukumar Swaminathan 48082527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 48182527734SSukumar Swaminathan if (buf_info->virt == NULL) { 48282527734SSukumar Swaminathan 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); 48582527734SSukumar Swaminathan 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; 49382527734SSukumar Swaminathan } 49482527734SSukumar Swaminathan 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++; 53082527734SSukumar Swaminathan } 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)); 53582527734SSukumar Swaminathan } 53682527734SSukumar Swaminathan 5378f23e9faSHans Rosenfeld goto done; 53882527734SSukumar Swaminathan 53982527734SSukumar Swaminathan vmem_pool: 54082527734SSukumar Swaminathan 5418f23e9faSHans Rosenfeld for (i = 0; i < count; i++) { 5428f23e9faSHans Rosenfeld bzero(buf_info, sizeof (MBUF_INFO)); 5438f23e9faSHans Rosenfeld buf_info->size = seg->fc_memsize; 54482527734SSukumar Swaminathan 5458f23e9faSHans Rosenfeld (void) emlxs_mem_alloc(hba, buf_info); 5468f23e9faSHans Rosenfeld if (buf_info->virt == NULL) { 54782527734SSukumar Swaminathan 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); 55082527734SSukumar Swaminathan 5518f23e9faSHans Rosenfeld goto done; 55282527734SSukumar Swaminathan } 5538f23e9faSHans Rosenfeld bp = (uint8_t *)buf_info->virt; 55482527734SSukumar Swaminathan 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; 56482527734SSukumar Swaminathan 5658f23e9faSHans Rosenfeld seg->fc_numblks++; 5668f23e9faSHans Rosenfeld seg->fc_total_memsize += seg->fc_memsize; 56782527734SSukumar Swaminathan } 56882527734SSukumar Swaminathan 5698f23e9faSHans Rosenfeld done: 57082527734SSukumar Swaminathan 5718f23e9faSHans Rosenfeld return ((seg->fc_numblks - fc_numblks)); 57282527734SSukumar Swaminathan 57382527734SSukumar Swaminathan } /* emlxs_mem_pool_alloc() */ 57482527734SSukumar Swaminathan 57582527734SSukumar Swaminathan 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; 58582527734SSukumar Swaminathan 5868f23e9faSHans Rosenfeld if ((seg->fc_memsize == 0) || 5878f23e9faSHans Rosenfeld (seg->fc_numblks == 0) || 5888f23e9faSHans Rosenfeld (count == 0)) { 58982527734SSukumar Swaminathan return; 59082527734SSukumar Swaminathan } 59182527734SSukumar Swaminathan 5928f23e9faSHans Rosenfeld /* Check max count */ 5938f23e9faSHans Rosenfeld if (count > seg->fc_numblks) { 5948f23e9faSHans Rosenfeld count = seg->fc_numblks; 5958f23e9faSHans Rosenfeld } 5968f23e9faSHans Rosenfeld 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; 6078f23e9faSHans Rosenfeld 6088f23e9faSHans Rosenfeld seg->fc_memput_ptr = NULL; 6098f23e9faSHans Rosenfeld seg->fc_memput_end = NULL; 6108f23e9faSHans Rosenfeld seg->fc_memput_cnt = 0; 6118f23e9faSHans Rosenfeld } 6128f23e9faSHans Rosenfeld 61382527734SSukumar Swaminathan buf_info = &local_buf_info; 61482527734SSukumar Swaminathan 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); 62482527734SSukumar Swaminathan } 62582527734SSukumar Swaminathan 6268f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MBUF_DMA)) { 6278f23e9faSHans Rosenfeld goto vmem_pool; 6288f23e9faSHans Rosenfeld } 6298f23e9faSHans Rosenfeld 6308f23e9faSHans Rosenfeld dma_pool: 6318f23e9faSHans Rosenfeld 6328f23e9faSHans Rosenfeld /* 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; 64582527734SSukumar Swaminathan 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); 66182527734SSukumar Swaminathan 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--; 67282527734SSukumar Swaminathan } 67382527734SSukumar Swaminathan 67482527734SSukumar Swaminathan return; 67582527734SSukumar Swaminathan 6768f23e9faSHans Rosenfeld vmem_pool: 67782527734SSukumar 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 */ 68182527734SSukumar Swaminathan if (seg->fc_memget_end == bp) { 68282527734SSukumar Swaminathan seg->fc_memget_ptr = NULL; 68382527734SSukumar Swaminathan seg->fc_memget_end = NULL; 68482527734SSukumar Swaminathan seg->fc_memget_cnt = 0; 68582527734SSukumar Swaminathan 68682527734SSukumar Swaminathan } else { 68782527734SSukumar Swaminathan seg->fc_memget_ptr = *((uint8_t **)bp); 68882527734SSukumar Swaminathan seg->fc_memget_cnt--; 68982527734SSukumar Swaminathan } 69082527734SSukumar Swaminathan 6918f23e9faSHans Rosenfeld /* Free the Virtual memory itself */ 6928f23e9faSHans Rosenfeld bzero(buf_info, sizeof (MBUF_INFO)); 6938f23e9faSHans Rosenfeld buf_info->size = seg->fc_memsize; 6948f23e9faSHans Rosenfeld buf_info->virt = bp; 6958f23e9faSHans Rosenfeld 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--; 70182527734SSukumar Swaminathan } 70282527734SSukumar Swaminathan 7038f23e9faSHans Rosenfeld return; 7048f23e9faSHans Rosenfeld 7058f23e9faSHans Rosenfeld } /* emlxs_mem_pool_free() */ 7068f23e9faSHans Rosenfeld 7078f23e9faSHans Rosenfeld 7088f23e9faSHans Rosenfeld extern uint32_t 7098f23e9faSHans Rosenfeld emlxs_mem_pool_create(emlxs_hba_t *hba, MEMSEG *seg) 7108f23e9faSHans Rosenfeld { 7118f23e9faSHans Rosenfeld emlxs_config_t *cfg = &CFG; 7128f23e9faSHans Rosenfeld 7138f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMGET_LOCK); 7148f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMPUT_LOCK); 7158f23e9faSHans Rosenfeld 7168f23e9faSHans Rosenfeld if (seg->fc_memsize == 0) { 7178f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 7188f23e9faSHans Rosenfeld 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; 7318f23e9faSHans Rosenfeld } 7328f23e9faSHans Rosenfeld 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; 7378f23e9faSHans Rosenfeld 7388f23e9faSHans Rosenfeld if (seg->fc_step == 0) { 7398f23e9faSHans Rosenfeld seg->fc_step = 1; 7408f23e9faSHans Rosenfeld } 74182527734SSukumar Swaminathan } else { 7428f23e9faSHans Rosenfeld seg->fc_step = 0; 7438f23e9faSHans Rosenfeld } 7448f23e9faSHans Rosenfeld 7458f23e9faSHans Rosenfeld seg->fc_numblks = 0; 7468f23e9faSHans Rosenfeld seg->fc_total_memsize = 0; 7478f23e9faSHans Rosenfeld seg->fc_low = 0; 7488f23e9faSHans Rosenfeld 7498f23e9faSHans Rosenfeld (void) emlxs_mem_pool_alloc(hba, seg, seg->fc_lo_water); 7508f23e9faSHans Rosenfeld 7518f23e9faSHans Rosenfeld seg->fc_memflag |= (FC_MEMSEG_PUT_ENABLED|FC_MEMSEG_GET_ENABLED); 7528f23e9faSHans Rosenfeld 7538f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 7548f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 7558f23e9faSHans Rosenfeld 7568f23e9faSHans Rosenfeld return (seg->fc_numblks); 7578f23e9faSHans Rosenfeld 7588f23e9faSHans Rosenfeld } /* emlxs_mem_pool_create() */ 7598f23e9faSHans Rosenfeld 7608f23e9faSHans Rosenfeld 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); 7868f23e9faSHans Rosenfeld } 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; 92282527734SSukumar Swaminathan } 92382527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 9248f23e9faSHans Rosenfeld } 92582527734SSukumar Swaminathan 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 } 9338f23e9faSHans Rosenfeld 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 } 97182527734SSukumar Swaminathan } 97282527734SSukumar Swaminathan 97382527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 97482527734SSukumar Swaminathan 97582527734SSukumar Swaminathan return (bp); 97682527734SSukumar Swaminathan 97782527734SSukumar Swaminathan } /* emlxs_mem_pool_get() */ 97882527734SSukumar Swaminathan 97982527734SSukumar Swaminathan 980a9800bebSGarrett D'Amore extern void 981a9800bebSGarrett D'Amore emlxs_mem_pool_put(emlxs_hba_t *hba, MEMSEG *seg, void *bp) 98282527734SSukumar Swaminathan { 98382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 98482527734SSukumar Swaminathan MATCHMAP *mp; 98582527734SSukumar Swaminathan 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; 99382527734SSukumar Swaminathan } 99482527734SSukumar 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); 99982527734SSukumar Swaminathan 100082527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 1001a9800bebSGarrett D'Amore return; 100282527734SSukumar Swaminathan } 100382527734SSukumar Swaminathan 10048f23e9faSHans Rosenfeld /* Validate DMA buffer */ 100582527734SSukumar Swaminathan if (seg->fc_memflag & FC_MBUF_DMA) { 100682527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 100782527734SSukumar 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); 101482527734SSukumar Swaminathan 101582527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 101682527734SSukumar Swaminathan 101782527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 101882527734SSukumar Swaminathan 101982527734SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_shutdown_thread, 102082527734SSukumar Swaminathan NULL, NULL); 102182527734SSukumar Swaminathan 1022a9800bebSGarrett D'Amore return; 102382527734SSukumar Swaminathan } 102482527734SSukumar Swaminathan } 102582527734SSukumar Swaminathan 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); 103882527734SSukumar Swaminathan 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; 104782527734SSukumar Swaminathan 104882527734SSukumar Swaminathan } /* emlxs_mem_pool_put() */ 104982527734SSukumar Swaminathan 105082527734SSukumar Swaminathan 105182527734SSukumar Swaminathan extern MATCHMAP * 105282527734SSukumar Swaminathan emlxs_mem_buf_alloc(emlxs_hba_t *hba, uint32_t size) 105382527734SSukumar Swaminathan { 105482527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 105582527734SSukumar Swaminathan 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 1109fcf3ce44SJohn Forte } /* 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 1140fcf3ce44SJohn Forte } /* 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 { 1146fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1147a9800bebSGarrett D'Amore void *bp; 1148fcf3ce44SJohn Forte MAILBOXQ *mbq; 1149fcf3ce44SJohn Forte IOCBQ *iocbq; 1150fcf3ce44SJohn Forte NODELIST *node; 115182527734SSukumar Swaminathan 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]; 1162291a2b48SSukumar Swaminathan 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: 1169fcf3ce44SJohn Forte mbq = (MAILBOXQ *)bp; 1170fcf3ce44SJohn Forte mbq->flag |= MBQ_POOL_ALLOCATED; 1171fcf3ce44SJohn Forte break; 1172fcf3ce44SJohn Forte 1173fcf3ce44SJohn Forte case MEM_IOCB: 1174fcf3ce44SJohn Forte iocbq = (IOCBQ *)bp; 1175fcf3ce44SJohn Forte iocbq->flag |= IOCB_POOL_ALLOCATED; 1176fcf3ce44SJohn Forte break; 1177fcf3ce44SJohn Forte 1178fcf3ce44SJohn Forte case MEM_NLP: 1179fcf3ce44SJohn Forte 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 1187fcf3ce44SJohn Forte } /* 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 { 1193fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1194fcf3ce44SJohn Forte MAILBOXQ *mbq; 119582527734SSukumar Swaminathan IOCBQ *iocbq; 1196fcf3ce44SJohn Forte NODELIST *node; 119782527734SSukumar Swaminathan MEMSEG *seg; 119882527734SSukumar Swaminathan 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); 120582527734SSukumar 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: 1213fcf3ce44SJohn Forte 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: 1221fcf3ce44SJohn Forte 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: 1235fcf3ce44SJohn Forte 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 1265fcf3ce44SJohn Forte } /* 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) { 1280fcf3ce44SJohn Forte 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; 1306fcf3ce44SJohn Forte 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 1315fcf3ce44SJohn Forte 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; 1341fcf3ce44SJohn Forte 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 1350fcf3ce44SJohn Forte 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; 1376fcf3ce44SJohn Forte 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) { 1385fcf3ce44SJohn Forte 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; 1411fcf3ce44SJohn Forte 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 1418fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 1419fcf3ce44SJohn Forte } 1420fcf3ce44SJohn Forte 1421fcf3ce44SJohn Forte return (0); 1422fcf3ce44SJohn Forte 1423fcf3ce44SJohn Forte } /* 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 1453fcf3ce44SJohn Forte /* return mapped address */ 145482527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 1455291a2b48SSukumar Swaminathan /* 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 1549fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 1550fcf3ce44SJohn Forte } 1551fcf3ce44SJohn Forte } /* 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 } 1591291a2b48SSukumar Swaminathan 1592fcf3ce44SJohn Forte return (0); 1593fcf3ce44SJohn Forte 1594fcf3ce44SJohn Forte } /* emlxs_hbq_alloc() */ 1595