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