xref: /titanic_51/usr/src/uts/common/io/dma_engine.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1990, 1991 UNIX System Laboratories, Inc.	*/
30*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T	*/
31*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate /*
34*7c478bd9Sstevel@tonic-gate  * This is the implementation of the kernel DMA interface for the
35*7c478bd9Sstevel@tonic-gate  * AT Class machines using Intel 8237A DMAC.
36*7c478bd9Sstevel@tonic-gate  *
37*7c478bd9Sstevel@tonic-gate  * The following routines in the interface are implemented:
38*7c478bd9Sstevel@tonic-gate  *	i_dmae_init()
39*7c478bd9Sstevel@tonic-gate  *	_dmae_nxcookie()
40*7c478bd9Sstevel@tonic-gate  *	i_dmae_acquire()
41*7c478bd9Sstevel@tonic-gate  *	i_dmae_free()
42*7c478bd9Sstevel@tonic-gate  *	i_dmae_prog()
43*7c478bd9Sstevel@tonic-gate  *	i_dmae_swsetup()
44*7c478bd9Sstevel@tonic-gate  *	i_dmae_swstart()
45*7c478bd9Sstevel@tonic-gate  *	i_dmae_stop()
46*7c478bd9Sstevel@tonic-gate  *	i_dmae_enable()
47*7c478bd9Sstevel@tonic-gate  *	i_dmae_disable()
48*7c478bd9Sstevel@tonic-gate  *	i_dmae_get_best_mode()
49*7c478bd9Sstevel@tonic-gate  *	i_dmae_get_chan_stat()
50*7c478bd9Sstevel@tonic-gate  *
51*7c478bd9Sstevel@tonic-gate  */
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
54*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
55*7c478bd9Sstevel@tonic-gate #include <sys/buf.h>
56*7c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
57*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
58*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
59*7c478bd9Sstevel@tonic-gate #include <sys/dma_engine.h>
60*7c478bd9Sstevel@tonic-gate #include <sys/dma_i8237A.h>
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
63*7c478bd9Sstevel@tonic-gate #include <sys/promif.h>
64*7c478bd9Sstevel@tonic-gate static int dmaedebug = 0;
65*7c478bd9Sstevel@tonic-gate #define	dprintf(x)	if (dmaedebug) prom_printf x
66*7c478bd9Sstevel@tonic-gate #else
67*7c478bd9Sstevel@tonic-gate #define	dprintf(x)
68*7c478bd9Sstevel@tonic-gate #endif
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate static struct dmae_chnl dmae_stat[NCHANS];
72*7c478bd9Sstevel@tonic-gate static uintptr_t dmae_call_list[NCHANS] = {0, 0, 0, 0, 0, 0, 0, 0};
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate /*
75*7c478bd9Sstevel@tonic-gate  *  routine: i_dmae_init()
76*7c478bd9Sstevel@tonic-gate  *  purpose: called to initialize the dma interface, the DMAC, and any
77*7c478bd9Sstevel@tonic-gate  *           dma data structures. Called during system initialization.
78*7c478bd9Sstevel@tonic-gate  *  caller:  main()
79*7c478bd9Sstevel@tonic-gate  *  calls:   d37A_init()
80*7c478bd9Sstevel@tonic-gate  */
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate int
83*7c478bd9Sstevel@tonic-gate i_dmae_init(dev_info_t *dip)
84*7c478bd9Sstevel@tonic-gate {
85*7c478bd9Sstevel@tonic-gate 	int chnl;
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate 	dprintf(("i_dmae_init: initializing dma.\n"));
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 	/* initialize semaphore map */
90*7c478bd9Sstevel@tonic-gate 	for (chnl = 0; chnl < NCHANS; chnl++) {
91*7c478bd9Sstevel@tonic-gate 		sema_init(&dmae_stat[chnl].dch_lock, 1, NULL, SEMA_DRIVER,
92*7c478bd9Sstevel@tonic-gate 		    (void *)NULL);
93*7c478bd9Sstevel@tonic-gate 	}
94*7c478bd9Sstevel@tonic-gate 	return (d37A_init(dip));
95*7c478bd9Sstevel@tonic-gate }
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate /*
99*7c478bd9Sstevel@tonic-gate  *  routine: i_dmae_acquire()
100*7c478bd9Sstevel@tonic-gate  *  purpose: Request the semaphore for the indicated channel.
101*7c478bd9Sstevel@tonic-gate  *           A call_back function can be passed if caller does/cannot
102*7c478bd9Sstevel@tonic-gate  *           wait for the semaphore.
103*7c478bd9Sstevel@tonic-gate  *  caller:  drivers
104*7c478bd9Sstevel@tonic-gate  *  calls:   sema_p(), sema_tryp(), ddi_set_callback()
105*7c478bd9Sstevel@tonic-gate  */
106*7c478bd9Sstevel@tonic-gate int
107*7c478bd9Sstevel@tonic-gate i_dmae_acquire(dev_info_t *dip, int chnl, int (*dmae_waitfp)(), caddr_t arg)
108*7c478bd9Sstevel@tonic-gate {
109*7c478bd9Sstevel@tonic-gate #if defined(lint)
110*7c478bd9Sstevel@tonic-gate 	dip = dip;
111*7c478bd9Sstevel@tonic-gate #endif
112*7c478bd9Sstevel@tonic-gate 	dprintf(("i_dmae_acquire: channel %d, waitfp %p\n",
113*7c478bd9Sstevel@tonic-gate 	    chnl, (void *)dmae_waitfp));
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 	if (!d37A_dma_valid(chnl))
116*7c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate 	if (dmae_waitfp == DDI_DMA_SLEEP) {
119*7c478bd9Sstevel@tonic-gate 		sema_p(&dmae_stat[chnl].dch_lock);
120*7c478bd9Sstevel@tonic-gate 	} else if (sema_tryp(&dmae_stat[chnl].dch_lock) == 0) {
121*7c478bd9Sstevel@tonic-gate 		if (dmae_waitfp == DDI_DMA_DONTWAIT) {
122*7c478bd9Sstevel@tonic-gate 			dprintf(("_dma_acquire: channel %d is busy.\n", chnl));
123*7c478bd9Sstevel@tonic-gate 		} else {
124*7c478bd9Sstevel@tonic-gate 			ddi_set_callback(dmae_waitfp, arg,
125*7c478bd9Sstevel@tonic-gate 			    &dmae_call_list[chnl]);
126*7c478bd9Sstevel@tonic-gate 		}
127*7c478bd9Sstevel@tonic-gate 		return (DDI_DMA_NORESOURCES);
128*7c478bd9Sstevel@tonic-gate 	}
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 	/*
131*7c478bd9Sstevel@tonic-gate 	 * XXX -  save dip for authentication later ??
132*7c478bd9Sstevel@tonic-gate 	 */
133*7c478bd9Sstevel@tonic-gate 	dprintf(("_dma_acquire: channel %d now allocated.\n", chnl));
134*7c478bd9Sstevel@tonic-gate 	return (DDI_SUCCESS);
135*7c478bd9Sstevel@tonic-gate }
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate /*
139*7c478bd9Sstevel@tonic-gate  *  routine: i_dmae_free()
140*7c478bd9Sstevel@tonic-gate  *  purpose: Release the channel semaphore on chnl. Assumes caller actually
141*7c478bd9Sstevel@tonic-gate  *           owns the semaphore (no check made for this).
142*7c478bd9Sstevel@tonic-gate  *  caller:  drivers
143*7c478bd9Sstevel@tonic-gate  *  calls:   none
144*7c478bd9Sstevel@tonic-gate  */
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate int
147*7c478bd9Sstevel@tonic-gate i_dmae_free(dev_info_t *dip, int chnl)
148*7c478bd9Sstevel@tonic-gate {
149*7c478bd9Sstevel@tonic-gate #if defined(lint)
150*7c478bd9Sstevel@tonic-gate 	dip = dip;
151*7c478bd9Sstevel@tonic-gate #endif
152*7c478bd9Sstevel@tonic-gate 	dprintf(("i_dmae_free: channel %d\n", chnl));
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate 	d37A_dma_release(chnl);
155*7c478bd9Sstevel@tonic-gate 	/*
156*7c478bd9Sstevel@tonic-gate 	 * XXX - should dip be authenticated as the one that did acquire?
157*7c478bd9Sstevel@tonic-gate 	 */
158*7c478bd9Sstevel@tonic-gate 	sema_v(&dmae_stat[chnl].dch_lock);
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 	if (dmae_call_list[chnl])
161*7c478bd9Sstevel@tonic-gate 		ddi_run_callback(&dmae_call_list[chnl]);
162*7c478bd9Sstevel@tonic-gate 	return (DDI_SUCCESS);
163*7c478bd9Sstevel@tonic-gate }
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate /*
166*7c478bd9Sstevel@tonic-gate  *  routine: i_dmae_get_best_mode()
167*7c478bd9Sstevel@tonic-gate  *  purpose: confirm that data is aligned for efficient flyby mode
168*7c478bd9Sstevel@tonic-gate  *  caller:  driver routines.
169*7c478bd9Sstevel@tonic-gate  *  calls:   d37A_get_best_mode.
170*7c478bd9Sstevel@tonic-gate  */
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate uchar_t
173*7c478bd9Sstevel@tonic-gate i_dmae_get_best_mode(dev_info_t *dip, struct ddi_dmae_req *dmaereqp)
174*7c478bd9Sstevel@tonic-gate {
175*7c478bd9Sstevel@tonic-gate #if defined(lint)
176*7c478bd9Sstevel@tonic-gate 	dip = dip;
177*7c478bd9Sstevel@tonic-gate #endif
178*7c478bd9Sstevel@tonic-gate 	return (d37A_get_best_mode(dmaereqp));
179*7c478bd9Sstevel@tonic-gate }
180*7c478bd9Sstevel@tonic-gate 
181*7c478bd9Sstevel@tonic-gate /*
182*7c478bd9Sstevel@tonic-gate  *  routine: _dmae_nxcookie()
183*7c478bd9Sstevel@tonic-gate  *  purpose: service the interrupt by calling device driver routine for next
184*7c478bd9Sstevel@tonic-gate  *		DMA cookie.
185*7c478bd9Sstevel@tonic-gate  *  caller:  d37A_intr()
186*7c478bd9Sstevel@tonic-gate  *  calls:   routine provided in request structure
187*7c478bd9Sstevel@tonic-gate  */
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate ddi_dma_cookie_t *
190*7c478bd9Sstevel@tonic-gate _dmae_nxcookie(int chnl)
191*7c478bd9Sstevel@tonic-gate {
192*7c478bd9Sstevel@tonic-gate 	ddi_dma_cookie_t *cookiep = NULL;
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate 	dprintf(("_dmae_nxcookie: chnl %d\n", chnl));
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate 	if (dmae_stat[chnl].proc) {
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate 		cookiep = dmae_stat[chnl].proc(dmae_stat[chnl].procparms);
199*7c478bd9Sstevel@tonic-gate 		/*
200*7c478bd9Sstevel@tonic-gate 		 * expect a cookie pointer from user's routine;
201*7c478bd9Sstevel@tonic-gate 		 * null cookie pointer will terminate chaining
202*7c478bd9Sstevel@tonic-gate 		 */
203*7c478bd9Sstevel@tonic-gate 	}
204*7c478bd9Sstevel@tonic-gate 	return (cookiep);
205*7c478bd9Sstevel@tonic-gate }
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate /*
209*7c478bd9Sstevel@tonic-gate  *  routine: i_dmae_prog()
210*7c478bd9Sstevel@tonic-gate  *  purpose: Program channel for the to_be_initiated_by_hardware operation.
211*7c478bd9Sstevel@tonic-gate  *           _dma_acquire is called to request the channel semaphore and
212*7c478bd9Sstevel@tonic-gate  *	     mode is passed as the sleep parameter.
213*7c478bd9Sstevel@tonic-gate  *	     The channel is enabled after it is setup.
214*7c478bd9Sstevel@tonic-gate  *	     Note that the ddi_dmae_req pointer can be to NULL if the mode
215*7c478bd9Sstevel@tonic-gate  *	     registers have already been setup by a prior call; this implements
216*7c478bd9Sstevel@tonic-gate  *	     a prog_next() to update the address and count registers.
217*7c478bd9Sstevel@tonic-gate  *  caller:  driver routines
218*7c478bd9Sstevel@tonic-gate  *  calls:   d37A_prog_chan()
219*7c478bd9Sstevel@tonic-gate  */
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate int
222*7c478bd9Sstevel@tonic-gate i_dmae_prog(dev_info_t *dip, struct ddi_dmae_req *dmaereqp,
223*7c478bd9Sstevel@tonic-gate     ddi_dma_cookie_t *cp, int chnl)
224*7c478bd9Sstevel@tonic-gate {
225*7c478bd9Sstevel@tonic-gate 	struct dmae_chnl *dcp;
226*7c478bd9Sstevel@tonic-gate 	int rval;
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate #if defined(lint)
229*7c478bd9Sstevel@tonic-gate 	dip = dip;
230*7c478bd9Sstevel@tonic-gate #endif
231*7c478bd9Sstevel@tonic-gate 	rval = d37A_prog_chan(dmaereqp, cp, chnl);
232*7c478bd9Sstevel@tonic-gate 	if (rval != DDI_SUCCESS) {
233*7c478bd9Sstevel@tonic-gate 		dprintf(("i_dmae_prog: failure on channel %d dmaereq=%p\n",
234*7c478bd9Sstevel@tonic-gate 		    chnl, (void *)dmaereqp));
235*7c478bd9Sstevel@tonic-gate 	} else {
236*7c478bd9Sstevel@tonic-gate 		dprintf(("i_dmae_prog: channel %d dmaereq=%p\n",
237*7c478bd9Sstevel@tonic-gate 		    chnl, (void *)dmaereqp));
238*7c478bd9Sstevel@tonic-gate 		dcp = &dmae_stat[chnl];
239*7c478bd9Sstevel@tonic-gate 		dcp->dch_cookiep = cp;
240*7c478bd9Sstevel@tonic-gate 		if (dmaereqp) {
241*7c478bd9Sstevel@tonic-gate 			dcp->proc = dmaereqp->proc;
242*7c478bd9Sstevel@tonic-gate 			dcp->procparms = dmaereqp->procparms;
243*7c478bd9Sstevel@tonic-gate 		}
244*7c478bd9Sstevel@tonic-gate 		d37A_dma_enable(chnl);
245*7c478bd9Sstevel@tonic-gate 	}
246*7c478bd9Sstevel@tonic-gate 	return (rval);
247*7c478bd9Sstevel@tonic-gate }
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate /*
251*7c478bd9Sstevel@tonic-gate  *  routine: i_dmae_swsetup()
252*7c478bd9Sstevel@tonic-gate  *  purpose: Setup chan for the operation given in dmacbptr.
253*7c478bd9Sstevel@tonic-gate  *           _dma_acquire is first called
254*7c478bd9Sstevel@tonic-gate  *           to request the channel semaphore for chnl; mode is
255*7c478bd9Sstevel@tonic-gate  *           passed to _dma_acquire().
256*7c478bd9Sstevel@tonic-gate  *  caller:  driver routines
257*7c478bd9Sstevel@tonic-gate  *  calls:   d37A_dma_swsetup()
258*7c478bd9Sstevel@tonic-gate  */
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate int
261*7c478bd9Sstevel@tonic-gate i_dmae_swsetup(dev_info_t *dip, struct ddi_dmae_req *dmaereqp,
262*7c478bd9Sstevel@tonic-gate     ddi_dma_cookie_t *cp, int chnl)
263*7c478bd9Sstevel@tonic-gate {
264*7c478bd9Sstevel@tonic-gate 	struct dmae_chnl *dcp;
265*7c478bd9Sstevel@tonic-gate 	int rval;
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate #if defined(lint)
268*7c478bd9Sstevel@tonic-gate 	dip = dip;
269*7c478bd9Sstevel@tonic-gate #endif
270*7c478bd9Sstevel@tonic-gate 	rval = d37A_dma_swsetup(dmaereqp, cp, chnl);
271*7c478bd9Sstevel@tonic-gate 	if (rval != DDI_SUCCESS) {
272*7c478bd9Sstevel@tonic-gate 		dprintf(("i_dmae_swsetup: failure on channel %d dmaereq=%p\n",
273*7c478bd9Sstevel@tonic-gate 		    chnl, (void *)dmaereqp));
274*7c478bd9Sstevel@tonic-gate 	} else {
275*7c478bd9Sstevel@tonic-gate 		dprintf(("i_dmae_swsetup: channel %d: dmaereq=%p\n",
276*7c478bd9Sstevel@tonic-gate 		    chnl, (void *)dmaereqp));
277*7c478bd9Sstevel@tonic-gate 		dcp = &dmae_stat[chnl];
278*7c478bd9Sstevel@tonic-gate 		dcp->dch_cookiep = cp;
279*7c478bd9Sstevel@tonic-gate 		dcp->proc = dmaereqp->proc;
280*7c478bd9Sstevel@tonic-gate 		dcp->procparms = dmaereqp->procparms;
281*7c478bd9Sstevel@tonic-gate 	}
282*7c478bd9Sstevel@tonic-gate 	return (rval);
283*7c478bd9Sstevel@tonic-gate }
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate 
286*7c478bd9Sstevel@tonic-gate /*
287*7c478bd9Sstevel@tonic-gate  *  routine: i_dmae_swstart()
288*7c478bd9Sstevel@tonic-gate  *  purpose: Start the operation setup by i_dmae_swsetup().
289*7c478bd9Sstevel@tonic-gate  *  caller:  driver routines
290*7c478bd9Sstevel@tonic-gate  *  calls:   d37A_dma_swstart().
291*7c478bd9Sstevel@tonic-gate  */
292*7c478bd9Sstevel@tonic-gate 
293*7c478bd9Sstevel@tonic-gate void
294*7c478bd9Sstevel@tonic-gate i_dmae_swstart(dev_info_t *dip, int chnl)
295*7c478bd9Sstevel@tonic-gate {
296*7c478bd9Sstevel@tonic-gate #if defined(lint)
297*7c478bd9Sstevel@tonic-gate 	dip = dip;
298*7c478bd9Sstevel@tonic-gate #endif
299*7c478bd9Sstevel@tonic-gate 	dprintf(("i_dmae_swstart: channel %d.\n", chnl));
300*7c478bd9Sstevel@tonic-gate 
301*7c478bd9Sstevel@tonic-gate 	d37A_dma_swstart(chnl);
302*7c478bd9Sstevel@tonic-gate }
303*7c478bd9Sstevel@tonic-gate 
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate /*
306*7c478bd9Sstevel@tonic-gate  *  routine: i_dmae_stop()
307*7c478bd9Sstevel@tonic-gate  *  purpose: stop DMA activity on chnl.
308*7c478bd9Sstevel@tonic-gate  *  caller:  driver routines
309*7c478bd9Sstevel@tonic-gate  *  calls:   splhi(), _dma_relse(), splx(),
310*7c478bd9Sstevel@tonic-gate  *           d37A_dma_stop().
311*7c478bd9Sstevel@tonic-gate  */
312*7c478bd9Sstevel@tonic-gate 
313*7c478bd9Sstevel@tonic-gate void
314*7c478bd9Sstevel@tonic-gate i_dmae_stop(dev_info_t *dip, int chnl)
315*7c478bd9Sstevel@tonic-gate {
316*7c478bd9Sstevel@tonic-gate #if defined(lint)
317*7c478bd9Sstevel@tonic-gate 	dip = dip;
318*7c478bd9Sstevel@tonic-gate #endif
319*7c478bd9Sstevel@tonic-gate 	dprintf(("i_dmae_stop: channel %d\n", chnl));
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate 	/* call d37A the stop the channel */
322*7c478bd9Sstevel@tonic-gate 	d37A_dma_stop(chnl);
323*7c478bd9Sstevel@tonic-gate 
324*7c478bd9Sstevel@tonic-gate 	dmae_stat[chnl].dch_cookiep = NULL;
325*7c478bd9Sstevel@tonic-gate }
326*7c478bd9Sstevel@tonic-gate 
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate /*
329*7c478bd9Sstevel@tonic-gate  *  routine: i_dmae_enable()
330*7c478bd9Sstevel@tonic-gate  *  purpose: Allow the hardware tied to channel chnl to request service
331*7c478bd9Sstevel@tonic-gate  *           from the DMAC. i_dmae_prog() should have been called prior
332*7c478bd9Sstevel@tonic-gate  *           to this.
333*7c478bd9Sstevel@tonic-gate  *  caller:  driver routines.
334*7c478bd9Sstevel@tonic-gate  *  calls:   d37A_dma_enable()
335*7c478bd9Sstevel@tonic-gate  */
336*7c478bd9Sstevel@tonic-gate 
337*7c478bd9Sstevel@tonic-gate void
338*7c478bd9Sstevel@tonic-gate i_dmae_enable(dev_info_t *dip, int chnl)
339*7c478bd9Sstevel@tonic-gate {
340*7c478bd9Sstevel@tonic-gate #if defined(lint)
341*7c478bd9Sstevel@tonic-gate 	dip = dip;
342*7c478bd9Sstevel@tonic-gate #endif
343*7c478bd9Sstevel@tonic-gate 	dprintf(("i_dmae_enable: channel %d\n", chnl));
344*7c478bd9Sstevel@tonic-gate 
345*7c478bd9Sstevel@tonic-gate 	d37A_dma_enable(chnl);
346*7c478bd9Sstevel@tonic-gate }
347*7c478bd9Sstevel@tonic-gate 
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate /*
350*7c478bd9Sstevel@tonic-gate  *  routine: i_dmae_disable()
351*7c478bd9Sstevel@tonic-gate  *  purpose: Called to mask off hardware requests on channel chnl. Assumes
352*7c478bd9Sstevel@tonic-gate  *           the caller owns the channel.
353*7c478bd9Sstevel@tonic-gate  *  caller:  driver routines.
354*7c478bd9Sstevel@tonic-gate  *  calls:   d37A_dma_disable()
355*7c478bd9Sstevel@tonic-gate  */
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate void
358*7c478bd9Sstevel@tonic-gate i_dmae_disable(dev_info_t *dip, int chnl)
359*7c478bd9Sstevel@tonic-gate {
360*7c478bd9Sstevel@tonic-gate #if defined(lint)
361*7c478bd9Sstevel@tonic-gate 	dip = dip;
362*7c478bd9Sstevel@tonic-gate #endif
363*7c478bd9Sstevel@tonic-gate 	/* dprintf(("i_dmae_disable: disable channel %d.\n", chnl)); */
364*7c478bd9Sstevel@tonic-gate 
365*7c478bd9Sstevel@tonic-gate 	d37A_dma_disable(chnl);
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate 	dmae_stat[chnl].dch_cookiep = NULL;
368*7c478bd9Sstevel@tonic-gate }
369*7c478bd9Sstevel@tonic-gate 
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate /*
372*7c478bd9Sstevel@tonic-gate  *  routine: i_dmae_get_chan_stat()
373*7c478bd9Sstevel@tonic-gate  *  purpose: Obtain the current channel status from the DMAC
374*7c478bd9Sstevel@tonic-gate  *  caller:  driver routines.
375*7c478bd9Sstevel@tonic-gate  *  calls:   d37A_get_chan_stat()
376*7c478bd9Sstevel@tonic-gate  */
377*7c478bd9Sstevel@tonic-gate 
378*7c478bd9Sstevel@tonic-gate void
379*7c478bd9Sstevel@tonic-gate i_dmae_get_chan_stat(dev_info_t *dip, int chnl, ulong_t *addressp, int *countp)
380*7c478bd9Sstevel@tonic-gate {
381*7c478bd9Sstevel@tonic-gate #if defined(lint)
382*7c478bd9Sstevel@tonic-gate 	dip = dip;
383*7c478bd9Sstevel@tonic-gate #endif
384*7c478bd9Sstevel@tonic-gate 	dprintf(("i_dmae_get_chan_stat: channel %d", chnl));
385*7c478bd9Sstevel@tonic-gate 
386*7c478bd9Sstevel@tonic-gate 	d37A_get_chan_stat(chnl, addressp, countp);
387*7c478bd9Sstevel@tonic-gate }
388