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