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