Annotation of sys/dev/ic/lsi64854.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: lsi64854.c,v 1.8 2007/02/28 18:48:35 miod Exp $ */
2: /* $NetBSD: lsi64854.c,v 1.18 2001/06/04 20:56:51 mrg Exp $ */
3:
4: /*-
5: * Copyright (c) 1998 The NetBSD Foundation, Inc.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to The NetBSD Foundation
9: * by Paul Kranenburg.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the NetBSD
22: * Foundation, Inc. and its contributors.
23: * 4. Neither the name of The NetBSD Foundation nor the names of its
24: * contributors may be used to endorse or promote products derived
25: * from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: * POSSIBILITY OF SUCH DAMAGE.
38: */
39:
40: #include <sys/types.h>
41: #include <sys/param.h>
42: #include <sys/systm.h>
43: #include <sys/kernel.h>
44: #include <sys/errno.h>
45: #include <sys/device.h>
46:
47: #include <uvm/uvm_extern.h>
48:
49: #include <machine/bus.h>
50: #include <machine/autoconf.h>
51: #include <machine/cpu.h>
52:
53: #include <scsi/scsi_all.h>
54: #include <scsi/scsiconf.h>
55:
56: #include <dev/ic/lsi64854reg.h>
57: #include <dev/ic/lsi64854var.h>
58:
59: #include <dev/ic/ncr53c9xreg.h>
60: #include <dev/ic/ncr53c9xvar.h>
61:
62: void lsi64854_reset(struct lsi64854_softc *);
63: int lsi64854_setup(struct lsi64854_softc *, caddr_t *, size_t *,
64: int, size_t *);
65: int lsi64854_setup_pp(struct lsi64854_softc *, caddr_t *, size_t *,
66: int, size_t *);
67: int lsi64854_scsi_intr(void *);
68: int lsi64854_pp_intr(void *);
69:
70: #ifdef DEBUG
71: #define LDB_SCSI 1
72: #define LDB_ENET 2
73: #define LDB_PP 4
74: #define LDB_ANY 0xff
75: int lsi64854debug = 0;
76: #define DPRINTF(a,x) do { if (lsi64854debug & (a)) printf x ; } while (0)
77: #else
78: #define DPRINTF(a,x)
79: #endif
80:
81: #define MAX_DMA_SZ (16*1024*1024)
82:
83: /*
84: * Finish attaching this DMA device.
85: * Front-end must fill in these fields:
86: * sc_bustag
87: * sc_dmatag
88: * sc_regs
89: * sc_burst
90: * sc_channel (one of SCSI, ENET, PP)
91: * sc_client (one of SCSI, ENET, PP `soft_c' pointers)
92: */
93: int
94: lsi64854_attach(sc)
95: struct lsi64854_softc *sc;
96: {
97: u_int32_t csr;
98: int rc;
99:
100: /* Indirect functions */
101: switch (sc->sc_channel) {
102: case L64854_CHANNEL_SCSI:
103: sc->intr = lsi64854_scsi_intr;
104: sc->setup = lsi64854_setup;
105: break;
106: case L64854_CHANNEL_ENET:
107: sc->intr = lsi64854_enet_intr;
108: sc->setup = lsi64854_setup;
109: break;
110: case L64854_CHANNEL_PP:
111: sc->intr = lsi64854_pp_intr;
112: sc->setup = lsi64854_setup_pp;
113: break;
114: default:
115: printf("%s: unknown channel\n", sc->sc_dev.dv_xname);
116: }
117: sc->reset = lsi64854_reset;
118:
119: /* Allocate a dmamap */
120: if ((rc = bus_dmamap_create(sc->sc_dmatag, MAX_DMA_SZ, 1, MAX_DMA_SZ,
121: 0, BUS_DMA_WAITOK, &sc->sc_dmamap)) != 0) {
122: printf(": dma map create failed\n");
123: return (rc);
124: }
125:
126: printf(": dma rev ");
127: csr = L64854_GCSR(sc);
128: sc->sc_rev = csr & L64854_DEVID;
129: switch (sc->sc_rev) {
130: case DMAREV_0:
131: printf("0");
132: break;
133: case DMAREV_ESC:
134: printf("esc");
135: break;
136: case DMAREV_1:
137: printf("1");
138: break;
139: case DMAREV_PLUS:
140: printf("1+");
141: break;
142: case DMAREV_2:
143: printf("2");
144: break;
145: case DMAREV_HME:
146: printf("fas");
147: break;
148: default:
149: printf("unknown (0x%x)", sc->sc_rev);
150: }
151:
152: DPRINTF(LDB_ANY, (", burst 0x%x, csr 0x%x", sc->sc_burst, csr));
153: printf("\n");
154:
155: return (0);
156: }
157:
158: /*
159: * DMAWAIT waits while condition is true
160: */
161: #define DMAWAIT(SC, COND, MSG, DONTPANIC) do if (COND) { \
162: int count = 500000; \
163: while ((COND) && --count > 0) DELAY(1); \
164: if (count == 0) { \
165: printf("%s: line %d: CSR = 0x%lx\n", __FILE__, __LINE__, \
166: (u_long)L64854_GCSR(SC)); \
167: if (DONTPANIC) \
168: printf(MSG); \
169: else \
170: panic(MSG); \
171: } \
172: } while (0)
173:
174: #define DMA_DRAIN(sc, dontpanic) do { \
175: u_int32_t csr; \
176: /* \
177: * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \
178: * and "drain" bits while it is still thinking about a \
179: * request. \
180: * other revs: D_ESC_R_PEND bit reads as 0 \
181: */ \
182: DMAWAIT(sc, L64854_GCSR(sc) & D_ESC_R_PEND, "R_PEND", dontpanic);\
183: if (sc->sc_rev != DMAREV_HME) { \
184: /* \
185: * Select drain bit based on revision \
186: * also clears errors and D_TC flag \
187: */ \
188: csr = L64854_GCSR(sc); \
189: if (sc->sc_rev == DMAREV_1 || sc->sc_rev == DMAREV_0) \
190: csr |= D_ESC_DRAIN; \
191: else \
192: csr |= L64854_INVALIDATE; \
193: \
194: L64854_SCSR(sc,csr); \
195: } \
196: /* \
197: * Wait for draining to finish \
198: * rev0 & rev1 call this PACKCNT \
199: */ \
200: DMAWAIT(sc, L64854_GCSR(sc) & L64854_DRAINING, "DRAINING", dontpanic);\
201: } while(0)
202:
203: #define DMA_FLUSH(sc, dontpanic) do { \
204: u_int32_t csr; \
205: /* \
206: * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \
207: * and "drain" bits while it is still thinking about a \
208: * request. \
209: * other revs: D_ESC_R_PEND bit reads as 0 \
210: */ \
211: DMAWAIT(sc, L64854_GCSR(sc) & D_ESC_R_PEND, "R_PEND", dontpanic);\
212: csr = L64854_GCSR(sc); \
213: csr &= ~(L64854_WRITE|L64854_EN_DMA); /* no-ops on ENET */ \
214: csr |= L64854_INVALIDATE; /* XXX FAS ? */ \
215: L64854_SCSR(sc,csr); \
216: } while(0)
217:
218: void
219: lsi64854_reset(sc)
220: struct lsi64854_softc *sc;
221: {
222: u_int32_t csr;
223:
224: DMA_FLUSH(sc, 1);
225: csr = L64854_GCSR(sc);
226:
227: DPRINTF(LDB_ANY, ("lsi64854_reset: csr 0x%x\n", csr));
228:
229: /*
230: * XXX is sync needed?
231: */
232: if (sc->sc_dmamap->dm_nsegs > 0)
233: bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
234:
235: if (sc->sc_rev == DMAREV_HME)
236: L64854_SCSR(sc, csr | D_HW_RESET_FAS366);
237:
238:
239: csr |= L64854_RESET; /* reset DMA */
240: L64854_SCSR(sc, csr);
241: DELAY(200); /* > 10 Sbus clocks(?) */
242:
243: /*DMAWAIT1(sc); why was this here? */
244: csr = L64854_GCSR(sc);
245: csr &= ~L64854_RESET; /* de-assert reset line */
246: L64854_SCSR(sc, csr);
247: DELAY(5); /* allow a few ticks to settle */
248:
249: csr = L64854_GCSR(sc);
250: csr |= L64854_INT_EN; /* enable interrupts */
251: if (sc->sc_rev > DMAREV_1 && sc->sc_channel == L64854_CHANNEL_SCSI) {
252: if (sc->sc_rev == DMAREV_HME)
253: csr |= D_TWO_CYCLE;
254: else
255: csr |= D_FASTER;
256: }
257:
258: /* Set burst */
259: switch (sc->sc_rev) {
260: case DMAREV_HME:
261: case DMAREV_2:
262: csr &= ~L64854_BURST_SIZE;
263: if (sc->sc_burst == 32) {
264: csr |= L64854_BURST_32;
265: } else if (sc->sc_burst == 16) {
266: csr |= L64854_BURST_16;
267: } else {
268: csr |= L64854_BURST_0;
269: }
270: break;
271: case DMAREV_ESC:
272: csr |= D_ESC_AUTODRAIN; /* Auto-drain */
273: if (sc->sc_burst == 32) {
274: csr &= ~D_ESC_BURST;
275: } else
276: csr |= D_ESC_BURST;
277: break;
278: default:
279: break;
280: }
281: L64854_SCSR(sc, csr);
282:
283: if (sc->sc_rev == DMAREV_HME) {
284: bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_ADDR, 0);
285: sc->sc_dmactl = csr;
286: }
287: sc->sc_active = 0;
288:
289: DPRINTF(LDB_ANY, ("lsi64854_reset: done, csr 0x%x\n", csr));
290: }
291:
292:
293: #define DMAMAX(a) (MAX_DMA_SZ - ((a) & (MAX_DMA_SZ-1)))
294: /*
295: * setup a dma transfer
296: */
297: int
298: lsi64854_setup(sc, addr, len, datain, dmasize)
299: struct lsi64854_softc *sc;
300: caddr_t *addr;
301: size_t *len;
302: int datain;
303: size_t *dmasize; /* IN-OUT */
304: {
305: u_int32_t csr;
306:
307: DMA_FLUSH(sc, 0);
308:
309: #if 0
310: DMACSR(sc) &= ~D_INT_EN;
311: #endif
312: sc->sc_dmaaddr = addr;
313: sc->sc_dmalen = len;
314:
315: /*
316: * the rules say we cannot transfer more than the limit
317: * of this DMA chip (64k for old and 16Mb for new),
318: * and we cannot cross a 16Mb boundary.
319: */
320: *dmasize = sc->sc_dmasize =
321: min(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
322:
323: DPRINTF(LDB_ANY, ("dma_setup: dmasize = %ld\n", (long)sc->sc_dmasize));
324:
325: /*
326: * XXX what length?
327: */
328: if (sc->sc_rev == DMAREV_HME) {
329:
330: L64854_SCSR(sc, sc->sc_dmactl | L64854_RESET);
331: L64854_SCSR(sc, sc->sc_dmactl);
332:
333: bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_CNT, *dmasize);
334: }
335:
336: /* Program the DMA address */
337: if (sc->sc_dmasize) {
338: sc->sc_dvmaaddr = *sc->sc_dmaaddr;
339: if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap,
340: *sc->sc_dmaaddr, sc->sc_dmasize,
341: NULL /* kernel address */,
342: BUS_DMA_NOWAIT | BUS_DMA_STREAMING))
343: panic("%s: cannot allocate DVMA address",
344: sc->sc_dev.dv_xname);
345: bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, sc->sc_dmasize,
346: datain
347: ? BUS_DMASYNC_PREREAD
348: : BUS_DMASYNC_PREWRITE);
349: bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_ADDR,
350: sc->sc_dmamap->dm_segs[0].ds_addr);
351: }
352:
353: if (sc->sc_rev == DMAREV_ESC) {
354: /* DMA ESC chip bug work-around */
355: long bcnt = sc->sc_dmasize;
356: long eaddr = bcnt + (long)*sc->sc_dmaaddr;
357: if ((eaddr & PGOFSET) != 0)
358: bcnt = roundup(bcnt, PAGE_SIZE);
359: bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_CNT,
360: bcnt);
361: }
362:
363: /* Setup DMA control register */
364: csr = L64854_GCSR(sc);
365:
366: if (datain)
367: csr |= L64854_WRITE;
368: else
369: csr &= ~L64854_WRITE;
370: csr |= L64854_INT_EN;
371:
372: if (sc->sc_rev == DMAREV_HME) {
373: csr |= (D_DSBL_SCSI_DRN | D_EN_DMA);
374: }
375:
376: L64854_SCSR(sc, csr);
377:
378: return (0);
379: }
380:
381: /*
382: * Pseudo (chained) interrupt from the esp driver to kick the
383: * current running DMA transfer. Called from ncr53c9x_intr()
384: * for now.
385: *
386: * return 1 if it was a DMA continue.
387: */
388: int
389: lsi64854_scsi_intr(arg)
390: void *arg;
391: {
392: struct lsi64854_softc *sc = arg;
393: struct ncr53c9x_softc *nsc = sc->sc_client;
394: char bits[64];
395: int trans, resid;
396: u_int32_t csr;
397:
398: csr = L64854_GCSR(sc);
399:
400: DPRINTF(LDB_SCSI, ("%s: dmaintr: addr 0x%x, csr %b\n", sc->sc_dev.dv_xname,
401: bus_space_read_4(sc->sc_bustag, sc->sc_regs, L64854_REG_ADDR),
402: csr, DDMACSR_BITS));
403:
404: if (csr & (D_ERR_PEND|D_SLAVE_ERR)) {
405: snprintf(bits, sizeof(bits), "%b", csr, DDMACSR_BITS);
406: printf("%s: error: csr=%s\n", sc->sc_dev.dv_xname, bits);
407: csr &= ~D_EN_DMA; /* Stop DMA */
408: /* Invalidate the queue; SLAVE_ERR bit is write-to-clear */
409: csr |= D_INVALIDATE|D_SLAVE_ERR;
410: L64854_SCSR(sc, csr);
411: return (-1);
412: }
413:
414: /* This is an "assertion" :) */
415: if (sc->sc_active == 0)
416: panic("dmaintr: DMA wasn't active");
417:
418: DMA_DRAIN(sc, 0);
419:
420: /* DMA has stopped */
421: csr &= ~D_EN_DMA;
422: L64854_SCSR(sc, csr);
423: sc->sc_active = 0;
424:
425: if (sc->sc_dmasize == 0) {
426: /* A "Transfer Pad" operation completed */
427: DPRINTF(LDB_SCSI, ("dmaintr: discarded %d bytes (tcl=%d, tcm=%d)\n",
428: NCR_READ_REG(nsc, NCR_TCL) |
429: (NCR_READ_REG(nsc, NCR_TCM) << 8),
430: NCR_READ_REG(nsc, NCR_TCL),
431: NCR_READ_REG(nsc, NCR_TCM)));
432: return 0;
433: }
434:
435: resid = 0;
436: /*
437: * If a transfer onto the SCSI bus gets interrupted by the device
438: * (e.g. for a SAVEPOINTER message), the data in the FIFO counts
439: * as residual since the NCR53C9X counter registers get decremented
440: * as bytes are clocked into the FIFO.
441: */
442: if (!(csr & D_WRITE) &&
443: (resid = (NCR_READ_REG(nsc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
444: DPRINTF(LDB_SCSI, ("dmaintr: empty esp FIFO of %d ", resid));
445: if (nsc->sc_rev == NCR_VARIANT_FAS366 &&
446: (NCR_READ_REG(nsc, NCR_CFG3) & NCRFASCFG3_EWIDE))
447: resid <<= 1;
448: }
449:
450: if ((nsc->sc_espstat & NCRSTAT_TC) == 0) {
451: /*
452: * `Terminal count' is off, so read the residue
453: * out of the NCR53C9X counter registers.
454: */
455: resid += (NCR_READ_REG(nsc, NCR_TCL) |
456: (NCR_READ_REG(nsc, NCR_TCM) << 8) |
457: ((nsc->sc_cfg2 & NCRCFG2_FE)
458: ? (NCR_READ_REG(nsc, NCR_TCH) << 16)
459: : 0));
460:
461: if (resid == 0 && sc->sc_dmasize == 65536 &&
462: (nsc->sc_cfg2 & NCRCFG2_FE) == 0)
463: /* A transfer of 64K is encoded as `TCL=TCM=0' */
464: resid = 65536;
465: }
466:
467: trans = sc->sc_dmasize - resid;
468: if (trans < 0) { /* transferred < 0 ? */
469: #if 0
470: /*
471: * This situation can happen in perfectly normal operation
472: * if the ESP is reselected while using DMA to select
473: * another target. As such, don't print the warning.
474: */
475: printf("%s: xfer (%d) > req (%d)\n",
476: sc->sc_dev.dv_xname, trans, sc->sc_dmasize);
477: #endif
478: trans = sc->sc_dmasize;
479: }
480:
481: DPRINTF(LDB_SCSI, ("dmaintr: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
482: NCR_READ_REG(nsc, NCR_TCL),
483: NCR_READ_REG(nsc, NCR_TCM),
484: (nsc->sc_cfg2 & NCRCFG2_FE)
485: ? NCR_READ_REG(nsc, NCR_TCH) : 0,
486: trans, resid));
487:
488: if (sc->sc_dmamap->dm_nsegs > 0) {
489: bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, sc->sc_dmasize,
490: (csr & D_WRITE) != 0
491: ? BUS_DMASYNC_POSTREAD
492: : BUS_DMASYNC_POSTWRITE);
493: bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
494: }
495:
496: *sc->sc_dmalen -= trans;
497: *sc->sc_dmaaddr += trans;
498:
499: #if 0 /* this is not normal operation just yet */
500: if (*sc->sc_dmalen == 0 ||
501: nsc->sc_phase != nsc->sc_prevphase)
502: return 0;
503:
504: /* and again */
505: dma_start(sc, sc->sc_dmaaddr, sc->sc_dmalen, DMACSR(sc) & D_WRITE);
506: return 1;
507: #endif
508: return 0;
509: }
510:
511: /*
512: * Pseudo (chained) interrupt to le driver to handle DMA errors.
513: */
514: int
515: lsi64854_enet_intr(arg)
516: void *arg;
517: {
518: struct lsi64854_softc *sc = arg;
519: char bits[64];
520: u_int32_t csr;
521: static int dodrain = 0;
522: int rv;
523:
524: csr = L64854_GCSR(sc);
525:
526: /* If the DMA logic shows an interrupt, claim it */
527: rv = ((csr & E_INT_PEND) != 0) ? 1 : 0;
528:
529: if (csr & (E_ERR_PEND|E_SLAVE_ERR)) {
530: snprintf(bits, sizeof(bits), "%b", csr, EDMACSR_BITS);
531: printf("%s: error: csr=%s\n", sc->sc_dev.dv_xname, bits);
532: csr &= ~L64854_EN_DMA; /* Stop DMA */
533: /* Invalidate the queue; SLAVE_ERR bit is write-to-clear */
534: csr |= E_INVALIDATE|E_SLAVE_ERR;
535: L64854_SCSR(sc, csr);
536: DMA_RESET(sc);
537: dodrain = 1;
538: return (1);
539: }
540:
541: if (dodrain) { /* XXX - is this necessary with D_DSBL_WRINVAL on? */
542: int i = 10;
543: csr |= E_DRAIN;
544: L64854_SCSR(sc, csr);
545: while (i-- > 0 && (L64854_GCSR(sc) & D_DRAINING))
546: delay(1);
547: }
548:
549: return (rv | (*sc->sc_intrchain)(sc->sc_intrchainarg));
550: }
551:
552: /*
553: * setup a dma transfer
554: */
555: int
556: lsi64854_setup_pp(sc, addr, len, datain, dmasize)
557: struct lsi64854_softc *sc;
558: caddr_t *addr;
559: size_t *len;
560: int datain;
561: size_t *dmasize; /* IN-OUT */
562: {
563: u_int32_t csr;
564:
565: DMA_FLUSH(sc, 0);
566:
567: sc->sc_dmaaddr = addr;
568: sc->sc_dmalen = len;
569:
570: DPRINTF(LDB_PP, ("%s: pp start %ld@%p,%d\n", sc->sc_dev.dv_xname,
571: (long)*sc->sc_dmalen, *sc->sc_dmaaddr, datain ? 1 : 0));
572:
573: /*
574: * the rules say we cannot transfer more than the limit
575: * of this DMA chip (64k for old and 16Mb for new),
576: * and we cannot cross a 16Mb boundary.
577: */
578: *dmasize = sc->sc_dmasize =
579: min(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
580:
581: DPRINTF(LDB_PP, ("dma_setup_pp: dmasize = %ld\n", (long)sc->sc_dmasize));
582:
583: /* Program the DMA address */
584: if (sc->sc_dmasize) {
585: sc->sc_dvmaaddr = *sc->sc_dmaaddr;
586: if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap,
587: *sc->sc_dmaaddr, sc->sc_dmasize,
588: NULL /* kernel address */,
589: BUS_DMA_NOWAIT/*|BUS_DMA_COHERENT*/))
590: panic("%s: pp cannot allocate DVMA address",
591: sc->sc_dev.dv_xname);
592: bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, sc->sc_dmasize,
593: datain
594: ? BUS_DMASYNC_PREREAD
595: : BUS_DMASYNC_PREWRITE);
596: bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_ADDR,
597: sc->sc_dmamap->dm_segs[0].ds_addr);
598:
599: bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_CNT,
600: sc->sc_dmasize);
601: }
602:
603: /* Setup DMA control register */
604: csr = L64854_GCSR(sc);
605: csr &= ~L64854_BURST_SIZE;
606: if (sc->sc_burst == 32) {
607: csr |= L64854_BURST_32;
608: } else if (sc->sc_burst == 16) {
609: csr |= L64854_BURST_16;
610: } else {
611: csr |= L64854_BURST_0;
612: }
613: csr |= P_EN_DMA|P_INT_EN|P_EN_CNT;
614: #if 0
615: /* This bit is read-only in PP csr register */
616: if (datain)
617: csr |= P_WRITE;
618: else
619: csr &= ~P_WRITE;
620: #endif
621: L64854_SCSR(sc, csr);
622:
623: return (0);
624: }
625: /*
626: * Parallel port DMA interrupt.
627: */
628: int
629: lsi64854_pp_intr(arg)
630: void *arg;
631: {
632: struct lsi64854_softc *sc = arg;
633: int ret, trans, resid = 0;
634: u_int32_t csr;
635:
636: csr = L64854_GCSR(sc);
637:
638: DPRINTF(LDB_PP, ("%s: pp intr: addr 0x%x, csr %b\n", sc->sc_dev.dv_xname,
639: bus_space_read_4(sc->sc_bustag, sc->sc_regs, L64854_REG_ADDR),
640: csr, PDMACSR_BITS));
641:
642: if (csr & (P_ERR_PEND|P_SLAVE_ERR)) {
643: resid = bus_space_read_4(sc->sc_bustag, sc->sc_regs,
644: L64854_REG_CNT);
645: printf("%s: pp error: resid %d csr=%b\n", sc->sc_dev.dv_xname,
646: resid, csr, PDMACSR_BITS);
647: csr &= ~P_EN_DMA; /* Stop DMA */
648: /* Invalidate the queue; SLAVE_ERR bit is write-to-clear */
649: csr |= P_INVALIDATE|P_SLAVE_ERR;
650: L64854_SCSR(sc, csr);
651: return (1);
652: }
653:
654: ret = (csr & P_INT_PEND) != 0;
655:
656: if (sc->sc_active != 0) {
657: DMA_DRAIN(sc, 0);
658: resid = bus_space_read_4(sc->sc_bustag, sc->sc_regs,
659: L64854_REG_CNT);
660: }
661:
662: /* DMA has stopped */
663: csr &= ~D_EN_DMA;
664: L64854_SCSR(sc, csr);
665: sc->sc_active = 0;
666:
667: trans = sc->sc_dmasize - resid;
668: if (trans < 0) { /* transferred < 0 ? */
669: trans = sc->sc_dmasize;
670: }
671: *sc->sc_dmalen -= trans;
672: *sc->sc_dmaaddr += trans;
673:
674: if (sc->sc_dmamap->dm_nsegs > 0) {
675: bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, sc->sc_dmasize,
676: (csr & D_WRITE) != 0
677: ? BUS_DMASYNC_POSTREAD
678: : BUS_DMASYNC_POSTWRITE);
679: bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
680: }
681:
682: return (ret != 0);
683: }
CVSweb