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