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: releng/6.4/sys/sparc64/sbus/lsi64854.c 146392 2005-05-19 14:51:10Z marius $");
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("");
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 }
Cache object: 189283399d1b58f7f5c8611b603d2ec8
|