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