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