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