1 /* $NetBSD: esp.c,v 1.67 2023/02/03 23:17:49 tsutsui 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 and by Jason R. Thorpe of the Numerical Aerospace 9 * Simulation Facility, NASA Ames Research Center. 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 /* 34 * Copyright (c) 1994 Peter Galbavy 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. All advertising materials mentioning features or use of this software 46 * must display the following acknowledgement: 47 * This product includes software developed by Peter Galbavy 48 * 4. The name of the author may not be used to endorse or promote products 49 * derived from this software without specific prior written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 52 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 53 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 54 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 55 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 56 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 57 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 60 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 * POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64 /* 65 * Based on aic6360 by Jarle Greipsland 66 * 67 * Acknowledgements: Many of the algorithms used in this driver are 68 * inspired by the work of Julian Elischer (julian@tfs.com) and 69 * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million! 70 */ 71 72 /* 73 * Grabbed from the sparc port at revision 1.73 for the NeXT. 74 * Darrin B. Jewell <dbj@NetBSD.org> Sat Jul 4 15:41:32 1998 75 */ 76 77 #include <sys/cdefs.h> 78 __KERNEL_RCSID(0, "$NetBSD: esp.c,v 1.67 2023/02/03 23:17:49 tsutsui Exp $"); 79 80 #include <sys/types.h> 81 #include <sys/param.h> 82 #include <sys/systm.h> 83 #include <sys/kernel.h> 84 #include <sys/errno.h> 85 #include <sys/ioctl.h> 86 #include <sys/device.h> 87 #include <sys/buf.h> 88 #include <sys/proc.h> 89 #include <sys/queue.h> 90 91 #include <uvm/uvm_extern.h> 92 93 #include <dev/scsipi/scsi_all.h> 94 #include <dev/scsipi/scsipi_all.h> 95 #include <dev/scsipi/scsiconf.h> 96 #include <dev/scsipi/scsi_message.h> 97 98 #include <machine/bus.h> 99 #include <machine/autoconf.h> 100 #include <machine/cpu.h> 101 102 #include <dev/ic/ncr53c9xreg.h> 103 #include <dev/ic/ncr53c9xvar.h> 104 105 #include <next68k/next68k/isr.h> 106 107 #include <next68k/dev/intiovar.h> 108 #include <next68k/dev/nextdmareg.h> 109 #include <next68k/dev/nextdmavar.h> 110 111 #include <next68k/dev/espreg.h> 112 #include <next68k/dev/espvar.h> 113 114 #ifdef DEBUG 115 #undef ESP_DEBUG 116 #endif 117 118 #ifdef ESP_DEBUG 119 int esp_debug = 0; 120 #define DPRINTF(x) if (esp_debug) printf x; 121 #define NDTRACEIF(x) if (10) do {x;} while (0) 122 #else 123 #define DPRINTF(x) 124 #define NDTRACEIF(x) 125 #endif 126 #define PRINTF(x) printf x; 127 128 129 static int espmatch_intio(device_t, cfdata_t, void *); 130 static void espattach_intio(device_t, device_t, void *); 131 132 /* DMA callbacks */ 133 static bus_dmamap_t esp_dmacb_continue(void *); 134 static void esp_dmacb_completed(bus_dmamap_t, void *); 135 static void esp_dmacb_shutdown(void *); 136 137 static void findchannel_defer(device_t); 138 139 #ifdef ESP_DEBUG 140 char esp_dma_dump[5*1024] = ""; 141 struct ncr53c9x_softc *esp_debug_sc = 0; 142 void esp_dma_store(struct ncr53c9x_softc *); 143 void esp_dma_print(struct ncr53c9x_softc *); 144 int esp_dma_nest = 0; 145 int esptraceshow; 146 #endif 147 148 149 /* Linkup to the rest of the kernel */ 150 CFATTACH_DECL_NEW(esp, sizeof(struct esp_softc), 151 espmatch_intio, espattach_intio, NULL, NULL); 152 153 static int attached = 0; 154 155 /* 156 * Functions and the switch for the MI code. 157 */ 158 static uint8_t esp_read_reg(struct ncr53c9x_softc *, int); 159 static void esp_write_reg(struct ncr53c9x_softc *, int, uint8_t); 160 static int esp_dma_isintr(struct ncr53c9x_softc *); 161 static void esp_dma_reset(struct ncr53c9x_softc *); 162 static int esp_dma_intr(struct ncr53c9x_softc *); 163 static int esp_dma_setup(struct ncr53c9x_softc *, uint8_t **, size_t *, int, 164 size_t *); 165 static void esp_dma_go(struct ncr53c9x_softc *); 166 static void esp_dma_stop(struct ncr53c9x_softc *); 167 static int esp_dma_isactive(struct ncr53c9x_softc *); 168 169 static int doze(volatile int); 170 171 static struct ncr53c9x_glue esp_glue = { 172 .gl_read_reg = esp_read_reg, 173 .gl_write_reg = esp_write_reg, 174 .gl_dma_isintr = esp_dma_isintr, 175 .gl_dma_reset = esp_dma_reset, 176 .gl_dma_intr = esp_dma_intr, 177 .gl_dma_setup = esp_dma_setup, 178 .gl_dma_go = esp_dma_go, 179 .gl_dma_stop = esp_dma_stop, 180 .gl_dma_isactive = esp_dma_isactive, 181 .gl_clear_latched_intr = NULL 182 }; 183 184 #define nd_bsr4(reg) \ 185 bus_space_read_4(nsc->sc_bst, nsc->sc_bsh, (reg)) 186 #define nd_bsw4(reg, val) \ 187 bus_space_write_4(nsc->sc_bst, nsc->sc_bsh, (reg), (val)) 188 189 #ifdef ESP_DEBUG 190 #define XCHR(x) hexdigits[(x) & 0xf] 191 static void 192 esp_hex_dump(unsigned char *pkt, size_t len) 193 { 194 size_t i, j; 195 196 printf("00000000 "); 197 for(i = 0; i < len; i++) { 198 printf("%c%c ", XCHR(pkt[i] >> 4), XCHR(pkt[i])); 199 if ((i + 1) % 16 == 8) { 200 printf(" "); 201 } 202 if ((i + 1) % 16 == 0) { 203 printf(" %c", '|'); 204 for(j = 0; j < 16; j++) { 205 printf("%c", pkt[i - 15 + j] >= 32 && 206 pkt[i - 15 + j] < 127 ? 207 pkt[i - 15 + j] : '.'); 208 } 209 printf("%c\n%c%c%c%c%c%c%c%c ", '|', 210 XCHR((i + 1) >> 28), XCHR((i + 1) >> 24), 211 XCHR((i + 1) >> 20), XCHR((i + 1) >> 16), 212 XCHR((i + 1) >> 12), XCHR((i + 1) >> 8), 213 XCHR((i + 1) >> 4), XCHR(i + 1)); 214 } 215 } 216 printf("\n"); 217 } 218 #endif 219 220 static int 221 espmatch_intio(device_t parent, cfdata_t cf, void *aux) 222 { 223 struct intio_attach_args *ia = aux; 224 225 if (attached) 226 return 0; 227 228 ia->ia_addr = (void *)NEXT_P_SCSI; 229 230 return 1; 231 } 232 233 static void 234 findchannel_defer(device_t self) 235 { 236 struct esp_softc *esc = device_private(self); 237 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; 238 int error; 239 240 if (esc->sc_dma == NULL) { 241 aprint_normal("%s", device_xname(sc->sc_dev)); 242 esc->sc_dma = nextdma_findchannel("scsi"); 243 if (esc->sc_dma == NULL) 244 panic("%s: can't find DMA channel", 245 device_xname(sc->sc_dev)); 246 } 247 248 nextdma_setconf(esc->sc_dma, shutdown_cb, &esp_dmacb_shutdown); 249 nextdma_setconf(esc->sc_dma, continue_cb, &esp_dmacb_continue); 250 nextdma_setconf(esc->sc_dma, completed_cb, &esp_dmacb_completed); 251 nextdma_setconf(esc->sc_dma, cb_arg, sc); 252 253 error = bus_dmamap_create(esc->sc_dma->sc_dmat, 254 sc->sc_maxxfer, sc->sc_maxxfer / PAGE_SIZE + 1, sc->sc_maxxfer, 255 0, BUS_DMA_ALLOCNOW, &esc->sc_main_dmamap); 256 if (error != 0) { 257 panic("%s: can't create main i/o DMA map, error = %d", 258 device_xname(sc->sc_dev), error); 259 } 260 261 error = bus_dmamap_create(esc->sc_dma->sc_dmat, 262 ESP_DMA_TAILBUFSIZE, 1, ESP_DMA_TAILBUFSIZE, 263 0, BUS_DMA_ALLOCNOW, &esc->sc_tail_dmamap); 264 if (error != 0) { 265 panic("%s: can't create tail i/o DMA map, error = %d", 266 device_xname(sc->sc_dev), error); 267 } 268 269 #if 0 270 /* Turn on target selection using the `DMA' method */ 271 sc->sc_features |= NCR_F_DMASELECT; 272 #endif 273 274 /* Do the common parts of attachment. */ 275 sc->sc_adapter.adapt_minphys = minphys; 276 sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request; 277 ncr53c9x_attach(sc); 278 279 /* Establish interrupt channel */ 280 isrlink_autovec(ncr53c9x_intr, sc, NEXT_I_IPL(NEXT_I_SCSI), 0, NULL); 281 INTR_ENABLE(NEXT_I_SCSI); 282 283 /* register interrupt stats */ 284 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL, 285 device_xname(sc->sc_dev), "intr"); 286 287 aprint_normal_dev(sc->sc_dev, "using DMA channel %s\n", 288 device_xname(esc->sc_dma->sc_dev)); 289 } 290 291 static void 292 espattach_intio(device_t parent, device_t self, void *aux) 293 { 294 struct esp_softc *esc = device_private(self); 295 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; 296 struct intio_attach_args *ia = aux; 297 298 sc->sc_dev = self; 299 300 #ifdef ESP_DEBUG 301 esp_debug_sc = sc; 302 #endif 303 304 esc->sc_bst = ia->ia_bst; 305 if (bus_space_map(esc->sc_bst, NEXT_P_SCSI, 306 ESP_DEVICE_SIZE, 0, &esc->sc_bsh)) { 307 aprint_normal("\n"); 308 panic("%s: can't map ncr53c90 registers", 309 device_xname(self)); 310 } 311 312 sc->sc_id = 7; 313 sc->sc_freq = 20; /* MHz */ 314 315 /* 316 * Set up glue for MI code early; we use some of it here. 317 */ 318 sc->sc_glue = &esp_glue; 319 320 /* 321 * XXX More of this should be in ncr53c9x_attach(), but 322 * XXX should we really poke around the chip that much in 323 * XXX the MI code? Think about this more... 324 */ 325 326 /* 327 * It is necessary to try to load the 2nd config register here, 328 * to find out what rev the esp chip is, else the ncr53c9x_reset 329 * will not set up the defaults correctly. 330 */ 331 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; 332 sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE; 333 sc->sc_cfg3 = NCRCFG3_CDB; 334 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 335 336 if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) != 337 (NCRCFG2_SCSI2 | NCRCFG2_RPE)) { 338 sc->sc_rev = NCR_VARIANT_ESP100; 339 } else { 340 sc->sc_cfg2 = NCRCFG2_SCSI2; 341 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 342 sc->sc_cfg3 = 0; 343 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 344 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK); 345 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 346 if (NCR_READ_REG(sc, NCR_CFG3) != 347 (NCRCFG3_CDB | NCRCFG3_FCLK)) { 348 sc->sc_rev = NCR_VARIANT_ESP100A; 349 } else { 350 /* NCRCFG2_FE enables > 64K transfers */ 351 sc->sc_cfg2 |= NCRCFG2_FE; 352 sc->sc_cfg3 = 0; 353 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 354 sc->sc_rev = NCR_VARIANT_ESP200; 355 } 356 } 357 358 /* 359 * XXX minsync and maxxfer _should_ be set up in MI code, 360 * XXX but it appears to have some dependency on what sort 361 * XXX of DMA we're hooked up to, etc. 362 */ 363 364 /* 365 * This is the value used to start sync negotiations 366 * Note that the NCR register "SYNCTP" is programmed 367 * in "clocks per byte", and has a minimum value of 4. 368 * The SCSI period used in negotiation is one-fourth 369 * of the time (in nanoseconds) needed to transfer one byte. 370 * Since the chip's clock is given in MHz, we have the following 371 * formula: 4 * period = (1000 / freq) * 4 372 */ 373 sc->sc_minsync = /* 1000 / sc->sc_freq */ 0; 374 375 /* 376 * Alas, we must now modify the value a bit, because it's 377 * only valid when can switch on FASTCLK and FASTSCSI bits 378 * in config register 3... 379 */ 380 switch (sc->sc_rev) { 381 case NCR_VARIANT_ESP100: 382 sc->sc_maxxfer = 64 * 1024; 383 sc->sc_minsync = 0; /* No synch on old chip? */ 384 break; 385 386 case NCR_VARIANT_ESP100A: 387 sc->sc_maxxfer = 64 * 1024; 388 /* Min clocks/byte is 5 */ 389 sc->sc_minsync = /* ncr53c9x_cpb2stp(sc, 5) */ 0; 390 break; 391 392 case NCR_VARIANT_ESP200: 393 sc->sc_maxxfer = 16 * 1024 * 1024; 394 /* XXX - do actually set FAST* bits */ 395 break; 396 } 397 398 /* @@@ Some ESP_DCTL bits probably need setting */ 399 NCR_WRITE_REG(sc, ESP_DCTL, 400 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_RESET); 401 DELAY(10); 402 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc,ESP_DCTL))); 403 NCR_WRITE_REG(sc, ESP_DCTL, ESPDCTL_16MHZ | ESPDCTL_INTENB); 404 DELAY(10); 405 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc, ESP_DCTL))); 406 407 esc->sc_dma = nextdma_findchannel("scsi"); 408 if (esc->sc_dma != NULL) { 409 findchannel_defer(self); 410 } else { 411 aprint_normal("\n"); 412 config_defer(self, findchannel_defer); 413 } 414 415 attached = 1; 416 } 417 418 /* 419 * Glue functions. 420 */ 421 422 static uint8_t 423 esp_read_reg(struct ncr53c9x_softc *sc, int reg) 424 { 425 struct esp_softc *esc = (struct esp_softc *)sc; 426 427 return bus_space_read_1(esc->sc_bst, esc->sc_bsh, reg); 428 } 429 430 static void 431 esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t val) 432 { 433 struct esp_softc *esc = (struct esp_softc *)sc; 434 435 bus_space_write_1(esc->sc_bst, esc->sc_bsh, reg, val); 436 } 437 438 volatile uint32_t save1; 439 440 #define xADDR 0x0211a000 441 static int 442 doze(volatile int c) 443 { 444 #if 0 445 static int tmp1; 446 #endif 447 uint32_t tmp1; 448 volatile uint8_t tmp2; 449 volatile uint8_t *reg = (volatile uint8_t *)IIOV(xADDR); 450 451 if (c > 244) 452 return 0; 453 if (c == 0) 454 return 0; 455 #if 0 456 ((*(volatile u_long *)IIOV(NEXT_P_INTRMASK)) &= (~NEXT_I_BIT(x))); 457 #endif 458 (*reg) = 0; 459 (*reg) = 0; 460 do { 461 save1 = (*reg); 462 tmp2 = *(reg + 3); 463 tmp1 = tmp2; 464 } while (tmp1 <= c); 465 return 0; 466 } 467 468 static int 469 esp_dma_isintr(struct ncr53c9x_softc *sc) 470 { 471 struct esp_softc *esc = (struct esp_softc *)sc; 472 473 if (INTR_OCCURRED(NEXT_I_SCSI)) { 474 NDTRACEIF(ndtrace_addc('i')); 475 NCR_WRITE_REG(sc, ESP_DCTL, 476 ESPDCTL_16MHZ | ESPDCTL_INTENB | 477 (esc->sc_datain ? ESPDCTL_DMARD : 0)); 478 return 1; 479 } else { 480 return 0; 481 } 482 } 483 484 static int 485 esp_dma_intr(struct ncr53c9x_softc *sc) 486 { 487 struct esp_softc *esc = (struct esp_softc *)sc; 488 struct nextdma_softc *nsc = esc->sc_dma; 489 struct nextdma_status *stat = &nsc->sc_stat; 490 int r = (INTR_OCCURRED(NEXT_I_SCSI)); 491 int flushcount; 492 493 r = 1; 494 495 NDTRACEIF(ndtrace_addc('I')); 496 if (r) { 497 #if 0 498 printf("esp_dma_isintr start\n"); 499 #endif 500 { 501 int s = spldma(); 502 void *ndmap = stat->nd_map; 503 int ndidx = stat->nd_idx; 504 splx(s); 505 506 flushcount = 0; 507 508 #ifdef ESP_DEBUG 509 #if 0 510 esp_dma_nest++; 511 #endif 512 513 if (esp_debug) { 514 char sbuf[256]; 515 516 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS, 517 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT))); 518 519 printf("esp_dma_isintr = %s\n", sbuf); 520 } 521 #endif 522 523 mutex_exit(&sc->sc_lock); /* for nextdma intr */ 524 while (!nextdma_finished(nsc)) { 525 NDTRACEIF(ndtrace_addc('w')); 526 NDTRACEIF( 527 ndtrace_printf("f%dm%dl%dw", 528 NCR_READ_REG(sc, NCR_FFLAG) & 529 NCRFIFO_FF, 530 NCR_READ_REG((sc), NCR_TCM), 531 NCR_READ_REG((sc), NCR_TCL)); 532 ); 533 if (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF) 534 flushcount = 5; 535 NCR_WRITE_REG(sc, ESP_DCTL, 536 ESPDCTL_16MHZ | ESPDCTL_INTENB | 537 ESPDCTL_DMAMOD | 538 (esc->sc_datain ? ESPDCTL_DMARD : 0)); 539 540 s = spldma(); 541 while (ndmap == stat->nd_map && 542 ndidx == stat->nd_idx && 543 (nd_bsr4(DD_CSR) & 0x08000000) == 0 && 544 ++flushcount < 5) { 545 splx(s); 546 NDTRACEIF(ndtrace_addc('F')); 547 NCR_WRITE_REG(sc, ESP_DCTL, 548 ESPDCTL_FLUSH | ESPDCTL_16MHZ | 549 ESPDCTL_INTENB | ESPDCTL_DMAMOD | 550 (esc->sc_datain ? 551 ESPDCTL_DMARD : 0)); 552 doze(0x32); 553 NCR_WRITE_REG(sc, ESP_DCTL, 554 ESPDCTL_16MHZ | ESPDCTL_INTENB | 555 ESPDCTL_DMAMOD | 556 (esc->sc_datain ? 557 ESPDCTL_DMARD : 0)); 558 doze(0x32); 559 s = spldma(); 560 } 561 NDTRACEIF(ndtrace_addc('0' + flushcount)); 562 if (flushcount > 4) { 563 int next; 564 int onext = 0; 565 566 splx(s); 567 DPRINTF(("DMA reset\n")); 568 while (((next = nd_bsr4(DD_NEXT)) != 569 (nd_bsr4(DD_LIMIT) & 0x7FFFFFFF)) && 570 onext != next) { 571 onext = next; 572 DELAY(50); 573 } 574 NDTRACEIF(ndtrace_addc('R')); 575 NCR_WRITE_REG(sc, ESP_DCTL, 576 ESPDCTL_16MHZ | ESPDCTL_INTENB); 577 NDTRACEIF( 578 ndtrace_printf( 579 "ff:%d tcm:%d tcl:%d ", 580 NCR_READ_REG(sc, NCR_FFLAG) 581 & NCRFIFO_FF, 582 NCR_READ_REG((sc), NCR_TCM), 583 NCR_READ_REG((sc), 584 NCR_TCL)); 585 ); 586 s = spldma(); 587 nextdma_reset(nsc); 588 splx(s); 589 goto out; 590 } 591 splx(s); 592 593 #ifdef DIAGNOSTIC 594 if (flushcount > 4) { 595 NDTRACEIF(ndtrace_addc('+')); 596 printf("%s: unexpected flushcount" 597 " %d on %s\n", 598 device_xname(sc->sc_dev), 599 flushcount, 600 esc->sc_datain ? "read" : "write"); 601 } 602 #endif 603 604 if (!nextdma_finished(nsc)) { 605 NDTRACEIF(ndtrace_addc('1')); 606 } 607 flushcount = 0; 608 s = spldma(); 609 ndmap = stat->nd_map; 610 ndidx = stat->nd_idx; 611 splx(s); 612 613 } 614 out: 615 mutex_enter(&sc->sc_lock); /* for nextdma intr */ 616 617 #ifdef ESP_DEBUG 618 #if 0 619 esp_dma_nest--; 620 #endif 621 #endif 622 623 } 624 625 doze(0x32); 626 NCR_WRITE_REG(sc, ESP_DCTL, 627 ESPDCTL_16MHZ | ESPDCTL_INTENB | 628 (esc->sc_datain ? ESPDCTL_DMARD : 0)); 629 NDTRACEIF(ndtrace_addc('b')); 630 631 while (esc->sc_datain != -1) 632 DELAY(50); 633 634 if (esc->sc_dmaaddr) { 635 bus_size_t xfer_len = 0; 636 int resid; 637 638 NCR_WRITE_REG(sc, ESP_DCTL, 639 ESPDCTL_16MHZ | ESPDCTL_INTENB); 640 if (stat->nd_exception == 0) { 641 resid = NCR_READ_REG((sc), NCR_TCL) + 642 (NCR_READ_REG((sc), NCR_TCM) << 8); 643 if (resid) { 644 resid += (NCR_READ_REG(sc, NCR_FFLAG) & 645 NCRFIFO_FF); 646 #ifdef ESP_DEBUG 647 if (NCR_READ_REG(sc, NCR_FFLAG) & 648 NCRFIFO_FF) 649 if ((NCR_READ_REG(sc, 650 NCR_FFLAG) & NCRFIFO_FF) != 651 16 || 652 NCR_READ_REG((sc), 653 NCR_TCL) != 240) 654 esptraceshow++; 655 #endif 656 } 657 xfer_len = esc->sc_dmasize - resid; 658 } else { 659 #define ncr53c9x_sched_msgout(m) \ 660 do { \ 661 NCR_MISC(("ncr53c9x_sched_msgout %x %d", m, __LINE__)); \ 662 NCRCMD(sc, NCRCMD_SETATN); \ 663 sc->sc_flags |= NCR_ATN; \ 664 sc->sc_msgpriq |= (m); \ 665 } while (0) 666 int i; 667 668 xfer_len = 0; 669 if (esc->sc_begin) 670 xfer_len += esc->sc_begin_size; 671 if (esc->sc_main_dmamap) 672 xfer_len += 673 esc->sc_main_dmamap->dm_xfer_len; 674 if (esc->sc_tail_dmamap) 675 xfer_len += 676 esc->sc_tail_dmamap->dm_xfer_len; 677 resid = 0; 678 printf("X\n"); 679 for (i = 0; i < 16; i++) { 680 NCR_WRITE_REG(sc, ESP_DCTL, 681 ESPDCTL_FLUSH | ESPDCTL_16MHZ | 682 ESPDCTL_INTENB | 683 (esc->sc_datain ? 684 ESPDCTL_DMARD : 0)); 685 NCR_WRITE_REG(sc, ESP_DCTL, 686 ESPDCTL_16MHZ | ESPDCTL_INTENB | 687 (esc->sc_datain ? 688 ESPDCTL_DMARD : 0)); 689 } 690 #if 0 691 printf("ff:%02x tcm:%d tcl:%d esp_dstat:%02x" 692 " stat:%02x step: %02x intr:%02x" 693 " new stat:%02X\n", 694 NCR_READ_REG(sc, NCR_FFLAG), 695 NCR_READ_REG((sc), NCR_TCM), 696 NCR_READ_REG((sc), NCR_TCL), 697 NCR_READ_REG(sc, ESP_DSTAT), 698 sc->sc_espstat, sc->sc_espstep, 699 sc->sc_espintr, 700 NCR_READ_REG(sc, NCR_STAT)); 701 printf("sc->sc_state: %x sc->sc_phase: %x" 702 " sc->sc_espstep:%x sc->sc_prevphase:%x" 703 " sc->sc_flags:%x\n", 704 sc->sc_state, sc->sc_phase, sc->sc_espstep, 705 sc->sc_prevphase, sc->sc_flags); 706 #endif 707 #if 0 708 sc->sc_flags &= ~NCR_ICCS; 709 #endif 710 sc->sc_nexus->flags |= ECB_ABORT; 711 if (sc->sc_phase == MESSAGE_IN_PHASE) { 712 #if 0 713 ncr53c9x_sched_msgout(SEND_ABORT); 714 #endif 715 ncr53c9x_abort(sc, sc->sc_nexus); 716 } else if (sc->sc_phase != STATUS_PHASE) { 717 printf("ATTENTION!!! " 718 "not message/status phase: %d\n", 719 sc->sc_phase); 720 } 721 } 722 723 NDTRACEIF(ndtrace_printf("f%dm%dl%ds%dx%dr%dS", 724 NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF, 725 NCR_READ_REG((sc), NCR_TCM), 726 NCR_READ_REG((sc), NCR_TCL), 727 esc->sc_dmasize, (int)xfer_len, resid); 728 ); 729 730 *esc->sc_dmaaddr += xfer_len; 731 *esc->sc_dmalen -= xfer_len; 732 esc->sc_dmaaddr = 0; 733 esc->sc_dmalen = 0; 734 esc->sc_dmasize = 0; 735 } 736 737 NDTRACEIF(ndtrace_addc('B')); 738 sc->sc_espstat = NCR_READ_REG(sc, NCR_STAT) | 739 (sc->sc_espstat & NCRSTAT_INT); 740 741 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc, ESP_DCTL))); 742 #if 0 743 printf("esp_dma_isintr DONE\n"); 744 #endif 745 } 746 747 return r; 748 } 749 750 static void 751 esp_dma_reset(struct ncr53c9x_softc *sc) 752 { 753 struct esp_softc *esc = (struct esp_softc *)sc; 754 755 DPRINTF(("esp DMA reset\n")); 756 757 #ifdef ESP_DEBUG 758 if (esp_debug) { 759 char sbuf[256]; 760 761 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS, 762 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT))); 763 printf(" *intrstat = %s\n", sbuf); 764 765 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS, 766 (*(volatile u_long *)IIOV(NEXT_P_INTRMASK))); 767 printf(" *intrmask = %s\n", sbuf); 768 } 769 #endif 770 771 #if 0 772 /* Clear the DMAMOD bit in the DCTL register: */ 773 NCR_WRITE_REG(sc, ESP_DCTL, ESPDCTL_16MHZ | ESPDCTL_INTENB); 774 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 775 #endif 776 777 nextdma_reset(esc->sc_dma); 778 nextdma_init(esc->sc_dma); 779 780 esc->sc_datain = -1; 781 esc->sc_dmaaddr = 0; 782 esc->sc_dmalen = 0; 783 esc->sc_dmasize = 0; 784 785 esc->sc_loaded = 0; 786 787 esc->sc_begin = 0; 788 esc->sc_begin_size = 0; 789 790 if (esc->sc_main_dmamap->dm_mapsize) { 791 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_main_dmamap); 792 } 793 esc->sc_main = 0; 794 esc->sc_main_size = 0; 795 796 if (esc->sc_tail_dmamap->dm_mapsize) { 797 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap); 798 } 799 esc->sc_tail = 0; 800 esc->sc_tail_size = 0; 801 } 802 803 /* 804 * it appears that: 805 * addr and len arguments to this need to be kept up to date 806 * with the status of the transfter. 807 * the dmasize of this is the actual length of the transfer 808 * request, which is guaranteed to be less than maxxfer. 809 * (len may be > maxxfer) 810 */ 811 812 static int 813 esp_dma_setup(struct ncr53c9x_softc *sc, uint8_t **addr, size_t *len, 814 int datain, size_t *dmasize) 815 { 816 struct esp_softc *esc = (struct esp_softc *)sc; 817 818 NDTRACEIF(ndtrace_addc('h')); 819 #ifdef DIAGNOSTIC 820 #ifdef ESP_DEBUG 821 /* 822 * if this is a read DMA, pre-fill the buffer with 0xdeadbeef 823 * to identify bogus reads 824 */ 825 if (datain) { 826 int *v = (int *)(*addr); 827 int i; 828 for (i = 0; i < ((*len) / 4); i++) 829 v[i] = 0xdeadbeef; 830 v = (int *)(&(esc->sc_tailbuf[0])); 831 for (i = 0; i < ((sizeof(esc->sc_tailbuf) / 4)); i++) 832 v[i] = 0xdeafbeef; 833 } else { 834 int *v; 835 int i; 836 v = (int *)(&(esc->sc_tailbuf[0])); 837 for (i = 0; i < ((sizeof(esc->sc_tailbuf) / 4)); i++) 838 v[i] = 0xfeeb1eed; 839 } 840 #endif 841 #endif 842 843 DPRINTF(("esp_dma_setup(%p,0x%08x,0x%08x)\n", *addr, *len, *dmasize)); 844 845 #if 0 846 #ifdef DIAGNOSTIC 847 /* 848 * @@@ this is ok sometimes. verify that we handle it ok 849 * and then remove this check 850 */ 851 if (*len != *dmasize) { 852 panic("esp dmalen 0x%lx != size 0x%lx", *len, *dmasize); 853 } 854 #endif 855 #endif 856 857 #ifdef DIAGNOSTIC 858 if ((esc->sc_datain != -1) || 859 (esc->sc_main_dmamap->dm_mapsize != 0) || 860 (esc->sc_tail_dmamap->dm_mapsize != 0) || 861 (esc->sc_dmasize != 0)) { 862 panic("%s: map already loaded in esp_dma_setup" 863 "\tdatain = %d\n\tmain_mapsize=%ld\n" 864 "\tail_mapsize=%ld\n\tdmasize = %d", 865 device_xname(sc->sc_dev), esc->sc_datain, 866 esc->sc_main_dmamap->dm_mapsize, 867 esc->sc_tail_dmamap->dm_mapsize, 868 esc->sc_dmasize); 869 } 870 #endif 871 872 /* we are sometimes asked to DMA zero bytes, that's easy */ 873 if (*dmasize <= 0) { 874 return 0; 875 } 876 877 if (*dmasize > ESP_MAX_DMASIZE) 878 *dmasize = ESP_MAX_DMASIZE; 879 880 /* Save these in case we have to abort DMA */ 881 esc->sc_datain = datain; 882 esc->sc_dmaaddr = addr; 883 esc->sc_dmalen = len; 884 esc->sc_dmasize = *dmasize; 885 886 esc->sc_loaded = 0; 887 888 #define DMA_SCSI_ALIGNMENT 16 889 #define DMA_SCSI_ALIGN(type, addr) \ 890 ((type)(((unsigned int)(addr) + DMA_SCSI_ALIGNMENT - 1) \ 891 & ~(DMA_SCSI_ALIGNMENT-1))) 892 #define DMA_SCSI_ALIGNED(addr) \ 893 (((unsigned int)(addr) & (DMA_SCSI_ALIGNMENT - 1)) == 0) 894 895 { 896 size_t slop_bgn_size; /* # bytes to be fifo'd at beginning */ 897 size_t slop_end_size; /* # bytes to be transferred in 898 tail buffer */ 899 900 { 901 u_long bgn = (u_long)(*esc->sc_dmaaddr); 902 u_long end = bgn + esc->sc_dmasize; 903 904 slop_bgn_size = 905 DMA_SCSI_ALIGNMENT - (bgn % DMA_SCSI_ALIGNMENT); 906 if (slop_bgn_size == DMA_SCSI_ALIGNMENT) 907 slop_bgn_size = 0; 908 slop_end_size = end % DMA_ENDALIGNMENT; 909 } 910 911 /* 912 * Force a minimum slop end size. This ensures that write 913 * requests will overrun, as required to get completion 914 * interrupts. 915 * In addition, since the tail buffer is guaranteed to be mapped 916 * in a single DMA segment, the overrun won't accidentally 917 * end up in its own segment. 918 */ 919 if (!esc->sc_datain) { 920 #if 0 921 slop_end_size += ESP_DMA_MAXTAIL; 922 #else 923 slop_end_size += 0x10; 924 #endif 925 } 926 927 /* 928 * Check to make sure we haven't counted extra slop 929 * as would happen for a very short DMA buffer, also 930 * for short buffers, just stuff the entire thing in the tail 931 */ 932 if ((slop_bgn_size+slop_end_size >= esc->sc_dmasize) 933 #if 0 934 || (esc->sc_dmasize <= ESP_DMA_MAXTAIL) 935 #endif 936 ) { 937 slop_bgn_size = 0; 938 slop_end_size = esc->sc_dmasize; 939 } 940 941 /* initialize the fifo buffer */ 942 if (slop_bgn_size != 0) { 943 esc->sc_begin = *esc->sc_dmaaddr; 944 esc->sc_begin_size = slop_bgn_size; 945 } else { 946 esc->sc_begin = 0; 947 esc->sc_begin_size = 0; 948 } 949 950 #if 1 951 /* Load the normal DMA map */ 952 { 953 esc->sc_main = *esc->sc_dmaaddr; 954 esc->sc_main += slop_bgn_size; 955 esc->sc_main_size = 956 (esc->sc_dmasize) - (slop_end_size + slop_bgn_size); 957 958 if (esc->sc_main_size != 0) { 959 int error; 960 961 if (!esc->sc_datain || 962 DMA_ENDALIGNED(esc->sc_main_size + 963 slop_end_size)) { 964 KASSERT(DMA_SCSI_ALIGNMENT == 965 DMA_ENDALIGNMENT); 966 KASSERT(DMA_BEGINALIGNMENT == 967 DMA_ENDALIGNMENT); 968 esc->sc_main_size += slop_end_size; 969 slop_end_size = 0; 970 if (!esc->sc_datain) { 971 esc->sc_main_size = 972 DMA_ENDALIGN(uint8_t *, 973 esc->sc_main + 974 esc->sc_main_size) - 975 esc->sc_main; 976 } 977 } 978 979 error = bus_dmamap_load(esc->sc_dma->sc_dmat, 980 esc->sc_main_dmamap, 981 esc->sc_main, esc->sc_main_size, 982 NULL, BUS_DMA_NOWAIT); 983 if (error != 0) { 984 #ifdef ESP_DEBUG 985 printf("%s: esc->sc_main_dmamap->" 986 "_dm_size = %ld\n", 987 device_xname(sc->sc_dev), 988 esc->sc_main_dmamap->_dm_size); 989 printf("%s: esc->sc_main_dmamap->" 990 "_dm_segcnt = %d\n", 991 device_xname(sc->sc_dev), 992 esc->sc_main_dmamap->_dm_segcnt); 993 #ifdef notdef 994 printf("%s: esc->sc_main_dmamap->" 995 "_dm_maxsegsz = %ld\n", 996 device_xname(sc->sc_dev), 997 esc->sc_main_dmamap->_dm_maxsegsz); 998 #endif 999 printf("%s: esc->sc_main_dmamap->" 1000 "_dm_boundary = %ld\n", 1001 device_xname(sc->sc_dev), 1002 esc->sc_main_dmamap->_dm_boundary); 1003 esp_dma_print(sc); 1004 #endif 1005 panic("%s: can't load main DMA map." 1006 " error = %d, addr=%p, size=0x%08x", 1007 device_xname(sc->sc_dev), 1008 error, esc->sc_main, 1009 esc->sc_main_size); 1010 } 1011 if (!esc->sc_datain) { 1012 /* 1013 * patch the DMA map for write overrun 1014 */ 1015 esc->sc_main_dmamap->dm_mapsize += 1016 ESP_DMA_OVERRUN; 1017 esc->sc_main_dmamap->dm_segs[ 1018 esc->sc_main_dmamap->dm_nsegs - 1019 1].ds_len += 1020 ESP_DMA_OVERRUN; 1021 } 1022 #if 0 1023 bus_dmamap_sync(esc->sc_dma->sc_dmat, 1024 esc->sc_main_dmamap, 1025 0, esc->sc_main_dmamap->dm_mapsize, 1026 (esc->sc_datain ? BUS_DMASYNC_PREREAD : 1027 BUS_DMASYNC_PREWRITE)); 1028 esc->sc_main_dmamap->dm_xfer_len = 0; 1029 #endif 1030 } else { 1031 esc->sc_main = 0; 1032 } 1033 } 1034 1035 /* Load the tail DMA map */ 1036 if (slop_end_size != 0) { 1037 esc->sc_tail = DMA_ENDALIGN(uint8_t *, 1038 esc->sc_tailbuf + slop_end_size) - slop_end_size; 1039 /* 1040 * If the beginning of the tail is not correctly 1041 * aligned, we have no choice but to align the start, 1042 * which might then unalign the end. 1043 */ 1044 esc->sc_tail = DMA_SCSI_ALIGN(uint8_t *, esc->sc_tail); 1045 /* 1046 * So therefore, we change the tail size to be 1047 * end aligned again. 1048 */ 1049 esc->sc_tail_size = DMA_ENDALIGN(uint8_t *, 1050 esc->sc_tail + slop_end_size) - esc->sc_tail; 1051 1052 /* @@@ next DMA overrun lossage */ 1053 if (!esc->sc_datain) { 1054 esc->sc_tail_size += ESP_DMA_OVERRUN; 1055 } 1056 1057 { 1058 int error; 1059 error = bus_dmamap_load(esc->sc_dma->sc_dmat, 1060 esc->sc_tail_dmamap, 1061 esc->sc_tail, esc->sc_tail_size, 1062 NULL, BUS_DMA_NOWAIT); 1063 if (error) { 1064 panic("%s: can't load tail DMA map." 1065 " error = %d, addr=%p, size=0x%08x", 1066 device_xname(sc->sc_dev), error, 1067 esc->sc_tail,esc->sc_tail_size); 1068 } 1069 #if 0 1070 bus_dmamap_sync(esc->sc_dma->sc_dmat, 1071 esc->sc_tail_dmamap, 0, 1072 esc->sc_tail_dmamap->dm_mapsize, 1073 (esc->sc_datain ? BUS_DMASYNC_PREREAD : 1074 BUS_DMASYNC_PREWRITE)); 1075 esc->sc_tail_dmamap->dm_xfer_len = 0; 1076 #endif 1077 } 1078 } 1079 #else 1080 1081 esc->sc_begin = *esc->sc_dmaaddr; 1082 slop_bgn_size = DMA_SCSI_ALIGNMENT - 1083 ((u_long)esc->sc_begin % DMA_SCSI_ALIGNMENT); 1084 if (slop_bgn_size == DMA_SCSI_ALIGNMENT) 1085 slop_bgn_size = 0; 1086 slop_end_size = esc->sc_dmasize - slop_bgn_size; 1087 1088 if (slop_bgn_size < esc->sc_dmasize) { 1089 int error; 1090 1091 esc->sc_tail = 0; 1092 esc->sc_tail_size = 0; 1093 1094 esc->sc_begin_size = slop_bgn_size; 1095 esc->sc_main = *esc->sc_dmaaddr; 1096 esc->sc_main += slop_bgn_size; 1097 esc->sc_main_size = DMA_ENDALIGN(uint8_t *, 1098 esc->sc_main + esc->sc_dmasize - slop_bgn_size) - 1099 esc->sc_main; 1100 1101 if (!esc->sc_datain) { 1102 esc->sc_main_size += ESP_DMA_OVERRUN; 1103 } 1104 error = bus_dmamap_load(esc->sc_dma->sc_dmat, 1105 esc->sc_main_dmamap, 1106 esc->sc_main, esc->sc_main_size, 1107 NULL, BUS_DMA_NOWAIT); 1108 if (error) { 1109 panic("%s: can't load main DMA map." 1110 " error = %d, addr=%p, size=0x%08x", 1111 device_xname(sc->sc_dev), error, 1112 esc->sc_main,esc->sc_main_size); 1113 } 1114 } else { 1115 esc->sc_begin = 0; 1116 esc->sc_begin_size = 0; 1117 esc->sc_main = 0; 1118 esc->sc_main_size = 0; 1119 1120 #if 0 1121 esc->sc_tail = DMA_ENDALIGN(uint8_t *, 1122 esc->sc_tailbuf + slop_bgn_size) - slop_bgn_size; 1123 /* 1124 * If the beginning of the tail is not correctly 1125 * aligned, we have no choice but to align the start, 1126 * which might then unalign the end. 1127 */ 1128 #endif 1129 esc->sc_tail = DMA_SCSI_ALIGN(void *, esc->sc_tailbuf); 1130 /* 1131 * So therefore, we change the tail size to be 1132 * end aligned again. 1133 */ 1134 esc->sc_tail_size = DMA_ENDALIGN(uint8_t *, 1135 esc->sc_tail + esc->sc_dmasize) - esc->sc_tail; 1136 1137 /* @@@ next DMA overrun lossage */ 1138 if (!esc->sc_datain) { 1139 esc->sc_tail_size += ESP_DMA_OVERRUN; 1140 } 1141 1142 { 1143 int error; 1144 error = bus_dmamap_load(esc->sc_dma->sc_dmat, 1145 esc->sc_tail_dmamap, 1146 esc->sc_tail, esc->sc_tail_size, 1147 NULL, BUS_DMA_NOWAIT); 1148 if (error != 0) { 1149 panic("%s: can't load tail DMA map." 1150 " error = %d, addr=%p, size=0x%08x", 1151 device_xname(sc->sc_dev), error, 1152 esc->sc_tail, esc->sc_tail_size); 1153 } 1154 } 1155 } 1156 #endif 1157 1158 DPRINTF(("%s: setup: %8p %d %8p %d %8p %d %8p %d\n", 1159 device_xname(sc->sc_dev), 1160 *esc->sc_dmaaddr, esc->sc_dmasize, 1161 esc->sc_begin, esc->sc_begin_size, 1162 esc->sc_main, esc->sc_main_size, 1163 esc->sc_tail, esc->sc_tail_size)); 1164 } 1165 1166 return 0; 1167 } 1168 1169 #ifdef ESP_DEBUG 1170 /* For debugging */ 1171 void 1172 esp_dma_store(struct ncr53c9x_softc *sc) 1173 { 1174 struct esp_softc *esc = (struct esp_softc *)sc; 1175 char *p = esp_dma_dump; 1176 size_t l = 0; 1177 size_t len = sizeof(esp_dma_dump); 1178 1179 l += snprintf(p + l, len - l, "%s: sc_datain=%d\n", 1180 device_xname(sc->sc_dev), esc->sc_datain); 1181 if (l > len) 1182 return; 1183 l += snprintf(p + l, len - l, "%s: sc_loaded=0x%08x\n", 1184 device_xname(sc->sc_dev), esc->sc_loaded); 1185 if (l > len) 1186 return; 1187 1188 if (esc->sc_dmaaddr != 0) { 1189 l += snprintf(p + l, len - l, "%s: sc_dmaaddr=%p\n", 1190 device_xname(sc->sc_dev), *esc->sc_dmaaddr); 1191 } else { 1192 l += snprintf(p + l, len - l, "%s: sc_dmaaddr=NULL\n", 1193 device_xname(sc->sc_dev)); 1194 } 1195 if (l > len) 1196 return; 1197 if (esc->sc_dmalen) { 1198 l += snprintf(p + l, len - l, "%s: sc_dmalen=0x%08x\n", 1199 device_xname(sc->sc_dev), *esc->sc_dmalen); 1200 } else { 1201 l += snprintf(p + l, len - l, "%s: sc_dmalen=NULL\n", 1202 device_xname(sc->sc_dev)); 1203 } 1204 if (l > len) 1205 return; 1206 l += snprintf(p + l, len - l, "%s: sc_dmasize=0x%08x\n", 1207 device_xname(sc->sc_dev), esc->sc_dmasize); 1208 if (l > len) 1209 return; 1210 1211 l += snprintf(p + l, len - l, 1212 "%s: sc_begin = %p, sc_begin_size = 0x%08x\n", 1213 device_xname(sc->sc_dev), esc->sc_begin, esc->sc_begin_size); 1214 if (l > len) 1215 return; 1216 l += snprintf(p + l, len - l, 1217 "%s: sc_main = %p, sc_main_size = 0x%08x\n", 1218 device_xname(sc->sc_dev), esc->sc_main, esc->sc_main_size); 1219 if (l > len) 1220 return; 1221 #if 0 1222 if (esc->sc_main) 1223 #endif 1224 { 1225 int i; 1226 bus_dmamap_t map = esc->sc_main_dmamap; 1227 l += snprintf(p + l, len - l, "%s: sc_main_dmamap." 1228 " mapsize = 0x%08lx, nsegs = %d\n", 1229 device_xname(sc->sc_dev), map->dm_mapsize, map->dm_nsegs); 1230 if (l > len) 1231 return; 1232 for(i = 0; i < map->dm_nsegs; i++) { 1233 l += snprintf(p + l, len - l, "%s:" 1234 " map->dm_segs[%d].ds_addr = 0x%08lx," 1235 " len = 0x%08lx\n", 1236 device_xname(sc->sc_dev), 1237 i, map->dm_segs[i].ds_addr, 1238 map->dm_segs[i].ds_len); 1239 if (l > len) 1240 return; 1241 } 1242 } 1243 l += snprintf(p + l, len - l, 1244 "%s: sc_tail = %p, sc_tail_size = 0x%08x\n", 1245 device_xname(sc->sc_dev), esc->sc_tail, esc->sc_tail_size); 1246 if (l > len) 1247 return; 1248 #if 0 1249 if (esc->sc_tail) 1250 #endif 1251 { 1252 int i; 1253 bus_dmamap_t map = esc->sc_tail_dmamap; 1254 l += snprintf(p + l, len - l, "%s: sc_tail_dmamap." 1255 " mapsize = 0x%08lx, nsegs = %d\n", 1256 device_xname(sc->sc_dev), map->dm_mapsize, map->dm_nsegs); 1257 if (l > len) 1258 return; 1259 for (i = 0; i < map->dm_nsegs; i++) { 1260 l += snprintf(p + l, len - l, "%s:" 1261 " map->dm_segs[%d].ds_addr = 0x%08lx," 1262 " len = 0x%08lx\n", 1263 device_xname(sc->sc_dev), 1264 i, map->dm_segs[i].ds_addr, 1265 map->dm_segs[i].ds_len); 1266 if (l > len) 1267 return; 1268 } 1269 } 1270 } 1271 1272 void 1273 esp_dma_print(struct ncr53c9x_softc *sc) 1274 { 1275 1276 esp_dma_store(sc); 1277 printf("%s", esp_dma_dump); 1278 } 1279 #endif 1280 1281 static void 1282 esp_dma_go(struct ncr53c9x_softc *sc) 1283 { 1284 struct esp_softc *esc = (struct esp_softc *)sc; 1285 struct nextdma_softc *nsc = esc->sc_dma; 1286 struct nextdma_status *stat = &nsc->sc_stat; 1287 #if 0 1288 int s = spldma(); 1289 #endif 1290 1291 #ifdef ESP_DEBUG 1292 if (!ndtrace_empty()) { 1293 if (esptraceshow) { 1294 printf("esp ndtrace: %s\n", ndtrace_get()); 1295 esptraceshow = 0; 1296 } else { 1297 DPRINTF(("X")); 1298 } 1299 ndtrace_reset(); 1300 } 1301 #endif 1302 1303 DPRINTF(("%s: esp_dma_go(datain = %d)\n", 1304 device_xname(sc->sc_dev), esc->sc_datain)); 1305 1306 #ifdef ESP_DEBUG 1307 if (esp_debug) 1308 esp_dma_print(sc); 1309 else 1310 esp_dma_store(sc); 1311 #endif 1312 1313 #ifdef ESP_DEBUG 1314 { 1315 int n = NCR_READ_REG(sc, NCR_FFLAG); 1316 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n", 1317 device_xname(sc->sc_dev), 1318 n & NCRFIFO_FF, (n & NCRFIFO_SS) >> 5)); 1319 } 1320 #endif 1321 1322 /* zero length DMA transfers are boring */ 1323 if (esc->sc_dmasize == 0) { 1324 #if 0 1325 splx(s); 1326 #endif 1327 return; 1328 } 1329 1330 #if defined(DIAGNOSTIC) 1331 if ((esc->sc_begin_size == 0) && 1332 (esc->sc_main_dmamap->dm_mapsize == 0) && 1333 (esc->sc_tail_dmamap->dm_mapsize == 0)) { 1334 #ifdef ESP_DEBUG 1335 esp_dma_print(sc); 1336 #endif 1337 panic("%s: No DMA requested!", device_xname(sc->sc_dev)); 1338 } 1339 #endif 1340 1341 /* Stuff the fifo with the begin buffer */ 1342 if (esc->sc_datain) { 1343 int i; 1344 DPRINTF(("%s: FIFO read of %d bytes:", 1345 device_xname(sc->sc_dev), esc->sc_begin_size)); 1346 for (i = 0; i < esc->sc_begin_size; i++) { 1347 esc->sc_begin[i] = NCR_READ_REG(sc, NCR_FIFO); 1348 DPRINTF((" %02x", esc->sc_begin[i] & 0xff)); 1349 } 1350 DPRINTF(("\n")); 1351 } else { 1352 int i; 1353 DPRINTF(("%s: FIFO write of %d bytes:", 1354 device_xname(sc->sc_dev), esc->sc_begin_size)); 1355 for (i = 0; i < esc->sc_begin_size; i++) { 1356 NCR_WRITE_REG(sc, NCR_FIFO, esc->sc_begin[i]); 1357 DPRINTF((" %02x",esc->sc_begin[i] & 0xff)); 1358 } 1359 DPRINTF(("\n")); 1360 } 1361 1362 if (esc->sc_main_dmamap->dm_mapsize != 0) { 1363 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap, 1364 0, esc->sc_main_dmamap->dm_mapsize, 1365 (esc->sc_datain ? 1366 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1367 esc->sc_main_dmamap->dm_xfer_len = 0; 1368 } 1369 1370 if (esc->sc_tail_dmamap->dm_mapsize != 0) { 1371 /* if we are a DMA write cycle, copy the end slop */ 1372 if (!esc->sc_datain) { 1373 memcpy(esc->sc_tail, *esc->sc_dmaaddr + 1374 esc->sc_begin_size+esc->sc_main_size, 1375 esc->sc_dmasize - 1376 (esc->sc_begin_size + esc->sc_main_size)); 1377 } 1378 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap, 1379 0, esc->sc_tail_dmamap->dm_mapsize, 1380 (esc->sc_datain ? 1381 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1382 esc->sc_tail_dmamap->dm_xfer_len = 0; 1383 } 1384 1385 stat->nd_exception = 0; 1386 nextdma_start(nsc, (esc->sc_datain ? DMACSR_SETREAD : DMACSR_SETWRITE)); 1387 1388 if (esc->sc_datain) { 1389 NCR_WRITE_REG(sc, ESP_DCTL, 1390 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | 1391 ESPDCTL_DMARD); 1392 } else { 1393 NCR_WRITE_REG(sc, ESP_DCTL, 1394 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD); 1395 } 1396 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 1397 1398 NDTRACEIF( 1399 if (esc->sc_begin_size != 0) { 1400 ndtrace_addc('1'); 1401 ndtrace_addc('A' + esc->sc_begin_size); 1402 } 1403 ); 1404 NDTRACEIF( 1405 if (esc->sc_main_size != 0) { 1406 ndtrace_addc('2'); 1407 ndtrace_addc('0' + esc->sc_main_dmamap->dm_nsegs); 1408 } 1409 ); 1410 NDTRACEIF( 1411 if (esc->sc_tail_size != 0) { 1412 ndtrace_addc('3'); 1413 ndtrace_addc('A' + esc->sc_tail_size); 1414 } 1415 ); 1416 1417 #if 0 1418 splx(s); 1419 #endif 1420 } 1421 1422 static void 1423 esp_dma_stop(struct ncr53c9x_softc *sc) 1424 { 1425 struct esp_softc *esc = (struct esp_softc *)sc; 1426 1427 nextdma_print(esc->sc_dma); 1428 #ifdef ESP_DEBUG 1429 esp_dma_print(sc); 1430 #endif 1431 #if 1 1432 panic("%s: stop not yet implemented", device_xname(sc->sc_dev)); 1433 #endif 1434 } 1435 1436 static int 1437 esp_dma_isactive(struct ncr53c9x_softc *sc) 1438 { 1439 struct esp_softc *esc = (struct esp_softc *)sc; 1440 int r; 1441 1442 #if 0 1443 r = !nextdma_finished(esc->sc_dma); 1444 #else 1445 r = (esc->sc_dmaaddr != NULL); 1446 #endif 1447 DPRINTF(("esp_dma_isactive = %d\n",r)); 1448 return r; 1449 } 1450 1451 /****************************************************************/ 1452 1453 int esp_dma_int(void *); /* XXX: called from nextdma.c */ 1454 int esp_dma_int(void *arg) 1455 { 1456 void nextdma_rotate(struct nextdma_softc *); /* XXX */ 1457 void nextdma_setup_curr_regs(struct nextdma_softc *); /* XXX */ 1458 void nextdma_setup_cont_regs(struct nextdma_softc *); /* XXX */ 1459 1460 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1461 struct esp_softc *esc = (struct esp_softc *)sc; 1462 struct nextdma_softc *nsc = esc->sc_dma; 1463 struct nextdma_status *stat = &nsc->sc_stat; 1464 unsigned int state; 1465 1466 NDTRACEIF(ndtrace_addc('E')); 1467 1468 state = nd_bsr4(DD_CSR); 1469 1470 #if 1 1471 NDTRACEIF( 1472 if (state & DMACSR_COMPLETE) 1473 ndtrace_addc('c'); 1474 if (state & DMACSR_ENABLE) 1475 ndtrace_addc('e'); 1476 if (state & DMACSR_BUSEXC) 1477 ndtrace_addc('b'); 1478 if (state & DMACSR_READ) 1479 ndtrace_addc('r'); 1480 if (state & DMACSR_SUPDATE) 1481 ndtrace_addc('s'); 1482 ); 1483 1484 NDTRACEIF(ndtrace_addc('E')); 1485 1486 #ifdef ESP_DEBUG 1487 if (0) 1488 if ((state & DMACSR_BUSEXC) && (state & DMACSR_ENABLE)) 1489 esptraceshow++; 1490 if (0) 1491 if ((state & DMACSR_SUPDATE)) 1492 esptraceshow++; 1493 #endif 1494 #endif 1495 1496 if ((stat->nd_exception == 0) && 1497 ((state & DMACSR_COMPLETE) != 0) && 1498 ((state & DMACSR_ENABLE) != 0)) { 1499 stat->nd_map->dm_xfer_len += 1500 stat->nd_map->dm_segs[stat->nd_idx].ds_len; 1501 } 1502 1503 if ((stat->nd_idx + 1) == stat->nd_map->dm_nsegs) { 1504 if (nsc->sc_conf.nd_completed_cb) 1505 (*nsc->sc_conf.nd_completed_cb)(stat->nd_map, 1506 nsc->sc_conf.nd_cb_arg); 1507 } 1508 nextdma_rotate(nsc); 1509 1510 if ((state & DMACSR_COMPLETE) != 0 && 1511 (state & DMACSR_ENABLE) != 0) { 1512 #if 0 1513 int l = nd_bsr4(DD_LIMIT) & 0x7FFFFFFF; 1514 int s = nd_bsr4(DD_STOP); 1515 #endif 1516 #if 0 1517 nextdma_setup_cont_regs(nsc); 1518 #endif 1519 if (stat->nd_map_cont != NULL) { 1520 nd_bsw4(DD_START, stat->nd_map_cont->dm_segs[ 1521 stat->nd_idx_cont].ds_addr); 1522 nd_bsw4(DD_STOP, (stat->nd_map_cont->dm_segs[ 1523 stat->nd_idx_cont].ds_addr + 1524 stat->nd_map_cont->dm_segs[ 1525 stat->nd_idx_cont].ds_len)); 1526 } 1527 1528 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE | 1529 (state & DMACSR_READ ? DMACSR_SETREAD : DMACSR_SETWRITE) | 1530 (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0)); 1531 1532 #if 0 1533 #ifdef ESP_DEBUG 1534 if ((state & DMACSR_BUSEXC) != 0) { 1535 ndtrace_printf("CE/BUSEXC: %08lX %08X %08X\n", 1536 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr + 1537 stat->nd_map->dm_segs[stat->nd_idx].ds_len), 1538 l, s); 1539 } 1540 #endif 1541 #endif 1542 } else { 1543 #if 0 1544 if ((state & DMACSR_BUSEXC) != 0) { 1545 while (nd_bsr4(DD_NEXT) != 1546 (nd_bsr4(DD_LIMIT) & 0x7FFFFFFF)) 1547 printf("Y"); /* DELAY(50); */ 1548 state = nd_bsr4(DD_CSR); 1549 } 1550 #endif 1551 1552 if ((state & DMACSR_SUPDATE) == 0) { 1553 nextdma_rotate(nsc); 1554 } else { 1555 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE | 1556 DMACSR_INITBUF | DMACSR_RESET | 1557 (state & DMACSR_READ ? 1558 DMACSR_SETREAD : DMACSR_SETWRITE)); 1559 1560 nd_bsw4(DD_NEXT, 1561 stat->nd_map->dm_segs[stat->nd_idx].ds_addr); 1562 nd_bsw4(DD_LIMIT, 1563 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr + 1564 stat->nd_map->dm_segs[stat->nd_idx].ds_len) | 1565 0/* x80000000 */); 1566 if (stat->nd_map_cont) { 1567 nd_bsw4(DD_START, 1568 stat->nd_map_cont->dm_segs[ 1569 stat->nd_idx_cont].ds_addr); 1570 nd_bsw4(DD_STOP, 1571 (stat->nd_map_cont->dm_segs[ 1572 stat->nd_idx_cont].ds_addr + 1573 stat->nd_map_cont->dm_segs[ 1574 stat->nd_idx_cont].ds_len) | 1575 0/* x80000000 */); 1576 } 1577 nd_bsw4(DD_CSR, DMACSR_SETENABLE | DMACSR_CLRCOMPLETE | 1578 (state & DMACSR_READ ? 1579 DMACSR_SETREAD : DMACSR_SETWRITE) | 1580 (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0)); 1581 #if 1 1582 #ifdef ESP_DEBUG 1583 ndtrace_printf("supdate "); 1584 ndtrace_printf("%08X %08X %08X %08X ", 1585 nd_bsr4(DD_NEXT), 1586 nd_bsr4(DD_LIMIT) & 0x7FFFFFFF, 1587 nd_bsr4(DD_START), 1588 nd_bsr4(DD_STOP) & 0x7FFFFFFF); 1589 #endif 1590 #endif 1591 stat->nd_exception++; 1592 return 1; 1593 /* NCR_WRITE_REG(sc, ESP_DCTL, ctl); */ 1594 goto restart; 1595 } 1596 1597 if (stat->nd_map != NULL) { 1598 #if 1 1599 #ifdef ESP_DEBUG 1600 ndtrace_printf("%08X %08X %08X %08X ", 1601 nd_bsr4(DD_NEXT), 1602 nd_bsr4(DD_LIMIT) & 0x7FFFFFFF, 1603 nd_bsr4(DD_START), 1604 nd_bsr4(DD_STOP) & 0x7FFFFFFF); 1605 #endif 1606 #endif 1607 1608 #if 0 1609 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE | DMACSR_RESET); 1610 1611 nd_bsw4(DD_CSR, 0); 1612 #endif 1613 #if 1 1614 /* 6/2 */ 1615 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE | 1616 DMACSR_INITBUF | DMACSR_RESET | 1617 (state & DMACSR_READ ? 1618 DMACSR_SETREAD : DMACSR_SETWRITE)); 1619 1620 /* nextdma_setup_curr_regs(nsc); */ 1621 nd_bsw4(DD_NEXT, 1622 stat->nd_map->dm_segs[stat->nd_idx].ds_addr); 1623 nd_bsw4(DD_LIMIT, 1624 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr + 1625 stat->nd_map->dm_segs[stat->nd_idx].ds_len) | 1626 0/* x80000000 */); 1627 /* nextdma_setup_cont_regs(nsc); */ 1628 if (stat->nd_map_cont != NULL) { 1629 nd_bsw4(DD_START, 1630 stat->nd_map_cont->dm_segs[ 1631 stat->nd_idx_cont].ds_addr); 1632 nd_bsw4(DD_STOP, 1633 (stat->nd_map_cont->dm_segs[ 1634 stat->nd_idx_cont].ds_addr + 1635 stat->nd_map_cont->dm_segs[ 1636 stat->nd_idx_cont].ds_len) | 1637 0/* x80000000 */); 1638 } 1639 1640 nd_bsw4(DD_CSR, DMACSR_SETENABLE | 1641 (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0) | 1642 (state & DMACSR_READ ? 1643 DMACSR_SETREAD : DMACSR_SETWRITE)); 1644 #ifdef ESP_DEBUG 1645 #if 0 1646 esptraceshow++; 1647 #endif 1648 #endif 1649 stat->nd_exception++; 1650 return 1; 1651 #endif 1652 #if 0 1653 NCR_WRITE_REG(sc, ESP_DCTL, ctl); 1654 #endif 1655 goto restart; 1656 restart: 1657 #if 1 1658 #ifdef ESP_DEBUG 1659 ndtrace_printf("restart %08lX %08lX\n", 1660 stat->nd_map->dm_segs[stat->nd_idx].ds_addr, 1661 stat->nd_map->dm_segs[stat->nd_idx].ds_addr + 1662 stat->nd_map->dm_segs[stat->nd_idx].ds_len); 1663 if (stat->nd_map_cont != NULL) { 1664 ndtrace_printf(" %08lX %08lX\n", 1665 stat->nd_map_cont->dm_segs[ 1666 stat->nd_idx_cont].ds_addr, 1667 stat->nd_map_cont->dm_segs[ 1668 stat->nd_idx_cont].ds_addr + 1669 stat->nd_map_cont->dm_segs[ 1670 stat->nd_idx_cont].ds_len); 1671 } 1672 #endif 1673 #endif 1674 nextdma_print(nsc); 1675 NCR_WRITE_REG(sc, ESP_DCTL, 1676 ESPDCTL_16MHZ | ESPDCTL_INTENB); 1677 printf("ff:%02x tcm:%d tcl:%d esp_dstat:%02x" 1678 " state:%02x step: %02x intr:%02x state:%08X\n", 1679 NCR_READ_REG(sc, NCR_FFLAG), 1680 NCR_READ_REG((sc), NCR_TCM), 1681 NCR_READ_REG((sc), NCR_TCL), 1682 NCR_READ_REG(sc, ESP_DSTAT), 1683 NCR_READ_REG(sc, NCR_STAT), 1684 NCR_READ_REG(sc, NCR_STEP), 1685 NCR_READ_REG(sc, NCR_INTR), state); 1686 #ifdef ESP_DEBUG 1687 printf("ndtrace: %s\n", ndtrace_get()); 1688 #endif 1689 panic("%s: busexc/supdate occurred." 1690 " Please email this output to chris@pin.lu.", 1691 device_xname(sc->sc_dev)); 1692 #ifdef ESP_DEBUG 1693 esptraceshow++; 1694 #endif 1695 } else { 1696 nd_bsw4(DD_CSR, DMACSR_CLRCOMPLETE | DMACSR_RESET); 1697 if (nsc->sc_conf.nd_shutdown_cb) 1698 (*nsc->sc_conf.nd_shutdown_cb)( 1699 nsc->sc_conf.nd_cb_arg); 1700 } 1701 } 1702 return 1; 1703 } 1704 1705 /* Internal DMA callback routines */ 1706 static bus_dmamap_t 1707 esp_dmacb_continue(void *arg) 1708 { 1709 struct ncr53c9x_softc *sc = arg; 1710 struct esp_softc *esc = (struct esp_softc *)sc; 1711 1712 NDTRACEIF(ndtrace_addc('x')); 1713 DPRINTF(("%s: DMA continue\n", device_xname(sc->sc_dev))); 1714 1715 #ifdef DIAGNOSTIC 1716 if (esc->sc_datain < 0 || esc->sc_datain > 1) { 1717 panic("%s: map not loaded in DMA continue callback," 1718 " datain = %d", 1719 device_xname(sc->sc_dev), esc->sc_datain); 1720 } 1721 #endif 1722 1723 if ((esc->sc_loaded & ESP_LOADED_MAIN) == 0 && 1724 esc->sc_main_dmamap->dm_mapsize != 0) { 1725 DPRINTF(("%s: Loading main map\n", device_xname(sc->sc_dev))); 1726 #if 0 1727 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap, 1728 0, esc->sc_main_dmamap->dm_mapsize, 1729 (esc->sc_datain ? 1730 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1731 esc->sc_main_dmamap->dm_xfer_len = 0; 1732 #endif 1733 esc->sc_loaded |= ESP_LOADED_MAIN; 1734 return esc->sc_main_dmamap; 1735 } 1736 1737 if ((esc->sc_loaded & ESP_LOADED_TAIL) == 0 && 1738 esc->sc_tail_dmamap->dm_mapsize != 0) { 1739 DPRINTF(("%s: Loading tail map\n", device_xname(sc->sc_dev))); 1740 #if 0 1741 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap, 1742 0, esc->sc_tail_dmamap->dm_mapsize, 1743 (esc->sc_datain ? 1744 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1745 esc->sc_tail_dmamap->dm_xfer_len = 0; 1746 #endif 1747 esc->sc_loaded |= ESP_LOADED_TAIL; 1748 return esc->sc_tail_dmamap; 1749 } 1750 1751 DPRINTF(("%s: not loading map\n", device_xname(sc->sc_dev))); 1752 return 0; 1753 } 1754 1755 1756 static void 1757 esp_dmacb_completed(bus_dmamap_t map, void *arg) 1758 { 1759 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1760 struct esp_softc *esc = (struct esp_softc *)sc; 1761 1762 NDTRACEIF(ndtrace_addc('X')); 1763 DPRINTF(("%s: DMA completed\n", device_xname(sc->sc_dev))); 1764 1765 #ifdef DIAGNOSTIC 1766 if (esc->sc_datain < 0 || esc->sc_datain > 1) { 1767 panic("%s: invalid DMA direction in completed callback," 1768 " datain = %d", 1769 device_xname(sc->sc_dev), esc->sc_datain); 1770 } 1771 #endif 1772 1773 #if defined(DIAGNOSTIC) && 0 1774 { 1775 int i; 1776 for(i = 0; i < map->dm_nsegs; i++) { 1777 if (map->dm_xfer_len != map->dm_mapsize) { 1778 printf("%s: map->dm_mapsize = %d\n", 1779 device_xname(sc->sc_dev), map->dm_mapsize); 1780 printf("%s: map->dm_nsegs = %d\n", 1781 device_xname(sc->sc_dev), map->dm_nsegs); 1782 printf("%s: map->dm_xfer_len = %d\n", 1783 device_xname(sc->sc_dev), map->dm_xfer_len); 1784 for(i = 0; i < map->dm_nsegs; i++) { 1785 printf("%s: map->dm_segs[%d].ds_addr =" 1786 " 0x%08lx\n", 1787 device_xname(sc->sc_dev), i, 1788 map->dm_segs[i].ds_addr); 1789 printf("%s: map->dm_segs[%d].ds_len =" 1790 " %d\n", 1791 device_xname(sc->sc_dev), i, 1792 map->dm_segs[i].ds_len); 1793 } 1794 panic("%s: incomplete DMA transfer", 1795 device_xname(sc->sc_dev)); 1796 } 1797 } 1798 } 1799 #endif 1800 1801 if (map == esc->sc_main_dmamap) { 1802 #ifdef DIAGNOSTIC 1803 if ((esc->sc_loaded & ESP_UNLOADED_MAIN) || 1804 (esc->sc_loaded & ESP_LOADED_MAIN) == 0) { 1805 panic("%s: unexpected completed call for main map", 1806 device_xname(sc->sc_dev)); 1807 } 1808 #endif 1809 esc->sc_loaded |= ESP_UNLOADED_MAIN; 1810 } else if (map == esc->sc_tail_dmamap) { 1811 #ifdef DIAGNOSTIC 1812 if ((esc->sc_loaded & ESP_UNLOADED_TAIL) || 1813 (esc->sc_loaded & ESP_LOADED_TAIL) == 0) { 1814 panic("%s: unexpected completed call for tail map", 1815 device_xname(sc->sc_dev)); 1816 } 1817 #endif 1818 esc->sc_loaded |= ESP_UNLOADED_TAIL; 1819 } 1820 #ifdef DIAGNOSTIC 1821 else { 1822 panic("%s: unexpected completed map", device_xname(sc->sc_dev)); 1823 } 1824 #endif 1825 1826 #ifdef ESP_DEBUG 1827 if (esp_debug) { 1828 if (map == esc->sc_main_dmamap) { 1829 printf("%s: completed main map\n", 1830 device_xname(sc->sc_dev)); 1831 } else if (map == esc->sc_tail_dmamap) { 1832 printf("%s: completed tail map\n", 1833 device_xname(sc->sc_dev)); 1834 } 1835 } 1836 #endif 1837 1838 #if 0 1839 if ((map == esc->sc_tail_dmamap) || 1840 ((esc->sc_tail_size == 0) && (map == esc->sc_main_dmamap))) { 1841 1842 /* 1843 * Clear the DMAMOD bit in the DCTL register to give control 1844 * back to the scsi chip. 1845 */ 1846 if (esc->sc_datain) { 1847 NCR_WRITE_REG(sc, ESP_DCTL, 1848 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 1849 } else { 1850 NCR_WRITE_REG(sc, ESP_DCTL, 1851 ESPDCTL_16MHZ | ESPDCTL_INTENB); 1852 } 1853 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc, ESP_DCTL))); 1854 } 1855 #endif 1856 1857 1858 #if 0 1859 bus_dmamap_sync(esc->sc_dma->sc_dmat, map, 1860 0, map->dm_mapsize, 1861 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1862 #endif 1863 1864 } 1865 1866 static void 1867 esp_dmacb_shutdown(void *arg) 1868 { 1869 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1870 struct esp_softc *esc = (struct esp_softc *)sc; 1871 1872 NDTRACEIF (ndtrace_addc('S')); 1873 DPRINTF(("%s: DMA shutdown\n", device_xname(sc->sc_dev))); 1874 1875 if (esc->sc_loaded == 0) 1876 return; 1877 1878 #if 0 1879 { 1880 /* Clear the DMAMOD bit in the DCTL register to give control 1881 * back to the scsi chip. 1882 */ 1883 if (esc->sc_datain) { 1884 NCR_WRITE_REG(sc, ESP_DCTL, 1885 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 1886 } else { 1887 NCR_WRITE_REG(sc, ESP_DCTL, 1888 ESPDCTL_16MHZ | ESPDCTL_INTENB); 1889 } 1890 DPRINTF(("esp dctl is 0x%02x\n", NCR_READ_REG(sc, ESP_DCTL))); 1891 } 1892 #endif 1893 1894 DPRINTF(("%s: esp_dma_nest == %d\n", 1895 device_xname(sc->sc_dev), esp_dma_nest)); 1896 1897 /* Stuff the end slop into fifo */ 1898 1899 #ifdef ESP_DEBUG 1900 if (esp_debug) { 1901 int n = NCR_READ_REG(sc, NCR_FFLAG); 1902 1903 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n", 1904 device_xname(sc->sc_dev), n & NCRFIFO_FF, 1905 (n & NCRFIFO_SS) >> 5)); 1906 } 1907 #endif 1908 1909 if (esc->sc_main_dmamap->dm_mapsize != 0) { 1910 if (!esc->sc_datain) { 1911 /* unpatch the DMA map for write overrun */ 1912 esc->sc_main_dmamap->dm_mapsize -= ESP_DMA_OVERRUN; 1913 esc->sc_main_dmamap->dm_segs[ 1914 esc->sc_main_dmamap->dm_nsegs - 1].ds_len -= 1915 ESP_DMA_OVERRUN; 1916 } 1917 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap, 1918 0, esc->sc_main_dmamap->dm_mapsize, 1919 (esc->sc_datain ? 1920 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1921 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_main_dmamap); 1922 NDTRACEIF( 1923 ndtrace_printf("m%ld", 1924 esc->sc_main_dmamap->dm_xfer_len); 1925 ); 1926 } 1927 1928 if (esc->sc_tail_dmamap->dm_mapsize != 0) { 1929 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap, 1930 0, esc->sc_tail_dmamap->dm_mapsize, 1931 (esc->sc_datain ? 1932 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1933 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap); 1934 /* copy the tail DMA buffer data for read transfers */ 1935 if (esc->sc_datain) { 1936 memcpy(*esc->sc_dmaaddr + esc->sc_begin_size + 1937 esc->sc_main_size, esc->sc_tail, 1938 esc->sc_dmasize - 1939 (esc->sc_begin_size + esc->sc_main_size)); 1940 } 1941 NDTRACEIF( 1942 ndtrace_printf("t%ld", 1943 esc->sc_tail_dmamap->dm_xfer_len); 1944 ); 1945 } 1946 1947 #ifdef ESP_DEBUG 1948 if (esp_debug) { 1949 printf("%s: dma_shutdown: addr=%p,len=0x%08x,size=0x%08x\n", 1950 device_xname(sc->sc_dev), 1951 *esc->sc_dmaaddr, *esc->sc_dmalen, esc->sc_dmasize); 1952 if (esp_debug > 10) { 1953 esp_hex_dump(*(esc->sc_dmaaddr), esc->sc_dmasize); 1954 printf("%s: tail=%p,tailbuf=%p,tail_size=0x%08x\n", 1955 device_xname(sc->sc_dev), 1956 esc->sc_tail, &(esc->sc_tailbuf[0]), 1957 esc->sc_tail_size); 1958 esp_hex_dump(&(esc->sc_tailbuf[0]), 1959 sizeof(esc->sc_tailbuf)); 1960 } 1961 } 1962 #endif 1963 1964 esc->sc_main = 0; 1965 esc->sc_main_size = 0; 1966 esc->sc_tail = 0; 1967 esc->sc_tail_size = 0; 1968 1969 esc->sc_datain = -1; 1970 #if 0 1971 esc->sc_dmaaddr = 0; 1972 esc->sc_dmalen = 0; 1973 esc->sc_dmasize = 0; 1974 #endif 1975 1976 esc->sc_loaded = 0; 1977 1978 esc->sc_begin = 0; 1979 esc->sc_begin_size = 0; 1980 1981 #ifdef ESP_DEBUG 1982 if (esp_debug) { 1983 char sbuf[256]; 1984 1985 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS, 1986 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT))); 1987 printf(" *intrstat = %s\n", sbuf); 1988 1989 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS, 1990 (*(volatile u_long *)IIOV(NEXT_P_INTRMASK))); 1991 printf(" *intrmask = %s\n", sbuf); 1992 } 1993 #endif 1994 } 1995