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