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 /* 23291a2b48SSukumar Swaminathan * Copyright 2009 Emulex. All rights reserved. 24*82527734SSukumar Swaminathan * Use is subject to license terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 27*82527734SSukumar 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; 39*82527734SSukumar Swaminathan MEMSEG *seg; 40fcf3ce44SJohn Forte MBUF_INFO bufinfo; 41fcf3ce44SJohn Forte int32_t i; 42*82527734SSukumar Swaminathan int32_t cnt; 43fcf3ce44SJohn Forte #ifdef EMLXS_SPARC 44*82527734SSukumar Swaminathan MATCHMAP *mp; 45*82527734SSukumar Swaminathan MATCHMAP **fcp_bpl_table; 46fcf3ce44SJohn Forte #endif /* EMLXS_SPARC */ 47fcf3ce44SJohn Forte 48fcf3ce44SJohn Forte buf_info = &bufinfo; 49fcf3ce44SJohn Forte cfg = &CFG; 50fcf3ce44SJohn Forte 51*82527734SSukumar Swaminathan bzero(hba->memseg, sizeof (hba->memseg)); 52fcf3ce44SJohn Forte 53fcf3ce44SJohn Forte /* 54fcf3ce44SJohn Forte * Initialize fc_table 55fcf3ce44SJohn Forte */ 56*82527734SSukumar Swaminathan cnt = cfg[CFG_NUM_IOTAGS].current; 57*82527734SSukumar Swaminathan if (cnt) { 58*82527734SSukumar Swaminathan hba->max_iotag = cnt; 59*82527734SSukumar Swaminathan } 60*82527734SSukumar 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)); 64*82527734SSukumar 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 72*82527734SSukumar Swaminathan goto failed; 73fcf3ce44SJohn Forte } 74*82527734SSukumar Swaminathan hba->fc_table = buf_info->virt; 75*82527734SSukumar Swaminathan bzero(hba->fc_table, buf_info->size); 76fcf3ce44SJohn Forte 77fcf3ce44SJohn Forte #ifdef EMLXS_SPARC 78*82527734SSukumar Swaminathan if (!(hba->model_info.sli_mask & EMLXS_SLI4_MASK)) { 79fcf3ce44SJohn Forte /* 80*82527734SSukumar 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)); 84*82527734SSukumar 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 92*82527734SSukumar Swaminathan goto failed; 93fcf3ce44SJohn Forte } 94*82527734SSukumar Swaminathan hba->sli.sli3.fcp_bpl_table = buf_info->virt; 95*82527734SSukumar Swaminathan bzero(hba->sli.sli3.fcp_bpl_table, buf_info->size); 96fcf3ce44SJohn Forte 97*82527734SSukumar Swaminathan /* Allocate a pool of BPLs for the FCP MEM_BPL table */ 98*82527734SSukumar Swaminathan seg = &hba->sli.sli3.fcp_bpl_seg; 99*82527734SSukumar Swaminathan bzero(seg, sizeof (MEMSEG)); 100*82527734SSukumar Swaminathan (void) strcpy(seg->fc_label, "FCP BPL Pool"); 101*82527734SSukumar Swaminathan seg->fc_memtag = MEM_BPL; 102*82527734SSukumar Swaminathan seg->fc_memsize = (3 * sizeof (ULP_BDE64)); 103*82527734SSukumar Swaminathan seg->fc_numblks = hba->max_iotag; 104*82527734SSukumar Swaminathan seg->fc_reserved = 0; 105*82527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 106*82527734SSukumar Swaminathan seg->fc_memalign = 32; 107fcf3ce44SJohn Forte 108*82527734SSukumar Swaminathan if (emlxs_mem_pool_alloc(hba, seg) == NULL) { 109*82527734SSukumar Swaminathan goto failed; 110fcf3ce44SJohn Forte } 111fcf3ce44SJohn Forte 112*82527734SSukumar Swaminathan /* Initialize the FCP MEM_BPL table */ 113*82527734SSukumar Swaminathan fcp_bpl_table = (MATCHMAP**)hba->sli.sli3.fcp_bpl_table; 114*82527734SSukumar Swaminathan mp = (MATCHMAP*)seg->fc_memget_ptr; 115*82527734SSukumar Swaminathan for (i = 0; i < seg->fc_numblks; i++) { 116*82527734SSukumar Swaminathan mp->flag |= MAP_TABLE_ALLOCATED; 117*82527734SSukumar Swaminathan *fcp_bpl_table = mp; 118fcf3ce44SJohn Forte 119*82527734SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr; 120*82527734SSukumar Swaminathan fcp_bpl_table++; 121*82527734SSukumar Swaminathan } 122fcf3ce44SJohn Forte } 123fcf3ce44SJohn Forte #endif /* EMLXS_SPARC */ 124fcf3ce44SJohn Forte 125*82527734SSukumar Swaminathan /* Prepare the memory pools */ 126fcf3ce44SJohn Forte for (i = 0; i < FC_MAX_SEG; i++) { 127*82527734SSukumar Swaminathan seg = &hba->memseg[i]; 128fcf3ce44SJohn Forte 129fcf3ce44SJohn Forte switch (i) { 130fcf3ce44SJohn Forte case MEM_NLP: 131*82527734SSukumar Swaminathan (void) strcpy(seg->fc_label, "Node Pool"); 132*82527734SSukumar Swaminathan seg->fc_memtag = MEM_NLP; 133*82527734SSukumar Swaminathan seg->fc_memsize = sizeof (NODELIST); 134*82527734SSukumar Swaminathan seg->fc_numblks = (int16_t)hba->max_nodes + 2; 135*82527734SSukumar Swaminathan seg->fc_reserved = 0; 136*82527734SSukumar Swaminathan seg->fc_memflag = 0; 137fcf3ce44SJohn Forte break; 138*82527734SSukumar Swaminathan 139fcf3ce44SJohn Forte case MEM_IOCB: 140*82527734SSukumar Swaminathan (void) strcpy(seg->fc_label, "IOCB Pool"); 141*82527734SSukumar Swaminathan seg->fc_memtag = MEM_IOCB; 142*82527734SSukumar Swaminathan seg->fc_memsize = sizeof (IOCBQ); 143*82527734SSukumar Swaminathan seg->fc_numblks = (uint16_t)cfg[CFG_NUM_IOCBS].current; 144*82527734SSukumar Swaminathan seg->fc_reserved = 0; 145*82527734SSukumar Swaminathan seg->fc_memflag = 0; 146fcf3ce44SJohn Forte break; 147*82527734SSukumar Swaminathan 148fcf3ce44SJohn Forte case MEM_MBOX: 149*82527734SSukumar Swaminathan (void) strcpy(seg->fc_label, "MBOX Pool"); 150*82527734SSukumar Swaminathan seg->fc_memtag = MEM_MBOX; 151*82527734SSukumar Swaminathan seg->fc_memsize = sizeof (MAILBOXQ); 152*82527734SSukumar Swaminathan seg->fc_numblks = (int16_t)hba->max_nodes + 32; 153*82527734SSukumar Swaminathan seg->fc_reserved = 0; 154*82527734SSukumar Swaminathan seg->fc_memflag = 0; 155fcf3ce44SJohn Forte break; 156*82527734SSukumar Swaminathan 157fcf3ce44SJohn Forte case MEM_BPL: 158*82527734SSukumar Swaminathan if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) { 159*82527734SSukumar Swaminathan continue; 160*82527734SSukumar Swaminathan } 161*82527734SSukumar Swaminathan (void) strcpy(seg->fc_label, "BPL Pool"); 162*82527734SSukumar Swaminathan seg->fc_memtag = MEM_BPL; 163*82527734SSukumar Swaminathan seg->fc_memsize = hba->sli.sli3.mem_bpl_size; 164*82527734SSukumar Swaminathan seg->fc_numblks = (int16_t)hba->max_iotag + 2; 165*82527734SSukumar Swaminathan seg->fc_reserved = 0; 166*82527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 167*82527734SSukumar Swaminathan seg->fc_memalign = 32; 168fcf3ce44SJohn Forte break; 169*82527734SSukumar Swaminathan 170fcf3ce44SJohn Forte case MEM_BUF: 171*82527734SSukumar Swaminathan /* These are the unsolicited ELS buffers. */ 172*82527734SSukumar Swaminathan (void) strcpy(seg->fc_label, "BUF Pool"); 173*82527734SSukumar Swaminathan seg->fc_memtag = MEM_BUF; 174*82527734SSukumar Swaminathan seg->fc_memsize = MEM_BUF_SIZE; 175*82527734SSukumar Swaminathan seg->fc_numblks = MEM_ELSBUF_COUNT + MEM_BUF_COUNT; 176*82527734SSukumar Swaminathan seg->fc_reserved = 0; 177*82527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 178*82527734SSukumar Swaminathan seg->fc_memalign = 32; 179fcf3ce44SJohn Forte break; 180*82527734SSukumar Swaminathan 181fcf3ce44SJohn Forte case MEM_IPBUF: 182*82527734SSukumar Swaminathan /* These are the unsolicited IP buffers. */ 183*82527734SSukumar Swaminathan if (cfg[CFG_NETWORK_ON].current == 0) { 184*82527734SSukumar Swaminathan continue; 185fcf3ce44SJohn Forte } 186fcf3ce44SJohn Forte 187*82527734SSukumar Swaminathan (void) strcpy(seg->fc_label, "IPBUF Pool"); 188*82527734SSukumar Swaminathan seg->fc_memtag = MEM_IPBUF; 189*82527734SSukumar Swaminathan seg->fc_memsize = MEM_IPBUF_SIZE; 190*82527734SSukumar Swaminathan seg->fc_numblks = MEM_IPBUF_COUNT; 191*82527734SSukumar Swaminathan seg->fc_reserved = 0; 192*82527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 193*82527734SSukumar Swaminathan seg->fc_memalign = 32; 194*82527734SSukumar Swaminathan break; 195*82527734SSukumar Swaminathan 196*82527734SSukumar Swaminathan case MEM_CTBUF: 197*82527734SSukumar Swaminathan /* These are the unsolicited CT buffers. */ 198*82527734SSukumar Swaminathan (void) strcpy(seg->fc_label, "CTBUF Pool"); 199*82527734SSukumar Swaminathan seg->fc_memtag = MEM_CTBUF; 200*82527734SSukumar Swaminathan seg->fc_memsize = MEM_CTBUF_SIZE; 201*82527734SSukumar Swaminathan seg->fc_numblks = MEM_CTBUF_COUNT; 202*82527734SSukumar Swaminathan seg->fc_reserved = 0; 203*82527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 204*82527734SSukumar Swaminathan seg->fc_memalign = 32; 205*82527734SSukumar Swaminathan break; 206*82527734SSukumar Swaminathan 207*82527734SSukumar Swaminathan case MEM_FCTBUF: 208*82527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 209*82527734SSukumar Swaminathan /* These are the unsolicited FCT buffers. */ 210*82527734SSukumar Swaminathan if (hba->tgt_mode == 0) { 211*82527734SSukumar Swaminathan continue; 212*82527734SSukumar Swaminathan } 213*82527734SSukumar Swaminathan 214*82527734SSukumar Swaminathan (void) strcpy(seg->fc_label, "FCTBUF Pool"); 215*82527734SSukumar Swaminathan seg->fc_memtag = MEM_FCTBUF; 216*82527734SSukumar Swaminathan seg->fc_memsize = MEM_FCTBUF_SIZE; 217*82527734SSukumar Swaminathan seg->fc_numblks = MEM_FCTBUF_COUNT; 218*82527734SSukumar Swaminathan seg->fc_reserved = 0; 219*82527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG; 220*82527734SSukumar Swaminathan seg->fc_memalign = 32; 221*82527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 222*82527734SSukumar Swaminathan break; 223*82527734SSukumar Swaminathan 224*82527734SSukumar Swaminathan default: 225*82527734SSukumar Swaminathan continue; 226*82527734SSukumar Swaminathan } 227*82527734SSukumar Swaminathan 228*82527734SSukumar Swaminathan if (seg->fc_memsize == 0) { 229*82527734SSukumar Swaminathan continue; 230*82527734SSukumar Swaminathan } 231*82527734SSukumar Swaminathan 232*82527734SSukumar Swaminathan if (emlxs_mem_pool_alloc(hba, seg) == NULL) { 233*82527734SSukumar Swaminathan goto failed; 234*82527734SSukumar Swaminathan } 235fcf3ce44SJohn Forte 236fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg, 237*82527734SSukumar Swaminathan "%s: seg=%p size=%x count=%d flags=%x base=%p", 238*82527734SSukumar Swaminathan seg->fc_label, seg, seg->fc_memsize, seg->fc_numblks, 239*82527734SSukumar Swaminathan seg->fc_memflag, seg->fc_memget_ptr); 240fcf3ce44SJohn Forte } 241fcf3ce44SJohn Forte 242fcf3ce44SJohn Forte return (1); 243fcf3ce44SJohn Forte 244*82527734SSukumar Swaminathan failed: 245fcf3ce44SJohn Forte 246*82527734SSukumar Swaminathan (void) emlxs_mem_free_buffer(hba); 247*82527734SSukumar Swaminathan return (0); 248*82527734SSukumar Swaminathan 249*82527734SSukumar Swaminathan } /* emlxs_mem_alloc_buffer() */ 250fcf3ce44SJohn Forte 251fcf3ce44SJohn Forte 252fcf3ce44SJohn Forte /* 253fcf3ce44SJohn Forte * emlxs_mem_free_buffer 254fcf3ce44SJohn Forte * 255fcf3ce44SJohn Forte * This routine will free iocb/data buffer space 256fcf3ce44SJohn Forte * and TGTM resource. 257fcf3ce44SJohn Forte */ 258fcf3ce44SJohn Forte extern int 259fcf3ce44SJohn Forte emlxs_mem_free_buffer(emlxs_hba_t *hba) 260fcf3ce44SJohn Forte { 261fcf3ce44SJohn Forte emlxs_port_t *vport; 262fcf3ce44SJohn Forte int32_t j; 263*82527734SSukumar Swaminathan MATCHMAP *mp; 264*82527734SSukumar Swaminathan CHANNEL *cp; 265fcf3ce44SJohn Forte RING *rp; 266fcf3ce44SJohn Forte MBUF_INFO *buf_info; 267fcf3ce44SJohn Forte MBUF_INFO bufinfo; 268fcf3ce44SJohn Forte 269fcf3ce44SJohn Forte buf_info = &bufinfo; 270fcf3ce44SJohn Forte 271*82527734SSukumar Swaminathan for (j = 0; j < hba->chan_count; j++) { 272*82527734SSukumar Swaminathan cp = &hba->chan[j]; 273fcf3ce44SJohn Forte 274fcf3ce44SJohn Forte /* Flush the ring */ 275*82527734SSukumar Swaminathan (void) emlxs_tx_channel_flush(hba, cp, 0); 276*82527734SSukumar Swaminathan } 277*82527734SSukumar Swaminathan 278*82527734SSukumar Swaminathan if (!(hba->model_info.sli_mask & EMLXS_SLI4_MASK)) { 279*82527734SSukumar Swaminathan /* free the mapped address match area for each ring */ 280*82527734SSukumar Swaminathan for (j = 0; j < MAX_RINGS; j++) { 281*82527734SSukumar Swaminathan rp = &hba->sli.sli3.ring[j]; 282fcf3ce44SJohn Forte 283fcf3ce44SJohn Forte while (rp->fc_mpoff) { 284fcf3ce44SJohn Forte uint64_t addr; 285fcf3ce44SJohn Forte 286fcf3ce44SJohn Forte addr = 0; 287*82527734SSukumar Swaminathan mp = (MATCHMAP *)(rp->fc_mpoff); 288fcf3ce44SJohn Forte 289*82527734SSukumar Swaminathan if ((j == hba->channel_els) || 290*82527734SSukumar Swaminathan (j == hba->channel_ct) || 291fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 292*82527734SSukumar Swaminathan (j == hba->CHANNEL_FCT) || 293fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 294*82527734SSukumar Swaminathan (j == hba->channel_ip)) { 295*82527734SSukumar Swaminathan addr = mp->phys; 296fcf3ce44SJohn Forte } 297291a2b48SSukumar Swaminathan 298*82527734SSukumar Swaminathan if ((mp = emlxs_mem_get_vaddr(hba, rp, addr))) { 299*82527734SSukumar Swaminathan if (j == hba->channel_els) { 300*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, 301*82527734SSukumar Swaminathan MEM_ELSBUF, (uint8_t *)mp); 302*82527734SSukumar Swaminathan } else if (j == hba->channel_ct) { 303*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, 304*82527734SSukumar Swaminathan MEM_CTBUF, (uint8_t *)mp); 305*82527734SSukumar Swaminathan } else if (j == hba->channel_ip) { 306*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, 307*82527734SSukumar Swaminathan MEM_IPBUF, (uint8_t *)mp); 308fcf3ce44SJohn Forte } 309fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 310*82527734SSukumar Swaminathan else if (j == hba->CHANNEL_FCT) { 311*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, 312*82527734SSukumar Swaminathan MEM_FCTBUF, (uint8_t *)mp); 313fcf3ce44SJohn Forte } 314fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 315fcf3ce44SJohn Forte 316fcf3ce44SJohn Forte } 317fcf3ce44SJohn Forte } 318fcf3ce44SJohn Forte } 319*82527734SSukumar Swaminathan } 320fcf3ce44SJohn Forte 321fcf3ce44SJohn Forte if (hba->flag & FC_HBQ_ENABLED) { 322fcf3ce44SJohn Forte emlxs_hbq_free_all(hba, EMLXS_ELS_HBQ_ID); 323fcf3ce44SJohn Forte emlxs_hbq_free_all(hba, EMLXS_IP_HBQ_ID); 324fcf3ce44SJohn Forte emlxs_hbq_free_all(hba, EMLXS_CT_HBQ_ID); 325*82527734SSukumar Swaminathan 326fcf3ce44SJohn Forte if (hba->tgt_mode) { 327fcf3ce44SJohn Forte emlxs_hbq_free_all(hba, EMLXS_FCT_HBQ_ID); 328fcf3ce44SJohn Forte } 329fcf3ce44SJohn Forte } 330fcf3ce44SJohn Forte 331fcf3ce44SJohn Forte /* Free the nodes */ 332fcf3ce44SJohn Forte for (j = 0; j < MAX_VPORTS; j++) { 333fcf3ce44SJohn Forte vport = &VPORT(j); 334fcf3ce44SJohn Forte if (vport->node_count) { 335fcf3ce44SJohn Forte emlxs_node_destroy_all(vport); 336fcf3ce44SJohn Forte } 337fcf3ce44SJohn Forte } 338fcf3ce44SJohn Forte 339*82527734SSukumar Swaminathan /* Make sure the mailbox queue is empty */ 340*82527734SSukumar Swaminathan emlxs_mb_flush(hba); 341*82527734SSukumar Swaminathan 342fcf3ce44SJohn Forte /* Free memory associated with all buffers on get buffer pool */ 343*82527734SSukumar Swaminathan if (hba->fc_table) { 344fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 345*82527734SSukumar Swaminathan buf_info->size = hba->max_iotag * sizeof (emlxs_buf_t *); 346*82527734SSukumar Swaminathan buf_info->virt = hba->fc_table; 347fcf3ce44SJohn Forte emlxs_mem_free(hba, buf_info); 348*82527734SSukumar Swaminathan hba->fc_table = NULL; 349fcf3ce44SJohn Forte } 350*82527734SSukumar Swaminathan 351fcf3ce44SJohn Forte #ifdef EMLXS_SPARC 352*82527734SSukumar Swaminathan if (hba->sli.sli3.fcp_bpl_table) { 353fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 354*82527734SSukumar Swaminathan buf_info->size = hba->max_iotag * sizeof (MATCHMAP *); 355*82527734SSukumar Swaminathan buf_info->virt = hba->sli.sli3.fcp_bpl_table; 356fcf3ce44SJohn Forte emlxs_mem_free(hba, buf_info); 357*82527734SSukumar Swaminathan hba->sli.sli3.fcp_bpl_table = NULL; 358fcf3ce44SJohn Forte } 359291a2b48SSukumar Swaminathan 360*82527734SSukumar Swaminathan if (hba->sli.sli3.fcp_bpl_seg.fc_memsize) { 361*82527734SSukumar Swaminathan emlxs_mem_pool_free(hba, &hba->sli.sli3.fcp_bpl_seg); 362*82527734SSukumar Swaminathan bzero(&hba->sli.sli3.fcp_bpl_seg, sizeof (MEMSEG)); 363fcf3ce44SJohn Forte } 364fcf3ce44SJohn Forte #endif /* EMLXS_SPARC */ 365fcf3ce44SJohn Forte 366fcf3ce44SJohn Forte /* Free the memory segments */ 367fcf3ce44SJohn Forte for (j = 0; j < FC_MAX_SEG; j++) { 368*82527734SSukumar Swaminathan emlxs_mem_pool_free(hba, &hba->memseg[j]); 369fcf3ce44SJohn Forte } 370fcf3ce44SJohn Forte 371fcf3ce44SJohn Forte return (0); 372fcf3ce44SJohn Forte 373fcf3ce44SJohn Forte } /* emlxs_mem_free_buffer() */ 374fcf3ce44SJohn Forte 375fcf3ce44SJohn Forte 376*82527734SSukumar Swaminathan extern MEMSEG * 377*82527734SSukumar Swaminathan emlxs_mem_pool_alloc(emlxs_hba_t *hba, MEMSEG *seg) 378fcf3ce44SJohn Forte { 379fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 380fcf3ce44SJohn Forte uint8_t *bp = NULL; 381*82527734SSukumar Swaminathan MATCHMAP *mp = NULL; 382*82527734SSukumar Swaminathan MBUF_INFO *buf_info; 383*82527734SSukumar Swaminathan MBUF_INFO local_buf_info; 384*82527734SSukumar Swaminathan uint32_t i; 385*82527734SSukumar Swaminathan 386*82527734SSukumar Swaminathan buf_info = &local_buf_info; 387*82527734SSukumar Swaminathan 388*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMGET_LOCK); 389*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMPUT_LOCK); 390*82527734SSukumar Swaminathan 391*82527734SSukumar Swaminathan /* Calculate total memory size */ 392*82527734SSukumar Swaminathan seg->fc_total_memsize = (seg->fc_memsize * seg->fc_numblks); 393*82527734SSukumar Swaminathan 394*82527734SSukumar Swaminathan if (seg->fc_total_memsize == 0) { 395*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 396*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 397*82527734SSukumar Swaminathan return (NULL); 398*82527734SSukumar Swaminathan } 399*82527734SSukumar Swaminathan 400*82527734SSukumar Swaminathan if (!(seg->fc_memflag & FC_MBUF_DMA)) { 401*82527734SSukumar Swaminathan goto vmem_pool; 402*82527734SSukumar Swaminathan } 403*82527734SSukumar Swaminathan 404*82527734SSukumar Swaminathan /* dma_pool */ 405*82527734SSukumar Swaminathan 406*82527734SSukumar Swaminathan for (i = 0; i < seg->fc_numblks; i++) { 407*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 408*82527734SSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 409*82527734SSukumar Swaminathan buf_info->align = sizeof (void *); 410*82527734SSukumar Swaminathan 411*82527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 412*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 413*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 414*82527734SSukumar Swaminathan "%s desc[%d]. size=%d", seg->fc_label, i, 415*82527734SSukumar Swaminathan buf_info->size); 416*82527734SSukumar Swaminathan 417*82527734SSukumar Swaminathan goto failed; 418*82527734SSukumar Swaminathan } 419*82527734SSukumar Swaminathan 420*82527734SSukumar Swaminathan mp = (MATCHMAP *)buf_info->virt; 421*82527734SSukumar Swaminathan bzero(mp, sizeof (MATCHMAP)); 422*82527734SSukumar Swaminathan 423*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 424*82527734SSukumar Swaminathan buf_info->size = seg->fc_memsize; 425*82527734SSukumar Swaminathan buf_info->flags = seg->fc_memflag; 426*82527734SSukumar Swaminathan buf_info->align = seg->fc_memalign; 427*82527734SSukumar Swaminathan 428*82527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 429*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 430*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 431*82527734SSukumar Swaminathan "%s buffer[%d]. size=%d", seg->fc_label, i, 432*82527734SSukumar Swaminathan buf_info->size); 433*82527734SSukumar Swaminathan 434*82527734SSukumar Swaminathan /* Free the mp object */ 435*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 436*82527734SSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 437*82527734SSukumar Swaminathan buf_info->virt = (uint32_t *)mp; 438*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 439*82527734SSukumar Swaminathan 440*82527734SSukumar Swaminathan goto failed; 441*82527734SSukumar Swaminathan } 442*82527734SSukumar Swaminathan bp = (uint8_t *)buf_info->virt; 443*82527734SSukumar Swaminathan bzero(bp, seg->fc_memsize); 444*82527734SSukumar Swaminathan 445*82527734SSukumar Swaminathan mp->virt = buf_info->virt; 446*82527734SSukumar Swaminathan mp->phys = buf_info->phys; 447*82527734SSukumar Swaminathan mp->size = buf_info->size; 448*82527734SSukumar Swaminathan mp->dma_handle = buf_info->dma_handle; 449*82527734SSukumar Swaminathan mp->data_handle = buf_info->data_handle; 450*82527734SSukumar Swaminathan mp->tag = seg->fc_memtag; 451*82527734SSukumar Swaminathan mp->segment = seg; 452*82527734SSukumar Swaminathan mp->flag |= MAP_POOL_ALLOCATED; 453*82527734SSukumar Swaminathan 454*82527734SSukumar Swaminathan /* Add the buffer desc to the tail of the pool freelist */ 455*82527734SSukumar Swaminathan if (seg->fc_memget_end == NULL) { 456*82527734SSukumar Swaminathan seg->fc_memget_ptr = (uint8_t *)mp; 457*82527734SSukumar Swaminathan seg->fc_memget_cnt = 1; 458*82527734SSukumar Swaminathan } else { 459*82527734SSukumar Swaminathan *((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)mp; 460*82527734SSukumar Swaminathan seg->fc_memget_cnt++; 461*82527734SSukumar Swaminathan } 462*82527734SSukumar Swaminathan seg->fc_memget_end = (uint8_t *)mp; 463*82527734SSukumar Swaminathan } 464*82527734SSukumar Swaminathan 465*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 466*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 467*82527734SSukumar Swaminathan return (seg); 468*82527734SSukumar Swaminathan 469*82527734SSukumar Swaminathan vmem_pool: 470*82527734SSukumar Swaminathan 471*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 472*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 473*82527734SSukumar Swaminathan 474*82527734SSukumar Swaminathan seg->fc_memstart_virt = kmem_zalloc(seg->fc_total_memsize, KM_SLEEP); 475*82527734SSukumar Swaminathan 476*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMGET_LOCK); 477*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMPUT_LOCK); 478*82527734SSukumar Swaminathan 479*82527734SSukumar Swaminathan if (seg->fc_memstart_virt == NULL) { 480*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 481*82527734SSukumar Swaminathan "%s base. size=%d", seg->fc_label, 482*82527734SSukumar Swaminathan seg->fc_total_memsize); 483*82527734SSukumar Swaminathan 484*82527734SSukumar Swaminathan goto failed; 485*82527734SSukumar Swaminathan } 486*82527734SSukumar Swaminathan 487*82527734SSukumar Swaminathan bp = (uint8_t *)seg->fc_memstart_virt; 488*82527734SSukumar Swaminathan for (i = 0; i < seg->fc_numblks; i++) { 489*82527734SSukumar Swaminathan 490*82527734SSukumar Swaminathan /* Add the buffer to the tail of the pool freelist */ 491*82527734SSukumar Swaminathan if (seg->fc_memget_end == NULL) { 492*82527734SSukumar Swaminathan seg->fc_memget_ptr = (uint8_t *)bp; 493*82527734SSukumar Swaminathan seg->fc_memget_cnt = 1; 494*82527734SSukumar Swaminathan } else { 495*82527734SSukumar Swaminathan *((uint8_t **)(seg->fc_memget_end)) = (uint8_t *)bp; 496*82527734SSukumar Swaminathan seg->fc_memget_cnt++; 497*82527734SSukumar Swaminathan } 498*82527734SSukumar Swaminathan seg->fc_memget_end = (uint8_t *)bp; 499*82527734SSukumar Swaminathan 500*82527734SSukumar Swaminathan bp += seg->fc_memsize; 501*82527734SSukumar Swaminathan } 502*82527734SSukumar Swaminathan 503*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 504*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 505*82527734SSukumar Swaminathan return (seg); 506*82527734SSukumar Swaminathan 507*82527734SSukumar Swaminathan failed: 508*82527734SSukumar Swaminathan 509*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 510*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 511*82527734SSukumar Swaminathan emlxs_mem_pool_free(hba, seg); 512*82527734SSukumar Swaminathan return (NULL); 513*82527734SSukumar Swaminathan 514*82527734SSukumar Swaminathan } /* emlxs_mem_pool_alloc() */ 515*82527734SSukumar Swaminathan 516*82527734SSukumar Swaminathan 517*82527734SSukumar Swaminathan extern void 518*82527734SSukumar Swaminathan emlxs_mem_pool_free(emlxs_hba_t *hba, MEMSEG *seg) 519*82527734SSukumar Swaminathan { 520*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 521*82527734SSukumar Swaminathan uint8_t *bp = NULL; 522*82527734SSukumar Swaminathan MATCHMAP *mp = NULL; 523*82527734SSukumar Swaminathan MBUF_INFO *buf_info; 524*82527734SSukumar Swaminathan MBUF_INFO local_buf_info; 525*82527734SSukumar Swaminathan MEMSEG segment; 526*82527734SSukumar Swaminathan uint32_t free; 527*82527734SSukumar Swaminathan 528*82527734SSukumar Swaminathan /* Save a local copy of the segment and */ 529*82527734SSukumar Swaminathan /* destroy the original outside of locks */ 530*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMGET_LOCK); 531*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMPUT_LOCK); 532*82527734SSukumar Swaminathan 533*82527734SSukumar Swaminathan free = seg->fc_memget_cnt + seg->fc_memput_cnt; 534*82527734SSukumar Swaminathan if (free < seg->fc_numblks) { 535*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_detail_msg, 536*82527734SSukumar Swaminathan "emlxs_mem_pool_free: %s not full. (%d < %d)", 537*82527734SSukumar Swaminathan seg->fc_label, free, seg->fc_numblks); 538*82527734SSukumar Swaminathan } 539*82527734SSukumar Swaminathan 540*82527734SSukumar Swaminathan bcopy(seg, &segment, sizeof (MEMSEG)); 541*82527734SSukumar Swaminathan bzero((char *)seg, sizeof (MEMSEG)); 542*82527734SSukumar Swaminathan seg = &segment; 543*82527734SSukumar Swaminathan 544*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 545*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 546*82527734SSukumar Swaminathan 547*82527734SSukumar Swaminathan /* Now free the memory */ 548*82527734SSukumar Swaminathan 549*82527734SSukumar Swaminathan if (!(seg->fc_memflag & FC_MBUF_DMA)) { 550*82527734SSukumar Swaminathan if (seg->fc_memstart_virt) { 551*82527734SSukumar Swaminathan kmem_free(seg->fc_memstart_virt, seg->fc_total_memsize); 552*82527734SSukumar Swaminathan } 553*82527734SSukumar Swaminathan 554*82527734SSukumar Swaminathan return; 555*82527734SSukumar Swaminathan } 556*82527734SSukumar Swaminathan 557*82527734SSukumar Swaminathan buf_info = &local_buf_info; 558*82527734SSukumar Swaminathan 559*82527734SSukumar Swaminathan /* Free memory associated with all buffers on get buffer pool */ 560*82527734SSukumar Swaminathan while ((bp = seg->fc_memget_ptr) != NULL) { 561*82527734SSukumar Swaminathan seg->fc_memget_ptr = *((uint8_t **)bp); 562*82527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 563*82527734SSukumar Swaminathan 564*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 565*82527734SSukumar Swaminathan buf_info->size = mp->size; 566*82527734SSukumar Swaminathan buf_info->virt = mp->virt; 567*82527734SSukumar Swaminathan buf_info->phys = mp->phys; 568*82527734SSukumar Swaminathan buf_info->dma_handle = mp->dma_handle; 569*82527734SSukumar Swaminathan buf_info->data_handle = mp->data_handle; 570*82527734SSukumar Swaminathan buf_info->flags = seg->fc_memflag; 571*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 572*82527734SSukumar Swaminathan 573*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 574*82527734SSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 575*82527734SSukumar Swaminathan buf_info->virt = (uint32_t *)mp; 576*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 577*82527734SSukumar Swaminathan } 578*82527734SSukumar Swaminathan 579*82527734SSukumar Swaminathan /* Free memory associated with all buffers on put buffer pool */ 580*82527734SSukumar Swaminathan while ((bp = seg->fc_memput_ptr) != NULL) { 581*82527734SSukumar Swaminathan seg->fc_memput_ptr = *((uint8_t **)bp); 582*82527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 583*82527734SSukumar Swaminathan 584*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 585*82527734SSukumar Swaminathan buf_info->size = mp->size; 586*82527734SSukumar Swaminathan buf_info->virt = mp->virt; 587*82527734SSukumar Swaminathan buf_info->phys = mp->phys; 588*82527734SSukumar Swaminathan buf_info->dma_handle = mp->dma_handle; 589*82527734SSukumar Swaminathan buf_info->data_handle = mp->data_handle; 590*82527734SSukumar Swaminathan buf_info->flags = seg->fc_memflag; 591*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 592*82527734SSukumar Swaminathan 593*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 594*82527734SSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 595*82527734SSukumar Swaminathan buf_info->virt = (uint32_t *)mp; 596*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 597*82527734SSukumar Swaminathan } 598*82527734SSukumar Swaminathan 599*82527734SSukumar Swaminathan return; 600*82527734SSukumar Swaminathan 601*82527734SSukumar Swaminathan } /* emlxs_mem_pool_free() */ 602*82527734SSukumar Swaminathan 603*82527734SSukumar Swaminathan 604*82527734SSukumar Swaminathan extern uint8_t * 605*82527734SSukumar Swaminathan emlxs_mem_pool_get(emlxs_hba_t *hba, MEMSEG *seg, uint32_t priority) 606*82527734SSukumar Swaminathan { 607*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 608*82527734SSukumar Swaminathan uint8_t *bp = NULL; 609*82527734SSukumar Swaminathan MATCHMAP *mp; 610*82527734SSukumar Swaminathan uint32_t free; 611*82527734SSukumar Swaminathan 612*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMGET_LOCK); 613*82527734SSukumar Swaminathan 614*82527734SSukumar Swaminathan /* Check if memory segment destroyed! */ 615*82527734SSukumar Swaminathan if (seg->fc_total_memsize == 0) { 616*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 617*82527734SSukumar Swaminathan return (NULL); 618*82527734SSukumar Swaminathan } 619*82527734SSukumar Swaminathan 620*82527734SSukumar Swaminathan /* Check priority and reserved status */ 621*82527734SSukumar Swaminathan if ((priority == 0) && seg->fc_reserved) { 622*82527734SSukumar Swaminathan free = seg->fc_memget_cnt + seg->fc_memput_cnt; 623*82527734SSukumar Swaminathan if (free <= seg->fc_reserved) { 624*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_alloc_failed_msg, 625*82527734SSukumar Swaminathan "%s low. (%d <= %d)", seg->fc_label, 626*82527734SSukumar Swaminathan free, seg->fc_reserved); 627*82527734SSukumar Swaminathan 628*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 629*82527734SSukumar Swaminathan return (NULL); 630*82527734SSukumar Swaminathan } 631*82527734SSukumar Swaminathan } 632*82527734SSukumar Swaminathan 633*82527734SSukumar Swaminathan top: 634*82527734SSukumar Swaminathan 635*82527734SSukumar Swaminathan if (seg->fc_memget_ptr) { 636*82527734SSukumar Swaminathan 637*82527734SSukumar Swaminathan bp = seg->fc_memget_ptr; 638*82527734SSukumar Swaminathan 639*82527734SSukumar Swaminathan /* Remove buffer from freelist */ 640*82527734SSukumar Swaminathan if (seg->fc_memget_end == bp) { 641*82527734SSukumar Swaminathan seg->fc_memget_ptr = NULL; 642*82527734SSukumar Swaminathan seg->fc_memget_end = NULL; 643*82527734SSukumar Swaminathan seg->fc_memget_cnt = 0; 644*82527734SSukumar Swaminathan 645*82527734SSukumar Swaminathan } else { 646*82527734SSukumar Swaminathan seg->fc_memget_ptr = *((uint8_t **)bp); 647*82527734SSukumar Swaminathan seg->fc_memget_cnt--; 648*82527734SSukumar Swaminathan } 649*82527734SSukumar Swaminathan 650*82527734SSukumar Swaminathan if (!(seg->fc_memflag & FC_MBUF_DMA)) { 651*82527734SSukumar Swaminathan bzero(bp, seg->fc_memsize); 652*82527734SSukumar Swaminathan } else { 653*82527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 654*82527734SSukumar Swaminathan mp->fc_mptr = NULL; 655*82527734SSukumar Swaminathan mp->flag |= MAP_POOL_ALLOCATED; 656*82527734SSukumar Swaminathan } 657*82527734SSukumar Swaminathan 658*82527734SSukumar Swaminathan } else { 659*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMPUT_LOCK); 660*82527734SSukumar Swaminathan if (seg->fc_memput_ptr) { 661*82527734SSukumar Swaminathan /* 662*82527734SSukumar Swaminathan * Move list from memput to memget 663*82527734SSukumar Swaminathan */ 664*82527734SSukumar Swaminathan seg->fc_memget_ptr = seg->fc_memput_ptr; 665*82527734SSukumar Swaminathan seg->fc_memget_end = seg->fc_memput_end; 666*82527734SSukumar Swaminathan seg->fc_memget_cnt = seg->fc_memput_cnt; 667*82527734SSukumar Swaminathan seg->fc_memput_ptr = NULL; 668*82527734SSukumar Swaminathan seg->fc_memput_end = NULL; 669*82527734SSukumar Swaminathan seg->fc_memput_cnt = 0; 670*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 671*82527734SSukumar Swaminathan 672*82527734SSukumar Swaminathan goto top; 673*82527734SSukumar Swaminathan } 674*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 675*82527734SSukumar Swaminathan 676*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_alloc_failed_msg, 677*82527734SSukumar Swaminathan "%s empty.", seg->fc_label); 678*82527734SSukumar Swaminathan } 679*82527734SSukumar Swaminathan 680*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMGET_LOCK); 681*82527734SSukumar Swaminathan 682*82527734SSukumar Swaminathan return (bp); 683*82527734SSukumar Swaminathan 684*82527734SSukumar Swaminathan } /* emlxs_mem_pool_get() */ 685*82527734SSukumar Swaminathan 686*82527734SSukumar Swaminathan 687*82527734SSukumar Swaminathan extern MEMSEG * 688*82527734SSukumar Swaminathan emlxs_mem_pool_put(emlxs_hba_t *hba, MEMSEG *seg, uint8_t *bp) 689*82527734SSukumar Swaminathan { 690*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 691*82527734SSukumar Swaminathan MATCHMAP *mp; 692*82527734SSukumar Swaminathan uint8_t *base; 693*82527734SSukumar Swaminathan uint8_t *end; 694*82527734SSukumar Swaminathan 695*82527734SSukumar Swaminathan /* Free the pool object */ 696*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MEMPUT_LOCK); 697*82527734SSukumar Swaminathan 698*82527734SSukumar Swaminathan /* Check if memory segment destroyed! */ 699*82527734SSukumar Swaminathan if (seg->fc_total_memsize == 0) { 700*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 701*82527734SSukumar Swaminathan return (NULL); 702*82527734SSukumar Swaminathan } 703*82527734SSukumar Swaminathan 704*82527734SSukumar Swaminathan /* Check if buffer was just freed */ 705*82527734SSukumar Swaminathan if (seg->fc_memput_ptr == bp) { 706*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 707*82527734SSukumar Swaminathan "%s: Freeing free object: bp=%p", seg->fc_label, bp); 708*82527734SSukumar Swaminathan 709*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 710*82527734SSukumar Swaminathan return (NULL); 711*82527734SSukumar Swaminathan } 712*82527734SSukumar Swaminathan 713*82527734SSukumar Swaminathan /* Validate the buffer belongs to this pool */ 714*82527734SSukumar Swaminathan if (seg->fc_memflag & FC_MBUF_DMA) { 715*82527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 716*82527734SSukumar Swaminathan 717*82527734SSukumar Swaminathan if (!(mp->flag & MAP_POOL_ALLOCATED) || 718*82527734SSukumar Swaminathan (mp->segment != seg)) { 719*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 720*82527734SSukumar Swaminathan "emlxs_mem_pool_put: %s invalid: mp=%p " \ 721*82527734SSukumar Swaminathan "tag=0x%x flag=%x", seg->fc_label, 722*82527734SSukumar Swaminathan mp, mp->tag, mp->flag); 723*82527734SSukumar Swaminathan 724*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 725*82527734SSukumar Swaminathan 726*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 727*82527734SSukumar Swaminathan 728*82527734SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_shutdown_thread, 729*82527734SSukumar Swaminathan NULL, NULL); 730*82527734SSukumar Swaminathan 731*82527734SSukumar Swaminathan return (NULL); 732*82527734SSukumar Swaminathan } 733*82527734SSukumar Swaminathan 734*82527734SSukumar Swaminathan } else { /* Vmem_pool */ 735*82527734SSukumar Swaminathan base = seg->fc_memstart_virt; 736*82527734SSukumar Swaminathan end = seg->fc_memstart_virt + seg->fc_total_memsize; 737*82527734SSukumar Swaminathan 738*82527734SSukumar Swaminathan if (bp < base || bp >= end) { 739*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 740*82527734SSukumar Swaminathan "emlxs_mem_pool_put: %s Invalid: bp=%p base=%p " \ 741*82527734SSukumar Swaminathan "end=%p", seg->fc_label, 742*82527734SSukumar Swaminathan bp, base, end); 743*82527734SSukumar Swaminathan 744*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 745*82527734SSukumar Swaminathan 746*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 747*82527734SSukumar Swaminathan 748*82527734SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_shutdown_thread, 749*82527734SSukumar Swaminathan NULL, NULL); 750*82527734SSukumar Swaminathan 751*82527734SSukumar Swaminathan return (NULL); 752*82527734SSukumar Swaminathan } 753*82527734SSukumar Swaminathan } 754*82527734SSukumar Swaminathan 755*82527734SSukumar Swaminathan /* Release buffer to the end of the freelist */ 756*82527734SSukumar Swaminathan if (seg->fc_memput_end == NULL) { 757*82527734SSukumar Swaminathan seg->fc_memput_ptr = bp; 758*82527734SSukumar Swaminathan seg->fc_memput_cnt = 1; 759*82527734SSukumar Swaminathan } else { 760*82527734SSukumar Swaminathan *((uint8_t **)(seg->fc_memput_end)) = bp; 761*82527734SSukumar Swaminathan seg->fc_memput_cnt++; 762*82527734SSukumar Swaminathan } 763*82527734SSukumar Swaminathan seg->fc_memput_end = bp; 764*82527734SSukumar Swaminathan *((uint8_t **)(bp)) = NULL; 765*82527734SSukumar Swaminathan 766*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MEMPUT_LOCK); 767*82527734SSukumar Swaminathan 768*82527734SSukumar Swaminathan return (seg); 769*82527734SSukumar Swaminathan 770*82527734SSukumar Swaminathan } /* emlxs_mem_pool_put() */ 771*82527734SSukumar Swaminathan 772*82527734SSukumar Swaminathan 773*82527734SSukumar Swaminathan extern MATCHMAP * 774*82527734SSukumar Swaminathan emlxs_mem_buf_alloc(emlxs_hba_t *hba, uint32_t size) 775*82527734SSukumar Swaminathan { 776*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 777*82527734SSukumar Swaminathan uint8_t *bp = NULL; 778*82527734SSukumar Swaminathan MATCHMAP *mp = NULL; 779fcf3ce44SJohn Forte MBUF_INFO *buf_info; 780fcf3ce44SJohn Forte MBUF_INFO bufinfo; 781fcf3ce44SJohn Forte 782fcf3ce44SJohn Forte buf_info = &bufinfo; 783fcf3ce44SJohn Forte 784fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 785fcf3ce44SJohn Forte buf_info->size = sizeof (MATCHMAP); 786fcf3ce44SJohn Forte buf_info->align = sizeof (void *); 787fcf3ce44SJohn Forte 788fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 789fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 790fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 791fcf3ce44SJohn Forte "MEM_BUF_ALLOC buffer."); 792fcf3ce44SJohn Forte 793*82527734SSukumar Swaminathan return (NULL); 794fcf3ce44SJohn Forte } 795291a2b48SSukumar Swaminathan 796*82527734SSukumar Swaminathan mp = (MATCHMAP *)buf_info->virt; 797*82527734SSukumar Swaminathan bzero(mp, sizeof (MATCHMAP)); 798fcf3ce44SJohn Forte 799fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 800*82527734SSukumar Swaminathan buf_info->size = size; 801*82527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 802fcf3ce44SJohn Forte buf_info->align = 32; 803fcf3ce44SJohn Forte 804fcf3ce44SJohn Forte (void) emlxs_mem_alloc(hba, buf_info); 805fcf3ce44SJohn Forte if (buf_info->virt == NULL) { 806fcf3ce44SJohn Forte 807fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg, 808fcf3ce44SJohn Forte "MEM_BUF_ALLOC DMA buffer."); 809fcf3ce44SJohn Forte 810*82527734SSukumar Swaminathan /* Free the mp object */ 811728bdc9bSSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 812728bdc9bSSukumar Swaminathan buf_info->size = sizeof (MATCHMAP); 813*82527734SSukumar Swaminathan buf_info->virt = (uint32_t *)mp; 814728bdc9bSSukumar Swaminathan emlxs_mem_free(hba, buf_info); 815728bdc9bSSukumar Swaminathan 816fcf3ce44SJohn Forte return (0); 817fcf3ce44SJohn Forte } 818fcf3ce44SJohn Forte bp = (uint8_t *)buf_info->virt; 819fcf3ce44SJohn Forte bzero(bp, MEM_BUF_SIZE); 820fcf3ce44SJohn Forte 821*82527734SSukumar Swaminathan mp->virt = buf_info->virt; 822*82527734SSukumar Swaminathan mp->phys = buf_info->phys; 823*82527734SSukumar Swaminathan mp->size = buf_info->size; 824*82527734SSukumar Swaminathan mp->dma_handle = buf_info->dma_handle; 825*82527734SSukumar Swaminathan mp->data_handle = buf_info->data_handle; 826*82527734SSukumar Swaminathan mp->tag = MEM_BUF; 827*82527734SSukumar Swaminathan mp->flag |= MAP_BUF_ALLOCATED; 828fcf3ce44SJohn Forte 829*82527734SSukumar Swaminathan return (mp); 830fcf3ce44SJohn Forte 831fcf3ce44SJohn Forte } /* emlxs_mem_buf_alloc() */ 832fcf3ce44SJohn Forte 833fcf3ce44SJohn Forte 834*82527734SSukumar Swaminathan extern MATCHMAP * 835*82527734SSukumar Swaminathan emlxs_mem_buf_free(emlxs_hba_t *hba, MATCHMAP *mp) 836fcf3ce44SJohn Forte { 837fcf3ce44SJohn Forte MBUF_INFO bufinfo; 838fcf3ce44SJohn Forte MBUF_INFO *buf_info; 839fcf3ce44SJohn Forte 840fcf3ce44SJohn Forte buf_info = &bufinfo; 841fcf3ce44SJohn Forte 842*82527734SSukumar Swaminathan if (!(mp->flag & MAP_BUF_ALLOCATED)) { 843fcf3ce44SJohn Forte return (NULL); 844fcf3ce44SJohn Forte } 845fcf3ce44SJohn Forte 846fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 847*82527734SSukumar Swaminathan buf_info->size = mp->size; 848*82527734SSukumar Swaminathan buf_info->virt = mp->virt; 849*82527734SSukumar Swaminathan buf_info->phys = mp->phys; 850*82527734SSukumar Swaminathan buf_info->dma_handle = mp->dma_handle; 851*82527734SSukumar Swaminathan buf_info->data_handle = mp->data_handle; 852fcf3ce44SJohn Forte buf_info->flags = FC_MBUF_DMA; 853fcf3ce44SJohn Forte emlxs_mem_free(hba, buf_info); 854fcf3ce44SJohn Forte 855fcf3ce44SJohn Forte bzero(buf_info, sizeof (MBUF_INFO)); 856fcf3ce44SJohn Forte buf_info->size = sizeof (MATCHMAP); 857*82527734SSukumar Swaminathan buf_info->virt = (uint32_t *)mp; 858fcf3ce44SJohn Forte emlxs_mem_free(hba, buf_info); 859fcf3ce44SJohn Forte 860*82527734SSukumar Swaminathan return (mp); 861fcf3ce44SJohn Forte 862fcf3ce44SJohn Forte } /* emlxs_mem_buf_free() */ 863fcf3ce44SJohn Forte 864fcf3ce44SJohn Forte 865fcf3ce44SJohn Forte extern uint8_t * 866*82527734SSukumar Swaminathan emlxs_mem_get(emlxs_hba_t *hba, uint32_t seg_id, uint32_t priority) 867fcf3ce44SJohn Forte { 868fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 869*82527734SSukumar Swaminathan uint8_t *bp; 870fcf3ce44SJohn Forte MAILBOXQ *mbq; 871fcf3ce44SJohn Forte IOCBQ *iocbq; 872fcf3ce44SJohn Forte NODELIST *node; 873*82527734SSukumar Swaminathan MEMSEG *seg; 874fcf3ce44SJohn Forte 875*82527734SSukumar Swaminathan if (seg_id >= FC_MAX_SEG) { 876291a2b48SSukumar Swaminathan 877*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 878*82527734SSukumar Swaminathan "emlxs_mem_get: Invalid segment id = %d", 879*82527734SSukumar Swaminathan seg_id); 880fcf3ce44SJohn Forte 881fcf3ce44SJohn Forte return (NULL); 882fcf3ce44SJohn Forte } 883*82527734SSukumar Swaminathan seg = &hba->memseg[seg_id]; 884291a2b48SSukumar Swaminathan 885*82527734SSukumar Swaminathan /* Alloc a buffer from the pool */ 886*82527734SSukumar Swaminathan bp = emlxs_mem_pool_get(hba, seg, priority); 887fcf3ce44SJohn Forte 888*82527734SSukumar Swaminathan if (bp) { 889*82527734SSukumar Swaminathan switch (seg_id) { 890fcf3ce44SJohn Forte case MEM_MBOX: 891fcf3ce44SJohn Forte mbq = (MAILBOXQ *)bp; 892fcf3ce44SJohn Forte mbq->flag |= MBQ_POOL_ALLOCATED; 893fcf3ce44SJohn Forte break; 894fcf3ce44SJohn Forte 895fcf3ce44SJohn Forte case MEM_IOCB: 896fcf3ce44SJohn Forte iocbq = (IOCBQ *)bp; 897fcf3ce44SJohn Forte iocbq->flag |= IOCB_POOL_ALLOCATED; 898fcf3ce44SJohn Forte break; 899fcf3ce44SJohn Forte 900fcf3ce44SJohn Forte case MEM_NLP: 901fcf3ce44SJohn Forte node = (NODELIST *)bp; 902fcf3ce44SJohn Forte node->flag |= NODE_POOL_ALLOCATED; 903fcf3ce44SJohn Forte break; 904fcf3ce44SJohn Forte } 905fcf3ce44SJohn Forte } 906fcf3ce44SJohn Forte 907fcf3ce44SJohn Forte return (bp); 908fcf3ce44SJohn Forte 909fcf3ce44SJohn Forte } /* emlxs_mem_get() */ 910fcf3ce44SJohn Forte 911fcf3ce44SJohn Forte 912fcf3ce44SJohn Forte extern uint8_t * 913*82527734SSukumar Swaminathan emlxs_mem_put(emlxs_hba_t *hba, uint32_t seg_id, uint8_t *bp) 914fcf3ce44SJohn Forte { 915fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 916fcf3ce44SJohn Forte MAILBOXQ *mbq; 917*82527734SSukumar Swaminathan IOCBQ *iocbq; 918fcf3ce44SJohn Forte NODELIST *node; 919*82527734SSukumar Swaminathan MEMSEG *seg; 920*82527734SSukumar Swaminathan MATCHMAP *mp; 921fcf3ce44SJohn Forte 922*82527734SSukumar Swaminathan if (seg_id >= FC_MAX_SEG) { 923*82527734SSukumar Swaminathan 924*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pool_error_msg, 925*82527734SSukumar Swaminathan "emlxs_mem_put: Invalid segment id = %d: bp=%p", 926*82527734SSukumar Swaminathan seg_id, bp); 927*82527734SSukumar Swaminathan 928fcf3ce44SJohn Forte return (NULL); 929fcf3ce44SJohn Forte } 930*82527734SSukumar Swaminathan seg = &hba->memseg[seg_id]; 931291a2b48SSukumar Swaminathan 932*82527734SSukumar Swaminathan /* Verify buffer */ 933*82527734SSukumar Swaminathan switch (seg_id) { 934fcf3ce44SJohn Forte case MEM_MBOX: 935fcf3ce44SJohn Forte mbq = (MAILBOXQ *)bp; 936fcf3ce44SJohn Forte 937fcf3ce44SJohn Forte if (!(mbq->flag & MBQ_POOL_ALLOCATED)) { 938*82527734SSukumar Swaminathan return (NULL); 939fcf3ce44SJohn Forte } 940fcf3ce44SJohn Forte break; 941fcf3ce44SJohn Forte 942fcf3ce44SJohn Forte case MEM_IOCB: 943fcf3ce44SJohn Forte iocbq = (IOCBQ *)bp; 944fcf3ce44SJohn Forte 945fcf3ce44SJohn Forte if (!(iocbq->flag & IOCB_POOL_ALLOCATED)) { 946*82527734SSukumar Swaminathan return (NULL); 947fcf3ce44SJohn Forte } 948291a2b48SSukumar Swaminathan 949291a2b48SSukumar Swaminathan /* Any IOCBQ with a packet attached did not come */ 950291a2b48SSukumar Swaminathan /* from our pool */ 951fcf3ce44SJohn Forte if (iocbq->sbp) { 952*82527734SSukumar Swaminathan return (NULL); 953fcf3ce44SJohn Forte } 954fcf3ce44SJohn Forte break; 955fcf3ce44SJohn Forte 956fcf3ce44SJohn Forte case MEM_NLP: 957fcf3ce44SJohn Forte node = (NODELIST *)bp; 958fcf3ce44SJohn Forte 959fcf3ce44SJohn Forte if (!(node->flag & NODE_POOL_ALLOCATED)) { 960*82527734SSukumar Swaminathan return (NULL); 961fcf3ce44SJohn Forte } 962fcf3ce44SJohn Forte break; 963fcf3ce44SJohn Forte 964fcf3ce44SJohn Forte default: 965*82527734SSukumar Swaminathan mp = (MATCHMAP *)bp; 966fcf3ce44SJohn Forte 967*82527734SSukumar Swaminathan if (mp->flag & MAP_BUF_ALLOCATED) { 968*82527734SSukumar Swaminathan return ((uint8_t *)emlxs_mem_buf_free(hba, mp)); 969fcf3ce44SJohn Forte } 970291a2b48SSukumar Swaminathan 971*82527734SSukumar Swaminathan if (mp->flag & MAP_TABLE_ALLOCATED) { 972fcf3ce44SJohn Forte return (bp); 973fcf3ce44SJohn Forte } 974291a2b48SSukumar Swaminathan 975*82527734SSukumar Swaminathan if (!(mp->flag & MAP_POOL_ALLOCATED)) { 976*82527734SSukumar Swaminathan return (NULL); 977fcf3ce44SJohn Forte } 978fcf3ce44SJohn Forte break; 979fcf3ce44SJohn Forte } 980fcf3ce44SJohn Forte 981*82527734SSukumar Swaminathan /* Free a buffer to the pool */ 982*82527734SSukumar Swaminathan if (emlxs_mem_pool_put(hba, seg, bp) == NULL) { 983fcf3ce44SJohn Forte return (NULL); 984fcf3ce44SJohn Forte } 985291a2b48SSukumar Swaminathan 986fcf3ce44SJohn Forte return (bp); 987fcf3ce44SJohn Forte 988fcf3ce44SJohn Forte } /* emlxs_mem_put() */ 989fcf3ce44SJohn Forte 990fcf3ce44SJohn Forte 991fcf3ce44SJohn Forte /* 992fcf3ce44SJohn Forte * Look up the virtual address given a mapped address 993fcf3ce44SJohn Forte */ 994*82527734SSukumar 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 1002*82527734SSukumar Swaminathan if (rp->ringno == hba->channel_els) { 1003fcf3ce44SJohn Forte 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 1014fcf3ce44SJohn Forte if (rp->fc_mpon == (uint8_t *)mp) { 1015fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)prev; 1016fcf3ce44SJohn Forte } 1017291a2b48SSukumar Swaminathan 1018fcf3ce44SJohn Forte mp->fc_mptr = 0; 1019fcf3ce44SJohn Forte 1020*82527734SSukumar 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; 1029fcf3ce44SJohn Forte 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 1036*82527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ct) { 1037fcf3ce44SJohn Forte 1038fcf3ce44SJohn Forte 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 1049fcf3ce44SJohn Forte if (rp->fc_mpon == (uint8_t *)mp) { 1050fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)prev; 1051fcf3ce44SJohn Forte } 1052291a2b48SSukumar Swaminathan 1053fcf3ce44SJohn Forte mp->fc_mptr = 0; 1054fcf3ce44SJohn Forte 1055*82527734SSukumar 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; 1064fcf3ce44SJohn Forte 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 1071*82527734SSukumar Swaminathan } else if (rp->ringno == hba->channel_ip) { 1072fcf3ce44SJohn Forte 1073fcf3ce44SJohn Forte 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 1084fcf3ce44SJohn Forte if (rp->fc_mpon == (uint8_t *)mp) { 1085fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)prev; 1086fcf3ce44SJohn Forte } 1087291a2b48SSukumar Swaminathan 1088fcf3ce44SJohn Forte mp->fc_mptr = 0; 1089fcf3ce44SJohn Forte 1090*82527734SSukumar 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; 1099fcf3ce44SJohn Forte 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 1107*82527734SSukumar Swaminathan } else if (rp->ringno == hba->CHANNEL_FCT) { 1108fcf3ce44SJohn Forte 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 1119fcf3ce44SJohn Forte if (rp->fc_mpon == (uint8_t *)mp) { 1120fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)prev; 1121fcf3ce44SJohn Forte } 1122291a2b48SSukumar Swaminathan 1123fcf3ce44SJohn Forte mp->fc_mptr = 0; 1124fcf3ce44SJohn Forte 1125*82527734SSukumar 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; 1134fcf3ce44SJohn Forte 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 1141fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 1142fcf3ce44SJohn Forte } 1143fcf3ce44SJohn Forte 1144fcf3ce44SJohn Forte return (0); 1145fcf3ce44SJohn Forte 1146fcf3ce44SJohn Forte } /* 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 */ 1153*82527734SSukumar 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 { 1158*82527734SSukumar 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 */ 1164fcf3ce44SJohn Forte mp->fc_mptr = 0; 1165fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1166fcf3ce44SJohn Forte rp->fc_mpoff = (uint8_t *)mp; 1167fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)mp; 1168fcf3ce44SJohn Forte } else { 1169291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1170291a2b48SSukumar Swaminathan (uint8_t *)mp; 1171fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)mp; 1172fcf3ce44SJohn Forte } 1173fcf3ce44SJohn Forte 1174fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1175291a2b48SSukumar Swaminathan 1176fcf3ce44SJohn Forte /* return mapped address */ 1177*82527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 1178291a2b48SSukumar Swaminathan /* return mapped address */ 1179*82527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1180fcf3ce44SJohn Forte } else { 1181fcf3ce44SJohn Forte /* return mapped address */ 1182*82527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1183fcf3ce44SJohn Forte } 1184fcf3ce44SJohn Forte 1185fcf3ce44SJohn Forte HBASTATS.ElsUbPosted++; 1186fcf3ce44SJohn Forte 1187*82527734SSukumar 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 */ 1193fcf3ce44SJohn Forte mp->fc_mptr = 0; 1194fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1195fcf3ce44SJohn Forte rp->fc_mpoff = (uint8_t *)mp; 1196fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)mp; 1197fcf3ce44SJohn Forte } else { 1198291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1199291a2b48SSukumar Swaminathan (uint8_t *)mp; 1200fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)mp; 1201fcf3ce44SJohn Forte } 1202fcf3ce44SJohn Forte 1203fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1204fcf3ce44SJohn Forte /* return mapped address */ 1205*82527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 1206291a2b48SSukumar Swaminathan /* return mapped address */ 1207*82527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1208fcf3ce44SJohn Forte } else { 1209fcf3ce44SJohn Forte /* return mapped address */ 1210*82527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1211fcf3ce44SJohn Forte } 1212fcf3ce44SJohn Forte 1213fcf3ce44SJohn Forte HBASTATS.CtUbPosted++; 1214fcf3ce44SJohn Forte 1215fcf3ce44SJohn Forte 1216*82527734SSukumar 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 */ 1222fcf3ce44SJohn Forte mp->fc_mptr = 0; 1223fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1224fcf3ce44SJohn Forte rp->fc_mpoff = (uint8_t *)mp; 1225fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)mp; 1226fcf3ce44SJohn Forte } else { 1227291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1228291a2b48SSukumar Swaminathan (uint8_t *)mp; 1229fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)mp; 1230fcf3ce44SJohn Forte } 1231fcf3ce44SJohn Forte 1232fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1233fcf3ce44SJohn Forte /* return mapped address */ 1234*82527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 1235*82527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1236fcf3ce44SJohn Forte } else { 1237*82527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1238fcf3ce44SJohn Forte } 1239fcf3ce44SJohn Forte 1240fcf3ce44SJohn Forte HBASTATS.IpUbPosted++; 1241fcf3ce44SJohn Forte 1242fcf3ce44SJohn Forte 1243fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 1244*82527734SSukumar 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 */ 1250fcf3ce44SJohn Forte mp->fc_mptr = 0; 1251fcf3ce44SJohn Forte if (rp->fc_mpoff == 0) { 1252fcf3ce44SJohn Forte rp->fc_mpoff = (uint8_t *)mp; 1253fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)mp; 1254fcf3ce44SJohn Forte } else { 1255291a2b48SSukumar Swaminathan ((MATCHMAP *)(rp->fc_mpon))->fc_mptr = 1256291a2b48SSukumar Swaminathan (uint8_t *)mp; 1257fcf3ce44SJohn Forte rp->fc_mpon = (uint8_t *)mp; 1258fcf3ce44SJohn Forte } 1259fcf3ce44SJohn Forte 1260fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 1261fcf3ce44SJohn Forte /* return mapped address */ 1262*82527734SSukumar Swaminathan *haddr = PADDR_HI(mp->phys); 1263291a2b48SSukumar Swaminathan /* return mapped address */ 1264*82527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1265fcf3ce44SJohn Forte } else { 1266fcf3ce44SJohn Forte /* return mapped address */ 1267*82527734SSukumar Swaminathan *laddr = PADDR_LO(mp->phys); 1268fcf3ce44SJohn Forte } 1269fcf3ce44SJohn Forte 1270fcf3ce44SJohn Forte HBASTATS.FctUbPosted++; 1271*82527734SSukumar Swaminathan 1272fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 1273fcf3ce44SJohn Forte } 1274fcf3ce44SJohn Forte } /* emlxs_mem_map_vaddr() */ 1275fcf3ce44SJohn Forte 1276fcf3ce44SJohn Forte 1277*82527734SSukumar 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 1286*82527734SSukumar 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 1305fcf3ce44SJohn Forte hbq->HBQ_host_buf.virt = (void *)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 } 1314291a2b48SSukumar Swaminathan 1315fcf3ce44SJohn Forte return (0); 1316fcf3ce44SJohn Forte 1317fcf3ce44SJohn Forte } /* emlxs_hbq_alloc() */ 1318