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