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