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