1 /* $NetBSD: esp.c,v 1.54 2007/03/05 15:05:24 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 * 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.54 2007/03/05 15:05:24 tsutsui 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 *, void **, 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 = (char *)*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, void **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 = bgn + 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; 877 esc->sc_main += slop_bgn_size; 878 esc->sc_main_size = (esc->sc_dmasize)-(slop_end_size+slop_bgn_size); 879 880 if (esc->sc_main_size) { 881 int error; 882 883 if (!esc->sc_datain || DMA_ENDALIGNED(esc->sc_main_size + slop_end_size)) { 884 KASSERT(DMA_SCSI_ALIGNMENT == DMA_ENDALIGNMENT); 885 KASSERT(DMA_BEGINALIGNMENT == DMA_ENDALIGNMENT); 886 esc->sc_main_size += slop_end_size; 887 slop_end_size = 0; 888 if (!esc->sc_datain) { 889 esc->sc_main_size = DMA_ENDALIGN(uint8_t *,esc->sc_main+esc->sc_main_size)-esc->sc_main; 890 } 891 } 892 893 error = bus_dmamap_load(esc->sc_dma->sc_dmat, 894 esc->sc_main_dmamap, 895 esc->sc_main, esc->sc_main_size, 896 NULL, BUS_DMA_NOWAIT); 897 if (error) { 898 #ifdef ESP_DEBUG 899 printf("%s: esc->sc_main_dmamap->_dm_size = %ld\n", 900 sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_size); 901 printf("%s: esc->sc_main_dmamap->_dm_segcnt = %d\n", 902 sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_segcnt); 903 printf("%s: esc->sc_main_dmamap->_dm_maxsegsz = %ld\n", 904 sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_maxsegsz); 905 printf("%s: esc->sc_main_dmamap->_dm_boundary = %ld\n", 906 sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_boundary); 907 esp_dma_print(sc); 908 #endif 909 panic("%s: can't load main DMA map. error = %d, addr=%p, size=0x%08x", 910 sc->sc_dev.dv_xname, error,esc->sc_main,esc->sc_main_size); 911 } 912 if (!esc->sc_datain) { /* patch the DMA map for write overrun */ 913 esc->sc_main_dmamap->dm_mapsize += ESP_DMA_OVERRUN; 914 esc->sc_main_dmamap->dm_segs[esc->sc_main_dmamap->dm_nsegs - 1].ds_len += 915 ESP_DMA_OVERRUN; 916 } 917 #if 0 918 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap, 919 0, esc->sc_main_dmamap->dm_mapsize, 920 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 921 esc->sc_main_dmamap->dm_xfer_len = 0; 922 #endif 923 } else { 924 esc->sc_main = 0; 925 } 926 } 927 928 /* Load the tail DMA map */ 929 if (slop_end_size) { 930 esc->sc_tail = DMA_ENDALIGN(uint8_t *,esc->sc_tailbuf+slop_end_size)-slop_end_size; 931 /* If the beginning of the tail is not correctly aligned, 932 * we have no choice but to align the start, which might then unalign the end. 933 */ 934 esc->sc_tail = DMA_SCSI_ALIGN(uint8_t *,esc->sc_tail); 935 /* So therefore, we change the tail size to be end aligned again. */ 936 esc->sc_tail_size = DMA_ENDALIGN(uint8_t *,esc->sc_tail+slop_end_size)-esc->sc_tail; 937 938 /* @@@ next DMA overrun lossage */ 939 if (!esc->sc_datain) { 940 esc->sc_tail_size += ESP_DMA_OVERRUN; 941 } 942 943 { 944 int error; 945 error = bus_dmamap_load(esc->sc_dma->sc_dmat, 946 esc->sc_tail_dmamap, 947 esc->sc_tail, esc->sc_tail_size, 948 NULL, BUS_DMA_NOWAIT); 949 if (error) { 950 panic("%s: can't load tail DMA map. error = %d, addr=%p, size=0x%08x", 951 sc->sc_dev.dv_xname, error,esc->sc_tail,esc->sc_tail_size); 952 } 953 #if 0 954 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap, 955 0, esc->sc_tail_dmamap->dm_mapsize, 956 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 957 esc->sc_tail_dmamap->dm_xfer_len = 0; 958 #endif 959 } 960 } 961 #else 962 963 esc->sc_begin = *esc->sc_dmaaddr; 964 slop_bgn_size = DMA_SCSI_ALIGNMENT-((ulong)esc->sc_begin % DMA_SCSI_ALIGNMENT); 965 if (slop_bgn_size == DMA_SCSI_ALIGNMENT) slop_bgn_size = 0; 966 slop_end_size = esc->sc_dmasize - slop_bgn_size; 967 968 if (slop_bgn_size < esc->sc_dmasize) { 969 int error; 970 971 esc->sc_tail = 0; 972 esc->sc_tail_size = 0; 973 974 esc->sc_begin_size = slop_bgn_size; 975 esc->sc_main = *esc->sc_dmaaddr; 976 esc->sc_main += slop_bgn_size; 977 esc->sc_main_size = DMA_ENDALIGN(uint8_t *,esc->sc_main+esc->sc_dmasize-slop_bgn_size)-esc->sc_main; 978 979 if (!esc->sc_datain) { 980 esc->sc_main_size += ESP_DMA_OVERRUN; 981 } 982 error = bus_dmamap_load(esc->sc_dma->sc_dmat, 983 esc->sc_main_dmamap, 984 esc->sc_main, esc->sc_main_size, 985 NULL, BUS_DMA_NOWAIT); 986 if (error) { 987 panic("%s: can't load main DMA map. error = %d, addr=%p, size=0x%08x", 988 sc->sc_dev.dv_xname, error,esc->sc_main,esc->sc_main_size); 989 } 990 } else { 991 esc->sc_begin = 0; 992 esc->sc_begin_size = 0; 993 esc->sc_main = 0; 994 esc->sc_main_size = 0; 995 996 #if 0 997 esc->sc_tail = DMA_ENDALIGN(uint8_t *,esc->sc_tailbuf+slop_bgn_size)-slop_bgn_size; 998 /* If the beginning of the tail is not correctly aligned, 999 * we have no choice but to align the start, which might then unalign the end. 1000 */ 1001 #endif 1002 esc->sc_tail = DMA_SCSI_ALIGN(void *,esc->sc_tailbuf); 1003 /* So therefore, we change the tail size to be end aligned again. */ 1004 esc->sc_tail_size = DMA_ENDALIGN(uint8_t *,esc->sc_tail+esc->sc_dmasize)-esc->sc_tail; 1005 1006 /* @@@ next DMA overrun lossage */ 1007 if (!esc->sc_datain) { 1008 esc->sc_tail_size += ESP_DMA_OVERRUN; 1009 } 1010 1011 { 1012 int error; 1013 error = bus_dmamap_load(esc->sc_dma->sc_dmat, 1014 esc->sc_tail_dmamap, 1015 esc->sc_tail, esc->sc_tail_size, 1016 NULL, BUS_DMA_NOWAIT); 1017 if (error) { 1018 panic("%s: can't load tail DMA map. error = %d, addr=%p, size=0x%08x", 1019 sc->sc_dev.dv_xname, error,esc->sc_tail,esc->sc_tail_size); 1020 } 1021 } 1022 } 1023 #endif 1024 1025 DPRINTF(("%s: setup: %8p %d %8p %d %8p %d %8p %d\n", sc->sc_dev.dv_xname, 1026 *esc->sc_dmaaddr, esc->sc_dmasize, esc->sc_begin, 1027 esc->sc_begin_size, esc->sc_main, esc->sc_main_size, esc->sc_tail, 1028 esc->sc_tail_size)); 1029 } 1030 1031 return (0); 1032 } 1033 1034 #ifdef ESP_DEBUG 1035 /* For debugging */ 1036 void 1037 esp_dma_store(struct ncr53c9x_softc *sc) 1038 { 1039 struct esp_softc *esc = (struct esp_softc *)sc; 1040 char *p = &esp_dma_dump[0]; 1041 1042 p += sprintf(p,"%s: sc_datain=%d\n",sc->sc_dev.dv_xname,esc->sc_datain); 1043 p += sprintf(p,"%s: sc_loaded=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_loaded); 1044 1045 if (esc->sc_dmaaddr) { 1046 p += sprintf(p,"%s: sc_dmaaddr=%p\n",sc->sc_dev.dv_xname,*esc->sc_dmaaddr); 1047 } else { 1048 p += sprintf(p,"%s: sc_dmaaddr=NULL\n",sc->sc_dev.dv_xname); 1049 } 1050 if (esc->sc_dmalen) { 1051 p += sprintf(p,"%s: sc_dmalen=0x%08x\n",sc->sc_dev.dv_xname,*esc->sc_dmalen); 1052 } else { 1053 p += sprintf(p,"%s: sc_dmalen=NULL\n",sc->sc_dev.dv_xname); 1054 } 1055 p += sprintf(p,"%s: sc_dmasize=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_dmasize); 1056 1057 p += sprintf(p,"%s: sc_begin = %p, sc_begin_size = 0x%08x\n", 1058 sc->sc_dev.dv_xname, esc->sc_begin, esc->sc_begin_size); 1059 p += sprintf(p,"%s: sc_main = %p, sc_main_size = 0x%08x\n", 1060 sc->sc_dev.dv_xname, esc->sc_main, esc->sc_main_size); 1061 /* if (esc->sc_main) */ { 1062 int i; 1063 bus_dmamap_t map = esc->sc_main_dmamap; 1064 p += sprintf(p,"%s: sc_main_dmamap. mapsize = 0x%08lx, nsegs = %d\n", 1065 sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs); 1066 for(i=0;i<map->dm_nsegs;i++) { 1067 p += sprintf(p,"%s: map->dm_segs[%d].ds_addr = 0x%08lx, len = 0x%08lx\n", 1068 sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len); 1069 } 1070 } 1071 p += sprintf(p,"%s: sc_tail = %p, sc_tail_size = 0x%08x\n", 1072 sc->sc_dev.dv_xname, esc->sc_tail, esc->sc_tail_size); 1073 /* if (esc->sc_tail) */ { 1074 int i; 1075 bus_dmamap_t map = esc->sc_tail_dmamap; 1076 p += sprintf(p,"%s: sc_tail_dmamap. mapsize = 0x%08lx, nsegs = %d\n", 1077 sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs); 1078 for(i=0;i<map->dm_nsegs;i++) { 1079 p += sprintf(p,"%s: map->dm_segs[%d].ds_addr = 0x%08lx, len = 0x%08lx\n", 1080 sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len); 1081 } 1082 } 1083 } 1084 1085 void 1086 esp_dma_print(struct ncr53c9x_softc *sc) 1087 { 1088 esp_dma_store(sc); 1089 printf("%s",esp_dma_dump); 1090 } 1091 #endif 1092 1093 void 1094 esp_dma_go(struct ncr53c9x_softc *sc) 1095 { 1096 struct esp_softc *esc = (struct esp_softc *)sc; 1097 struct nextdma_softc *nsc = esc->sc_dma; 1098 struct nextdma_status *stat = &nsc->sc_stat; 1099 /* int s = spldma(); */ 1100 1101 #ifdef ESP_DEBUG 1102 if (ndtracep != ndtrace) { 1103 if (ndtraceshow) { 1104 *ndtracep = '\0'; 1105 printf ("esp ndtrace: %s\n", ndtrace); 1106 ndtraceshow = 0; 1107 } else { 1108 DPRINTF (("X")); 1109 } 1110 ndtracep = ndtrace; 1111 } 1112 #endif 1113 1114 DPRINTF(("%s: esp_dma_go(datain = %d)\n", 1115 sc->sc_dev.dv_xname, esc->sc_datain)); 1116 1117 #ifdef ESP_DEBUG 1118 if (esp_debug) esp_dma_print(sc); 1119 else esp_dma_store(sc); 1120 #endif 1121 1122 #ifdef ESP_DEBUG 1123 { 1124 int n = NCR_READ_REG(sc, NCR_FFLAG); 1125 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n", 1126 sc->sc_dev.dv_xname, 1127 n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5)); 1128 } 1129 #endif 1130 1131 /* zero length DMA transfers are boring */ 1132 if (esc->sc_dmasize == 0) { 1133 /* splx(s); */ 1134 return; 1135 } 1136 1137 #if defined(DIAGNOSTIC) 1138 if ((esc->sc_begin_size == 0) && 1139 (esc->sc_main_dmamap->dm_mapsize == 0) && 1140 (esc->sc_tail_dmamap->dm_mapsize == 0)) { 1141 #ifdef ESP_DEBUG 1142 esp_dma_print(sc); 1143 #endif 1144 panic("%s: No DMA requested!",sc->sc_dev.dv_xname); 1145 } 1146 #endif 1147 1148 /* Stuff the fifo with the begin buffer */ 1149 if (esc->sc_datain) { 1150 int i; 1151 DPRINTF(("%s: FIFO read of %d bytes:", 1152 sc->sc_dev.dv_xname,esc->sc_begin_size)); 1153 for(i=0;i<esc->sc_begin_size;i++) { 1154 esc->sc_begin[i]=NCR_READ_REG(sc, NCR_FIFO); 1155 DPRINTF((" %02x",esc->sc_begin[i]&0xff)); 1156 } 1157 DPRINTF(("\n")); 1158 } else { 1159 int i; 1160 DPRINTF(("%s: FIFO write of %d bytes:", 1161 sc->sc_dev.dv_xname,esc->sc_begin_size)); 1162 for(i=0;i<esc->sc_begin_size;i++) { 1163 NCR_WRITE_REG(sc, NCR_FIFO, esc->sc_begin[i]); 1164 DPRINTF((" %02x",esc->sc_begin[i]&0xff)); 1165 } 1166 DPRINTF(("\n")); 1167 } 1168 1169 if (esc->sc_main_dmamap->dm_mapsize) { 1170 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap, 1171 0, esc->sc_main_dmamap->dm_mapsize, 1172 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1173 esc->sc_main_dmamap->dm_xfer_len = 0; 1174 } 1175 1176 if (esc->sc_tail_dmamap->dm_mapsize) { 1177 /* if we are a DMA write cycle, copy the end slop */ 1178 if (!esc->sc_datain) { 1179 memcpy(esc->sc_tail, (char *)*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size, 1180 esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size)); 1181 } 1182 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap, 1183 0, esc->sc_tail_dmamap->dm_mapsize, 1184 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1185 esc->sc_tail_dmamap->dm_xfer_len = 0; 1186 } 1187 1188 stat->nd_exception = 0; 1189 nextdma_start(nsc, (esc->sc_datain ? DMACSR_SETREAD : DMACSR_SETWRITE)); 1190 1191 if (esc->sc_datain) { 1192 NCR_WRITE_REG(sc, ESP_DCTL, 1193 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD); 1194 } else { 1195 NCR_WRITE_REG(sc, ESP_DCTL, 1196 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD); 1197 } 1198 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 1199 1200 NDTRACEIF (if (esc->sc_begin_size) { *ndtracep++ = '1'; *ndtracep++ = 'A' + esc->sc_begin_size; }); 1201 NDTRACEIF (if (esc->sc_main_size) { *ndtracep++ = '2'; *ndtracep++ = '0' + esc->sc_main_dmamap->dm_nsegs; }); 1202 NDTRACEIF (if (esc->sc_tail_size) { *ndtracep++ = '3'; *ndtracep++ = 'A' + esc->sc_tail_size; }); 1203 1204 /* splx(s); */ 1205 } 1206 1207 void 1208 esp_dma_stop(struct ncr53c9x_softc *sc) 1209 { 1210 struct esp_softc *esc = (struct esp_softc *)sc; 1211 nextdma_print(esc->sc_dma); 1212 #ifdef ESP_DEBUG 1213 esp_dma_print(sc); 1214 #endif 1215 #if 1 1216 panic("%s: stop not yet implemented",sc->sc_dev.dv_xname); 1217 #endif 1218 } 1219 1220 int 1221 esp_dma_isactive(struct ncr53c9x_softc *sc) 1222 { 1223 struct esp_softc *esc = (struct esp_softc *)sc; 1224 int r = (esc->sc_dmaaddr != NULL); /* !nextdma_finished(esc->sc_dma); */ 1225 DPRINTF(("esp_dma_isactive = %d\n",r)); 1226 return(r); 1227 } 1228 1229 /****************************************************************/ 1230 1231 int esp_dma_int(void *); 1232 int esp_dma_int(void *arg) 1233 { 1234 void nextdma_rotate(struct nextdma_softc *); 1235 void nextdma_setup_curr_regs(struct nextdma_softc *); 1236 void nextdma_setup_cont_regs(struct nextdma_softc *); 1237 1238 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1239 struct esp_softc *esc = (struct esp_softc *)sc; 1240 struct nextdma_softc *nsc = esc->sc_dma; 1241 struct nextdma_status *stat = &nsc->sc_stat; 1242 unsigned int state; 1243 1244 NDTRACEIF (*ndtracep++ = 'E'); 1245 1246 state = nd_bsr4 (DD_CSR); 1247 1248 #if 1 1249 NDTRACEIF ( 1250 if (state & DMACSR_COMPLETE) *ndtracep++ = 'c'; 1251 if (state & DMACSR_ENABLE) *ndtracep++ = 'e'; 1252 if (state & DMACSR_BUSEXC) *ndtracep++ = 'b'; 1253 if (state & DMACSR_READ) *ndtracep++ = 'r'; 1254 if (state & DMACSR_SUPDATE) *ndtracep++ = 's'; 1255 ); 1256 1257 NDTRACEIF (*ndtracep++ = 'E'); 1258 1259 #ifdef ESP_DEBUG 1260 if (0) if ((state & DMACSR_BUSEXC) && (state & DMACSR_ENABLE)) ndtraceshow++; 1261 if (0) if ((state & DMACSR_SUPDATE)) ndtraceshow++; 1262 #endif 1263 #endif 1264 1265 if ((stat->nd_exception == 0) && (state & DMACSR_COMPLETE) && (state & DMACSR_ENABLE)) { 1266 stat->nd_map->dm_xfer_len += stat->nd_map->dm_segs[stat->nd_idx].ds_len; 1267 } 1268 1269 if ((stat->nd_idx+1) == stat->nd_map->dm_nsegs) { 1270 if (nsc->sc_conf.nd_completed_cb) 1271 (*nsc->sc_conf.nd_completed_cb)(stat->nd_map, nsc->sc_conf.nd_cb_arg); 1272 } 1273 nextdma_rotate(nsc); 1274 1275 if ((state & DMACSR_COMPLETE) && (state & DMACSR_ENABLE)) { 1276 #if 0 1277 int l = nd_bsr4 (DD_LIMIT) & 0x7FFFFFFF; 1278 int s = nd_bsr4 (DD_STOP); 1279 #endif 1280 /* nextdma_setup_cont_regs(nsc); */ 1281 if (stat->nd_map_cont) { 1282 nd_bsw4 (DD_START, stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_addr); 1283 nd_bsw4 (DD_STOP, (stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_addr + 1284 stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_len)); 1285 } 1286 1287 nd_bsw4 (DD_CSR, DMACSR_CLRCOMPLETE | (state & DMACSR_READ ? DMACSR_SETREAD : DMACSR_SETWRITE) | 1288 (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0)); 1289 1290 #if 0 1291 #ifdef ESP_DEBUG 1292 if (state & DMACSR_BUSEXC) { 1293 sprintf (ndtracep, "CE/BUSEXC: %08lX %08X %08X\n", 1294 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr + stat->nd_map->dm_segs[stat->nd_idx].ds_len), 1295 l, s); 1296 ndtracep += strlen (ndtracep); 1297 } 1298 #endif 1299 #endif 1300 } else { 1301 #if 0 1302 if (state & DMACSR_BUSEXC) { 1303 while (nd_bsr4 (DD_NEXT) != 1304 (nd_bsr4 (DD_LIMIT) & 0x7FFFFFFF)) 1305 printf ("Y"); /* DELAY(50); */ 1306 state = nd_bsr4 (DD_CSR); 1307 } 1308 #endif 1309 1310 if (!(state & DMACSR_SUPDATE)) { 1311 nextdma_rotate(nsc); 1312 } else { 1313 nd_bsw4 (DD_CSR, DMACSR_CLRCOMPLETE | 1314 DMACSR_INITBUF | DMACSR_RESET | 1315 (state & DMACSR_READ ? DMACSR_SETREAD : DMACSR_SETWRITE)); 1316 1317 nd_bsw4 (DD_NEXT, stat->nd_map->dm_segs[stat->nd_idx].ds_addr); 1318 nd_bsw4 (DD_LIMIT, 1319 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr + 1320 stat->nd_map->dm_segs[stat->nd_idx].ds_len) | 0/* x80000000 */); 1321 if (stat->nd_map_cont) { 1322 nd_bsw4 (DD_START, 1323 stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_addr); 1324 nd_bsw4 (DD_STOP, 1325 (stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_addr + 1326 stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_len) | 0/* x80000000 */); 1327 } 1328 nd_bsw4 (DD_CSR, DMACSR_SETENABLE | 1329 DMACSR_CLRCOMPLETE | (state & DMACSR_READ ? DMACSR_SETREAD : DMACSR_SETWRITE) | 1330 (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0)); 1331 #if 1 1332 #ifdef ESP_DEBUG 1333 sprintf (ndtracep, "supdate "); 1334 ndtracep += strlen (ndtracep); 1335 sprintf (ndtracep, "%08X %08X %08X %08X ", 1336 nd_bsr4 (DD_NEXT), 1337 nd_bsr4 (DD_LIMIT) & 0x7FFFFFFF, 1338 nd_bsr4 (DD_START), 1339 nd_bsr4 (DD_STOP) & 0x7FFFFFFF); 1340 ndtracep += strlen (ndtracep); 1341 #endif 1342 #endif 1343 stat->nd_exception++; 1344 return(1); 1345 /* NCR_WRITE_REG(sc, ESP_DCTL, ctl); */ 1346 goto restart; 1347 } 1348 1349 if (stat->nd_map) { 1350 #if 1 1351 #ifdef ESP_DEBUG 1352 sprintf (ndtracep, "%08X %08X %08X %08X ", 1353 nd_bsr4 (DD_NEXT), 1354 nd_bsr4 (DD_LIMIT) & 0x7FFFFFFF, 1355 nd_bsr4 (DD_START), 1356 nd_bsr4 (DD_STOP) & 0x7FFFFFFF); 1357 ndtracep += strlen (ndtracep); 1358 #endif 1359 #endif 1360 1361 #if 0 1362 nd_bsw4 (DD_CSR, DMACSR_CLRCOMPLETE | DMACSR_RESET); 1363 1364 nd_bsw4 (DD_CSR, 0); 1365 #endif 1366 #if 1 1367 /* 6/2 */ 1368 nd_bsw4 (DD_CSR, DMACSR_CLRCOMPLETE | 1369 DMACSR_INITBUF | DMACSR_RESET | 1370 (state & DMACSR_READ ? DMACSR_SETREAD : DMACSR_SETWRITE)); 1371 1372 /* nextdma_setup_curr_regs(nsc); */ 1373 nd_bsw4 (DD_NEXT, stat->nd_map->dm_segs[stat->nd_idx].ds_addr); 1374 nd_bsw4 (DD_LIMIT, 1375 (stat->nd_map->dm_segs[stat->nd_idx].ds_addr + 1376 stat->nd_map->dm_segs[stat->nd_idx].ds_len) | 0/* x80000000 */); 1377 /* nextdma_setup_cont_regs(nsc); */ 1378 if (stat->nd_map_cont) { 1379 nd_bsw4 (DD_START, 1380 stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_addr); 1381 nd_bsw4 (DD_STOP, 1382 (stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_addr + 1383 stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_len) | 0/* x80000000 */); 1384 } 1385 1386 nd_bsw4 (DD_CSR, 1387 DMACSR_SETENABLE | (stat->nd_map_cont ? DMACSR_SETSUPDATE : 0) | 1388 (state & DMACSR_READ ? DMACSR_SETREAD : DMACSR_SETWRITE)); 1389 #ifdef ESP_DEBUG 1390 /* ndtraceshow++; */ 1391 #endif 1392 stat->nd_exception++; 1393 return(1); 1394 #endif 1395 /* NCR_WRITE_REG(sc, ESP_DCTL, ctl); */ 1396 goto restart; 1397 restart: 1398 #if 1 1399 #ifdef ESP_DEBUG 1400 sprintf (ndtracep, "restart %08lX %08lX\n", 1401 stat->nd_map->dm_segs[stat->nd_idx].ds_addr, 1402 stat->nd_map->dm_segs[stat->nd_idx].ds_addr + 1403 stat->nd_map->dm_segs[stat->nd_idx].ds_len); 1404 if (stat->nd_map_cont) { 1405 sprintf (ndtracep + strlen(ndtracep) - 1, " %08lX %08lX\n", 1406 stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_addr, 1407 stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_addr + 1408 stat->nd_map_cont->dm_segs[stat->nd_idx_cont].ds_len); 1409 } 1410 ndtracep += strlen (ndtracep); 1411 #endif 1412 #endif 1413 nextdma_print(nsc); 1414 NCR_WRITE_REG(sc, ESP_DCTL, ESPDCTL_16MHZ | ESPDCTL_INTENB); 1415 printf ("ff:%02x tcm:%d tcl:%d esp_dstat:%02x state:%02x step: %02x intr:%02x state:%08X\n", 1416 NCR_READ_REG(sc, NCR_FFLAG), 1417 NCR_READ_REG((sc), NCR_TCM), NCR_READ_REG((sc), NCR_TCL), 1418 NCR_READ_REG(sc, ESP_DSTAT), 1419 NCR_READ_REG(sc, NCR_STAT), NCR_READ_REG(sc, NCR_STEP), 1420 NCR_READ_REG(sc, NCR_INTR), state); 1421 #ifdef ESP_DEBUG 1422 *ndtracep = '\0'; 1423 printf ("ndtrace: %s\n", ndtrace); 1424 #endif 1425 panic("%s: busexc/supdate occurred. Please email this output to chris@pin.lu.", 1426 sc->sc_dev.dv_xname); 1427 #ifdef ESP_DEBUG 1428 ndtraceshow++; 1429 #endif 1430 } else { 1431 nd_bsw4 (DD_CSR, DMACSR_CLRCOMPLETE | DMACSR_RESET); 1432 if (nsc->sc_conf.nd_shutdown_cb) 1433 (*nsc->sc_conf.nd_shutdown_cb)(nsc->sc_conf.nd_cb_arg); 1434 } 1435 } 1436 return (1); 1437 } 1438 1439 /* Internal DMA callback routines */ 1440 bus_dmamap_t 1441 esp_dmacb_continue(void *arg) 1442 { 1443 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1444 struct esp_softc *esc = (struct esp_softc *)sc; 1445 1446 NDTRACEIF (*ndtracep++ = 'x'); 1447 DPRINTF(("%s: DMA continue\n",sc->sc_dev.dv_xname)); 1448 1449 #ifdef DIAGNOSTIC 1450 if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) { 1451 panic("%s: map not loaded in DMA continue callback, datain = %d", 1452 sc->sc_dev.dv_xname,esc->sc_datain); 1453 } 1454 #endif 1455 1456 if ((!(esc->sc_loaded & ESP_LOADED_MAIN)) && 1457 (esc->sc_main_dmamap->dm_mapsize)) { 1458 DPRINTF(("%s: Loading main map\n",sc->sc_dev.dv_xname)); 1459 #if 0 1460 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap, 1461 0, esc->sc_main_dmamap->dm_mapsize, 1462 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1463 esc->sc_main_dmamap->dm_xfer_len = 0; 1464 #endif 1465 esc->sc_loaded |= ESP_LOADED_MAIN; 1466 return(esc->sc_main_dmamap); 1467 } 1468 1469 if ((!(esc->sc_loaded & ESP_LOADED_TAIL)) && 1470 (esc->sc_tail_dmamap->dm_mapsize)) { 1471 DPRINTF(("%s: Loading tail map\n",sc->sc_dev.dv_xname)); 1472 #if 0 1473 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap, 1474 0, esc->sc_tail_dmamap->dm_mapsize, 1475 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1476 esc->sc_tail_dmamap->dm_xfer_len = 0; 1477 #endif 1478 esc->sc_loaded |= ESP_LOADED_TAIL; 1479 return(esc->sc_tail_dmamap); 1480 } 1481 1482 DPRINTF(("%s: not loading map\n",sc->sc_dev.dv_xname)); 1483 return(0); 1484 } 1485 1486 1487 void 1488 esp_dmacb_completed(bus_dmamap_t map, void *arg) 1489 { 1490 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1491 struct esp_softc *esc = (struct esp_softc *)sc; 1492 1493 NDTRACEIF (*ndtracep++ = 'X'); 1494 DPRINTF(("%s: DMA completed\n",sc->sc_dev.dv_xname)); 1495 1496 #ifdef DIAGNOSTIC 1497 if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) { 1498 panic("%s: invalid DMA direction in completed callback, datain = %d", 1499 sc->sc_dev.dv_xname,esc->sc_datain); 1500 } 1501 #endif 1502 1503 #if defined(DIAGNOSTIC) && 0 1504 { 1505 int i; 1506 for(i=0;i<map->dm_nsegs;i++) { 1507 if (map->dm_xfer_len != map->dm_mapsize) { 1508 printf("%s: map->dm_mapsize = %d\n", sc->sc_dev.dv_xname,map->dm_mapsize); 1509 printf("%s: map->dm_nsegs = %d\n", sc->sc_dev.dv_xname,map->dm_nsegs); 1510 printf("%s: map->dm_xfer_len = %d\n", sc->sc_dev.dv_xname,map->dm_xfer_len); 1511 for(i=0;i<map->dm_nsegs;i++) { 1512 printf("%s: map->dm_segs[%d].ds_addr = 0x%08lx\n", 1513 sc->sc_dev.dv_xname,i,map->dm_segs[i].ds_addr); 1514 printf("%s: map->dm_segs[%d].ds_len = %d\n", 1515 sc->sc_dev.dv_xname,i,map->dm_segs[i].ds_len); 1516 } 1517 panic("%s: incomplete DMA transfer",sc->sc_dev.dv_xname); 1518 } 1519 } 1520 } 1521 #endif 1522 1523 if (map == esc->sc_main_dmamap) { 1524 #ifdef DIAGNOSTIC 1525 if ((esc->sc_loaded & ESP_UNLOADED_MAIN) || 1526 !(esc->sc_loaded & ESP_LOADED_MAIN)) { 1527 panic("%s: unexpected completed call for main map",sc->sc_dev.dv_xname); 1528 } 1529 #endif 1530 esc->sc_loaded |= ESP_UNLOADED_MAIN; 1531 } else if (map == esc->sc_tail_dmamap) { 1532 #ifdef DIAGNOSTIC 1533 if ((esc->sc_loaded & ESP_UNLOADED_TAIL) || 1534 !(esc->sc_loaded & ESP_LOADED_TAIL)) { 1535 panic("%s: unexpected completed call for tail map",sc->sc_dev.dv_xname); 1536 } 1537 #endif 1538 esc->sc_loaded |= ESP_UNLOADED_TAIL; 1539 } 1540 #ifdef DIAGNOSTIC 1541 else { 1542 panic("%s: unexpected completed map", sc->sc_dev.dv_xname); 1543 } 1544 #endif 1545 1546 #ifdef ESP_DEBUG 1547 if (esp_debug) { 1548 if (map == esc->sc_main_dmamap) { 1549 printf("%s: completed main map\n",sc->sc_dev.dv_xname); 1550 } else if (map == esc->sc_tail_dmamap) { 1551 printf("%s: completed tail map\n",sc->sc_dev.dv_xname); 1552 } 1553 } 1554 #endif 1555 1556 #if 0 1557 if ((map == esc->sc_tail_dmamap) || 1558 ((esc->sc_tail_size == 0) && (map == esc->sc_main_dmamap))) { 1559 1560 /* Clear the DMAMOD bit in the DCTL register to give control 1561 * back to the scsi chip. 1562 */ 1563 if (esc->sc_datain) { 1564 NCR_WRITE_REG(sc, ESP_DCTL, 1565 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 1566 } else { 1567 NCR_WRITE_REG(sc, ESP_DCTL, 1568 ESPDCTL_16MHZ | ESPDCTL_INTENB); 1569 } 1570 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 1571 } 1572 #endif 1573 1574 1575 #if 0 1576 bus_dmamap_sync(esc->sc_dma->sc_dmat, map, 1577 0, map->dm_mapsize, 1578 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1579 #endif 1580 1581 } 1582 1583 void 1584 esp_dmacb_shutdown(void *arg) 1585 { 1586 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1587 struct esp_softc *esc = (struct esp_softc *)sc; 1588 1589 NDTRACEIF (*ndtracep++ = 'S'); 1590 DPRINTF(("%s: DMA shutdown\n",sc->sc_dev.dv_xname)); 1591 1592 if (esc->sc_loaded == 0) 1593 return; 1594 1595 #if 0 1596 { 1597 /* Clear the DMAMOD bit in the DCTL register to give control 1598 * back to the scsi chip. 1599 */ 1600 if (esc->sc_datain) { 1601 NCR_WRITE_REG(sc, ESP_DCTL, 1602 ESPDCTL_16MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 1603 } else { 1604 NCR_WRITE_REG(sc, ESP_DCTL, 1605 ESPDCTL_16MHZ | ESPDCTL_INTENB); 1606 } 1607 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 1608 } 1609 #endif 1610 1611 DPRINTF(("%s: esp_dma_nest == %d\n",sc->sc_dev.dv_xname,esp_dma_nest)); 1612 1613 /* Stuff the end slop into fifo */ 1614 1615 #ifdef ESP_DEBUG 1616 if (esp_debug) { 1617 1618 int n = NCR_READ_REG(sc, NCR_FFLAG); 1619 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n", 1620 sc->sc_dev.dv_xname,n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5)); 1621 } 1622 #endif 1623 1624 if (esc->sc_main_dmamap->dm_mapsize) { 1625 if (!esc->sc_datain) { /* unpatch the DMA map for write overrun */ 1626 esc->sc_main_dmamap->dm_mapsize -= ESP_DMA_OVERRUN; 1627 esc->sc_main_dmamap->dm_segs[esc->sc_main_dmamap->dm_nsegs - 1].ds_len -= 1628 ESP_DMA_OVERRUN; 1629 } 1630 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_main_dmamap, 1631 0, esc->sc_main_dmamap->dm_mapsize, 1632 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1633 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_main_dmamap); 1634 NDTRACEIF ( 1635 sprintf (ndtracep, "m%ld", esc->sc_main_dmamap->dm_xfer_len); 1636 ndtracep += strlen (ndtracep); 1637 ); 1638 } 1639 1640 if (esc->sc_tail_dmamap->dm_mapsize) { 1641 bus_dmamap_sync(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap, 1642 0, esc->sc_tail_dmamap->dm_mapsize, 1643 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1644 bus_dmamap_unload(esc->sc_dma->sc_dmat, esc->sc_tail_dmamap); 1645 /* copy the tail DMA buffer data for read transfers */ 1646 if (esc->sc_datain) { 1647 memcpy((char *)*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size, 1648 esc->sc_tail, esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size)); 1649 } 1650 NDTRACEIF ( 1651 sprintf (ndtracep, "t%ld", esc->sc_tail_dmamap->dm_xfer_len); 1652 ndtracep += strlen (ndtracep); 1653 ); 1654 } 1655 1656 #ifdef ESP_DEBUG 1657 if (esp_debug) { 1658 printf("%s: dma_shutdown: addr=%p,len=0x%08x,size=0x%08x\n", 1659 sc->sc_dev.dv_xname, 1660 *esc->sc_dmaaddr, *esc->sc_dmalen, esc->sc_dmasize); 1661 if (esp_debug > 10) { 1662 esp_hex_dump(*(esc->sc_dmaaddr),esc->sc_dmasize); 1663 printf("%s: tail=%p,tailbuf=%p,tail_size=0x%08x\n", 1664 sc->sc_dev.dv_xname, 1665 esc->sc_tail, &(esc->sc_tailbuf[0]), esc->sc_tail_size); 1666 esp_hex_dump(&(esc->sc_tailbuf[0]),sizeof(esc->sc_tailbuf)); 1667 } 1668 } 1669 #endif 1670 1671 esc->sc_main = 0; 1672 esc->sc_main_size = 0; 1673 esc->sc_tail = 0; 1674 esc->sc_tail_size = 0; 1675 1676 esc->sc_datain = -1; 1677 /* esc->sc_dmaaddr = 0; */ 1678 /* esc->sc_dmalen = 0; */ 1679 /* esc->sc_dmasize = 0; */ 1680 1681 esc->sc_loaded = 0; 1682 1683 esc->sc_begin = 0; 1684 esc->sc_begin_size = 0; 1685 1686 #ifdef ESP_DEBUG 1687 if (esp_debug) { 1688 char sbuf[256]; 1689 1690 bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)), 1691 NEXT_INTR_BITS, sbuf, sizeof(sbuf)); 1692 printf(" *intrstat = 0x%s\n", sbuf); 1693 1694 bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRMASK)), 1695 NEXT_INTR_BITS, sbuf, sizeof(sbuf)); 1696 printf(" *intrmask = 0x%s\n", sbuf); 1697 } 1698 #endif 1699 } 1700