si.c revision 1.19.2.2 1 1.19.2.2 rmind /* $NetBSD: si.c,v 1.19.2.2 2007/03/12 05:49:38 rmind Exp $ */
2 1.19.2.2 rmind
3 1.19.2.2 rmind /*
4 1.19.2.2 rmind * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 1.19.2.2 rmind * All rights reserved.
6 1.19.2.2 rmind *
7 1.19.2.2 rmind * This code is derived from software contributed to The NetBSD Foundation
8 1.19.2.2 rmind * by Adam Glass, David Jones, Gordon W. Ross, and Jens A. Nilsson.
9 1.19.2.2 rmind *
10 1.19.2.2 rmind * Redistribution and use in source and binary forms, with or without
11 1.19.2.2 rmind * modification, are permitted provided that the following conditions
12 1.19.2.2 rmind * are met:
13 1.19.2.2 rmind * 1. Redistributions of source code must retain the above copyright
14 1.19.2.2 rmind * notice, this list of conditions and the following disclaimer.
15 1.19.2.2 rmind * 2. Redistributions in binary form must reproduce the above copyright
16 1.19.2.2 rmind * notice, this list of conditions and the following disclaimer in the
17 1.19.2.2 rmind * documentation and/or other materials provided with the distribution.
18 1.19.2.2 rmind * 3. All advertising materials mentioning features or use of this software
19 1.19.2.2 rmind * must display the following acknowledgement:
20 1.19.2.2 rmind * This product includes software developed by the NetBSD
21 1.19.2.2 rmind * Foundation, Inc. and its contributors.
22 1.19.2.2 rmind * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.19.2.2 rmind * contributors may be used to endorse or promote products derived
24 1.19.2.2 rmind * from this software without specific prior written permission.
25 1.19.2.2 rmind *
26 1.19.2.2 rmind * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.19.2.2 rmind * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.19.2.2 rmind * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.19.2.2 rmind * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.19.2.2 rmind * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.19.2.2 rmind * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.19.2.2 rmind * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.19.2.2 rmind * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.19.2.2 rmind * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.19.2.2 rmind * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.19.2.2 rmind * POSSIBILITY OF SUCH DAMAGE.
37 1.19.2.2 rmind */
38 1.19.2.2 rmind
39 1.19.2.2 rmind /*
40 1.19.2.2 rmind * This file contains the machine-dependent parts of the Sony CXD1180
41 1.19.2.2 rmind * controller. The machine-independent parts are in ncr5380sbc.c.
42 1.19.2.2 rmind * Written by Izumi Tsutsui.
43 1.19.2.2 rmind *
44 1.19.2.2 rmind * This code is based on arch/vax/vsa/ncr.c and sun3/dev/si.c
45 1.19.2.2 rmind */
46 1.19.2.2 rmind
47 1.19.2.2 rmind #include <sys/cdefs.h>
48 1.19.2.2 rmind __KERNEL_RCSID(0, "$NetBSD: si.c,v 1.19.2.2 2007/03/12 05:49:38 rmind Exp $");
49 1.19.2.2 rmind
50 1.19.2.2 rmind #include <sys/param.h>
51 1.19.2.2 rmind #include <sys/systm.h>
52 1.19.2.2 rmind #include <sys/device.h>
53 1.19.2.2 rmind #include <sys/buf.h>
54 1.19.2.2 rmind
55 1.19.2.2 rmind #include <machine/cpu.h>
56 1.19.2.2 rmind #include <m68k/cacheops.h>
57 1.19.2.2 rmind
58 1.19.2.2 rmind #include <dev/scsipi/scsipi_all.h>
59 1.19.2.2 rmind #include <dev/scsipi/scsiconf.h>
60 1.19.2.2 rmind
61 1.19.2.2 rmind #include <dev/ic/ncr5380reg.h>
62 1.19.2.2 rmind #include <dev/ic/ncr5380var.h>
63 1.19.2.2 rmind
64 1.19.2.2 rmind #include <news68k/dev/hbvar.h>
65 1.19.2.2 rmind #include <news68k/dev/dmac_0266.h>
66 1.19.2.2 rmind
67 1.19.2.2 rmind #include "ioconf.h"
68 1.19.2.2 rmind
69 1.19.2.2 rmind #define MIN_DMA_LEN 128
70 1.19.2.2 rmind #define DMAC_BASE 0xe0e80000 /* XXX */
71 1.19.2.2 rmind #define SI_REGSIZE 8
72 1.19.2.2 rmind
73 1.19.2.2 rmind struct si_softc {
74 1.19.2.2 rmind struct ncr5380_softc ncr_sc;
75 1.19.2.2 rmind int sc_options;
76 1.19.2.2 rmind volatile struct dma_regs *sc_regs;
77 1.19.2.2 rmind int sc_xlen;
78 1.19.2.2 rmind };
79 1.19.2.2 rmind
80 1.19.2.2 rmind static void si_attach(struct device *, struct device *, void *);
81 1.19.2.2 rmind static int si_match(struct device *, struct cfdata *, void *);
82 1.19.2.2 rmind int si_intr(int);
83 1.19.2.2 rmind
84 1.19.2.2 rmind static void si_dma_alloc(struct ncr5380_softc *);
85 1.19.2.2 rmind static void si_dma_free(struct ncr5380_softc *);
86 1.19.2.2 rmind static void si_dma_start(struct ncr5380_softc *);
87 1.19.2.2 rmind static void si_dma_poll(struct ncr5380_softc *);
88 1.19.2.2 rmind static void si_dma_eop(struct ncr5380_softc *);
89 1.19.2.2 rmind static void si_dma_stop(struct ncr5380_softc *);
90 1.19.2.2 rmind
91 1.19.2.2 rmind CFATTACH_DECL(si, sizeof(struct si_softc),
92 1.19.2.2 rmind si_match, si_attach, NULL, NULL);
93 1.19.2.2 rmind
94 1.19.2.2 rmind /*
95 1.19.2.2 rmind * Options for disconnect/reselect, DMA, and interrupts.
96 1.19.2.2 rmind * By default, allow disconnect/reselect on targets 4-6.
97 1.19.2.2 rmind * Those are normally tapes that really need it enabled.
98 1.19.2.2 rmind * The options are taken from the config file.
99 1.19.2.2 rmind */
100 1.19.2.2 rmind #define SI_NO_DISCONNECT 0x000ff
101 1.19.2.2 rmind #define SI_NO_PARITY_CHK 0x0ff00
102 1.19.2.2 rmind #define SI_FORCE_POLLING 0x10000
103 1.19.2.2 rmind #define SI_DISABLE_DMA 0x20000
104 1.19.2.2 rmind
105 1.19.2.2 rmind int si_options = 0x00;
106 1.19.2.2 rmind
107 1.19.2.2 rmind
108 1.19.2.2 rmind static int
109 1.19.2.2 rmind si_match(struct device *parent, struct cfdata *cf, void *aux)
110 1.19.2.2 rmind {
111 1.19.2.2 rmind struct hb_attach_args *ha = aux;
112 1.19.2.2 rmind int addr;
113 1.19.2.2 rmind
114 1.19.2.2 rmind if (strcmp(ha->ha_name, "si"))
115 1.19.2.2 rmind return 0;
116 1.19.2.2 rmind
117 1.19.2.2 rmind addr = IIOV(ha->ha_address);
118 1.19.2.2 rmind
119 1.19.2.2 rmind if (badaddr((void *)addr, 1))
120 1.19.2.2 rmind return 0;
121 1.19.2.2 rmind
122 1.19.2.2 rmind ha->ha_size = SI_REGSIZE;
123 1.19.2.2 rmind
124 1.19.2.2 rmind return 1;
125 1.19.2.2 rmind }
126 1.19.2.2 rmind
127 1.19.2.2 rmind /*
128 1.19.2.2 rmind * Card attach function
129 1.19.2.2 rmind */
130 1.19.2.2 rmind
131 1.19.2.2 rmind static void
132 1.19.2.2 rmind si_attach(struct device *parent, struct device *self, void *aux)
133 1.19.2.2 rmind {
134 1.19.2.2 rmind struct si_softc *sc = (struct si_softc *)self;
135 1.19.2.2 rmind struct ncr5380_softc *ncr_sc = &sc->ncr_sc;
136 1.19.2.2 rmind struct cfdata *cf = device_cfdata(self);
137 1.19.2.2 rmind struct hb_attach_args *ha = aux;
138 1.19.2.2 rmind
139 1.19.2.2 rmind ncr_sc->sc_regt = ha->ha_bust;
140 1.19.2.2 rmind if (bus_space_map(ncr_sc->sc_regt, (bus_addr_t)ha->ha_address,
141 1.19.2.2 rmind ha->ha_size, 0, &ncr_sc->sc_regh) != 0) {
142 1.19.2.2 rmind printf("can't map device space\n");
143 1.19.2.2 rmind return;
144 1.19.2.2 rmind }
145 1.19.2.2 rmind
146 1.19.2.2 rmind /* Get options from config flags if specified. */
147 1.19.2.2 rmind if (cf->cf_flags)
148 1.19.2.2 rmind sc->sc_options = cf->cf_flags;
149 1.19.2.2 rmind else
150 1.19.2.2 rmind sc->sc_options = si_options;
151 1.19.2.2 rmind
152 1.19.2.2 rmind printf(": options=0x%x\n", sc->sc_options);
153 1.19.2.2 rmind
154 1.19.2.2 rmind ncr_sc->sc_no_disconnect = (sc->sc_options & SI_NO_DISCONNECT);
155 1.19.2.2 rmind ncr_sc->sc_parity_disable = (sc->sc_options & SI_NO_PARITY_CHK) >> 8;
156 1.19.2.2 rmind if (sc->sc_options & SI_FORCE_POLLING)
157 1.19.2.2 rmind ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
158 1.19.2.2 rmind
159 1.19.2.2 rmind ncr_sc->sc_min_dma_len = MIN_DMA_LEN;
160 1.19.2.2 rmind ncr_sc->sc_dma_alloc = si_dma_alloc;
161 1.19.2.2 rmind ncr_sc->sc_dma_free = si_dma_free;
162 1.19.2.2 rmind ncr_sc->sc_dma_poll = si_dma_poll;
163 1.19.2.2 rmind ncr_sc->sc_dma_start = si_dma_start;
164 1.19.2.2 rmind ncr_sc->sc_dma_eop = si_dma_eop;
165 1.19.2.2 rmind ncr_sc->sc_dma_stop = si_dma_stop;
166 1.19.2.2 rmind
167 1.19.2.2 rmind if (sc->sc_options & SI_DISABLE_DMA)
168 1.19.2.2 rmind /* Override this function pointer. */
169 1.19.2.2 rmind ncr_sc->sc_dma_alloc = NULL;
170 1.19.2.2 rmind
171 1.19.2.2 rmind ncr_sc->sci_r0 = 0;
172 1.19.2.2 rmind ncr_sc->sci_r1 = 1;
173 1.19.2.2 rmind ncr_sc->sci_r2 = 2;
174 1.19.2.2 rmind ncr_sc->sci_r3 = 3;
175 1.19.2.2 rmind ncr_sc->sci_r4 = 4;
176 1.19.2.2 rmind ncr_sc->sci_r5 = 5;
177 1.19.2.2 rmind ncr_sc->sci_r6 = 6;
178 1.19.2.2 rmind ncr_sc->sci_r7 = 7;
179 1.19.2.2 rmind
180 1.19.2.2 rmind ncr_sc->sc_rev = NCR_VARIANT_CXD1180;
181 1.19.2.2 rmind
182 1.19.2.2 rmind ncr_sc->sc_pio_in = ncr5380_pio_in;
183 1.19.2.2 rmind ncr_sc->sc_pio_out = ncr5380_pio_out;
184 1.19.2.2 rmind
185 1.19.2.2 rmind ncr_sc->sc_adapter.adapt_minphys = minphys;
186 1.19.2.2 rmind ncr_sc->sc_channel.chan_id = 7;
187 1.19.2.2 rmind
188 1.19.2.2 rmind /* soft reset DMAC */
189 1.19.2.2 rmind sc->sc_regs = (void *)IIOV(DMAC_BASE);
190 1.19.2.2 rmind sc->sc_regs->ctl = DC_CTL_RST;
191 1.19.2.2 rmind
192 1.19.2.2 rmind ncr5380_attach(ncr_sc);
193 1.19.2.2 rmind }
194 1.19.2.2 rmind
195 1.19.2.2 rmind int
196 1.19.2.2 rmind si_intr(int unit)
197 1.19.2.2 rmind {
198 1.19.2.2 rmind struct si_softc *sc;
199 1.19.2.2 rmind
200 1.19.2.2 rmind if (unit >= si_cd.cd_ndevs)
201 1.19.2.2 rmind return 0;
202 1.19.2.2 rmind
203 1.19.2.2 rmind sc = si_cd.cd_devs[unit];
204 1.19.2.2 rmind (void)ncr5380_intr(&sc->ncr_sc);
205 1.19.2.2 rmind
206 1.19.2.2 rmind return 0;
207 1.19.2.2 rmind }
208 1.19.2.2 rmind
209 1.19.2.2 rmind /*
210 1.19.2.2 rmind * DMA routines for news1700 machines
211 1.19.2.2 rmind */
212 1.19.2.2 rmind static void
213 1.19.2.2 rmind si_dma_alloc(struct ncr5380_softc *ncr_sc)
214 1.19.2.2 rmind {
215 1.19.2.2 rmind struct sci_req *sr = ncr_sc->sc_current;
216 1.19.2.2 rmind
217 1.19.2.2 rmind #ifdef DIAGNOSTIC
218 1.19.2.2 rmind if (sr->sr_dma_hand != NULL)
219 1.19.2.2 rmind panic("%s: DMA already in use", __func__);
220 1.19.2.2 rmind #endif
221 1.19.2.2 rmind
222 1.19.2.2 rmind /*
223 1.19.2.2 rmind * On news68k, SCSI has its own DMAC so no need allocate it.
224 1.19.2.2 rmind * Just mark that DMA is available.
225 1.19.2.2 rmind */
226 1.19.2.2 rmind sr->sr_dma_hand = (void *)-1;
227 1.19.2.2 rmind }
228 1.19.2.2 rmind
229 1.19.2.2 rmind static void
230 1.19.2.2 rmind si_dma_free(struct ncr5380_softc *ncr_sc)
231 1.19.2.2 rmind {
232 1.19.2.2 rmind struct sci_req *sr = ncr_sc->sc_current;
233 1.19.2.2 rmind
234 1.19.2.2 rmind #ifdef DIAGNOSTIC
235 1.19.2.2 rmind if (sr->sr_dma_hand == NULL)
236 1.19.2.2 rmind panic("%s: DMA not in use", __func__);
237 1.19.2.2 rmind #endif
238 1.19.2.2 rmind
239 1.19.2.2 rmind sr->sr_dma_hand = NULL;
240 1.19.2.2 rmind }
241 1.19.2.2 rmind
242 1.19.2.2 rmind
243 1.19.2.2 rmind static void
244 1.19.2.2 rmind si_dma_start(struct ncr5380_softc *ncr_sc)
245 1.19.2.2 rmind {
246 1.19.2.2 rmind struct si_softc *sc = (struct si_softc *)ncr_sc;
247 1.19.2.2 rmind volatile struct dma_regs *dmac = sc->sc_regs;
248 1.19.2.2 rmind struct sci_req *sr = ncr_sc->sc_current;
249 1.19.2.2 rmind u_int addr, offset, rest;
250 1.19.2.2 rmind long len;
251 1.19.2.2 rmind int i;
252 1.19.2.2 rmind
253 1.19.2.2 rmind /* reset DMAC */
254 1.19.2.2 rmind dmac->ctl = DC_CTL_RST;
255 1.19.2.2 rmind dmac->ctl = 0;
256 1.19.2.2 rmind
257 1.19.2.2 rmind addr = (u_int)ncr_sc->sc_dataptr;
258 1.19.2.2 rmind offset = addr & DMAC_SEG_OFFSET;
259 1.19.2.2 rmind len = sc->sc_xlen = ncr_sc->sc_datalen;
260 1.19.2.2 rmind
261 1.19.2.2 rmind /* set DMA transfer length */
262 1.19.2.2 rmind dmac->tcnt = (uint32_t)len;
263 1.19.2.2 rmind
264 1.19.2.2 rmind /* set offset of first segment */
265 1.19.2.2 rmind dmac->offset = offset;
266 1.19.2.2 rmind
267 1.19.2.2 rmind /* set first DMA segment address */
268 1.19.2.2 rmind dmac->tag = 0;
269 1.19.2.2 rmind dmac->mapent = kvtop((void *)addr) >> DMAC_SEG_SHIFT;
270 1.19.2.2 rmind rest = DMAC_SEG_SIZE - offset;
271 1.19.2.2 rmind addr += rest;
272 1.19.2.2 rmind len -= rest;
273 1.19.2.2 rmind
274 1.19.2.2 rmind /* set all the rest segments */
275 1.19.2.2 rmind for (i = 1; len > 0; i++) {
276 1.19.2.2 rmind dmac->tag = i;
277 1.19.2.2 rmind dmac->mapent = kvtop((void *)addr) >> DMAC_SEG_SHIFT;
278 1.19.2.2 rmind len -= DMAC_SEG_SIZE;
279 1.19.2.2 rmind addr += DMAC_SEG_SIZE;
280 1.19.2.2 rmind }
281 1.19.2.2 rmind /* terminate TAG */
282 1.19.2.2 rmind dmac->tag = 0;
283 1.19.2.2 rmind
284 1.19.2.2 rmind if (sr->sr_xs->xs_control & XS_CTL_DATA_OUT) {
285 1.19.2.2 rmind NCR5380_WRITE(ncr_sc, sci_tcmd, PHASE_DATA_OUT);
286 1.19.2.2 rmind NCR5380_WRITE(ncr_sc, sci_icmd, SCI_ICMD_DATA);
287 1.19.2.2 rmind NCR5380_WRITE(ncr_sc, sci_mode, NCR5380_READ(ncr_sc, sci_mode)
288 1.19.2.2 rmind | SCI_MODE_DMA | SCI_MODE_DMA_IE);
289 1.19.2.2 rmind
290 1.19.2.2 rmind /* set Dir */
291 1.19.2.2 rmind dmac->ctl = 0;
292 1.19.2.2 rmind
293 1.19.2.2 rmind /* start DMA */
294 1.19.2.2 rmind NCR5380_WRITE(ncr_sc, sci_dma_send, 0);
295 1.19.2.2 rmind dmac->ctl = DC_CTL_ENB;
296 1.19.2.2 rmind } else {
297 1.19.2.2 rmind NCR5380_WRITE(ncr_sc, sci_tcmd, PHASE_DATA_IN);
298 1.19.2.2 rmind NCR5380_WRITE(ncr_sc, sci_icmd, 0);
299 1.19.2.2 rmind NCR5380_WRITE(ncr_sc, sci_mode, NCR5380_READ(ncr_sc, sci_mode)
300 1.19.2.2 rmind | SCI_MODE_DMA | SCI_MODE_DMA_IE);
301 1.19.2.2 rmind
302 1.19.2.2 rmind /* set Dir */
303 1.19.2.2 rmind dmac->ctl = DC_CTL_MOD;
304 1.19.2.2 rmind
305 1.19.2.2 rmind /* start DMA */
306 1.19.2.2 rmind NCR5380_WRITE(ncr_sc, sci_irecv, 0);
307 1.19.2.2 rmind dmac->ctl = DC_CTL_MOD | DC_CTL_ENB;
308 1.19.2.2 rmind }
309 1.19.2.2 rmind ncr_sc->sc_state |= NCR_DOINGDMA;
310 1.19.2.2 rmind }
311 1.19.2.2 rmind
312 1.19.2.2 rmind /*
313 1.19.2.2 rmind * When?
314 1.19.2.2 rmind */
315 1.19.2.2 rmind static void
316 1.19.2.2 rmind si_dma_poll(struct ncr5380_softc *ncr_sc)
317 1.19.2.2 rmind {
318 1.19.2.2 rmind
319 1.19.2.2 rmind printf("si_dma_poll\n");
320 1.19.2.2 rmind }
321 1.19.2.2 rmind
322 1.19.2.2 rmind /*
323 1.19.2.2 rmind * news68k (probably) does not use the EOP signal.
324 1.19.2.2 rmind */
325 1.19.2.2 rmind static void
326 1.19.2.2 rmind si_dma_eop(struct ncr5380_softc *ncr_sc)
327 1.19.2.2 rmind {
328 1.19.2.2 rmind
329 1.19.2.2 rmind printf("si_dma_eop\n");
330 1.19.2.2 rmind }
331 1.19.2.2 rmind
332 1.19.2.2 rmind static void
333 1.19.2.2 rmind si_dma_stop(struct ncr5380_softc *ncr_sc)
334 1.19.2.2 rmind {
335 1.19.2.2 rmind struct si_softc *sc = (struct si_softc *)ncr_sc;
336 1.19.2.2 rmind volatile struct dma_regs *dmac = sc->sc_regs;
337 1.19.2.2 rmind struct sci_req *sr = ncr_sc->sc_current;
338 1.19.2.2 rmind int resid, ntrans;
339 1.19.2.2 rmind
340 1.19.2.2 rmind /* check DMAC interrupt status */
341 1.19.2.2 rmind if ((dmac->stat & DC_ST_INT) == 0) {
342 1.19.2.2 rmind #ifdef DEBUG
343 1.19.2.2 rmind printf("si_dma_stop: no DMA interrupt");
344 1.19.2.2 rmind #endif
345 1.19.2.2 rmind return; /* XXX */
346 1.19.2.2 rmind }
347 1.19.2.2 rmind
348 1.19.2.2 rmind if ((ncr_sc->sc_state & NCR_DOINGDMA) == 0) {
349 1.19.2.2 rmind #ifdef DEBUG
350 1.19.2.2 rmind printf("si_dma_stop: dma not running\n");
351 1.19.2.2 rmind #endif
352 1.19.2.2 rmind return;
353 1.19.2.2 rmind }
354 1.19.2.2 rmind ncr_sc->sc_state &= ~NCR_DOINGDMA;
355 1.19.2.2 rmind
356 1.19.2.2 rmind /* stop DMAC */
357 1.19.2.2 rmind resid = dmac->tcnt;
358 1.19.2.2 rmind dmac->ctl &= ~DC_CTL_ENB;
359 1.19.2.2 rmind
360 1.19.2.2 rmind /* OK, have either phase mis-match or end of DMA. */
361 1.19.2.2 rmind /* Set an impossible phase to prevent data movement? */
362 1.19.2.2 rmind NCR5380_WRITE(ncr_sc, sci_tcmd, PHASE_INVALID);
363 1.19.2.2 rmind
364 1.19.2.2 rmind /* Note that timeout may have set the error flag. */
365 1.19.2.2 rmind if (ncr_sc->sc_state & NCR_ABORTING)
366 1.19.2.2 rmind goto out;
367 1.19.2.2 rmind
368 1.19.2.2 rmind #ifdef DEBUG
369 1.19.2.2 rmind if (resid)
370 1.19.2.2 rmind printf("si_dma_stop: datalen = 0x%x, resid = 0x%x\n",
371 1.19.2.2 rmind sc->sc_xlen, resid);
372 1.19.2.2 rmind #endif
373 1.19.2.2 rmind
374 1.19.2.2 rmind ntrans = sc->sc_xlen - resid;
375 1.19.2.2 rmind
376 1.19.2.2 rmind ncr_sc->sc_dataptr += ntrans;
377 1.19.2.2 rmind ncr_sc->sc_datalen -= ntrans;
378 1.19.2.2 rmind
379 1.19.2.2 rmind if (sr->sr_xs->xs_control & XS_CTL_DATA_IN) {
380 1.19.2.2 rmind /* flush data cache */
381 1.19.2.2 rmind PCIA();
382 1.19.2.2 rmind }
383 1.19.2.2 rmind
384 1.19.2.2 rmind out:
385 1.19.2.2 rmind /* reset DMAC */
386 1.19.2.2 rmind dmac->ctl = DC_CTL_RST;
387 1.19.2.2 rmind dmac->ctl = 0;
388 1.19.2.2 rmind
389 1.19.2.2 rmind NCR5380_WRITE(ncr_sc, sci_mode, NCR5380_READ(ncr_sc, sci_mode) &
390 1.19.2.2 rmind ~(SCI_MODE_DMA | SCI_MODE_DMA_IE));
391 1.19.2.2 rmind NCR5380_WRITE(ncr_sc, sci_icmd, 0);
392 1.19.2.2 rmind }
393