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 * 8*8f23e9faSHans Rosenfeld * You can obtain a copy of the license at 9*8f23e9faSHans 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 /* 23*8f23e9faSHans Rosenfeld * Copyright (c) 2004-2011 Emulex. All rights reserved. 2482527734SSukumar Swaminathan * Use is subject to license terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 27291a2b48SSukumar Swaminathan #include <emlxs.h> 28fcf3ce44SJohn Forte 29*8f23e9faSHans Rosenfeld /* #define EMLXS_POOL_DEBUG */ 30*8f23e9faSHans Rosenfeld 31fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_MEM_C); 32fcf3ce44SJohn Forte 33fcf3ce44SJohn Forte 34*8f23e9faSHans Rosenfeld static uint32_t emlxs_mem_pool_alloc(emlxs_hba_t *hba, MEMSEG *seg, 35*8f23e9faSHans Rosenfeld uint32_t count); 36*8f23e9faSHans Rosenfeld static void emlxs_mem_pool_free(emlxs_hba_t *hba, MEMSEG *seg, uint32_t count); 37*8f23e9faSHans Rosenfeld 38*8f23e9faSHans Rosenfeld 39fcf3ce44SJohn Forte extern int32_t 40fcf3ce44SJohn Forte emlxs_mem_alloc_buffer(emlxs_hba_t *hba) 41fcf3ce44SJohn Forte { 42fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 43fcf3ce44SJohn Forte emlxs_config_t *cfg; 44fcf3ce44SJohn Forte MBUF_INFO *buf_info; 4582527734SSukumar Swaminathan MEMSEG *seg; 46fcf3ce44SJohn Forte MBUF_INFO bufinfo; 47fcf3ce44SJohn Forte int32_t i; 4882527734SSukumar Swaminathan MATCHMAP *mp; 49*8f23e9faSHans Rosenfeld MATCHMAP **bpl_table; 50fcf3ce44SJohn Forte 51fcf3ce44SJohn Forte buf_info = &bufinfo; 52fcf3ce44SJohn Forte cfg = &CFG; 53fcf3ce44SJohn Forte 5482527734SSukumar Swaminathan bzero(hba->memseg, sizeof (hba->memseg)); 55fcf3ce44SJohn Forte 56fcf3ce44SJohn Forte /* Allocate the fc_table */ 57fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 5882527734SSukumar Swaminathan buf_info->size = (hba->max_iotag * sizeof (emlxs_buf_t *)); 59fcf3ce44SJohn Forte 60fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 61fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 62fcf3ce44SJohn Forte 63fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 64fcf3ce44SJohn Forte "fc_table buffer."); 65fcf3ce44SJohn Forte 6682527734SSukumar Swaminathan goto failed; 67fcf3ce44SJohn Forte } 6882527734SSukumar Swaminathan hba->fc_table = buf_info->virt; 6982527734SSukumar Swaminathan bzero(hba->fc_table, buf_info->size); 70fcf3ce44SJohn Forte 7182527734SSukumar Swaminathan /* Prepare the memory pools */ 7282527734SSukumar Swaminathan for (i = 0; i < FC_MAX_SEG; i++) { 7382527734SSukumar Swaminathan seg = &hba->memseg[i]; 74fcf3ce44SJohn Forte 7582527734SSukumar Swaminathan switch (i) { 7682527734SSukumar Swaminathan case MEM_NLP: 77*8f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "Node Pool", 78*8f23e9faSHans Rosenfeld sizeof (seg->fc_label)); 7982527734SSukumar Swaminathan seg->fc_memtag = MEM_NLP; 8082527734SSukumar Swaminathan seg->fc_memsize = sizeof (NODELIST); 81*8f23e9faSHans Rosenfeld seg->fc_hi_water = hba->max_nodes + 2; 82*8f23e9faSHans Rosenfeld seg->fc_lo_water = 2; 83*8f23e9faSHans Rosenfeld seg->fc_step = 1; 8482527734SSukumar Swaminathan break; 85fcf3ce44SJohn Forte 8682527734SSukumar Swaminathan case MEM_IOCB: 87*8f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "IOCB Pool", 88*8f23e9faSHans Rosenfeld sizeof (seg->fc_label)); 8982527734SSukumar Swaminathan seg->fc_memtag = MEM_IOCB; 9082527734SSukumar Swaminathan seg->fc_memsize = sizeof (IOCBQ); 91*8f23e9faSHans Rosenfeld seg->fc_hi_water = cfg[CFG_NUM_IOCBS].current; 92*8f23e9faSHans Rosenfeld seg->fc_lo_water = cfg[CFG_NUM_IOCBS].low; 93*8f23e9faSHans Rosenfeld seg->fc_step = cfg[CFG_NUM_IOCBS].low; 9482527734SSukumar Swaminathan break; 95fcf3ce44SJohn Forte 9682527734SSukumar Swaminathan case MEM_MBOX: 97*8f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "MBOX Pool", 98*8f23e9faSHans Rosenfeld sizeof (seg->fc_label)); 9982527734SSukumar Swaminathan seg->fc_memtag = MEM_MBOX; 10082527734SSukumar Swaminathan seg->fc_memsize = sizeof (MAILBOXQ); 101*8f23e9faSHans Rosenfeld seg->fc_hi_water = hba->max_nodes + 32; 102*8f23e9faSHans Rosenfeld seg->fc_lo_water = 32; 103*8f23e9faSHans Rosenfeld seg->fc_step = 1; 10482527734SSukumar Swaminathan break; 105fcf3ce44SJohn Forte 10682527734SSukumar Swaminathan case MEM_BPL: 10782527734SSukumar Swaminathan if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) { 10882527734SSukumar Swaminathan continue; 10982527734SSukumar Swaminathan } 110*8f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "BPL Pool", 111*8f23e9faSHans Rosenfeld sizeof (seg->fc_label)); 11282527734SSukumar Swaminathan seg->fc_memtag = MEM_BPL; 11382527734SSukumar Swaminathan seg->fc_memsize = hba->sli.sli3.mem_bpl_size; 11482527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 11582527734SSukumar Swaminathan seg->fc_memalign = 32; 116*8f23e9faSHans Rosenfeld seg->fc_hi_water = hba->max_iotag; 117*8f23e9faSHans Rosenfeld seg->fc_lo_water = cfg[CFG_NUM_IOCBS].low; 118*8f23e9faSHans Rosenfeld seg->fc_step = cfg[CFG_NUM_IOCBS].low; 11982527734SSukumar Swaminathan break; 120fcf3ce44SJohn Forte 12182527734SSukumar Swaminathan case MEM_BUF: 12282527734SSukumar Swaminathan /* These are the unsolicited ELS buffers. */ 123*8f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "BUF Pool", 124*8f23e9faSHans Rosenfeld sizeof (seg->fc_label)); 12582527734SSukumar Swaminathan seg->fc_memtag = MEM_BUF; 12682527734SSukumar Swaminathan seg->fc_memsize = MEM_BUF_SIZE; 12782527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 12882527734SSukumar Swaminathan seg->fc_memalign = 32; 129*8f23e9faSHans Rosenfeld seg->fc_hi_water = MEM_ELSBUF_COUNT + MEM_BUF_COUNT; 130*8f23e9faSHans Rosenfeld seg->fc_lo_water = MEM_ELSBUF_COUNT; 131*8f23e9faSHans Rosenfeld seg->fc_step = 1; 13282527734SSukumar Swaminathan break; 133291a2b48SSukumar Swaminathan 13482527734SSukumar Swaminathan case MEM_IPBUF: 13582527734SSukumar Swaminathan /* These are the unsolicited IP buffers. */ 13682527734SSukumar Swaminathan if (cfg[CFG_NETWORK_ON].current == 0) { 13782527734SSukumar Swaminathan continue; 13882527734SSukumar Swaminathan } 139fcf3ce44SJohn Forte 140*8f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "IPBUF Pool", 141*8f23e9faSHans Rosenfeld sizeof (seg->fc_label)); 14282527734SSukumar Swaminathan seg->fc_memtag = MEM_IPBUF; 14382527734SSukumar Swaminathan seg->fc_memsize = MEM_IPBUF_SIZE; 14482527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 14582527734SSukumar Swaminathan seg->fc_memalign = 32; 146*8f23e9faSHans Rosenfeld seg->fc_hi_water = MEM_IPBUF_COUNT; 147*8f23e9faSHans Rosenfeld seg->fc_lo_water = 0; 148*8f23e9faSHans Rosenfeld seg->fc_step = 4; 14982527734SSukumar Swaminathan break; 150fcf3ce44SJohn Forte 15182527734SSukumar Swaminathan case MEM_CTBUF: 15282527734SSukumar Swaminathan /* These are the unsolicited CT buffers. */ 153*8f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "CTBUF Pool", 154*8f23e9faSHans Rosenfeld sizeof (seg->fc_label)); 15582527734SSukumar Swaminathan seg->fc_memtag = MEM_CTBUF; 15682527734SSukumar Swaminathan seg->fc_memsize = MEM_CTBUF_SIZE; 15782527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 15882527734SSukumar Swaminathan seg->fc_memalign = 32; 159*8f23e9faSHans Rosenfeld seg->fc_hi_water = MEM_CTBUF_COUNT; 160*8f23e9faSHans Rosenfeld seg->fc_lo_water = MEM_CTBUF_COUNT; 161*8f23e9faSHans Rosenfeld seg->fc_step = 1; 16282527734SSukumar Swaminathan break; 163fcf3ce44SJohn Forte 16482527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 165*8f23e9faSHans Rosenfeld case MEM_FCTBUF: 16682527734SSukumar Swaminathan /* These are the unsolicited FCT buffers. */ 167*8f23e9faSHans Rosenfeld if (!(port->flag & EMLXS_TGT_ENABLED)) { 16882527734SSukumar Swaminathan continue; 16982527734SSukumar Swaminathan } 170fcf3ce44SJohn Forte 171*8f23e9faSHans Rosenfeld (void) strlcpy(seg->fc_label, "FCTBUF Pool", 172*8f23e9faSHans Rosenfeld sizeof (seg->fc_label)); 17382527734SSukumar Swaminathan seg->fc_memtag = MEM_FCTBUF; 17482527734SSukumar Swaminathan seg->fc_memsize = MEM_FCTBUF_SIZE; 17582527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 17682527734SSukumar Swaminathan seg->fc_memalign = 32; 177*8f23e9faSHans Rosenfeld seg->fc_hi_water = MEM_FCTBUF_COUNT; 178*8f23e9faSHans Rosenfeld seg->fc_lo_water = 0; 179*8f23e9faSHans Rosenfeld seg->fc_step = 8; 18082527734SSukumar Swaminathan break; 181*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 182fcf3ce44SJohn Forte 18382527734SSukumar Swaminathan default: 18482527734SSukumar Swaminathan continue; 185fcf3ce44SJohn Forte } 186fcf3ce44SJohn Forte 18782527734SSukumar Swaminathan if (seg->fc_memsize == 0) { 18882527734SSukumar Swaminathan continue; 18982527734SSukumar Swaminathan } 190fcf3ce44SJohn Forte 191*8f23e9faSHans Rosenfeld (void) emlxs_mem_pool_create(hba, seg); 192*8f23e9faSHans Rosenfeld 193*8f23e9faSHans Rosenfeld if (seg->fc_numblks < seg->fc_lo_water) { 194*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 195*8f23e9faSHans Rosenfeld "%s: count=%d size=%d flags=%x lo=%d hi=%d", 196*8f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, 197*8f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water, 198*8f23e9faSHans Rosenfeld seg->fc_hi_water); 199*8f23e9faSHans Rosenfeld 200*8f23e9faSHans Rosenfeld goto failed; 201*8f23e9faSHans Rosenfeld } 202*8f23e9faSHans Rosenfeld } 203*8f23e9faSHans Rosenfeld 204*8f23e9faSHans Rosenfeld hba->sli.sli3.bpl_table = NULL; 205*8f23e9faSHans Rosenfeld seg = &hba->memseg[MEM_BPL]; 206*8f23e9faSHans Rosenfeld 207*8f23e9faSHans Rosenfeld /* If SLI3 and MEM_BPL pool is static */ 208*8f23e9faSHans Rosenfeld if (!(hba->model_info.sli_mask & EMLXS_SLI4_MASK) && 209*8f23e9faSHans Rosenfeld !(seg->fc_memflag & FC_MEMSEG_DYNAMIC)) { 210*8f23e9faSHans Rosenfeld /* 211*8f23e9faSHans Rosenfeld * Allocate and Initialize bpl_table 212*8f23e9faSHans Rosenfeld * This is for increased performance. 213*8f23e9faSHans Rosenfeld */ 214*8f23e9faSHans Rosenfeld bzero(buf_info, sizeof (MBUF_INFO)); 215*8f23e9faSHans Rosenfeld buf_info->size = hba->max_iotag * sizeof (MATCHMAP *); 216*8f23e9faSHans Rosenfeld 217*8f23e9faSHans Rosenfeld (void) emlxs_mem_alloc(hba, buf_info); 218*8f23e9faSHans Rosenfeld if (buf_info->virt == NULL) { 219*8f23e9faSHans Rosenfeld 220*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 221*8f23e9faSHans Rosenfeld &emlxs_mem_alloc_failed_msg, 222*8f23e9faSHans Rosenfeld "BPL table buffer."); 223*8f23e9faSHans Rosenfeld 22482527734SSukumar Swaminathan goto failed; 225fcf3ce44SJohn Forte } 226*8f23e9faSHans Rosenfeld hba->sli.sli3.bpl_table = buf_info->virt; 227291a2b48SSukumar Swaminathan 228*8f23e9faSHans Rosenfeld bpl_table = (MATCHMAP**)hba->sli.sli3.bpl_table; 229*8f23e9faSHans Rosenfeld for (i = 0; i < hba->max_iotag; i++) { 230*8f23e9faSHans Rosenfeld mp = (MATCHMAP *) emlxs_mem_get(hba, MEM_BPL); 231*8f23e9faSHans Rosenfeld mp->flag |= MAP_TABLE_ALLOCATED; 232*8f23e9faSHans Rosenfeld bpl_table[i] = mp; 233*8f23e9faSHans Rosenfeld } 234fcf3ce44SJohn Forte } 235fcf3ce44SJohn Forte 23682527734SSukumar Swaminathan return (1); 237fcf3ce44SJohn Forte 23882527734SSukumar Swaminathan failed: 239fcf3ce44SJohn Forte 24082527734SSukumar Swaminathan (void) emlxs_mem_free_buffer(hba); 24182527734SSukumar Swaminathan return (0); 242fcf3ce44SJohn Forte 24382527734SSukumar Swaminathan } /* emlxs_mem_alloc_buffer() */ 244fcf3ce44SJohn Forte 245fcf3ce44SJohn Forte 24682527734SSukumar Swaminathan /* 24782527734SSukumar Swaminathan * emlxs_mem_free_buffer 24882527734SSukumar Swaminathan * 24982527734SSukumar Swaminathan * This routine will free iocb/data buffer space 25082527734SSukumar Swaminathan * and TGTM resource. 25182527734SSukumar Swaminathan */ 25282527734SSukumar Swaminathan extern int 25382527734SSukumar Swaminathan emlxs_mem_free_buffer(emlxs_hba_t *hba) 25482527734SSukumar Swaminathan { 255*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 25682527734SSukumar Swaminathan emlxs_port_t *vport; 25782527734SSukumar Swaminathan int32_t j; 25882527734SSukumar Swaminathan MATCHMAP *mp; 25982527734SSukumar Swaminathan CHANNEL *cp; 26082527734SSukumar Swaminathan RING *rp; 26182527734SSukumar Swaminathan MBUF_INFO *buf_info; 26282527734SSukumar Swaminathan MBUF_INFO bufinfo; 263*8f23e9faSHans Rosenfeld MATCHMAP **bpl_table; 264fcf3ce44SJohn Forte 26582527734SSukumar Swaminathan buf_info = &bufinfo; 266291a2b48SSukumar Swaminathan 26782527734SSukumar Swaminathan for (j = 0; j < hba->chan_count; j++) { 26882527734SSukumar Swaminathan cp = &hba->chan[j]; 269fcf3ce44SJohn Forte 27082527734SSukumar Swaminathan /* Flush the ring */ 27182527734SSukumar Swaminathan (void) emlxs_tx_channel_flush(hba, cp, 0); 27282527734SSukumar Swaminathan } 273fcf3ce44SJohn Forte 27482527734SSukumar Swaminathan if (!(hba->model_info.sli_mask & EMLXS_SLI4_MASK)) { 27582527734SSukumar Swaminathan /* free the mapped address match area for each ring */ 27682527734SSukumar Swaminathan for (j = 0; j < MAX_RINGS; j++) { 27782527734SSukumar Swaminathan rp = &hba->sli.sli3.ring[j]; 278fcf3ce44SJohn Forte 27982527734SSukumar Swaminathan while (rp->fc_mpoff) { 28082527734SSukumar Swaminathan uint64_t addr; 281fcf3ce44SJohn Forte 28282527734SSukumar Swaminathan addr = 0; 28382527734SSukumar Swaminathan mp = (MATCHMAP *)(rp->fc_mpoff); 284fcf3ce44SJohn Forte 28582527734SSukumar Swaminathan if ((j == hba->channel_els) || 28682527734SSukumar Swaminathan (j == hba->channel_ct) || 28782527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 28882527734SSukumar Swaminathan (j == hba->CHANNEL_FCT) || 28982527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 29082527734SSukumar Swaminathan (j == hba->channel_ip)) { 29182527734SSukumar Swaminathan addr = mp->phys; 29282527734SSukumar Swaminathan } 293fcf3ce44SJohn Forte 29482527734SSukumar Swaminathan if ((mp = emlxs_mem_get_vaddr(hba, rp, addr))) { 29582527734SSukumar Swaminathan if (j == hba->channel_els) { 296a9800bebSGarrett D'Amore emlxs_mem_put(hba, 297a9800bebSGarrett D'Amore MEM_ELSBUF, (void *)mp); 29882527734SSukumar Swaminathan } else if (j == hba->channel_ct) { 299a9800bebSGarrett D'Amore emlxs_mem_put(hba, 300a9800bebSGarrett D'Amore MEM_CTBUF, (void *)mp); 30182527734SSukumar Swaminathan } else if (j == hba->channel_ip) { 302a9800bebSGarrett D'Amore emlxs_mem_put(hba, 303a9800bebSGarrett D'Amore MEM_IPBUF, (void *)mp); 30482527734SSukumar Swaminathan } 30582527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 30682527734SSukumar Swaminathan else if (j == hba->CHANNEL_FCT) { 307a9800bebSGarrett D'Amore emlxs_mem_put(hba, 308a9800bebSGarrett D'Amore MEM_FCTBUF, (void *)mp); 30982527734SSukumar Swaminathan } 31082527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 311fcf3ce44SJohn Forte 31282527734SSukumar Swaminathan } 31382527734SSukumar Swaminathan } 314fcf3ce44SJohn Forte } 31582527734SSukumar Swaminathan } 31682527734SSukumar Swaminathan 31782527734SSukumar Swaminathan if (hba->flag & FC_HBQ_ENABLED) { 31882527734SSukumar Swaminathan emlxs_hbq_free_all(hba, EMLXS_ELS_HBQ_ID); 31982527734SSukumar Swaminathan emlxs_hbq_free_all(hba, EMLXS_IP_HBQ_ID); 32082527734SSukumar Swaminathan emlxs_hbq_free_all(hba, EMLXS_CT_HBQ_ID); 321291a2b48SSukumar Swaminathan 322*8f23e9faSHans Rosenfeld if (port->flag & EMLXS_TGT_ENABLED) { 32382527734SSukumar Swaminathan emlxs_hbq_free_all(hba, EMLXS_FCT_HBQ_ID); 32482527734SSukumar Swaminathan } 325fcf3ce44SJohn Forte } 326fcf3ce44SJohn Forte 32782527734SSukumar Swaminathan /* Free the nodes */ 32882527734SSukumar Swaminathan for (j = 0; j < MAX_VPORTS; j++) { 32982527734SSukumar Swaminathan vport = &VPORT(j); 33082527734SSukumar Swaminathan if (vport->node_count) { 33182527734SSukumar Swaminathan emlxs_node_destroy_all(vport); 33282527734SSukumar Swaminathan } 33382527734SSukumar Swaminathan } 334fcf3ce44SJohn Forte 33582527734SSukumar Swaminathan /* Make sure the mailbox queue is empty */ 33682527734SSukumar Swaminathan emlxs_mb_flush(hba); 337fcf3ce44SJohn Forte 33882527734SSukumar Swaminathan if (hba->fc_table) { 339fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 34082527734SSukumar Swaminathan buf_info->size = hba->max_iotag * sizeof (emlxs_buf_t *); 34182527734SSukumar Swaminathan buf_info->virt = hba->fc_table; 34282527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 34382527734SSukumar Swaminathan hba->fc_table = NULL; 34482527734SSukumar Swaminathan } 345fcf3ce44SJohn Forte 346*8f23e9faSHans Rosenfeld if (hba->sli.sli3.bpl_table) { 347*8f23e9faSHans Rosenfeld /* Return MEM_BPLs to their pool */ 348*8f23e9faSHans Rosenfeld bpl_table = (MATCHMAP**)hba->sli.sli3.bpl_table; 349*8f23e9faSHans Rosenfeld for (j = 0; j < hba->max_iotag; j++) { 350*8f23e9faSHans Rosenfeld mp = bpl_table[j]; 351*8f23e9faSHans Rosenfeld mp->flag &= ~MAP_TABLE_ALLOCATED; 352*8f23e9faSHans Rosenfeld emlxs_mem_put(hba, MEM_BPL, (void*)mp); 353*8f23e9faSHans Rosenfeld } 354*8f23e9faSHans Rosenfeld 35582527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 35682527734SSukumar Swaminathan buf_info->size = hba->max_iotag * sizeof (MATCHMAP *); 357*8f23e9faSHans Rosenfeld buf_info->virt = hba->sli.sli3.bpl_table; 35882527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 359*8f23e9faSHans Rosenfeld hba->sli.sli3.bpl_table = NULL; 36082527734SSukumar Swaminathan } 361fcf3ce44SJohn Forte 36282527734SSukumar Swaminathan /* Free the memory segments */ 36382527734SSukumar Swaminathan for (j = 0; j < FC_MAX_SEG; j++) { 364*8f23e9faSHans Rosenfeld emlxs_mem_pool_destroy(hba, &hba->memseg[j]); 36582527734SSukumar Swaminathan } 366291a2b48SSukumar Swaminathan 36782527734SSukumar Swaminathan return (0); 368fcf3ce44SJohn Forte 36982527734SSukumar Swaminathan } /* emlxs_mem_free_buffer() */ 370fcf3ce44SJohn Forte 371fcf3ce44SJohn Forte 372*8f23e9faSHans Rosenfeld /* Must hold EMLXS_MEMGET_LOCK when calling */ 373*8f23e9faSHans Rosenfeld static uint32_t 374*8f23e9faSHans Rosenfeld emlxs_mem_pool_alloc(emlxs_hba_t *hba, MEMSEG *seg, uint32_t count) 37582527734SSukumar Swaminathan { 37682527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 37782527734SSukumar Swaminathan uint8_t *bp = NULL; 37882527734SSukumar Swaminathan MATCHMAP *mp = NULL; 37982527734SSukumar Swaminathan MBUF_INFO *buf_info; 38082527734SSukumar Swaminathan MBUF_INFO local_buf_info; 38182527734SSukumar Swaminathan uint32_t i; 382*8f23e9faSHans Rosenfeld uint32_t fc_numblks; 383fcf3ce44SJohn Forte 384*8f23e9faSHans Rosenfeld if (seg->fc_memsize == 0) { 385*8f23e9faSHans Rosenfeld return (0); 386*8f23e9faSHans Rosenfeld } 387fcf3ce44SJohn Forte 388*8f23e9faSHans Rosenfeld if (seg->fc_numblks >= seg->fc_hi_water) { 389*8f23e9faSHans Rosenfeld return (0); 390*8f23e9faSHans Rosenfeld } 391*8f23e9faSHans Rosenfeld 392*8f23e9faSHans Rosenfeld if (count == 0) { 393*8f23e9faSHans Rosenfeld return (0); 394*8f23e9faSHans Rosenfeld } 395fcf3ce44SJohn Forte 396*8f23e9faSHans Rosenfeld if (count > (seg->fc_hi_water - seg->fc_numblks)) { 397*8f23e9faSHans Rosenfeld count = (seg->fc_hi_water - seg->fc_numblks); 398*8f23e9faSHans Rosenfeld } 399fcf3ce44SJohn Forte 400*8f23e9faSHans Rosenfeld buf_info = &local_buf_info; 401*8f23e9faSHans Rosenfeld fc_numblks = seg->fc_numblks; 402*8f23e9faSHans Rosenfeld 403*8f23e9faSHans Rosenfeld /* Check for initial allocation */ 404*8f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_PUT_ENABLED)) { 405*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 406*8f23e9faSHans Rosenfeld "%s alloc:%d n=%d s=%d f=%x l=%d,%d,%d " 407*8f23e9faSHans Rosenfeld "f=%d:%d", 408*8f23e9faSHans Rosenfeld seg->fc_label, count, seg->fc_numblks, 409*8f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water, 410*8f23e9faSHans Rosenfeld seg->fc_hi_water, seg->fc_step, seg->fc_memget_cnt, 411*8f23e9faSHans Rosenfeld seg->fc_low); 41282527734SSukumar Swaminathan } 413291a2b48SSukumar Swaminathan 41482527734SSukumar Swaminathan if (!(seg->fc_memflag & FC_MBUF_DMA)) { 41582527734SSukumar Swaminathan goto vmem_pool; 416fcf3ce44SJohn Forte } 417fcf3ce44SJohn Forte 41882527734SSukumar Swaminathan /* dma_pool */ 41982527734SSukumar Swaminathan 420*8f23e9faSHans Rosenfeld for (i = 0; i < count; i++) { 421fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 422fcf3ce44SJohn Forte buf_info->size = sizeof (MATCHMAP); 423fcf3ce44SJohn Forte buf_info->align = sizeof (void *); 424fcf3ce44SJohn Forte 425fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 426fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 427fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 428*8f23e9faSHans Rosenfeld "%s: count=%d size=%d", 429*8f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, seg->fc_memsize); 430fcf3ce44SJohn Forte 431*8f23e9faSHans Rosenfeld goto done; 432fcf3ce44SJohn Forte } 433291a2b48SSukumar Swaminathan 43482527734SSukumar Swaminathan mp = (MATCHMAP *)buf_info->virt; 43582527734SSukumar Swaminathan bzero(mp, sizeof (MATCHMAP)); 436fcf3ce44SJohn Forte 437fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 43882527734SSukumar Swaminathan buf_info->size = seg->fc_memsize; 43982527734SSukumar Swaminathan buf_info->flags = seg->fc_memflag; 44082527734SSukumar Swaminathan buf_info->align = seg->fc_memalign; 441fcf3ce44SJohn Forte 442fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 443fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 444fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 445*8f23e9faSHans Rosenfeld "%s: count=%d size=%d", 446*8f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, seg->fc_memsize); 447fcf3ce44SJohn Forte 44882527734SSukumar Swaminathan /* Free the mp object */ 44982527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 45082527734SSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 451a9800bebSGarrett D'Amore buf_info->virt = (void *)mp; 45282527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 45382527734SSukumar Swaminathan 454*8f23e9faSHans Rosenfeld goto done; 455fcf3ce44SJohn Forte } 456fcf3ce44SJohn Forte bp = (uint8_t *)buf_info->virt; 45782527734SSukumar Swaminathan bzero(bp, seg->fc_memsize); 45882527734SSukumar Swaminathan 45982527734SSukumar Swaminathan mp->virt = buf_info->virt; 46082527734SSukumar Swaminathan mp->phys = buf_info->phys; 46182527734SSukumar Swaminathan mp->size = buf_info->size; 46282527734SSukumar Swaminathan mp->dma_handle = buf_info->dma_handle; 46382527734SSukumar Swaminathan mp->data_handle = buf_info->data_handle; 46482527734SSukumar Swaminathan mp->tag = seg->fc_memtag; 46582527734SSukumar Swaminathan mp->segment = seg; 46682527734SSukumar Swaminathan mp->flag |= MAP_POOL_ALLOCATED; 46782527734SSukumar Swaminathan 468*8f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 469*8f23e9faSHans Rosenfeld if (mp->tag >= MEM_FCTSEG) { 470*8f23e9faSHans Rosenfeld if (emlxs_fct_stmf_alloc(hba, mp)) { 471*8f23e9faSHans Rosenfeld /* Free the DMA memory itself */ 472*8f23e9faSHans Rosenfeld emlxs_mem_free(hba, buf_info); 473*8f23e9faSHans Rosenfeld 474*8f23e9faSHans Rosenfeld /* Free the mp object */ 475*8f23e9faSHans Rosenfeld bzero(buf_info, sizeof (MBUF_INFO)); 476*8f23e9faSHans Rosenfeld buf_info->size = sizeof (MATCHMAP); 477*8f23e9faSHans Rosenfeld buf_info->virt = (void *)mp; 478*8f23e9faSHans Rosenfeld emlxs_mem_free(hba, buf_info); 479*8f23e9faSHans Rosenfeld 480*8f23e9faSHans Rosenfeld goto done; 481*8f23e9faSHans Rosenfeld } 482*8f23e9faSHans Rosenfeld } 483*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 484*8f23e9faSHans Rosenfeld 48582527734SSukumar Swaminathan /* Add the buffer desc to the tail of the pool freelist */ 48682527734SSukumar Swaminathan if (seg->fc_memget_end == NULL) { 48782527734SSukumar Swaminathan seg->fc_memget_ptr = (uint8_t *)mp; 48882527734SSukumar Swaminathan seg->fc_memget_cnt = 1; 48982527734SSukumar Swaminathan } else { 49082527734SSukumar Swaminathan *((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)mp; 49182527734SSukumar Swaminathan seg->fc_memget_cnt++; 492fcf3ce44SJohn Forte } 49382527734SSukumar Swaminathan seg->fc_memget_end = (uint8_t *)mp; 494*8f23e9faSHans Rosenfeld 495*8f23e9faSHans Rosenfeld seg->fc_numblks++; 496*8f23e9faSHans Rosenfeld seg->fc_total_memsize += (seg->fc_memsize + sizeof (MATCHMAP)); 497fcf3ce44SJohn Forte } 498fcf3ce44SJohn Forte 499*8f23e9faSHans Rosenfeld goto done; 500fcf3ce44SJohn Forte 50182527734SSukumar Swaminathan vmem_pool: 502fcf3ce44SJohn Forte 503*8f23e9faSHans Rosenfeld for (i = 0; i < count; i++) { 504*8f23e9faSHans Rosenfeld bzero(buf_info, sizeof (MBUF_INFO)); 505*8f23e9faSHans Rosenfeld buf_info->size = seg->fc_memsize; 506fcf3ce44SJohn Forte 507*8f23e9faSHans Rosenfeld (void) emlxs_mem_alloc(hba, buf_info); 508*8f23e9faSHans Rosenfeld if (buf_info->virt == NULL) { 509*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 510*8f23e9faSHans Rosenfeld "%s: count=%d size=%d", 511*8f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, seg->fc_memsize); 512fcf3ce44SJohn Forte 513*8f23e9faSHans Rosenfeld goto done; 514*8f23e9faSHans Rosenfeld } 515*8f23e9faSHans Rosenfeld bp = (uint8_t *)buf_info->virt; 516fcf3ce44SJohn Forte 51782527734SSukumar Swaminathan /* Add the buffer to the tail of the pool freelist */ 51882527734SSukumar Swaminathan if (seg->fc_memget_end == NULL) { 51982527734SSukumar Swaminathan seg->fc_memget_ptr = (uint8_t *)bp; 52082527734SSukumar Swaminathan seg->fc_memget_cnt = 1; 52182527734SSukumar Swaminathan } else { 52282527734SSukumar Swaminathan *((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)bp; 52382527734SSukumar Swaminathan seg->fc_memget_cnt++; 52482527734SSukumar Swaminathan } 52582527734SSukumar Swaminathan seg->fc_memget_end = (uint8_t *)bp; 526fcf3ce44SJohn Forte 527*8f23e9faSHans Rosenfeld seg->fc_numblks++; 528*8f23e9faSHans Rosenfeld seg->fc_total_memsize += seg->fc_memsize; 52982527734SSukumar Swaminathan } 530fcf3ce44SJohn Forte 531*8f23e9faSHans Rosenfeld done: 532fcf3ce44SJohn Forte 533*8f23e9faSHans Rosenfeld return ((seg->fc_numblks - fc_numblks)); 534291a2b48SSukumar Swaminathan 53582527734SSukumar Swaminathan } /* emlxs_mem_pool_alloc() */ 536fcf3ce44SJohn Forte 537fcf3ce44SJohn Forte 538*8f23e9faSHans Rosenfeld /* Must hold EMLXS_MEMGET_LOCK & EMLXS_MEMPUT_LOCK when calling */ 539*8f23e9faSHans Rosenfeld static void 540*8f23e9faSHans Rosenfeld emlxs_mem_pool_free(emlxs_hba_t *hba, MEMSEG *seg, uint32_t count) 54182527734SSukumar Swaminathan { 54282527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 54382527734SSukumar Swaminathan uint8_t *bp = NULL; 54482527734SSukumar Swaminathan MATCHMAP *mp = NULL; 54582527734SSukumar Swaminathan MBUF_INFO *buf_info; 54682527734SSukumar Swaminathan MBUF_INFO local_buf_info; 547fcf3ce44SJohn Forte 548*8f23e9faSHans Rosenfeld if ((seg->fc_memsize == 0) || 549*8f23e9faSHans Rosenfeld (seg->fc_numblks == 0) || 550*8f23e9faSHans Rosenfeld (count == 0)) { 551*8f23e9faSHans Rosenfeld return; 552*8f23e9faSHans Rosenfeld } 553fcf3ce44SJohn Forte 554*8f23e9faSHans Rosenfeld /* Check max count */ 555*8f23e9faSHans Rosenfeld if (count > seg->fc_numblks) { 556*8f23e9faSHans Rosenfeld count = seg->fc_numblks; 557fcf3ce44SJohn Forte } 558fcf3ce44SJohn Forte 559*8f23e9faSHans Rosenfeld /* Move memput list to memget list */ 560*8f23e9faSHans Rosenfeld if (seg->fc_memput_ptr) { 561*8f23e9faSHans Rosenfeld if (seg->fc_memget_end == NULL) { 562*8f23e9faSHans Rosenfeld seg->fc_memget_ptr = seg->fc_memput_ptr; 563*8f23e9faSHans Rosenfeld } else { 564*8f23e9faSHans Rosenfeld *((uint8_t **)(seg->fc_memget_end)) =\ 565*8f23e9faSHans Rosenfeld seg->fc_memput_ptr; 566*8f23e9faSHans Rosenfeld } 567*8f23e9faSHans Rosenfeld seg->fc_memget_end = seg->fc_memput_end; 568*8f23e9faSHans Rosenfeld seg->fc_memget_cnt += seg->fc_memput_cnt; 569fcf3ce44SJohn Forte 570*8f23e9faSHans Rosenfeld seg->fc_memput_ptr = NULL; 571*8f23e9faSHans Rosenfeld seg->fc_memput_end = NULL; 572*8f23e9faSHans Rosenfeld seg->fc_memput_cnt = 0; 573*8f23e9faSHans Rosenfeld } 574fcf3ce44SJohn Forte 575*8f23e9faSHans Rosenfeld buf_info = &local_buf_info; 576fcf3ce44SJohn Forte 577*8f23e9faSHans Rosenfeld /* Check for final deallocation */ 578*8f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) { 579*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 580*8f23e9faSHans Rosenfeld "%s free:%d n=%d s=%d f=%x l=%d,%d,%d " 581*8f23e9faSHans Rosenfeld "f=%d:%d", 582*8f23e9faSHans Rosenfeld seg->fc_label, count, seg->fc_numblks, 583*8f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water, 584*8f23e9faSHans Rosenfeld seg->fc_hi_water, seg->fc_step, seg->fc_memget_cnt, 585*8f23e9faSHans Rosenfeld seg->fc_low); 586*8f23e9faSHans Rosenfeld } 587fcf3ce44SJohn Forte 588*8f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MBUF_DMA)) { 589*8f23e9faSHans Rosenfeld goto vmem_pool; 59082527734SSukumar Swaminathan } 591fcf3ce44SJohn Forte 592*8f23e9faSHans Rosenfeld dma_pool: 593fcf3ce44SJohn Forte 59482527734SSukumar Swaminathan /* Free memory associated with all buffers on get buffer pool */ 595*8f23e9faSHans Rosenfeld while (count && ((bp = seg->fc_memget_ptr) != NULL)) { 596*8f23e9faSHans Rosenfeld /* Remove buffer from list */ 597*8f23e9faSHans Rosenfeld if (seg->fc_memget_end == bp) { 598*8f23e9faSHans Rosenfeld seg->fc_memget_ptr = NULL; 599*8f23e9faSHans Rosenfeld seg->fc_memget_end = NULL; 600*8f23e9faSHans Rosenfeld seg->fc_memget_cnt = 0; 601*8f23e9faSHans Rosenfeld 602*8f23e9faSHans Rosenfeld } else { 603*8f23e9faSHans Rosenfeld seg->fc_memget_ptr = *((uint8_t **)bp); 604*8f23e9faSHans Rosenfeld seg->fc_memget_cnt--; 605*8f23e9faSHans Rosenfeld } 60682527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 607fcf3ce44SJohn Forte 608*8f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 609*8f23e9faSHans Rosenfeld if (mp->tag >= MEM_FCTSEG) { 610*8f23e9faSHans Rosenfeld emlxs_fct_stmf_free(hba, mp); 611*8f23e9faSHans Rosenfeld } 612*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 613*8f23e9faSHans Rosenfeld 614*8f23e9faSHans Rosenfeld /* Free the DMA memory itself */ 61582527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 61682527734SSukumar Swaminathan buf_info->size = mp->size; 61782527734SSukumar Swaminathan buf_info->virt = mp->virt; 61882527734SSukumar Swaminathan buf_info->phys = mp->phys; 61982527734SSukumar Swaminathan buf_info->dma_handle = mp->dma_handle; 62082527734SSukumar Swaminathan buf_info->data_handle = mp->data_handle; 62182527734SSukumar Swaminathan buf_info->flags = seg->fc_memflag; 62282527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 623fcf3ce44SJohn Forte 624*8f23e9faSHans Rosenfeld /* Free the handle */ 62582527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 62682527734SSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 627a9800bebSGarrett D'Amore buf_info->virt = (void *)mp; 62882527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 629*8f23e9faSHans Rosenfeld 630*8f23e9faSHans Rosenfeld seg->fc_numblks--; 631*8f23e9faSHans Rosenfeld seg->fc_total_memsize -= (seg->fc_memsize + sizeof (MATCHMAP)); 632*8f23e9faSHans Rosenfeld 633*8f23e9faSHans Rosenfeld count--; 634fcf3ce44SJohn Forte } 635291a2b48SSukumar Swaminathan 636*8f23e9faSHans Rosenfeld return; 637fcf3ce44SJohn Forte 638*8f23e9faSHans Rosenfeld vmem_pool: 639291a2b48SSukumar Swaminathan 640*8f23e9faSHans Rosenfeld /* Free memory associated with all buffers on get buffer pool */ 641*8f23e9faSHans Rosenfeld while (count && ((bp = seg->fc_memget_ptr) != NULL)) { 642*8f23e9faSHans Rosenfeld /* Remove buffer from list */ 643*8f23e9faSHans Rosenfeld if (seg->fc_memget_end == bp) { 644*8f23e9faSHans Rosenfeld seg->fc_memget_ptr = NULL; 645*8f23e9faSHans Rosenfeld seg->fc_memget_end = NULL; 646*8f23e9faSHans Rosenfeld seg->fc_memget_cnt = 0; 647*8f23e9faSHans Rosenfeld 648*8f23e9faSHans Rosenfeld } else { 649*8f23e9faSHans Rosenfeld seg->fc_memget_ptr = *((uint8_t **)bp); 650*8f23e9faSHans Rosenfeld seg->fc_memget_cnt--; 651*8f23e9faSHans Rosenfeld } 652*8f23e9faSHans Rosenfeld 653*8f23e9faSHans Rosenfeld /* Free the Virtual memory itself */ 65482527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 655*8f23e9faSHans Rosenfeld buf_info->size = seg->fc_memsize; 656*8f23e9faSHans Rosenfeld buf_info->virt = bp; 65782527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 658*8f23e9faSHans Rosenfeld 659*8f23e9faSHans Rosenfeld seg->fc_numblks--; 660*8f23e9faSHans Rosenfeld seg->fc_total_memsize -= seg->fc_memsize; 661*8f23e9faSHans Rosenfeld 662*8f23e9faSHans Rosenfeld count--; 663291a2b48SSukumar Swaminathan } 664fcf3ce44SJohn Forte 66582527734SSukumar Swaminathan return; 666fcf3ce44SJohn Forte 66782527734SSukumar Swaminathan } /* emlxs_mem_pool_free() */ 668fcf3ce44SJohn Forte 669fcf3ce44SJohn Forte 670*8f23e9faSHans Rosenfeld extern uint32_t 671*8f23e9faSHans Rosenfeld emlxs_mem_pool_create(emlxs_hba_t *hba, MEMSEG *seg) 67282527734SSukumar Swaminathan { 673*8f23e9faSHans Rosenfeld emlxs_config_t *cfg = &CFG; 674291a2b48SSukumar Swaminathan 67582527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMGET_LOCK); 676*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMPUT_LOCK); 67782527734SSukumar Swaminathan 678*8f23e9faSHans Rosenfeld if (seg->fc_memsize == 0) { 679*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 68082527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 681*8f23e9faSHans Rosenfeld 682*8f23e9faSHans Rosenfeld return (0); 683*8f23e9faSHans Rosenfeld } 684*8f23e9faSHans Rosenfeld 685*8f23e9faSHans Rosenfeld /* Sanity check hi > lo */ 686*8f23e9faSHans Rosenfeld if (seg->fc_lo_water > seg->fc_hi_water) { 687*8f23e9faSHans Rosenfeld seg->fc_hi_water = seg->fc_lo_water; 688*8f23e9faSHans Rosenfeld } 689*8f23e9faSHans Rosenfeld 690*8f23e9faSHans Rosenfeld /* If dynamic pools are disabled, then force pool to max level */ 691*8f23e9faSHans Rosenfeld if (cfg[CFG_MEM_DYNAMIC].current == 0) { 692*8f23e9faSHans Rosenfeld seg->fc_lo_water = seg->fc_hi_water; 693fcf3ce44SJohn Forte } 694291a2b48SSukumar Swaminathan 695*8f23e9faSHans Rosenfeld /* If pool is dynamic, then fc_step must be >0 */ 696*8f23e9faSHans Rosenfeld /* Otherwise, fc_step must be 0 */ 697*8f23e9faSHans Rosenfeld if (seg->fc_lo_water != seg->fc_hi_water) { 698*8f23e9faSHans Rosenfeld seg->fc_memflag |= FC_MEMSEG_DYNAMIC; 699fcf3ce44SJohn Forte 700*8f23e9faSHans Rosenfeld if (seg->fc_step == 0) { 701*8f23e9faSHans Rosenfeld seg->fc_step = 1; 70282527734SSukumar Swaminathan } 703*8f23e9faSHans Rosenfeld } else { 704*8f23e9faSHans Rosenfeld seg->fc_step = 0; 70582527734SSukumar Swaminathan } 706fcf3ce44SJohn Forte 707*8f23e9faSHans Rosenfeld seg->fc_numblks = 0; 708*8f23e9faSHans Rosenfeld seg->fc_total_memsize = 0; 709*8f23e9faSHans Rosenfeld seg->fc_low = 0; 710fcf3ce44SJohn Forte 711*8f23e9faSHans Rosenfeld (void) emlxs_mem_pool_alloc(hba, seg, seg->fc_lo_water); 712fcf3ce44SJohn Forte 713*8f23e9faSHans Rosenfeld seg->fc_memflag |= (FC_MEMSEG_PUT_ENABLED|FC_MEMSEG_GET_ENABLED); 714291a2b48SSukumar Swaminathan 715*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 716*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 717fcf3ce44SJohn Forte 718*8f23e9faSHans Rosenfeld return (seg->fc_numblks); 719*8f23e9faSHans Rosenfeld 720*8f23e9faSHans Rosenfeld } /* emlxs_mem_pool_create() */ 721fcf3ce44SJohn Forte 722fcf3ce44SJohn Forte 723*8f23e9faSHans Rosenfeld extern void 724*8f23e9faSHans Rosenfeld emlxs_mem_pool_destroy(emlxs_hba_t *hba, MEMSEG *seg) 725*8f23e9faSHans Rosenfeld { 726*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 727*8f23e9faSHans Rosenfeld 728*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMGET_LOCK); 729*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMPUT_LOCK); 730*8f23e9faSHans Rosenfeld 731*8f23e9faSHans Rosenfeld if (seg->fc_memsize == 0) { 732*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 733*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 734*8f23e9faSHans Rosenfeld return; 735*8f23e9faSHans Rosenfeld } 736*8f23e9faSHans Rosenfeld 737*8f23e9faSHans Rosenfeld /* Leave FC_MEMSEG_PUT_ENABLED set for now */ 738*8f23e9faSHans Rosenfeld seg->fc_memflag &= ~FC_MEMSEG_GET_ENABLED; 739*8f23e9faSHans Rosenfeld 740*8f23e9faSHans Rosenfeld /* Try to free all objects */ 741*8f23e9faSHans Rosenfeld emlxs_mem_pool_free(hba, seg, seg->fc_numblks); 742*8f23e9faSHans Rosenfeld 743*8f23e9faSHans Rosenfeld if (seg->fc_numblks) { 744*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 745*8f23e9faSHans Rosenfeld "mem_pool_destroy: %s leak detected: " 746*8f23e9faSHans Rosenfeld "%d objects still allocated.", 747*8f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks); 74882527734SSukumar Swaminathan } else { 749*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 750*8f23e9faSHans Rosenfeld "mem_pool_destroy: %s destroyed.", 751*8f23e9faSHans Rosenfeld seg->fc_label); 752*8f23e9faSHans Rosenfeld 753*8f23e9faSHans Rosenfeld /* Clear all */ 754*8f23e9faSHans Rosenfeld bzero(seg, sizeof (MEMSEG)); 755*8f23e9faSHans Rosenfeld } 756*8f23e9faSHans Rosenfeld 757*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 758*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 759*8f23e9faSHans Rosenfeld 760*8f23e9faSHans Rosenfeld return; 761*8f23e9faSHans Rosenfeld 762*8f23e9faSHans Rosenfeld } /* emlxs_mem_pool_destroy() */ 763*8f23e9faSHans Rosenfeld 764*8f23e9faSHans Rosenfeld 765*8f23e9faSHans Rosenfeld extern void 766*8f23e9faSHans Rosenfeld emlxs_mem_pool_clean(emlxs_hba_t *hba, MEMSEG *seg) 767*8f23e9faSHans Rosenfeld { 768*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 769*8f23e9faSHans Rosenfeld uint32_t clean_count; 770*8f23e9faSHans Rosenfeld uint32_t free_count; 771*8f23e9faSHans Rosenfeld uint32_t free_pad; 772*8f23e9faSHans Rosenfeld 773*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMGET_LOCK); 774*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMPUT_LOCK); 775*8f23e9faSHans Rosenfeld 776*8f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_DYNAMIC)) { 777*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 778*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 779*8f23e9faSHans Rosenfeld return; 780*8f23e9faSHans Rosenfeld } 781*8f23e9faSHans Rosenfeld 782*8f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) { 783*8f23e9faSHans Rosenfeld goto done; 784*8f23e9faSHans Rosenfeld } 785*8f23e9faSHans Rosenfeld 786*8f23e9faSHans Rosenfeld #ifdef EMLXS_POOL_DEBUG 787*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 788*8f23e9faSHans Rosenfeld "%s clean: n=%d s=%d f=%x l=%d,%d,%d " 789*8f23e9faSHans Rosenfeld "f=%d:%d", 790*8f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks, 791*8f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water, 792*8f23e9faSHans Rosenfeld seg->fc_hi_water, seg->fc_step, seg->fc_memget_cnt, 793*8f23e9faSHans Rosenfeld seg->fc_low); 794*8f23e9faSHans Rosenfeld #endif /* EMLXS_POOL_DEBUG */ 795*8f23e9faSHans Rosenfeld 796*8f23e9faSHans Rosenfeld /* Calculatge current free count */ 797*8f23e9faSHans Rosenfeld free_count = (seg->fc_memget_cnt + seg->fc_memput_cnt); 798*8f23e9faSHans Rosenfeld 799*8f23e9faSHans Rosenfeld /* Reset fc_low value to current free count */ 800*8f23e9faSHans Rosenfeld clean_count = seg->fc_low; 801*8f23e9faSHans Rosenfeld seg->fc_low = free_count; 802*8f23e9faSHans Rosenfeld 803*8f23e9faSHans Rosenfeld /* Return if pool is already at lo water mark */ 804*8f23e9faSHans Rosenfeld if (seg->fc_numblks <= seg->fc_lo_water) { 805*8f23e9faSHans Rosenfeld goto done; 806*8f23e9faSHans Rosenfeld } 807*8f23e9faSHans Rosenfeld 808*8f23e9faSHans Rosenfeld /* Return if there is nothing to clean */ 809*8f23e9faSHans Rosenfeld if ((free_count == 0) || 810*8f23e9faSHans Rosenfeld (clean_count <= 1)) { 811*8f23e9faSHans Rosenfeld goto done; 812*8f23e9faSHans Rosenfeld } 813*8f23e9faSHans Rosenfeld 814*8f23e9faSHans Rosenfeld /* Calculate a 3 percent free pad count (1 being minimum) */ 815*8f23e9faSHans Rosenfeld if (seg->fc_numblks > 66) { 816*8f23e9faSHans Rosenfeld free_pad = ((seg->fc_numblks * 3)/100); 817*8f23e9faSHans Rosenfeld } else { 818*8f23e9faSHans Rosenfeld free_pad = 1; 819*8f23e9faSHans Rosenfeld } 820*8f23e9faSHans Rosenfeld 821*8f23e9faSHans Rosenfeld /* Return if fc_low is below pool free pad */ 822*8f23e9faSHans Rosenfeld if (clean_count <= free_pad) { 823*8f23e9faSHans Rosenfeld goto done; 824*8f23e9faSHans Rosenfeld } 825*8f23e9faSHans Rosenfeld 826*8f23e9faSHans Rosenfeld clean_count -= free_pad; 827*8f23e9faSHans Rosenfeld 828*8f23e9faSHans Rosenfeld /* clean_count can't exceed minimum pool levels */ 829*8f23e9faSHans Rosenfeld if (clean_count > (seg->fc_numblks - seg->fc_lo_water)) { 830*8f23e9faSHans Rosenfeld clean_count = (seg->fc_numblks - seg->fc_lo_water); 831*8f23e9faSHans Rosenfeld } 832*8f23e9faSHans Rosenfeld 833*8f23e9faSHans Rosenfeld emlxs_mem_pool_free(hba, seg, clean_count); 834*8f23e9faSHans Rosenfeld 835*8f23e9faSHans Rosenfeld done: 836*8f23e9faSHans Rosenfeld if (seg->fc_last != seg->fc_numblks) { 837*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 838*8f23e9faSHans Rosenfeld "%s update: n=%d->%d s=%d f=%x l=%d,%d,%d " 839*8f23e9faSHans Rosenfeld "f=%d:%d", 840*8f23e9faSHans Rosenfeld seg->fc_label, seg->fc_last, seg->fc_numblks, 841*8f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water, 842*8f23e9faSHans Rosenfeld seg->fc_hi_water, seg->fc_step, seg->fc_memget_cnt, 843*8f23e9faSHans Rosenfeld seg->fc_low); 844*8f23e9faSHans Rosenfeld 845*8f23e9faSHans Rosenfeld seg->fc_last = seg->fc_numblks; 846*8f23e9faSHans Rosenfeld } 847*8f23e9faSHans Rosenfeld 848*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMPUT_LOCK); 849*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 850*8f23e9faSHans Rosenfeld return; 851*8f23e9faSHans Rosenfeld 852*8f23e9faSHans Rosenfeld } /* emlxs_mem_pool_clean() */ 853*8f23e9faSHans Rosenfeld 854*8f23e9faSHans Rosenfeld 855*8f23e9faSHans Rosenfeld extern void * 856*8f23e9faSHans Rosenfeld emlxs_mem_pool_get(emlxs_hba_t *hba, MEMSEG *seg) 857*8f23e9faSHans Rosenfeld { 858*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 859*8f23e9faSHans Rosenfeld void *bp = NULL; 860*8f23e9faSHans Rosenfeld MATCHMAP *mp; 861*8f23e9faSHans Rosenfeld uint32_t free_count; 862*8f23e9faSHans Rosenfeld 863*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_MEMGET_LOCK); 864*8f23e9faSHans Rosenfeld 865*8f23e9faSHans Rosenfeld /* Check if memory pool is GET enabled */ 866*8f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) { 867*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 868*8f23e9faSHans Rosenfeld return (NULL); 869*8f23e9faSHans Rosenfeld } 870*8f23e9faSHans Rosenfeld 871*8f23e9faSHans Rosenfeld /* If no entries on memget list, then check memput list */ 872*8f23e9faSHans Rosenfeld if (!seg->fc_memget_ptr) { 87382527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMPUT_LOCK); 87482527734SSukumar Swaminathan if (seg->fc_memput_ptr) { 87582527734SSukumar Swaminathan /* 87682527734SSukumar Swaminathan * Move list from memput to memget 87782527734SSukumar Swaminathan */ 87882527734SSukumar Swaminathan seg->fc_memget_ptr = seg->fc_memput_ptr; 87982527734SSukumar Swaminathan seg->fc_memget_end = seg->fc_memput_end; 88082527734SSukumar Swaminathan seg->fc_memget_cnt = seg->fc_memput_cnt; 88182527734SSukumar Swaminathan seg->fc_memput_ptr = NULL; 88282527734SSukumar Swaminathan seg->fc_memput_end = NULL; 88382527734SSukumar Swaminathan seg->fc_memput_cnt = 0; 884fcf3ce44SJohn Forte } 88582527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 886*8f23e9faSHans Rosenfeld } 887*8f23e9faSHans Rosenfeld 888*8f23e9faSHans Rosenfeld /* If no entries on memget list, then pool is empty */ 889*8f23e9faSHans Rosenfeld /* Try to allocate more if pool is dynamic */ 890*8f23e9faSHans Rosenfeld if (!seg->fc_memget_ptr && 891*8f23e9faSHans Rosenfeld (seg->fc_memflag & FC_MEMSEG_DYNAMIC)) { 892*8f23e9faSHans Rosenfeld (void) emlxs_mem_pool_alloc(hba, seg, seg->fc_step); 893*8f23e9faSHans Rosenfeld seg->fc_low = 0; 894*8f23e9faSHans Rosenfeld } 89582527734SSukumar Swaminathan 896*8f23e9faSHans Rosenfeld /* If no entries on memget list, then pool is empty */ 897*8f23e9faSHans Rosenfeld if (!seg->fc_memget_ptr) { 89882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_alloc_failed_msg, 89982527734SSukumar Swaminathan "%s empty.", seg->fc_label); 900*8f23e9faSHans Rosenfeld 901*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_MEMGET_LOCK); 902*8f23e9faSHans Rosenfeld return (NULL); 903*8f23e9faSHans Rosenfeld } 904*8f23e9faSHans Rosenfeld 905*8f23e9faSHans Rosenfeld /* Remove an entry from the get list */ 906*8f23e9faSHans Rosenfeld bp = seg->fc_memget_ptr; 907*8f23e9faSHans Rosenfeld 908*8f23e9faSHans Rosenfeld if (seg->fc_memget_end == bp) { 909*8f23e9faSHans Rosenfeld seg->fc_memget_ptr = NULL; 910*8f23e9faSHans Rosenfeld seg->fc_memget_end = NULL; 911*8f23e9faSHans Rosenfeld seg->fc_memget_cnt = 0; 912*8f23e9faSHans Rosenfeld 913*8f23e9faSHans Rosenfeld } else { 914*8f23e9faSHans Rosenfeld seg->fc_memget_ptr = *((uint8_t **)bp); 915*8f23e9faSHans Rosenfeld seg->fc_memget_cnt--; 916*8f23e9faSHans Rosenfeld } 917*8f23e9faSHans Rosenfeld 918*8f23e9faSHans Rosenfeld /* Initialize buffer */ 919*8f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MBUF_DMA)) { 920*8f23e9faSHans Rosenfeld bzero(bp, seg->fc_memsize); 921*8f23e9faSHans Rosenfeld } else { 922*8f23e9faSHans Rosenfeld mp = (MATCHMAP *)bp; 923*8f23e9faSHans Rosenfeld mp->fc_mptr = NULL; 924*8f23e9faSHans Rosenfeld mp->flag |= MAP_POOL_ALLOCATED; 925*8f23e9faSHans Rosenfeld } 926*8f23e9faSHans Rosenfeld 927*8f23e9faSHans Rosenfeld /* Set fc_low if pool is dynamic */ 928*8f23e9faSHans Rosenfeld if (seg->fc_memflag & FC_MEMSEG_DYNAMIC) { 929*8f23e9faSHans Rosenfeld free_count = (seg->fc_memget_cnt + seg->fc_memput_cnt); 930*8f23e9faSHans Rosenfeld if (free_count < seg->fc_low) { 931*8f23e9faSHans Rosenfeld seg->fc_low = free_count; 932*8f23e9faSHans Rosenfeld } 933fcf3ce44SJohn Forte } 934fcf3ce44SJohn Forte 93582527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 93682527734SSukumar Swaminathan 93782527734SSukumar Swaminathan return (bp); 938fcf3ce44SJohn Forte 93982527734SSukumar Swaminathan } /* emlxs_mem_pool_get() */ 940fcf3ce44SJohn Forte 941fcf3ce44SJohn Forte 942a9800bebSGarrett D'Amore extern void 943a9800bebSGarrett D'Amore emlxs_mem_pool_put(emlxs_hba_t *hba, MEMSEG *seg, void *bp) 94482527734SSukumar Swaminathan { 945a9800bebSGarrett D'Amore emlxs_port_t *port = &PPORT; 946a9800bebSGarrett D'Amore MATCHMAP *mp; 947fcf3ce44SJohn Forte 94882527734SSukumar Swaminathan /* Free the pool object */ 94982527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMPUT_LOCK); 95082527734SSukumar Swaminathan 951*8f23e9faSHans Rosenfeld /* Check if memory pool is PUT enabled */ 952*8f23e9faSHans Rosenfeld if (!(seg->fc_memflag & FC_MEMSEG_PUT_ENABLED)) { 95382527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 954a9800bebSGarrett D'Amore return; 955fcf3ce44SJohn Forte } 956291a2b48SSukumar Swaminathan 95782527734SSukumar Swaminathan /* Check if buffer was just freed */ 958*8f23e9faSHans Rosenfeld if ((seg->fc_memput_end == bp) || (seg->fc_memget_end == bp)) { 95982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 96082527734SSukumar Swaminathan "%s: Freeing free object: bp=%p", seg->fc_label, bp); 961fcf3ce44SJohn Forte 96282527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 963a9800bebSGarrett D'Amore return; 964fcf3ce44SJohn Forte } 965fcf3ce44SJohn Forte 966*8f23e9faSHans Rosenfeld /* Validate DMA buffer */ 96782527734SSukumar Swaminathan if (seg->fc_memflag & FC_MBUF_DMA) { 96882527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 969291a2b48SSukumar Swaminathan 97082527734SSukumar Swaminathan if (!(mp->flag & MAP_POOL_ALLOCATED) || 97182527734SSukumar Swaminathan (mp->segment != seg)) { 97282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 973*8f23e9faSHans Rosenfeld "mem_pool_put: %s invalid: mp=%p " \ 97482527734SSukumar Swaminathan "tag=0x%x flag=%x", seg->fc_label, 97582527734SSukumar Swaminathan mp, mp->tag, mp->flag); 976291a2b48SSukumar Swaminathan 97782527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 978fcf3ce44SJohn Forte 97982527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 980fcf3ce44SJohn Forte 98182527734SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_shutdown_thread, 98282527734SSukumar Swaminathan NULL, NULL); 98382527734SSukumar Swaminathan 984a9800bebSGarrett D'Amore return; 985fcf3ce44SJohn Forte } 986fcf3ce44SJohn Forte } 987fcf3ce44SJohn Forte 988*8f23e9faSHans Rosenfeld /* Release buffer to the end of the memput list */ 98982527734SSukumar Swaminathan if (seg->fc_memput_end == NULL) { 99082527734SSukumar Swaminathan seg->fc_memput_ptr = bp; 99182527734SSukumar Swaminathan seg->fc_memput_cnt = 1; 99282527734SSukumar Swaminathan } else { 993a9800bebSGarrett D'Amore *((void **)(seg->fc_memput_end)) = bp; 99482527734SSukumar Swaminathan seg->fc_memput_cnt++; 99582527734SSukumar Swaminathan } 99682527734SSukumar Swaminathan seg->fc_memput_end = bp; 997a9800bebSGarrett D'Amore *((void **)(bp)) = NULL; 99882527734SSukumar Swaminathan 99982527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 1000fcf3ce44SJohn Forte 1001*8f23e9faSHans Rosenfeld /* This is for late PUT's after an initial */ 1002*8f23e9faSHans Rosenfeld /* emlxs_mem_pool_destroy call */ 1003*8f23e9faSHans Rosenfeld if ((seg->fc_memflag & FC_MEMSEG_PUT_ENABLED) && 1004*8f23e9faSHans Rosenfeld !(seg->fc_memflag & FC_MEMSEG_GET_ENABLED)) { 1005*8f23e9faSHans Rosenfeld emlxs_mem_pool_destroy(hba, seg); 1006*8f23e9faSHans Rosenfeld } 1007*8f23e9faSHans Rosenfeld 1008a9800bebSGarrett D'Amore return; 1009fcf3ce44SJohn Forte 101082527734SSukumar Swaminathan } /* emlxs_mem_pool_put() */ 1011fcf3ce44SJohn Forte 101282527734SSukumar Swaminathan 101382527734SSukumar Swaminathan extern MATCHMAP * 101482527734SSukumar Swaminathan emlxs_mem_buf_alloc(emlxs_hba_t *hba, uint32_t size) 1015fcf3ce44SJohn Forte { 1016fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1017fcf3ce44SJohn Forte uint8_t *bp = NULL; 101882527734SSukumar Swaminathan MATCHMAP *mp = NULL; 1019fcf3ce44SJohn Forte MBUF_INFO *buf_info; 1020fcf3ce44SJohn Forte MBUF_INFO bufinfo; 1021fcf3ce44SJohn Forte 1022fcf3ce44SJohn Forte buf_info = &bufinfo; 1023fcf3ce44SJohn Forte 1024fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 1025fcf3ce44SJohn Forte buf_info->size = sizeof (MATCHMAP); 1026fcf3ce44SJohn Forte buf_info->align = sizeof (void *); 1027fcf3ce44SJohn Forte 1028fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 1029fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 1030fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 1031fcf3ce44SJohn Forte "MEM_BUF_ALLOC buffer."); 1032fcf3ce44SJohn Forte 103382527734SSukumar Swaminathan return (NULL); 1034fcf3ce44SJohn Forte } 1035291a2b48SSukumar Swaminathan 103682527734SSukumar Swaminathan mp = (MATCHMAP *)buf_info->virt; 103782527734SSukumar Swaminathan bzero(mp, sizeof (MATCHMAP)); 1038fcf3ce44SJohn Forte 1039fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 104082527734SSukumar Swaminathan buf_info->size = size; 104182527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 1042fcf3ce44SJohn Forte buf_info->align = 32; 1043fcf3ce44SJohn Forte 1044fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 1045fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 1046fcf3ce44SJohn Forte 1047fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 1048fcf3ce44SJohn Forte "MEM_BUF_ALLOC DMA buffer."); 1049fcf3ce44SJohn Forte 105082527734SSukumar Swaminathan /* Free the mp object */ 1051728bdc9bSSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 1052728bdc9bSSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 1053a9800bebSGarrett D'Amore buf_info->virt = (void *)mp; 1054728bdc9bSSukumar Swaminathan emlxs_mem_free(hba, buf_info); 1055728bdc9bSSukumar Swaminathan 1056fcf3ce44SJohn Forte return (0); 1057fcf3ce44SJohn Forte } 1058fcf3ce44SJohn Forte bp = (uint8_t *)buf_info->virt; 1059*8f23e9faSHans Rosenfeld bzero(bp, buf_info->size); 1060fcf3ce44SJohn Forte 106182527734SSukumar Swaminathan mp->virt = buf_info->virt; 106282527734SSukumar Swaminathan mp->phys = buf_info->phys; 106382527734SSukumar Swaminathan mp->size = buf_info->size; 106482527734SSukumar Swaminathan mp->dma_handle = buf_info->dma_handle; 106582527734SSukumar Swaminathan mp->data_handle = buf_info->data_handle; 106682527734SSukumar Swaminathan mp->tag = MEM_BUF; 106782527734SSukumar Swaminathan mp->flag |= MAP_BUF_ALLOCATED; 1068fcf3ce44SJohn Forte 106982527734SSukumar Swaminathan return (mp); 1070fcf3ce44SJohn Forte 107182527734SSukumar Swaminathan } /* emlxs_mem_buf_alloc() */ 1072fcf3ce44SJohn Forte 1073fcf3ce44SJohn Forte 1074a9800bebSGarrett D'Amore extern void 107582527734SSukumar Swaminathan emlxs_mem_buf_free(emlxs_hba_t *hba, MATCHMAP *mp) 1076fcf3ce44SJohn Forte { 1077fcf3ce44SJohn Forte MBUF_INFO bufinfo; 1078fcf3ce44SJohn Forte MBUF_INFO *buf_info; 1079fcf3ce44SJohn Forte 1080fcf3ce44SJohn Forte buf_info = &bufinfo; 1081fcf3ce44SJohn Forte 108282527734SSukumar Swaminathan if (!(mp->flag & MAP_BUF_ALLOCATED)) { 1083a9800bebSGarrett D'Amore return; 1084fcf3ce44SJohn Forte } 1085fcf3ce44SJohn Forte 1086fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 108782527734SSukumar Swaminathan buf_info->size = mp->size; 108882527734SSukumar Swaminathan buf_info->virt = mp->virt; 108982527734SSukumar Swaminathan buf_info->phys = mp->phys; 109082527734SSukumar Swaminathan buf_info->dma_handle = mp->dma_handle; 109182527734SSukumar Swaminathan buf_info->data_handle = mp->data_handle; 1092fcf3ce44SJohn Forte buf_info->flags = FC_MBUF_DMA; 1093fcf3ce44SJohn Forte emlxs_mem_free(hba, buf_info); 1094fcf3ce44SJohn Forte 1095fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 1096fcf3ce44SJohn Forte buf_info->size = sizeof (MATCHMAP); 1097a9800bebSGarrett D'Amore buf_info->virt = (void *)mp; 1098fcf3ce44SJohn Forte emlxs_mem_free(hba, buf_info); 1099fcf3ce44SJohn Forte 1100a9800bebSGarrett D'Amore return; 1101fcf3ce44SJohn Forte 110282527734SSukumar Swaminathan } /* emlxs_mem_buf_free() */ 1103fcf3ce44SJohn Forte 1104fcf3ce44SJohn Forte 1105a9800bebSGarrett D'Amore extern void * 1106*8f23e9faSHans Rosenfeld emlxs_mem_get(emlxs_hba_t *hba, uint32_t seg_id) 1107fcf3ce44SJohn Forte { 1108a9800bebSGarrett D'Amore emlxs_port_t *port = &PPORT; 1109a9800bebSGarrett D'Amore void *bp; 1110a9800bebSGarrett D'Amore MAILBOXQ *mbq; 1111a9800bebSGarrett D'Amore IOCBQ *iocbq; 1112a9800bebSGarrett D'Amore NODELIST *node; 1113a9800bebSGarrett D'Amore MEMSEG *seg; 1114fcf3ce44SJohn Forte 111582527734SSukumar Swaminathan if (seg_id >= FC_MAX_SEG) { 1116291a2b48SSukumar Swaminathan 111782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1118*8f23e9faSHans Rosenfeld "mem_get: Invalid segment id = %d", 111982527734SSukumar Swaminathan seg_id); 1120fcf3ce44SJohn Forte 1121fcf3ce44SJohn Forte return (NULL); 1122fcf3ce44SJohn Forte } 112382527734SSukumar Swaminathan seg = &hba->memseg[seg_id]; 1124fcf3ce44SJohn Forte 112582527734SSukumar Swaminathan /* Alloc a buffer from the pool */ 1126*8f23e9faSHans Rosenfeld bp = emlxs_mem_pool_get(hba, seg); 1127fcf3ce44SJohn Forte 112882527734SSukumar Swaminathan if (bp) { 112982527734SSukumar Swaminathan switch (seg_id) { 1130fcf3ce44SJohn Forte case MEM_MBOX: 1131291a2b48SSukumar Swaminathan mbq = (MAILBOXQ *)bp; 1132fcf3ce44SJohn Forte mbq->flag |= MBQ_POOL_ALLOCATED; 1133fcf3ce44SJohn Forte break; 1134fcf3ce44SJohn Forte 1135fcf3ce44SJohn Forte case MEM_IOCB: 1136291a2b48SSukumar Swaminathan iocbq = (IOCBQ *)bp; 1137fcf3ce44SJohn Forte iocbq->flag |= IOCB_POOL_ALLOCATED; 1138fcf3ce44SJohn Forte break; 1139fcf3ce44SJohn Forte 1140fcf3ce44SJohn Forte case MEM_NLP: 1141291a2b48SSukumar Swaminathan node = (NODELIST *)bp; 1142fcf3ce44SJohn Forte node->flag |= NODE_POOL_ALLOCATED; 1143fcf3ce44SJohn Forte break; 1144fcf3ce44SJohn Forte } 1145fcf3ce44SJohn Forte } 1146fcf3ce44SJohn Forte 1147fcf3ce44SJohn Forte return (bp); 1148fcf3ce44SJohn Forte 114982527734SSukumar Swaminathan } /* emlxs_mem_get() */ 1150fcf3ce44SJohn Forte 1151fcf3ce44SJohn Forte 1152a9800bebSGarrett D'Amore extern void 1153a9800bebSGarrett D'Amore emlxs_mem_put(emlxs_hba_t *hba, uint32_t seg_id, void *bp) 1154fcf3ce44SJohn Forte { 1155a9800bebSGarrett D'Amore emlxs_port_t *port = &PPORT; 1156a9800bebSGarrett D'Amore MAILBOXQ *mbq; 1157a9800bebSGarrett D'Amore IOCBQ *iocbq; 1158a9800bebSGarrett D'Amore NODELIST *node; 1159a9800bebSGarrett D'Amore MEMSEG *seg; 1160a9800bebSGarrett D'Amore MATCHMAP *mp; 1161fcf3ce44SJohn Forte 116282527734SSukumar Swaminathan if (seg_id >= FC_MAX_SEG) { 116382527734SSukumar Swaminathan 116482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1165*8f23e9faSHans Rosenfeld "mem_put: Invalid segment id = %d: bp=%p", 116682527734SSukumar Swaminathan seg_id, bp); 1167291a2b48SSukumar Swaminathan 1168a9800bebSGarrett D'Amore return; 1169fcf3ce44SJohn Forte } 117082527734SSukumar Swaminathan seg = &hba->memseg[seg_id]; 1171291a2b48SSukumar Swaminathan 117282527734SSukumar Swaminathan /* Verify buffer */ 117382527734SSukumar Swaminathan switch (seg_id) { 1174fcf3ce44SJohn Forte case MEM_MBOX: 1175291a2b48SSukumar Swaminathan mbq = (MAILBOXQ *)bp; 1176fcf3ce44SJohn Forte 1177fcf3ce44SJohn Forte if (!(mbq->flag & MBQ_POOL_ALLOCATED)) { 1178a9800bebSGarrett D'Amore return; 1179fcf3ce44SJohn Forte } 1180fcf3ce44SJohn Forte break; 1181fcf3ce44SJohn Forte 1182fcf3ce44SJohn Forte case MEM_IOCB: 1183291a2b48SSukumar Swaminathan iocbq = (IOCBQ *)bp; 1184fcf3ce44SJohn Forte 1185fcf3ce44SJohn Forte if (!(iocbq->flag & IOCB_POOL_ALLOCATED)) { 1186a9800bebSGarrett D'Amore return; 1187fcf3ce44SJohn Forte } 1188291a2b48SSukumar Swaminathan 1189291a2b48SSukumar Swaminathan /* Any IOCBQ with a packet attached did not come */ 1190291a2b48SSukumar Swaminathan /* from our pool */ 1191fcf3ce44SJohn Forte if (iocbq->sbp) { 1192a9800bebSGarrett D'Amore return; 1193fcf3ce44SJohn Forte } 1194fcf3ce44SJohn Forte break; 1195fcf3ce44SJohn Forte 1196fcf3ce44SJohn Forte case MEM_NLP: 1197291a2b48SSukumar Swaminathan node = (NODELIST *)bp; 1198fcf3ce44SJohn Forte 1199fcf3ce44SJohn Forte if (!(node->flag & NODE_POOL_ALLOCATED)) { 1200a9800bebSGarrett D'Amore return; 1201fcf3ce44SJohn Forte } 1202fcf3ce44SJohn Forte break; 1203fcf3ce44SJohn Forte 1204fcf3ce44SJohn Forte default: 120582527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 1206fcf3ce44SJohn Forte 120782527734SSukumar Swaminathan if (mp->flag & MAP_BUF_ALLOCATED) { 1208a9800bebSGarrett D'Amore emlxs_mem_buf_free(hba, mp); 1209a9800bebSGarrett D'Amore return; 1210fcf3ce44SJohn Forte } 1211291a2b48SSukumar Swaminathan 121282527734SSukumar Swaminathan if (mp->flag & MAP_TABLE_ALLOCATED) { 1213a9800bebSGarrett D'Amore return; 1214fcf3ce44SJohn Forte } 1215291a2b48SSukumar Swaminathan 121682527734SSukumar Swaminathan if (!(mp->flag & MAP_POOL_ALLOCATED)) { 1217a9800bebSGarrett D'Amore return; 1218fcf3ce44SJohn Forte } 1219fcf3ce44SJohn Forte break; 1220fcf3ce44SJohn Forte } 1221fcf3ce44SJohn Forte 122282527734SSukumar Swaminathan /* Free a buffer to the pool */ 1223a9800bebSGarrett D'Amore emlxs_mem_pool_put(hba, seg, bp); 1224291a2b48SSukumar Swaminathan 1225a9800bebSGarrett D'Amore return; 1226fcf3ce44SJohn Forte 122782527734SSukumar Swaminathan } /* emlxs_mem_put() */ 1228fcf3ce44SJohn Forte 1229fcf3ce44SJohn Forte 1230fcf3ce44SJohn Forte /* 1231fcf3ce44SJohn Forte * Look up the virtual address given a mapped address 1232fcf3ce44SJohn Forte */ 123382527734SSukumar Swaminathan /* SLI3 */ 1234fcf3ce44SJohn Forte extern MATCHMAP * 1235fcf3ce44SJohn Forte emlxs_mem_get_vaddr(emlxs_hba_t *hba, RING *rp, uint64_t mapbp) 1236fcf3ce44SJohn Forte { 1237fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1238fcf3ce44SJohn Forte MATCHMAP *prev; 1239fcf3ce44SJohn Forte MATCHMAP *mp; 1240fcf3ce44SJohn Forte 124182527734SSukumar Swaminathan if (rp->ringno == hba->channel_els) { 1242291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff; 1243fcf3ce44SJohn Forte prev = 0; 1244fcf3ce44SJohn Forte 1245fcf3ce44SJohn Forte while (mp) { 1246fcf3ce44SJohn Forte if (mp->phys == mapbp) { 1247fcf3ce44SJohn Forte if (prev == 0) { 1248fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr; 1249fcf3ce44SJohn Forte } else { 1250fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr; 1251fcf3ce44SJohn Forte } 1252fcf3ce44SJohn Forte 1253a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) { 1254a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev; 1255fcf3ce44SJohn Forte } 1256291a2b48SSukumar Swaminathan 1257a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1258fcf3ce44SJohn Forte 125982527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 1260fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 1261fcf3ce44SJohn Forte 1262fcf3ce44SJohn Forte HBASTATS.ElsUbPosted--; 1263fcf3ce44SJohn Forte 1264fcf3ce44SJohn Forte return (mp); 1265fcf3ce44SJohn Forte } 1266291a2b48SSukumar Swaminathan 1267fcf3ce44SJohn Forte prev = mp; 1268291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr; 1269fcf3ce44SJohn Forte } 1270fcf3ce44SJohn Forte 1271fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1272fcf3ce44SJohn Forte "ELS Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1273fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1274fcf3ce44SJohn Forte 127582527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ct) { 1276fcf3ce44SJohn Forte 1277291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff; 1278fcf3ce44SJohn Forte prev = 0; 1279fcf3ce44SJohn Forte 1280fcf3ce44SJohn Forte while (mp) { 1281fcf3ce44SJohn Forte if (mp->phys == mapbp) { 1282fcf3ce44SJohn Forte if (prev == 0) { 1283fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr; 1284fcf3ce44SJohn Forte } else { 1285fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr; 1286fcf3ce44SJohn Forte } 1287fcf3ce44SJohn Forte 1288a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) { 1289a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev; 1290fcf3ce44SJohn Forte } 1291291a2b48SSukumar Swaminathan 1292a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1293fcf3ce44SJohn Forte 129482527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 1295fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 1296fcf3ce44SJohn Forte 1297fcf3ce44SJohn Forte HBASTATS.CtUbPosted--; 1298fcf3ce44SJohn Forte 1299fcf3ce44SJohn Forte return (mp); 1300fcf3ce44SJohn Forte } 1301291a2b48SSukumar Swaminathan 1302fcf3ce44SJohn Forte prev = mp; 1303291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr; 1304fcf3ce44SJohn Forte } 1305fcf3ce44SJohn Forte 1306fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1307fcf3ce44SJohn Forte "CT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1308fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1309fcf3ce44SJohn Forte 131082527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ip) { 1311fcf3ce44SJohn Forte 1312291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff; 1313fcf3ce44SJohn Forte prev = 0; 1314fcf3ce44SJohn Forte 1315fcf3ce44SJohn Forte while (mp) { 1316fcf3ce44SJohn Forte if (mp->phys == mapbp) { 1317fcf3ce44SJohn Forte if (prev == 0) { 1318fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr; 1319fcf3ce44SJohn Forte } else { 1320fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr; 1321fcf3ce44SJohn Forte } 1322fcf3ce44SJohn Forte 1323a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) { 1324a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev; 1325fcf3ce44SJohn Forte } 1326291a2b48SSukumar Swaminathan 1327a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1328fcf3ce44SJohn Forte 132982527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 1330fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 1331fcf3ce44SJohn Forte 1332fcf3ce44SJohn Forte HBASTATS.IpUbPosted--; 1333fcf3ce44SJohn Forte 1334fcf3ce44SJohn Forte return (mp); 1335fcf3ce44SJohn Forte } 1336291a2b48SSukumar Swaminathan 1337fcf3ce44SJohn Forte prev = mp; 1338291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr; 1339fcf3ce44SJohn Forte } 1340fcf3ce44SJohn Forte 1341fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1342fcf3ce44SJohn Forte "IP Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1343fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1344fcf3ce44SJohn Forte 1345fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 134682527734SSukumar Swaminathan } else if (rp->ringno == hba->CHANNEL_FCT) { 1347291a2b48SSukumar Swaminathan mp = (MATCHMAP *)rp->fc_mpoff; 1348fcf3ce44SJohn Forte prev = 0; 1349fcf3ce44SJohn Forte 1350fcf3ce44SJohn Forte while (mp) { 1351fcf3ce44SJohn Forte if (mp->phys == mapbp) { 1352fcf3ce44SJohn Forte if (prev == 0) { 1353fcf3ce44SJohn Forte rp->fc_mpoff = mp->fc_mptr; 1354fcf3ce44SJohn Forte } else { 1355fcf3ce44SJohn Forte prev->fc_mptr = mp->fc_mptr; 1356fcf3ce44SJohn Forte } 1357fcf3ce44SJohn Forte 1358a9800bebSGarrett D'Amore if (rp->fc_mpon == mp) { 1359a9800bebSGarrett D'Amore rp->fc_mpon = (void *)prev; 1360fcf3ce44SJohn Forte } 1361291a2b48SSukumar Swaminathan 1362a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1363fcf3ce44SJohn Forte 136482527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 1365fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 1366fcf3ce44SJohn Forte 1367fcf3ce44SJohn Forte HBASTATS.FctUbPosted--; 1368fcf3ce44SJohn Forte 1369fcf3ce44SJohn Forte return (mp); 1370fcf3ce44SJohn Forte } 1371291a2b48SSukumar Swaminathan 1372fcf3ce44SJohn Forte prev = mp; 1373291a2b48SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr; 1374fcf3ce44SJohn Forte } 1375fcf3ce44SJohn Forte 1376fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 1377fcf3ce44SJohn Forte "FCT Buffer not mapped: bp=%lx ringno=%x mpoff=%p mpon=%p", 1378fcf3ce44SJohn Forte mapbp, rp->ringno, rp->fc_mpoff, rp->fc_mpon); 1379fcf3ce44SJohn Forte 1380291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 1381fcf3ce44SJohn Forte } 1382fcf3ce44SJohn Forte 1383fcf3ce44SJohn Forte return (0); 1384fcf3ce44SJohn Forte 138582527734SSukumar Swaminathan } /* emlxs_mem_get_vaddr() */ 1386fcf3ce44SJohn Forte 1387fcf3ce44SJohn Forte 1388fcf3ce44SJohn Forte /* 1389291a2b48SSukumar Swaminathan * Given a virtual address bp, generate the physical mapped address and 1390291a2b48SSukumar Swaminathan * place it where addr points to. Save the address pair for lookup later. 1391fcf3ce44SJohn Forte */ 139282527734SSukumar Swaminathan /* SLI3 */ 1393fcf3ce44SJohn Forte extern void 1394291a2b48SSukumar Swaminathan emlxs_mem_map_vaddr(emlxs_hba_t *hba, RING *rp, MATCHMAP *mp, 1395291a2b48SSukumar Swaminathan uint32_t *haddr, uint32_t *laddr) 1396fcf3ce44SJohn Forte { 139782527734SSukumar Swaminathan if (rp->ringno == hba->channel_els) { 1398fcf3ce44SJohn Forte /* 1399291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it 1400291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list. 1401291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list. 1402fcf3ce44SJohn Forte */ 1403a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1404fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1405a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp; 1406a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1407fcf3ce44SJohn Forte } else { 1408291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1409a9800bebSGarrett D'Amore (void *)mp; 1410a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1411fcf3ce44SJohn Forte } 1412fcf3ce44SJohn Forte 1413fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1414291a2b48SSukumar Swaminathan 1415291a2b48SSukumar Swaminathan /* return mapped address */ 141682527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 1417fcf3ce44SJohn Forte /* return mapped address */ 141882527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1419fcf3ce44SJohn Forte } else { 1420fcf3ce44SJohn Forte /* return mapped address */ 142182527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1422fcf3ce44SJohn Forte } 1423fcf3ce44SJohn Forte 1424fcf3ce44SJohn Forte HBASTATS.ElsUbPosted++; 1425fcf3ce44SJohn Forte 142682527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ct) { 1427fcf3ce44SJohn Forte /* 1428291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it 1429291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list. 1430291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list. 1431fcf3ce44SJohn Forte */ 1432a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1433fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1434a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp; 1435a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1436fcf3ce44SJohn Forte } else { 1437291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1438a9800bebSGarrett D'Amore (void *)mp; 1439a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1440fcf3ce44SJohn Forte } 1441fcf3ce44SJohn Forte 1442fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1443fcf3ce44SJohn Forte /* return mapped address */ 144482527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 1445291a2b48SSukumar Swaminathan /* return mapped address */ 144682527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1447fcf3ce44SJohn Forte } else { 1448fcf3ce44SJohn Forte /* return mapped address */ 144982527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1450fcf3ce44SJohn Forte } 1451fcf3ce44SJohn Forte 1452fcf3ce44SJohn Forte HBASTATS.CtUbPosted++; 1453fcf3ce44SJohn Forte 1454fcf3ce44SJohn Forte 145582527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ip) { 1456fcf3ce44SJohn Forte /* 1457291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it 1458291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list. 1459291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list. 1460fcf3ce44SJohn Forte */ 1461a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1462fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1463a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp; 1464a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1465fcf3ce44SJohn Forte } else { 1466291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1467a9800bebSGarrett D'Amore (void *)mp; 1468a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1469fcf3ce44SJohn Forte } 1470fcf3ce44SJohn Forte 1471fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1472fcf3ce44SJohn Forte /* return mapped address */ 147382527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 147482527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1475fcf3ce44SJohn Forte } else { 147682527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1477fcf3ce44SJohn Forte } 1478fcf3ce44SJohn Forte 1479fcf3ce44SJohn Forte HBASTATS.IpUbPosted++; 1480fcf3ce44SJohn Forte 1481fcf3ce44SJohn Forte 1482fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 148382527734SSukumar Swaminathan } else if (rp->ringno == hba->CHANNEL_FCT) { 1484fcf3ce44SJohn Forte /* 1485291a2b48SSukumar Swaminathan * Update slot fc_mpon points to then bump it 1486291a2b48SSukumar Swaminathan * fc_mpoff is pointer head of the list. 1487291a2b48SSukumar Swaminathan * fc_mpon is pointer tail of the list. 1488fcf3ce44SJohn Forte */ 1489a9800bebSGarrett D'Amore mp->fc_mptr = NULL; 1490fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1491a9800bebSGarrett D'Amore rp->fc_mpoff = (void *)mp; 1492a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1493fcf3ce44SJohn Forte } else { 1494291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1495a9800bebSGarrett D'Amore (void *)mp; 1496a9800bebSGarrett D'Amore rp->fc_mpon = (void *)mp; 1497fcf3ce44SJohn Forte } 1498fcf3ce44SJohn Forte 1499fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1500fcf3ce44SJohn Forte /* return mapped address */ 150182527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 1502291a2b48SSukumar Swaminathan /* return mapped address */ 150382527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1504fcf3ce44SJohn Forte } else { 1505fcf3ce44SJohn Forte /* return mapped address */ 150682527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1507fcf3ce44SJohn Forte } 1508fcf3ce44SJohn Forte 1509fcf3ce44SJohn Forte HBASTATS.FctUbPosted++; 151082527734SSukumar Swaminathan 1511291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 1512fcf3ce44SJohn Forte } 151382527734SSukumar Swaminathan } /* emlxs_mem_map_vaddr() */ 1514fcf3ce44SJohn Forte 1515fcf3ce44SJohn Forte 151682527734SSukumar Swaminathan /* SLI3 */ 1517291a2b48SSukumar Swaminathan uint32_t 1518fcf3ce44SJohn Forte emlxs_hbq_alloc(emlxs_hba_t *hba, uint32_t hbq_id) 1519fcf3ce44SJohn Forte { 1520fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1521fcf3ce44SJohn Forte HBQ_INIT_t *hbq; 1522fcf3ce44SJohn Forte MBUF_INFO *buf_info; 1523fcf3ce44SJohn Forte MBUF_INFO bufinfo; 1524fcf3ce44SJohn Forte 152582527734SSukumar Swaminathan hbq = &hba->sli.sli3.hbq_table[hbq_id]; 1526fcf3ce44SJohn Forte 1527fcf3ce44SJohn Forte if (hbq->HBQ_host_buf.virt == 0) { 1528fcf3ce44SJohn Forte buf_info = &bufinfo; 1529fcf3ce44SJohn Forte 1530fcf3ce44SJohn Forte /* Get the system's page size in a DDI-compliant way. */ 1531fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 1532fcf3ce44SJohn Forte buf_info->size = hbq->HBQ_numEntries * sizeof (HBQE_t); 1533fcf3ce44SJohn Forte buf_info->flags = FC_MBUF_DMA; 1534fcf3ce44SJohn Forte buf_info->align = 4096; 1535fcf3ce44SJohn Forte 1536fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 1537fcf3ce44SJohn Forte 1538fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 1539fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg, 1540fcf3ce44SJohn Forte "Unable to alloc HBQ."); 1541fcf3ce44SJohn Forte return (ENOMEM); 1542fcf3ce44SJohn Forte } 1543291a2b48SSukumar Swaminathan 1544a9800bebSGarrett D'Amore hbq->HBQ_host_buf.virt = buf_info->virt; 1545fcf3ce44SJohn Forte hbq->HBQ_host_buf.phys = buf_info->phys; 1546fcf3ce44SJohn Forte hbq->HBQ_host_buf.data_handle = buf_info->data_handle; 1547fcf3ce44SJohn Forte hbq->HBQ_host_buf.dma_handle = buf_info->dma_handle; 1548fcf3ce44SJohn Forte hbq->HBQ_host_buf.size = buf_info->size; 1549fcf3ce44SJohn Forte hbq->HBQ_host_buf.tag = hbq_id; 1550fcf3ce44SJohn Forte 1551fcf3ce44SJohn Forte bzero((char *)hbq->HBQ_host_buf.virt, buf_info->size); 1552fcf3ce44SJohn Forte } 1553fcf3ce44SJohn Forte 1554fcf3ce44SJohn Forte return (0); 1555fcf3ce44SJohn Forte 155682527734SSukumar Swaminathan } /* emlxs_hbq_alloc() */ 1557