xref: /openbsd-src/sys/dev/sbus/esp_sbus.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: esp_sbus.c,v 1.24 2014/01/18 22:33:59 dlg Exp $	*/
2 /*	$NetBSD: esp_sbus.c,v 1.14 2001/04/25 17:53:37 bouyer Exp $	*/
3 
4 /*-
5  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace
10  * Simulation Facility, NASA Ames Research Center; Paul Kranenburg.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38 #include <sys/buf.h>
39 #include <sys/malloc.h>
40 
41 #include <scsi/scsi_all.h>
42 #include <scsi/scsiconf.h>
43 #include <scsi/scsi_message.h>
44 
45 #include <machine/bus.h>
46 #include <machine/intr.h>
47 #include <machine/autoconf.h>
48 
49 #include <dev/ic/lsi64854reg.h>
50 #include <dev/ic/lsi64854var.h>
51 
52 #include <dev/ic/ncr53c9xreg.h>
53 #include <dev/ic/ncr53c9xvar.h>
54 
55 #include <dev/sbus/sbusvar.h>
56 
57 /* #define ESP_SBUS_DEBUG */
58 
59 static int esp_unit_offset;
60 
61 struct esp_softc {
62 	struct ncr53c9x_softc sc_ncr53c9x;	/* glue to MI code */
63 
64 	bus_space_tag_t	sc_bustag;
65 	bus_dma_tag_t	sc_dmatag;
66 
67 	bus_space_handle_t sc_reg;		/* the registers */
68 	struct lsi64854_softc *sc_dma;		/* pointer to my dma */
69 
70 	int	sc_pri;				/* SBUS priority */
71 };
72 
73 void	espattach_sbus(struct device *, struct device *, void *);
74 void	espattach_dma(struct device *, struct device *, void *);
75 int	espmatch_sbus(struct device *, void *, void *);
76 
77 
78 /* Linkup to the rest of the kernel */
79 struct cfattach esp_sbus_ca = {
80 	sizeof(struct esp_softc), espmatch_sbus, espattach_sbus
81 };
82 struct cfattach esp_dma_ca = {
83 	sizeof(struct esp_softc), espmatch_sbus, espattach_dma
84 };
85 
86 /*
87  * Functions and the switch for the MI code.
88  */
89 static u_char	esp_read_reg(struct ncr53c9x_softc *, int);
90 static void	esp_write_reg(struct ncr53c9x_softc *, int, u_char);
91 static u_char	esp_rdreg1(struct ncr53c9x_softc *, int);
92 static void	esp_wrreg1(struct ncr53c9x_softc *, int, u_char);
93 static int	esp_dma_isintr(struct ncr53c9x_softc *);
94 static void	esp_dma_reset(struct ncr53c9x_softc *);
95 static int	esp_dma_intr(struct ncr53c9x_softc *);
96 static int	esp_dma_setup(struct ncr53c9x_softc *, caddr_t *,
97 				    size_t *, int, size_t *);
98 static void	esp_dma_go(struct ncr53c9x_softc *);
99 static void	esp_dma_stop(struct ncr53c9x_softc *);
100 static int	esp_dma_isactive(struct ncr53c9x_softc *);
101 
102 static struct ncr53c9x_glue esp_sbus_glue = {
103 	esp_read_reg,
104 	esp_write_reg,
105 	esp_dma_isintr,
106 	esp_dma_reset,
107 	esp_dma_intr,
108 	esp_dma_setup,
109 	esp_dma_go,
110 	esp_dma_stop,
111 	esp_dma_isactive,
112 	NULL,			/* gl_clear_latched_intr */
113 };
114 
115 static struct ncr53c9x_glue esp_sbus_glue1 = {
116 	esp_rdreg1,
117 	esp_wrreg1,
118 	esp_dma_isintr,
119 	esp_dma_reset,
120 	esp_dma_intr,
121 	esp_dma_setup,
122 	esp_dma_go,
123 	esp_dma_stop,
124 	esp_dma_isactive,
125 	NULL,			/* gl_clear_latched_intr */
126 };
127 
128 static void	espattach(struct esp_softc *, struct ncr53c9x_glue *);
129 
130 int
131 espmatch_sbus(struct device *parent, void *vcf, void *aux)
132 {
133 	struct cfdata *cf = vcf;
134 	int rv;
135 	struct sbus_attach_args *sa = aux;
136 
137 	if (strcmp("SUNW,fas", sa->sa_name) == 0)
138 	        return 1;
139 
140 	rv = (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0 ||
141 	    strcmp("ptscII", sa->sa_name) == 0);
142 	return (rv);
143 }
144 
145 void
146 espattach_sbus(struct device *parent, struct device *self, void *aux)
147 {
148 	struct esp_softc *esc = (void *)self;
149 	struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
150 	struct sbus_attach_args *sa = aux;
151 	struct lsi64854_softc *lsc;
152 	int burst, sbusburst;
153 
154 	esc->sc_bustag = sa->sa_bustag;
155 	esc->sc_dmatag = sa->sa_dmatag;
156 
157 	sc->sc_id = getpropint(sa->sa_node, "initiator-id", 7);
158 	sc->sc_freq = getpropint(sa->sa_node, "clock-frequency", -1);
159 	if (sc->sc_freq < 0)
160 		sc->sc_freq = sa->sa_frequency;
161 
162 #ifdef ESP_SBUS_DEBUG
163 	printf("%s: espattach_sbus: sc_id %d, freq %d\n",
164 	       self->dv_xname, sc->sc_id, sc->sc_freq);
165 #endif
166 
167 	if (strcmp("SUNW,fas", sa->sa_name) == 0) {
168 		/*
169 		 * offset searches for other esp/dma devices.
170 		 */
171 		esp_unit_offset++;
172 
173 		/*
174 		 * fas has 2 register spaces: dma(lsi64854) and SCSI core (ncr53c9x)
175 		 */
176 		if (sa->sa_nreg != 2) {
177 			printf("%s: %d register spaces\n", self->dv_xname, sa->sa_nreg);
178 			return;
179 		}
180 
181 		/*
182 		 * allocate space for dma, in SUNW,fas there are no separate
183 		 * dma device
184 		 */
185 		lsc = malloc(sizeof (struct lsi64854_softc), M_DEVBUF, M_NOWAIT);
186 
187 		if (lsc == NULL) {
188 			printf("%s: out of memory (lsi64854_softc)\n",
189 			       self->dv_xname);
190 			return;
191 		}
192 		esc->sc_dma = lsc;
193 
194 		lsc->sc_bustag = sa->sa_bustag;
195 		lsc->sc_dmatag = sa->sa_dmatag;
196 
197 		bcopy(sc->sc_dev.dv_xname, lsc->sc_dev.dv_xname,
198 		      sizeof (lsc->sc_dev.dv_xname));
199 
200 		/* Map dma registers */
201 		if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
202 		    sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size,
203 		    0, 0, &lsc->sc_regs) != 0) {
204 			printf("%s: cannot map dma registers\n", self->dv_xname);
205 			return;
206 		}
207 
208 		/*
209 		 * XXX is this common(from bpp.c), the same in dma_sbus...etc.
210 		 *
211 		 * Get transfer burst size from PROM and plug it into the
212 		 * controller registers. This is needed on the Sun4m; do
213 		 * others need it too?
214 		 */
215 		sbusburst = ((struct sbus_softc *)parent)->sc_burst;
216 		if (sbusburst == 0)
217 			sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
218 
219 		burst = getpropint(sa->sa_node, "burst-sizes", -1);
220 
221 #ifdef ESP_SBUS_DEBUG
222 		printf("espattach_sbus: burst 0x%x, sbus 0x%x\n",
223 		    burst, sbusburst);
224 #endif
225 
226 		if (burst == -1)
227 			/* take SBus burst sizes */
228 			burst = sbusburst;
229 
230 		/* Clamp at parent's burst sizes */
231 		burst &= sbusburst;
232 		lsc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
233 		    (burst & SBUS_BURST_16) ? 16 : 0;
234 
235 		lsc->sc_channel = L64854_CHANNEL_SCSI;
236 		lsc->sc_client = sc;
237 
238 		lsi64854_attach(lsc);
239 
240 		/*
241 		 * map SCSI core registers
242 		 */
243 		if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[1].sbr_slot,
244 		    sa->sa_reg[1].sbr_offset, sa->sa_reg[1].sbr_size,
245 		    0, 0, &esc->sc_reg) != 0) {
246 			printf("%s: cannot map scsi core registers\n",
247 			       self->dv_xname);
248 			return;
249 		}
250 
251 		if (sa->sa_nintr == 0) {
252 			printf("%s: no interrupt property\n", self->dv_xname);
253 			return;
254 		}
255 
256 		esc->sc_pri = sa->sa_pri;
257 
258 		printf("%s", self->dv_xname);
259 		espattach(esc, &esp_sbus_glue);
260 
261 		return;
262 	}
263 
264 	/*
265 	 * Find the DMA by poking around the dma device structures
266 	 *
267 	 * What happens here is that if the dma driver has not been
268 	 * configured, then this returns a NULL pointer. Then when the
269 	 * dma actually gets configured, it does the opposing test, and
270 	 * if the sc->sc_esp field in its softc is NULL, then tries to
271 	 * find the matching esp driver.
272 	 */
273 	esc->sc_dma = (struct lsi64854_softc *)
274 	    getdevunit("dma", sc->sc_dev.dv_unit - esp_unit_offset);
275 
276 	/*
277 	 * and a back pointer to us, for DMA
278 	 */
279 	if (esc->sc_dma)
280 		esc->sc_dma->sc_client = sc;
281 	else {
282 		printf("\n");
283 		panic("espattach: no dma found");
284 	}
285 
286 	/*
287 	 * The `ESC' DMA chip must be reset before we can access
288 	 * the esp registers.
289 	 */
290 	if (esc->sc_dma->sc_rev == DMAREV_ESC)
291 		DMA_RESET(esc->sc_dma);
292 
293 	/*
294 	 * Map my registers in, if they aren't already in virtual
295 	 * address space.
296 	 */
297 	if (sa->sa_npromvaddrs) {
298 		if (bus_space_map(sa->sa_bustag, sa->sa_promvaddrs[0],
299 		    sa->sa_size, BUS_SPACE_MAP_PROMADDRESS,
300 		    &esc->sc_reg) != 0) {
301 			printf("%s @ sbus: cannot map registers\n",
302 				self->dv_xname);
303 			return;
304 		}
305 	} else {
306 		if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
307 		    sa->sa_offset, sa->sa_size, 0, 0, &esc->sc_reg) != 0) {
308 			printf("%s @ sbus: cannot map registers\n",
309 				self->dv_xname);
310 			return;
311 		}
312 	}
313 
314 	if (sa->sa_nintr == 0) {
315 		/*
316 		 * No interrupt properties: we quit; this might
317 		 * happen on e.g. a Sparc X terminal.
318 		 */
319 		printf("\n%s: no interrupt property\n", self->dv_xname);
320 		return;
321 	}
322 
323 	esc->sc_pri = sa->sa_pri;
324 
325 	if (strcmp("ptscII", sa->sa_name) == 0) {
326 		espattach(esc, &esp_sbus_glue1);
327 	} else {
328 		espattach(esc, &esp_sbus_glue);
329 	}
330 }
331 
332 void
333 espattach_dma(struct device *parent, struct device *self, void *aux)
334 {
335 	struct esp_softc *esc = (void *)self;
336 	struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
337 	struct sbus_attach_args *sa = aux;
338 
339 	if (strcmp("ptscII", sa->sa_name) == 0) {
340 		return;
341 	}
342 
343 	esc->sc_bustag = sa->sa_bustag;
344 	esc->sc_dmatag = sa->sa_dmatag;
345 
346 	sc->sc_id = getpropint(sa->sa_node, "initiator-id", 7);
347 	sc->sc_freq = getpropint(sa->sa_node, "clock-frequency", -1);
348 
349 	esc->sc_dma = (struct lsi64854_softc *)parent;
350 	esc->sc_dma->sc_client = sc;
351 
352 	/*
353 	 * Map my registers in, if they aren't already in virtual
354 	 * address space.
355 	 */
356 	if (sa->sa_npromvaddrs) {
357 		if (bus_space_map(sa->sa_bustag, sa->sa_promvaddrs[0],
358 		    sa->sa_size /* ??? */, BUS_SPACE_MAP_PROMADDRESS,
359 		    &esc->sc_reg) != 0) {
360 			printf("%s @ dma: cannot map registers\n",
361 				self->dv_xname);
362 			return;
363 		}
364 	} else {
365 		if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset,
366 		    sa->sa_size, 0, 0, &esc->sc_reg) != 0) {
367 			printf("%s @ dma: cannot map registers\n",
368 				self->dv_xname);
369 			return;
370 		}
371 	}
372 
373 	if (sa->sa_nintr == 0) {
374 		/*
375 		 * No interrupt properties: we quit; this might
376 		 * happen on e.g. a Sparc X terminal.
377 		 */
378 		printf("\n%s: no interrupt property\n", self->dv_xname);
379 		return;
380 	}
381 
382 	esc->sc_pri = sa->sa_pri;
383 
384 	espattach(esc, &esp_sbus_glue);
385 }
386 
387 
388 /*
389  * Attach this instance, and then all the sub-devices
390  */
391 void
392 espattach(struct esp_softc *esc, struct ncr53c9x_glue *gluep)
393 {
394 	struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
395 	void *icookie;
396 	unsigned int uid = 0;
397 
398 	/*
399 	 * Set up glue for MI code early; we use some of it here.
400 	 */
401 	sc->sc_glue = gluep;
402 
403 	/* gimme MHz */
404 	sc->sc_freq /= 1000000;
405 
406 	/*
407 	 * XXX More of this should be in ncr53c9x_attach(), but
408 	 * XXX should we really poke around the chip that much in
409 	 * XXX the MI code?  Think about this more...
410 	 */
411 
412 	/*
413 	 * It is necessary to try to load the 2nd config register here,
414 	 * to find out what rev the esp chip is, else the ncr53c9x_reset
415 	 * will not set up the defaults correctly.
416 	 */
417 	sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
418 	sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
419 	sc->sc_cfg3 = NCRCFG3_CDB;
420 	NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
421 
422 	if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
423 	    (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
424 		sc->sc_rev = NCR_VARIANT_ESP100;
425 	} else {
426 		sc->sc_cfg2 = NCRCFG2_SCSI2;
427 		NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
428 		sc->sc_cfg3 = 0;
429 		NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
430 		sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
431 		NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
432 		if (NCR_READ_REG(sc, NCR_CFG3) !=
433 		    (NCRCFG3_CDB | NCRCFG3_FCLK)) {
434 			sc->sc_rev = NCR_VARIANT_ESP100A;
435 		} else {
436 			/* NCRCFG2_FE enables > 64K transfers */
437 			sc->sc_cfg2 |= NCRCFG2_FE;
438 			sc->sc_cfg3 = 0;
439 			NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
440 			sc->sc_rev = NCR_VARIANT_ESP200;
441 
442 			/* XXX spec says it's valid after power up or chip reset */
443 			uid = NCR_READ_REG(sc, NCR_UID);
444 			if (((uid & 0xf8) >> 3) == 0x0a) /* XXX */
445 				sc->sc_rev = NCR_VARIANT_FAS366;
446 		}
447 	}
448 
449 #ifdef ESP_SBUS_DEBUG
450 	printf("espattach: revision %d, uid 0x%x\n", sc->sc_rev, uid);
451 #endif
452 
453 	/*
454 	 * XXX minsync and maxxfer _should_ be set up in MI code,
455 	 * XXX but it appears to have some dependency on what sort
456 	 * XXX of DMA we're hooked up to, etc.
457 	 */
458 
459 	/*
460 	 * This is the value used to start sync negotiations
461 	 * Note that the NCR register "SYNCTP" is programmed
462 	 * in "clocks per byte", and has a minimum value of 4.
463 	 * The SCSI period used in negotiation is one-fourth
464 	 * of the time (in nanoseconds) needed to transfer one byte.
465 	 * Since the chip's clock is given in MHz, we have the following
466 	 * formula: 4 * period = (1000 / freq) * 4
467 	 */
468 	sc->sc_minsync = 1000 / sc->sc_freq;
469 
470 	/*
471 	 * Alas, we must now modify the value a bit, because it's
472 	 * only valid when can switch on FASTCLK and FASTSCSI bits
473 	 * in config register 3...
474 	 */
475 	switch (sc->sc_rev) {
476 	case NCR_VARIANT_ESP100:
477 		sc->sc_maxxfer = 64 * 1024;
478 		sc->sc_minsync = 0;	/* No synch on old chip? */
479 		break;
480 
481 	case NCR_VARIANT_ESP100A:
482 		sc->sc_maxxfer = 64 * 1024;
483 		/* Min clocks/byte is 5 */
484 		sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
485 		break;
486 
487 	case NCR_VARIANT_ESP200:
488 	case NCR_VARIANT_FAS366:
489 		sc->sc_maxxfer = 16 * 1024 * 1024;
490 		/* XXX - do actually set FAST* bits */
491 		break;
492 	}
493 
494 	/* Establish interrupt channel */
495 	icookie = bus_intr_establish(esc->sc_bustag, esc->sc_pri, IPL_BIO, 0,
496 				     ncr53c9x_intr, sc, sc->sc_dev.dv_xname);
497 
498 	/* Turn on target selection using the `dma' method */
499 	if (sc->sc_rev != NCR_VARIANT_FAS366)
500 		sc->sc_features |= NCR_F_DMASELECT;
501 
502 	/* Do the common parts of attachment. */
503 	ncr53c9x_attach(sc);
504 }
505 
506 /*
507  * Glue functions.
508  */
509 
510 #ifdef ESP_SBUS_DEBUG
511 int esp_sbus_debug = 0;
512 
513 static struct {
514 	char *r_name;
515 	int   r_flag;
516 } esp__read_regnames [] = {
517 	{ "TCL", 0},			/* 0/00 */
518 	{ "TCM", 0},			/* 1/04 */
519 	{ "FIFO", 0},			/* 2/08 */
520 	{ "CMD", 0},			/* 3/0c */
521 	{ "STAT", 0},			/* 4/10 */
522 	{ "INTR", 0},			/* 5/14 */
523 	{ "STEP", 0},			/* 6/18 */
524 	{ "FFLAGS", 1},			/* 7/1c */
525 	{ "CFG1", 1},			/* 8/20 */
526 	{ "STAT2", 0},			/* 9/24 */
527 	{ "CFG4", 1},			/* a/28 */
528 	{ "CFG2", 1},			/* b/2c */
529 	{ "CFG3", 1},			/* c/30 */
530 	{ "-none", 1},			/* d/34 */
531 	{ "TCH", 1},			/* e/38 */
532 	{ "TCX", 1},			/* f/3c */
533 };
534 
535 static struct {
536 	char *r_name;
537 	int   r_flag;
538 } esp__write_regnames[] = {
539 	{ "TCL", 1},			/* 0/00 */
540 	{ "TCM", 1},			/* 1/04 */
541 	{ "FIFO", 0},			/* 2/08 */
542 	{ "CMD", 0},			/* 3/0c */
543 	{ "SELID", 1},			/* 4/10 */
544 	{ "TIMEOUT", 1},		/* 5/14 */
545 	{ "SYNCTP", 1},			/* 6/18 */
546 	{ "SYNCOFF", 1},		/* 7/1c */
547 	{ "CFG1", 1},			/* 8/20 */
548 	{ "CCF", 1},			/* 9/24 */
549 	{ "TEST", 1},			/* a/28 */
550 	{ "CFG2", 1},			/* b/2c */
551 	{ "CFG3", 1},			/* c/30 */
552 	{ "-none", 1},			/* d/34 */
553 	{ "TCH", 1},			/* e/38 */
554 	{ "TCX", 1},			/* f/3c */
555 };
556 #endif
557 
558 u_char
559 esp_read_reg(struct ncr53c9x_softc *sc, int reg)
560 {
561 	struct esp_softc *esc = (struct esp_softc *)sc;
562 	u_char v;
563 
564 	v = bus_space_read_1(esc->sc_bustag, esc->sc_reg, reg * 4);
565 #ifdef ESP_SBUS_DEBUG
566 	if (esp_sbus_debug && (reg < 0x10) && esp__read_regnames[reg].r_flag)
567 		printf("RD:%x <%s> %x\n", reg * 4,
568 		    ((unsigned)reg < 0x10) ? esp__read_regnames[reg].r_name : "<***>", v);
569 #endif
570 	return v;
571 }
572 
573 void
574 esp_write_reg(struct ncr53c9x_softc *sc, int reg, u_char v)
575 {
576 	struct esp_softc *esc = (struct esp_softc *)sc;
577 
578 #ifdef ESP_SBUS_DEBUG
579 	if (esp_sbus_debug && (reg < 0x10) && esp__write_regnames[reg].r_flag)
580 		printf("WR:%x <%s> %x\n", reg * 4,
581 		    ((unsigned)reg < 0x10) ? esp__write_regnames[reg].r_name : "<***>", v);
582 #endif
583 	bus_space_write_1(esc->sc_bustag, esc->sc_reg, reg * 4, v);
584 }
585 
586 u_char
587 esp_rdreg1(struct ncr53c9x_softc *sc, int reg)
588 {
589 	struct esp_softc *esc = (struct esp_softc *)sc;
590 
591 	return (bus_space_read_1(esc->sc_bustag, esc->sc_reg, reg));
592 }
593 
594 void
595 esp_wrreg1(struct ncr53c9x_softc *sc, int reg, u_char v)
596 {
597 	struct esp_softc *esc = (struct esp_softc *)sc;
598 
599 	bus_space_write_1(esc->sc_bustag, esc->sc_reg, reg, v);
600 }
601 
602 int
603 esp_dma_isintr(struct ncr53c9x_softc *sc)
604 {
605 	struct esp_softc *esc = (struct esp_softc *)sc;
606 
607 	return (DMA_ISINTR(esc->sc_dma));
608 }
609 
610 void
611 esp_dma_reset(struct ncr53c9x_softc *sc)
612 {
613 	struct esp_softc *esc = (struct esp_softc *)sc;
614 
615 	DMA_RESET(esc->sc_dma);
616 }
617 
618 int
619 esp_dma_intr(struct ncr53c9x_softc *sc)
620 {
621 	struct esp_softc *esc = (struct esp_softc *)sc;
622 
623 	return (DMA_INTR(esc->sc_dma));
624 }
625 
626 int
627 esp_dma_setup(struct ncr53c9x_softc *sc, caddr_t *addr, size_t *len,
628     int datain, size_t *dmasize)
629 {
630 	struct esp_softc *esc = (struct esp_softc *)sc;
631 
632 	return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize));
633 }
634 
635 void
636 esp_dma_go(struct ncr53c9x_softc *sc)
637 {
638 	struct esp_softc *esc = (struct esp_softc *)sc;
639 
640 	DMA_GO(esc->sc_dma);
641 }
642 
643 void
644 esp_dma_stop(struct ncr53c9x_softc *sc)
645 {
646 	struct esp_softc *esc = (struct esp_softc *)sc;
647 	u_int32_t csr;
648 
649 	csr = L64854_GCSR(esc->sc_dma);
650 	csr &= ~D_EN_DMA;
651 	L64854_SCSR(esc->sc_dma, csr);
652 }
653 
654 int
655 esp_dma_isactive(struct ncr53c9x_softc *sc)
656 {
657 	struct esp_softc *esc = (struct esp_softc *)sc;
658 
659 	return (DMA_ISACTIVE(esc->sc_dma));
660 }
661 
662 #if defined(DDB) && defined(notyet)
663 #include <machine/db_machdep.h>
664 #include <ddb/db_output.h>
665 
666 void db_esp(db_expr_t, int, db_expr_t, char *);
667 
668 void
669 db_esp(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
670 {
671 	struct ncr53c9x_softc *sc;
672 	struct ncr53c9x_ecb *ecb;
673 	struct ncr53c9x_linfo *li;
674 	int u, t, i;
675 
676 	for (u=0; u<10; u++) {
677 		sc = (struct ncr53c9x_softc *)
678 			getdevunit("esp", u);
679 		if (!sc) continue;
680 
681 		db_printf("esp%d: nexus %p phase %x prev %x dp %p dleft %lx ify %x\n",
682 			  u, sc->sc_nexus, sc->sc_phase, sc->sc_prevphase,
683 			  sc->sc_dp, sc->sc_dleft, sc->sc_msgify);
684 		db_printf("\tmsgout %x msgpriq %x msgin %x:%x:%x:%x:%x\n",
685 			  sc->sc_msgout, sc->sc_msgpriq, sc->sc_imess[0],
686 			  sc->sc_imess[1], sc->sc_imess[2], sc->sc_imess[3],
687 			  sc->sc_imess[0]);
688 		db_printf("ready: ");
689 		TAILQ_FOREACH(ecb, &sc->ready_list, chain) {
690 			db_printf("ecb %p ", ecb);
691 			if (ecb == TAILQ_NEXT(ecb, chain)) {
692 				db_printf("\nWARNING: tailq loop on ecb %p", ecb);
693 				break;
694 			}
695 		}
696 		db_printf("\n");
697 
698 		for (t=0; t<NCR_NTARG; t++) {
699 			LIST_FOREACH(li, &sc->sc_tinfo[t].luns, link) {
700 				db_printf("t%d lun %d untagged %p busy %d used %x\n",
701 					  t, (int)li->lun, li->untagged, li->busy,
702 					  li->used);
703 				for (i=0; i<256; i++)
704 					if ((ecb = li->queued[i])) {
705 						db_printf("ecb %p tag %x\n", ecb, i);
706 					}
707 			}
708 		}
709 	}
710 }
711 #endif
712 
713