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
i_dmae_init(dev_info_t * dip)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
i_dmae_acquire(dev_info_t * dip,int chnl,int (* dmae_waitfp)(),caddr_t arg)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
i_dmae_free(dev_info_t * dip,int chnl)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
i_dmae_get_best_mode(dev_info_t * dip,struct ddi_dmae_req * dmaereqp)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 *
_dmae_nxcookie(int chnl)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
i_dmae_prog(dev_info_t * dip,struct ddi_dmae_req * dmaereqp,ddi_dma_cookie_t * cp,int chnl)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
i_dmae_swsetup(dev_info_t * dip,struct ddi_dmae_req * dmaereqp,ddi_dma_cookie_t * cp,int chnl)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
i_dmae_swstart(dev_info_t * dip,int chnl)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
i_dmae_stop(dev_info_t * dip,int chnl)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
i_dmae_enable(dev_info_t * dip,int chnl)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
i_dmae_disable(dev_info_t * dip,int chnl)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
i_dmae_get_chan_stat(dev_info_t * dip,int chnl,ulong_t * addressp,int * countp)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