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