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 */ 21c4ddbbe1SDaniel Beauregard 22c4ddbbe1SDaniel Beauregard /* 23c4ddbbe1SDaniel Beauregard * Copyright 2009 QLogic Corporation. All rights reserved. 24c4ddbbe1SDaniel Beauregard * Use is subject to license terms. 25c4ddbbe1SDaniel Beauregard */ 26c4ddbbe1SDaniel Beauregard 27fcf3ce44SJohn Forte /* 28c4ddbbe1SDaniel Beauregard * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 29fcf3ce44SJohn Forte * Use is subject to license terms. 30fcf3ce44SJohn Forte */ 31fcf3ce44SJohn Forte 32fcf3ce44SJohn Forte #include <sys/conf.h> 33fcf3ce44SJohn Forte #include <sys/ddi.h> 34fcf3ce44SJohn Forte #include <sys/sunddi.h> 35fcf3ce44SJohn Forte #include <sys/modctl.h> 36fcf3ce44SJohn Forte 37fcf3ce44SJohn Forte #include <stmf_defines.h> 38fcf3ce44SJohn Forte #include <fct_defines.h> 39fcf3ce44SJohn Forte #include <stmf.h> 40fcf3ce44SJohn Forte #include <portif.h> 41fcf3ce44SJohn Forte #include <fct.h> 42fcf3ce44SJohn Forte #include <qlt.h> 43fcf3ce44SJohn Forte #include <qlt_dma.h> 44fcf3ce44SJohn Forte 45fcf3ce44SJohn Forte #define BUF_COUNT_2K 2048 46fcf3ce44SJohn Forte #define BUF_COUNT_8K 512 47*3f3ce7b9SDaniel Beauregard #define BUF_COUNT_64K 256 48*3f3ce7b9SDaniel Beauregard #define BUF_COUNT_128K 1024 49fcf3ce44SJohn Forte #define BUF_COUNT_256K 8 50fcf3ce44SJohn Forte 51fcf3ce44SJohn Forte #define QLT_DMEM_MAX_BUF_SIZE (4 * 65536) 52fcf3ce44SJohn Forte #define QLT_DMEM_NBUCKETS 5 53fcf3ce44SJohn Forte static qlt_dmem_bucket_t bucket2K = { 2048, BUF_COUNT_2K }, 54fcf3ce44SJohn Forte bucket8K = { 8192, BUF_COUNT_8K }, 55fcf3ce44SJohn Forte bucket64K = { 65536, BUF_COUNT_64K }, 56fcf3ce44SJohn Forte bucket128k = { (2 * 65536), BUF_COUNT_128K }, 57fcf3ce44SJohn Forte bucket256k = { (4 * 65536), BUF_COUNT_256K }; 58fcf3ce44SJohn Forte 59fcf3ce44SJohn Forte static qlt_dmem_bucket_t *dmem_buckets[] = { &bucket2K, &bucket8K, 60fcf3ce44SJohn Forte &bucket64K, &bucket128k, &bucket256k, NULL }; 61fcf3ce44SJohn Forte static ddi_device_acc_attr_t acc; 62fcf3ce44SJohn Forte static ddi_dma_attr_t qlt_scsi_dma_attr = { 63fcf3ce44SJohn Forte DMA_ATTR_V0, /* dma_attr_version */ 64fcf3ce44SJohn Forte 0, /* low DMA address range */ 65fcf3ce44SJohn Forte 0xffffffffffffffff, /* high DMA address range */ 66fcf3ce44SJohn Forte 0xffffffff, /* DMA counter register */ 67fcf3ce44SJohn Forte 8192, /* DMA address alignment */ 68fcf3ce44SJohn Forte 0xff, /* DMA burstsizes */ 69fcf3ce44SJohn Forte 1, /* min effective DMA size */ 70fcf3ce44SJohn Forte 0xffffffff, /* max DMA xfer size */ 71fcf3ce44SJohn Forte 0xffffffff, /* segment boundary */ 72fcf3ce44SJohn Forte 1, /* s/g list length */ 73fcf3ce44SJohn Forte 1, /* granularity of device */ 74fcf3ce44SJohn Forte 0 /* DMA transfer flags */ 75fcf3ce44SJohn Forte }; 76fcf3ce44SJohn Forte 77fcf3ce44SJohn Forte fct_status_t 78fcf3ce44SJohn Forte qlt_dmem_init(qlt_state_t *qlt) 79fcf3ce44SJohn Forte { 80fcf3ce44SJohn Forte qlt_dmem_bucket_t *p; 81fcf3ce44SJohn Forte qlt_dmem_bctl_t *bctl, *bc; 82fcf3ce44SJohn Forte qlt_dmem_bctl_t *prev; 83fcf3ce44SJohn Forte int ndx, i; 84fcf3ce44SJohn Forte uint32_t total_mem; 85fcf3ce44SJohn Forte uint8_t *addr; 86fcf3ce44SJohn Forte uint8_t *host_addr; 87fcf3ce44SJohn Forte uint64_t dev_addr; 88fcf3ce44SJohn Forte ddi_dma_cookie_t cookie; 89fcf3ce44SJohn Forte uint32_t ncookie; 90fcf3ce44SJohn Forte uint32_t bsize; 91fcf3ce44SJohn Forte size_t len; 92fcf3ce44SJohn Forte 93a2255df3SDaniel Beauregard if (qlt->qlt_bucketcnt[0] != 0) { 94a2255df3SDaniel Beauregard bucket2K.dmem_nbufs = qlt->qlt_bucketcnt[0]; 95a2255df3SDaniel Beauregard } 96a2255df3SDaniel Beauregard if (qlt->qlt_bucketcnt[1] != 0) { 97a2255df3SDaniel Beauregard bucket8K.dmem_nbufs = qlt->qlt_bucketcnt[1]; 98a2255df3SDaniel Beauregard } 99a2255df3SDaniel Beauregard if (qlt->qlt_bucketcnt[2] != 0) { 100a2255df3SDaniel Beauregard bucket64K.dmem_nbufs = qlt->qlt_bucketcnt[2]; 101a2255df3SDaniel Beauregard } 102a2255df3SDaniel Beauregard if (qlt->qlt_bucketcnt[3] != 0) { 103a2255df3SDaniel Beauregard bucket128k.dmem_nbufs = qlt->qlt_bucketcnt[3]; 104fcf3ce44SJohn Forte } 105a2255df3SDaniel Beauregard if (qlt->qlt_bucketcnt[4] != 0) { 106a2255df3SDaniel Beauregard bucket256k.dmem_nbufs = qlt->qlt_bucketcnt[4]; 107a2255df3SDaniel Beauregard } 108a2255df3SDaniel Beauregard 109fcf3ce44SJohn Forte bsize = sizeof (dmem_buckets); 110c4ddbbe1SDaniel Beauregard ndx = (int)(bsize / sizeof (void *)); 111fcf3ce44SJohn Forte /* 112fcf3ce44SJohn Forte * The reason it is ndx - 1 everywhere is becasue the last bucket 113fcf3ce44SJohn Forte * pointer is NULL. 114fcf3ce44SJohn Forte */ 115fcf3ce44SJohn Forte qlt->dmem_buckets = (qlt_dmem_bucket_t **)kmem_zalloc(bsize + 116c4ddbbe1SDaniel Beauregard ((ndx - 1) * (int)sizeof (qlt_dmem_bucket_t)), KM_SLEEP); 117fcf3ce44SJohn Forte for (i = 0; i < (ndx - 1); i++) { 118fcf3ce44SJohn Forte qlt->dmem_buckets[i] = (qlt_dmem_bucket_t *) 119c4ddbbe1SDaniel Beauregard ((uint8_t *)qlt->dmem_buckets + bsize + 120c4ddbbe1SDaniel Beauregard (i * (int)sizeof (qlt_dmem_bucket_t))); 121fcf3ce44SJohn Forte bcopy(dmem_buckets[i], qlt->dmem_buckets[i], 122c4ddbbe1SDaniel Beauregard sizeof (qlt_dmem_bucket_t)); 123fcf3ce44SJohn Forte } 124fcf3ce44SJohn Forte bzero(&acc, sizeof (acc)); 125fcf3ce44SJohn Forte acc.devacc_attr_version = DDI_DEVICE_ATTR_V0; 126fcf3ce44SJohn Forte acc.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; 127fcf3ce44SJohn Forte acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 128fcf3ce44SJohn Forte for (ndx = 0; (p = qlt->dmem_buckets[ndx]) != NULL; ndx++) { 129fcf3ce44SJohn Forte bctl = (qlt_dmem_bctl_t *)kmem_zalloc(p->dmem_nbufs * 130c4ddbbe1SDaniel Beauregard sizeof (qlt_dmem_bctl_t), KM_NOSLEEP); 131c4ddbbe1SDaniel Beauregard if (bctl == NULL) { 132c4ddbbe1SDaniel Beauregard EL(qlt, "bctl==NULL\n"); 133fcf3ce44SJohn Forte goto alloc_bctl_failed; 134c4ddbbe1SDaniel Beauregard } 135fcf3ce44SJohn Forte p->dmem_bctls_mem = bctl; 136fcf3ce44SJohn Forte mutex_init(&p->dmem_lock, NULL, MUTEX_DRIVER, NULL); 137c4ddbbe1SDaniel Beauregard if ((i = ddi_dma_alloc_handle(qlt->dip, &qlt_scsi_dma_attr, 138c4ddbbe1SDaniel Beauregard DDI_DMA_SLEEP, 0, &p->dmem_dma_handle)) != DDI_SUCCESS) { 139c4ddbbe1SDaniel Beauregard EL(qlt, "ddi_dma_alloc_handle status=%xh\n", i); 140fcf3ce44SJohn Forte goto alloc_handle_failed; 141c4ddbbe1SDaniel Beauregard } 142fcf3ce44SJohn Forte 143fcf3ce44SJohn Forte total_mem = p->dmem_buf_size * p->dmem_nbufs; 144fcf3ce44SJohn Forte 145c4ddbbe1SDaniel Beauregard if ((i = ddi_dma_mem_alloc(p->dmem_dma_handle, total_mem, &acc, 146fcf3ce44SJohn Forte DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, (caddr_t *)&addr, 147c4ddbbe1SDaniel Beauregard &len, &p->dmem_acc_handle)) != DDI_SUCCESS) { 148c4ddbbe1SDaniel Beauregard EL(qlt, "ddi_dma_mem_alloc status=%xh\n", i); 149fcf3ce44SJohn Forte goto mem_alloc_failed; 150c4ddbbe1SDaniel Beauregard } 151fcf3ce44SJohn Forte 152c4ddbbe1SDaniel Beauregard if ((i = ddi_dma_addr_bind_handle(p->dmem_dma_handle, NULL, 153fcf3ce44SJohn Forte (caddr_t)addr, total_mem, DDI_DMA_RDWR | DDI_DMA_STREAMING, 154c4ddbbe1SDaniel Beauregard DDI_DMA_DONTWAIT, 0, &cookie, &ncookie)) != DDI_SUCCESS) { 155c4ddbbe1SDaniel Beauregard EL(qlt, "ddi_dma_addr_bind_handle status=%xh\n", i); 156fcf3ce44SJohn Forte goto addr_bind_handle_failed; 157c4ddbbe1SDaniel Beauregard } 158c4ddbbe1SDaniel Beauregard if (ncookie != 1) { 159c4ddbbe1SDaniel Beauregard EL(qlt, "ncookie=%d\n", ncookie); 160fcf3ce44SJohn Forte goto dmem_init_failed; 161c4ddbbe1SDaniel Beauregard } 162fcf3ce44SJohn Forte 163fcf3ce44SJohn Forte p->dmem_host_addr = host_addr = addr; 164fcf3ce44SJohn Forte p->dmem_dev_addr = dev_addr = (uint64_t)cookie.dmac_laddress; 165fcf3ce44SJohn Forte bsize = p->dmem_buf_size; 166fcf3ce44SJohn Forte p->dmem_bctl_free_list = bctl; 167fcf3ce44SJohn Forte p->dmem_nbufs_free = p->dmem_nbufs; 168fcf3ce44SJohn Forte for (i = 0; i < p->dmem_nbufs; i++) { 169fcf3ce44SJohn Forte stmf_data_buf_t *db; 170fcf3ce44SJohn Forte prev = bctl; 171fcf3ce44SJohn Forte bctl->bctl_bucket = p; 172fcf3ce44SJohn Forte bctl->bctl_buf = db = stmf_alloc(STMF_STRUCT_DATA_BUF, 173c4ddbbe1SDaniel Beauregard 0, 0); 174fcf3ce44SJohn Forte db->db_port_private = bctl; 175fcf3ce44SJohn Forte db->db_sglist[0].seg_addr = host_addr; 176fcf3ce44SJohn Forte bctl->bctl_dev_addr = dev_addr; 177fcf3ce44SJohn Forte db->db_sglist[0].seg_length = db->db_buf_size = bsize; 178fcf3ce44SJohn Forte db->db_sglist_length = 1; 179fcf3ce44SJohn Forte host_addr += bsize; 180fcf3ce44SJohn Forte dev_addr += bsize; 181fcf3ce44SJohn Forte bctl++; 182fcf3ce44SJohn Forte prev->bctl_next = bctl; 183fcf3ce44SJohn Forte } 184fcf3ce44SJohn Forte prev->bctl_next = NULL; 185fcf3ce44SJohn Forte } 186fcf3ce44SJohn Forte 187fcf3ce44SJohn Forte return (QLT_SUCCESS); 188fcf3ce44SJohn Forte 189fcf3ce44SJohn Forte dmem_failure_loop:; 190fcf3ce44SJohn Forte bc = bctl; 191fcf3ce44SJohn Forte while (bc) { 192fcf3ce44SJohn Forte stmf_free(bc->bctl_buf); 193fcf3ce44SJohn Forte bc = bc->bctl_next; 194fcf3ce44SJohn Forte } 195fcf3ce44SJohn Forte dmem_init_failed:; 196fcf3ce44SJohn Forte (void) ddi_dma_unbind_handle(p->dmem_dma_handle); 197fcf3ce44SJohn Forte addr_bind_handle_failed:; 198fcf3ce44SJohn Forte ddi_dma_mem_free(&p->dmem_acc_handle); 199fcf3ce44SJohn Forte mem_alloc_failed:; 200fcf3ce44SJohn Forte ddi_dma_free_handle(&p->dmem_dma_handle); 201fcf3ce44SJohn Forte alloc_handle_failed:; 202fcf3ce44SJohn Forte kmem_free(p->dmem_bctls_mem, p->dmem_nbufs * sizeof (qlt_dmem_bctl_t)); 203fcf3ce44SJohn Forte mutex_destroy(&p->dmem_lock); 204fcf3ce44SJohn Forte alloc_bctl_failed:; 205fcf3ce44SJohn Forte if (--ndx >= 0) { 206fcf3ce44SJohn Forte p = qlt->dmem_buckets[ndx]; 207fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 208fcf3ce44SJohn Forte goto dmem_failure_loop; 209fcf3ce44SJohn Forte } 210fcf3ce44SJohn Forte kmem_free(qlt->dmem_buckets, sizeof (dmem_buckets) + 211fcf3ce44SJohn Forte ((sizeof (dmem_buckets)/sizeof (void *)) 212fcf3ce44SJohn Forte *sizeof (qlt_dmem_bucket_t))); 213fcf3ce44SJohn Forte qlt->dmem_buckets = NULL; 214fcf3ce44SJohn Forte 215fcf3ce44SJohn Forte return (QLT_FAILURE); 216fcf3ce44SJohn Forte } 217fcf3ce44SJohn Forte 218fcf3ce44SJohn Forte void 219fcf3ce44SJohn Forte qlt_dmem_fini(qlt_state_t *qlt) 220fcf3ce44SJohn Forte { 221fcf3ce44SJohn Forte qlt_dmem_bucket_t *p; 222fcf3ce44SJohn Forte qlt_dmem_bctl_t *bctl; 223fcf3ce44SJohn Forte int ndx; 224fcf3ce44SJohn Forte 225fcf3ce44SJohn Forte for (ndx = 0; (p = qlt->dmem_buckets[ndx]) != NULL; ndx++) { 226fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 227fcf3ce44SJohn Forte while (bctl) { 228fcf3ce44SJohn Forte stmf_free(bctl->bctl_buf); 229fcf3ce44SJohn Forte bctl = bctl->bctl_next; 230fcf3ce44SJohn Forte } 231fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 232fcf3ce44SJohn Forte (void) ddi_dma_unbind_handle(p->dmem_dma_handle); 233fcf3ce44SJohn Forte ddi_dma_mem_free(&p->dmem_acc_handle); 234fcf3ce44SJohn Forte ddi_dma_free_handle(&p->dmem_dma_handle); 235fcf3ce44SJohn Forte kmem_free(p->dmem_bctls_mem, 236c4ddbbe1SDaniel Beauregard p->dmem_nbufs * sizeof (qlt_dmem_bctl_t)); 237fcf3ce44SJohn Forte mutex_destroy(&p->dmem_lock); 238fcf3ce44SJohn Forte } 239fcf3ce44SJohn Forte kmem_free(qlt->dmem_buckets, sizeof (dmem_buckets) + 240fcf3ce44SJohn Forte (((sizeof (dmem_buckets)/sizeof (void *))-1)* 241c4ddbbe1SDaniel Beauregard sizeof (qlt_dmem_bucket_t))); 242fcf3ce44SJohn Forte qlt->dmem_buckets = NULL; 243fcf3ce44SJohn Forte } 244fcf3ce44SJohn Forte 245fcf3ce44SJohn Forte stmf_data_buf_t * 246fcf3ce44SJohn Forte qlt_dmem_alloc(fct_local_port_t *port, uint32_t size, uint32_t *pminsize, 247fcf3ce44SJohn Forte uint32_t flags) 248fcf3ce44SJohn Forte { 249fcf3ce44SJohn Forte return (qlt_i_dmem_alloc((qlt_state_t *) 250fcf3ce44SJohn Forte port->port_fca_private, size, pminsize, 251fcf3ce44SJohn Forte flags)); 252fcf3ce44SJohn Forte } 253fcf3ce44SJohn Forte 254fcf3ce44SJohn Forte /* ARGSUSED */ 255fcf3ce44SJohn Forte stmf_data_buf_t * 256fcf3ce44SJohn Forte qlt_i_dmem_alloc(qlt_state_t *qlt, uint32_t size, uint32_t *pminsize, 257fcf3ce44SJohn Forte uint32_t flags) 258fcf3ce44SJohn Forte { 259a2255df3SDaniel Beauregard qlt_dmem_bucket_t *p; 260*3f3ce7b9SDaniel Beauregard qlt_dmem_bctl_t *bctl; 261a2255df3SDaniel Beauregard int i; 262*3f3ce7b9SDaniel Beauregard uint32_t size_possible = 0; 263fcf3ce44SJohn Forte 264*3f3ce7b9SDaniel Beauregard if (size > QLT_DMEM_MAX_BUF_SIZE) { 265*3f3ce7b9SDaniel Beauregard goto qlt_try_partial_alloc; 266*3f3ce7b9SDaniel Beauregard } 267*3f3ce7b9SDaniel Beauregard 268*3f3ce7b9SDaniel Beauregard /* 1st try to do a full allocation */ 269*3f3ce7b9SDaniel Beauregard for (i = 0; (p = qlt->dmem_buckets[i]) != NULL; i++) { 270*3f3ce7b9SDaniel Beauregard if (p->dmem_buf_size >= size) { 271*3f3ce7b9SDaniel Beauregard if (p->dmem_nbufs_free) { 272*3f3ce7b9SDaniel Beauregard mutex_enter(&p->dmem_lock); 273*3f3ce7b9SDaniel Beauregard bctl = p->dmem_bctl_free_list; 274*3f3ce7b9SDaniel Beauregard if (bctl == NULL) { 275a2255df3SDaniel Beauregard mutex_exit(&p->dmem_lock); 276*3f3ce7b9SDaniel Beauregard continue; 277a2255df3SDaniel Beauregard } 278*3f3ce7b9SDaniel Beauregard p->dmem_bctl_free_list = 279*3f3ce7b9SDaniel Beauregard bctl->bctl_next; 280*3f3ce7b9SDaniel Beauregard p->dmem_nbufs_free--; 281*3f3ce7b9SDaniel Beauregard qlt->qlt_bufref[i]++; 282*3f3ce7b9SDaniel Beauregard mutex_exit(&p->dmem_lock); 283*3f3ce7b9SDaniel Beauregard bctl->bctl_buf->db_data_size = size; 284*3f3ce7b9SDaniel Beauregard return (bctl->bctl_buf); 285*3f3ce7b9SDaniel Beauregard } else { 286*3f3ce7b9SDaniel Beauregard qlt->qlt_bumpbucket++; 287fcf3ce44SJohn Forte } 288fcf3ce44SJohn Forte } 289fcf3ce44SJohn Forte } 290fcf3ce44SJohn Forte 291*3f3ce7b9SDaniel Beauregard qlt_try_partial_alloc: 292*3f3ce7b9SDaniel Beauregard 293*3f3ce7b9SDaniel Beauregard qlt->qlt_pmintry++; 294*3f3ce7b9SDaniel Beauregard 295*3f3ce7b9SDaniel Beauregard /* Now go from high to low */ 296*3f3ce7b9SDaniel Beauregard for (i = QLT_DMEM_NBUCKETS - 1; i >= 0; i--) { 297*3f3ce7b9SDaniel Beauregard p = qlt->dmem_buckets[i]; 298*3f3ce7b9SDaniel Beauregard if (p->dmem_nbufs_free == 0) 299*3f3ce7b9SDaniel Beauregard continue; 300*3f3ce7b9SDaniel Beauregard if (!size_possible) { 301*3f3ce7b9SDaniel Beauregard size_possible = p->dmem_buf_size; 302*3f3ce7b9SDaniel Beauregard } 303*3f3ce7b9SDaniel Beauregard if (*pminsize > p->dmem_buf_size) { 304*3f3ce7b9SDaniel Beauregard /* At this point we know the request is failing. */ 305*3f3ce7b9SDaniel Beauregard if (size_possible) { 306*3f3ce7b9SDaniel Beauregard /* 307*3f3ce7b9SDaniel Beauregard * This caller is asking too much. We already 308*3f3ce7b9SDaniel Beauregard * know what we can give, so get out. 309*3f3ce7b9SDaniel Beauregard */ 310*3f3ce7b9SDaniel Beauregard break; 311*3f3ce7b9SDaniel Beauregard } else { 312*3f3ce7b9SDaniel Beauregard /* 313*3f3ce7b9SDaniel Beauregard * Lets continue to find out and tell what 314*3f3ce7b9SDaniel Beauregard * we can give. 315*3f3ce7b9SDaniel Beauregard */ 316*3f3ce7b9SDaniel Beauregard continue; 317*3f3ce7b9SDaniel Beauregard } 318*3f3ce7b9SDaniel Beauregard } 319*3f3ce7b9SDaniel Beauregard mutex_enter(&p->dmem_lock); 320*3f3ce7b9SDaniel Beauregard if (*pminsize <= p->dmem_buf_size) { 321*3f3ce7b9SDaniel Beauregard bctl = p->dmem_bctl_free_list; 322*3f3ce7b9SDaniel Beauregard if (bctl == NULL) { 323*3f3ce7b9SDaniel Beauregard /* Someone took it. */ 324*3f3ce7b9SDaniel Beauregard size_possible = 0; 325*3f3ce7b9SDaniel Beauregard mutex_exit(&p->dmem_lock); 326*3f3ce7b9SDaniel Beauregard continue; 327*3f3ce7b9SDaniel Beauregard } 328*3f3ce7b9SDaniel Beauregard p->dmem_bctl_free_list = bctl->bctl_next; 329*3f3ce7b9SDaniel Beauregard p->dmem_nbufs_free--; 330*3f3ce7b9SDaniel Beauregard mutex_exit(&p->dmem_lock); 331*3f3ce7b9SDaniel Beauregard bctl->bctl_buf->db_data_size = p->dmem_buf_size; 332*3f3ce7b9SDaniel Beauregard qlt->qlt_pmin_ok++; 333*3f3ce7b9SDaniel Beauregard return (bctl->bctl_buf); 334*3f3ce7b9SDaniel Beauregard } 335fcf3ce44SJohn Forte } 336a2255df3SDaniel Beauregard 337*3f3ce7b9SDaniel Beauregard *pminsize = size_possible; 338*3f3ce7b9SDaniel Beauregard 339fcf3ce44SJohn Forte return (NULL); 340fcf3ce44SJohn Forte } 341fcf3ce44SJohn Forte 342fcf3ce44SJohn Forte /* ARGSUSED */ 343fcf3ce44SJohn Forte void 344fcf3ce44SJohn Forte qlt_i_dmem_free(qlt_state_t *qlt, stmf_data_buf_t *dbuf) 345fcf3ce44SJohn Forte { 346fcf3ce44SJohn Forte qlt_dmem_free(0, dbuf); 347fcf3ce44SJohn Forte } 348fcf3ce44SJohn Forte 349fcf3ce44SJohn Forte /* ARGSUSED */ 350fcf3ce44SJohn Forte void 351fcf3ce44SJohn Forte qlt_dmem_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf) 352fcf3ce44SJohn Forte { 353fcf3ce44SJohn Forte qlt_dmem_bctl_t *bctl = (qlt_dmem_bctl_t *)dbuf->db_port_private; 354fcf3ce44SJohn Forte qlt_dmem_bucket_t *p = bctl->bctl_bucket; 355fcf3ce44SJohn Forte 356fcf3ce44SJohn Forte mutex_enter(&p->dmem_lock); 357fcf3ce44SJohn Forte bctl->bctl_next = p->dmem_bctl_free_list; 358fcf3ce44SJohn Forte p->dmem_bctl_free_list = bctl; 359fcf3ce44SJohn Forte p->dmem_nbufs_free++; 360fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 361fcf3ce44SJohn Forte } 362fcf3ce44SJohn Forte 363fcf3ce44SJohn Forte void 364fcf3ce44SJohn Forte qlt_dmem_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type) 365fcf3ce44SJohn Forte { 366fcf3ce44SJohn Forte qlt_dmem_bctl_t *bctl = (qlt_dmem_bctl_t *)dbuf->db_port_private; 367fcf3ce44SJohn Forte qlt_dmem_bucket_t *p = bctl->bctl_bucket; 368fcf3ce44SJohn Forte 369c4ddbbe1SDaniel Beauregard (void) ddi_dma_sync(p->dmem_dma_handle, (off_t) 370fcf3ce44SJohn Forte (bctl->bctl_dev_addr - p->dmem_dev_addr), 371c4ddbbe1SDaniel Beauregard dbuf->db_data_size, sync_type); 372fcf3ce44SJohn Forte } 373