lsi64854.c revision 1.1 1 /* $NetBSD: lsi64854.c,v 1.1 1998/08/29 21:42:03 pk Exp $ */
2
3 /*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Paul Kranenburg.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/errno.h>
44 #include <sys/device.h>
45 #include <sys/malloc.h>
46
47 #include <machine/bus.h>
48 #include <machine/autoconf.h>
49 #include <machine/cpu.h>
50
51 #include <dev/scsipi/scsi_all.h>
52 #include <dev/scsipi/scsipi_all.h>
53 #include <dev/scsipi/scsiconf.h>
54
55 #include <dev/ic/lsi64854reg.h>
56 #include <dev/ic/lsi64854var.h>
57
58 #include <dev/ic/ncr53c9xreg.h>
59 #include <dev/ic/ncr53c9xvar.h>
60
61 void lsi64854_reset __P((struct lsi64854_softc *));
62 int lsi64854_setup __P((struct lsi64854_softc *, caddr_t *, size_t *,
63 int, size_t *));
64
65 #ifdef DEBUG
66 int lsi64854debug = 0;
67 #define DPRINTF(x) do { if (lsi64854debug != 0) printf x ; } while (0)
68 #else
69 #define DPRINTF(x)
70 #endif
71
72 #define MAX_DMA_SZ (16*1024*1024)
73
74 /*
75 * Finish attaching this DMA device.
76 * Front-end must fill in these fields:
77 * sc_bustag
78 * sc_dmatag
79 * sc_regs
80 * sc_burst
81 * sc_channel (one of SCSI, ENET, PP)
82 * sc_client (one of SCSI, ENET, PP `soft_c' pointers)
83 */
84 void
85 lsi64854_attach(sc)
86 struct lsi64854_softc *sc;
87 {
88
89 /* Indirect functions */
90 switch (sc->sc_channel) {
91 case L64854_CHANNEL_SCSI:
92 sc->intr = lsi64854_scsi_intr;
93 break;
94 case L64854_CHANNEL_ENET:
95 sc->intr = lsi64854_enet_intr;
96 break;
97 case L64854_CHANNEL_PP:
98 break;
99 default:
100 printf("%s: unknown channel\n", sc->sc_dev.dv_xname);
101 }
102 sc->reset = lsi64854_reset;
103 sc->setup = lsi64854_setup;
104
105 /* Allocate a dmamap */
106 if (bus_dmamap_create(sc->sc_dmatag, MAX_DMA_SZ, 1, MAX_DMA_SZ,
107 0, BUS_DMA_WAITOK, &sc->sc_dmamap) != 0) {
108 printf("%s: dma map create failed\n", sc->sc_dev.dv_xname);
109 return;
110 }
111
112 printf(": rev ");
113 sc->sc_rev = L64854_GCSR(sc) & D_DEV_ID;
114 switch (sc->sc_rev) {
115 case DMAREV_0:
116 printf("0");
117 break;
118 case DMAREV_ESC:
119 printf("esc");
120 break;
121 case DMAREV_1:
122 printf("1");
123 break;
124 case DMAREV_PLUS:
125 printf("1+");
126 break;
127 case DMAREV_2:
128 printf("2");
129 break;
130 default:
131 printf("unknown (0x%x)", sc->sc_rev);
132 }
133 printf("\n");
134
135 }
136
137 #define DMAWAIT(SC, COND, MSG, DONTPANIC) do if (COND) { \
138 int count = 500000; \
139 while ((COND) && --count > 0) DELAY(1); \
140 if (count == 0) { \
141 printf("%s: line %d: CSR = 0x%lx\n", __FILE__, __LINE__, \
142 (u_long)L64854_GCSR(SC)); \
143 if (DONTPANIC) \
144 printf(MSG); \
145 else \
146 panic(MSG); \
147 } \
148 } while (0)
149
150 #define DMA_DRAIN(sc, dontpanic) do { \
151 u_int32_t csr; \
152 /* \
153 * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \
154 * and "drain" bits while it is still thinking about a \
155 * request. \
156 * other revs: D_ESC_R_PEND bit reads as 0 \
157 */ \
158 DMAWAIT(sc, L64854_GCSR(sc) & D_ESC_R_PEND, "R_PEND", dontpanic);\
159 /* \
160 * Select drain bit based on revision \
161 * also clears errors and D_TC flag \
162 */ \
163 csr = L64854_GCSR(sc); \
164 if (sc->sc_rev == DMAREV_1 || sc->sc_rev == DMAREV_0) \
165 csr |= D_ESC_DRAIN; \
166 else \
167 csr |= L64854_INVALIDATE; \
168 \
169 L64854_SCSR(sc,csr); \
170 /* \
171 * Wait for draining to finish \
172 * rev0 & rev1 call this PACKCNT \
173 */ \
174 DMAWAIT(sc, L64854_GCSR(sc) & L64854_DRAINING, "DRAINING", dontpanic);\
175 } while(0)
176
177 #define DMA_FLUSH(sc, dontpanic) do { \
178 u_int32_t csr; \
179 /* \
180 * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \
181 * and "drain" bits while it is still thinking about a \
182 * request. \
183 * other revs: D_ESC_R_PEND bit reads as 0 \
184 */ \
185 DMAWAIT(sc, L64854_GCSR(sc) & D_ESC_R_PEND, "R_PEND", dontpanic);\
186 csr = L64854_GCSR(sc); \
187 csr &= ~(L64854_WRITE|L64854_EN_DMA); /* no-ops on ENET */ \
188 csr |= L64854_INVALIDATE; \
189 L64854_SCSR(sc,csr); \
190 } while(0)
191
192 void
193 lsi64854_reset(sc)
194 struct lsi64854_softc *sc;
195 {
196 u_int32_t csr;
197
198 DMA_FLUSH(sc, 1);
199 csr = L64854_GCSR(sc);
200 csr |= L64854_RESET; /* reset DMA */
201 L64854_SCSR(sc, csr);
202 DELAY(200); /* > 10 Sbus clocks(?) */
203
204 /*DMAWAIT1(sc); why was this here? */
205 csr = L64854_GCSR(sc);
206 csr &= ~L64854_RESET; /* de-assert reset line */
207 L64854_SCSR(sc, csr);
208 DELAY(5); /* allow a few ticks to settle */
209
210 csr = L64854_GCSR(sc);
211 csr |= L64854_INT_EN; /* enable interrupts */
212 if (sc->sc_rev > DMAREV_1 && sc->sc_channel == L64854_CHANNEL_SCSI)
213 csr |= D_FASTER;
214
215 /* Set burst */
216 switch (sc->sc_rev) {
217 case DMAREV_2:
218 csr &= ~L64854_BURST_SIZE;
219 if (sc->sc_burst == 32) {
220 csr |= L64854_BURST_32;
221 } else if (sc->sc_burst == 16) {
222 csr |= L64854_BURST_16;
223 } else {
224 csr |= L64854_BURST_0;
225 }
226 break;
227 case DMAREV_ESC:
228 csr |= D_ESC_AUTODRAIN; /* Auto-drain */
229 if (sc->sc_burst == 32) {
230 csr &= ~D_ESC_BURST;
231 } else
232 csr |= D_ESC_BURST;
233 break;
234 default:
235 }
236 L64854_SCSR(sc, csr);
237
238 sc->sc_active = 0;
239 }
240
241
242 #define DMAMAX(a) (MAX_DMA_SZ - ((a) & (MAX_DMA_SZ-1)))
243 /*
244 * setup a dma transfer
245 */
246 int
247 lsi64854_setup(sc, addr, len, datain, dmasize)
248 struct lsi64854_softc *sc;
249 caddr_t *addr;
250 size_t *len;
251 int datain;
252 size_t *dmasize; /* IN-OUT */
253 {
254 u_int32_t csr;
255
256 DMA_FLUSH(sc, 0);
257
258 #if 0
259 DMACSR(sc) &= ~D_INT_EN;
260 #endif
261 sc->sc_dmaaddr = addr;
262 sc->sc_dmalen = len;
263
264 DPRINTF(("%s: start %d@%p,%d\n", sc->sc_dev.dv_xname,
265 *sc->sc_dmalen, *sc->sc_dmaaddr, datain ? 1 : 0));
266
267 /*
268 * the rules say we cannot transfer more than the limit
269 * of this DMA chip (64k for old and 16Mb for new),
270 * and we cannot cross a 16Mb boundary.
271 */
272 *dmasize = sc->sc_dmasize =
273 min(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
274
275 DPRINTF(("dma_setup: dmasize = %d\n", sc->sc_dmasize));
276
277 /* Program the DMA address */
278 if (sc->sc_dmasize) {
279 sc->sc_dvmaaddr = *sc->sc_dmaaddr;
280 if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap,
281 *sc->sc_dmaaddr, sc->sc_dmasize,
282 NULL /* kernel address */,
283 BUS_DMA_NOWAIT))
284 panic("%s: cannot allocate DVMA address",
285 sc->sc_dev.dv_xname);
286 bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap,
287 (bus_addr_t)sc->sc_dvmaaddr, sc->sc_dmasize,
288 datain
289 ? BUS_DMASYNC_PREREAD
290 : BUS_DMASYNC_PREWRITE);
291 bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_ADDR,
292 sc->sc_dmamap->dm_segs[0].ds_addr);
293 }
294
295 if (sc->sc_rev == DMAREV_ESC) {
296 /* DMA ESC chip bug work-around */
297 long bcnt = sc->sc_dmasize;
298 long eaddr = bcnt + (long)*sc->sc_dmaaddr;
299 if ((eaddr & PGOFSET) != 0)
300 bcnt = roundup(bcnt, NBPG);
301 bus_space_write_4(sc->sc_bustag, sc->sc_regs, L64854_REG_CNT,
302 bcnt);
303 }
304 /* Setup DMA control register */
305 csr = L64854_GCSR(sc);
306 if (datain)
307 csr |= L64854_WRITE;
308 else
309 csr &= ~L64854_WRITE;
310 csr |= L64854_INT_EN;
311 L64854_SCSR(sc, csr);
312
313 return (0);
314 }
315
316 /*
317 * Pseudo (chained) interrupt from the esp driver to kick the
318 * current running DMA transfer. I am replying on espintr() to
319 * pickup and clean errors for now
320 *
321 * return 1 if it was a DMA continue.
322 */
323 int
324 lsi64854_scsi_intr(arg)
325 void *arg;
326 {
327 struct lsi64854_softc *sc = arg;
328 struct ncr53c9x_softc *nsc = sc->sc_client;
329 char bits[64];
330 int trans, resid;
331 u_int32_t csr;
332
333 csr = L64854_GCSR(sc);
334
335 DPRINTF(("%s: intr: addr 0x%x, csr %s\n", sc->sc_dev.dv_xname,
336 bus_space_read_4(sc->sc_bustag, sc->sc_regs, L64854_REG_ADDR),
337 bitmask_snprintf(csr, DMACSRBITS, bits, sizeof(bits))));
338
339 if (csr & D_ERR_PEND) {
340 csr &= ~D_EN_DMA; /* Stop DMA */
341 csr |= D_INVALIDATE;
342 L64854_SCSR(sc, csr);
343 printf("%s: error: csr=%s\n", sc->sc_dev.dv_xname,
344 bitmask_snprintf(csr, DMACSRBITS, bits, sizeof(bits)));
345 return (-1);
346 }
347
348 /* This is an "assertion" :) */
349 if (sc->sc_active == 0)
350 panic("dmaintr: DMA wasn't active");
351
352 DMA_DRAIN(sc, 0);
353
354 /* DMA has stopped */
355 csr &= ~D_EN_DMA;
356 L64854_SCSR(sc, csr);
357 sc->sc_active = 0;
358
359 if (sc->sc_dmasize == 0) {
360 /* A "Transfer Pad" operation completed */
361 DPRINTF(("dmaintr: discarded %d bytes (tcl=%d, tcm=%d)\n",
362 NCR_READ_REG(nsc, NCR_TCL) |
363 (NCR_READ_REG(nsc, NCR_TCM) << 8),
364 NCR_READ_REG(nsc, NCR_TCL),
365 NCR_READ_REG(nsc, NCR_TCM)));
366 return 0;
367 }
368
369 resid = 0;
370 /*
371 * If a transfer onto the SCSI bus gets interrupted by the device
372 * (e.g. for a SAVEPOINTER message), the data in the FIFO counts
373 * as residual since the NCR53C9X counter registers get decremented
374 * as bytes are clocked into the FIFO.
375 */
376 if (!(csr & D_WRITE) &&
377 (resid = (NCR_READ_REG(nsc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
378 DPRINTF(("dmaintr: empty esp FIFO of %d ", resid));
379 }
380
381 if ((nsc->sc_espstat & NCRSTAT_TC) == 0) {
382 /*
383 * `Terminal count' is off, so read the residue
384 * out of the NCR53C9X counter registers.
385 */
386 resid += (NCR_READ_REG(nsc, NCR_TCL) |
387 (NCR_READ_REG(nsc, NCR_TCM) << 8) |
388 ((nsc->sc_cfg2 & NCRCFG2_FE)
389 ? (NCR_READ_REG(nsc, NCR_TCH) << 16)
390 : 0));
391
392 if (resid == 0 && sc->sc_dmasize == 65536 &&
393 (nsc->sc_cfg2 & NCRCFG2_FE) == 0)
394 /* A transfer of 64K is encoded as `TCL=TCM=0' */
395 resid = 65536;
396 }
397
398 trans = sc->sc_dmasize - resid;
399 if (trans < 0) { /* transferred < 0 ? */
400 #if 0
401 /*
402 * This situation can happen in perfectly normal operation
403 * if the ESP is reselected while using DMA to select
404 * another target. As such, don't print the warning.
405 */
406 printf("%s: xfer (%d) > req (%d)\n",
407 sc->sc_dev.dv_xname, trans, sc->sc_dmasize);
408 #endif
409 trans = sc->sc_dmasize;
410 }
411
412 DPRINTF(("dmaintr: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
413 NCR_READ_REG(nsc, NCR_TCL),
414 NCR_READ_REG(nsc, NCR_TCM),
415 (nsc->sc_cfg2 & NCRCFG2_FE)
416 ? NCR_READ_REG(nsc, NCR_TCH) : 0,
417 trans, resid));
418
419 if (sc->sc_dmamap->dm_nsegs > 0) {
420 bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap,
421 (bus_addr_t)sc->sc_dvmaaddr, sc->sc_dmasize,
422 (csr & D_WRITE) != 0
423 ? BUS_DMASYNC_POSTREAD
424 : BUS_DMASYNC_POSTWRITE);
425 bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
426 }
427
428 *sc->sc_dmalen -= trans;
429 *sc->sc_dmaaddr += trans;
430
431 #if 0 /* this is not normal operation just yet */
432 if (*sc->sc_dmalen == 0 ||
433 nsc->sc_phase != nsc->sc_prevphase)
434 return 0;
435
436 /* and again */
437 dma_start(sc, sc->sc_dmaaddr, sc->sc_dmalen, DMACSR(sc) & D_WRITE);
438 return 1;
439 #endif
440 return 0;
441 }
442
443 /*
444 * Pseudo (chained) interrupt to le driver to handle DMA errors.
445 */
446 int
447 lsi64854_enet_intr(arg)
448 void *arg;
449 {
450 struct lsi64854_softc *sc = arg;
451 char bits[64];
452 u_int32_t csr;
453 static int dodrain=0;
454
455 csr = L64854_GCSR(sc);
456
457 if (csr & E_ERR_PEND) {
458 csr &= ~L64854_EN_DMA; /* Stop DMA */
459 csr |= E_INVALIDATE;
460 L64854_SCSR(sc, csr);
461 printf("%s: error: csr=%s\n", sc->sc_dev.dv_xname,
462 bitmask_snprintf(csr, DMACSRBITS, bits, sizeof(bits)));
463 DMA_RESET(sc);
464 dodrain = 1;
465 }
466
467 if (dodrain) { /* XXX - is this necessary with D_DSBL_WRINVAL on? */
468 int i = 10;
469 csr |= E_DRAIN;
470 L64854_SCSR(sc, csr);
471 while (i-- > 0 && (L64854_GCSR(sc) & D_DRAINING))
472 delay(1);
473 }
474
475 return (*sc->sc_intrchain)(sc->sc_intrchainarg);
476 }
477