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