1 /* $NetBSD: esp.c,v 1.27 2000/06/05 07:59:51 nisimura 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/types.h> 85 #include <sys/param.h> 86 #include <sys/systm.h> 87 #include <sys/kernel.h> 88 #include <sys/errno.h> 89 #include <sys/ioctl.h> 90 #include <sys/device.h> 91 #include <sys/buf.h> 92 #include <sys/proc.h> 93 #include <sys/user.h> 94 #include <sys/queue.h> 95 96 #include <dev/scsipi/scsi_all.h> 97 #include <dev/scsipi/scsipi_all.h> 98 #include <dev/scsipi/scsiconf.h> 99 #include <dev/scsipi/scsi_message.h> 100 101 #include <machine/bus.h> 102 #include <machine/autoconf.h> 103 #include <machine/cpu.h> 104 105 #include <dev/ic/ncr53c9xreg.h> 106 #include <dev/ic/ncr53c9xvar.h> 107 108 #include <next68k/next68k/isr.h> 109 110 #include <next68k/dev/nextdmareg.h> 111 #include <next68k/dev/nextdmavar.h> 112 113 #include "espreg.h" 114 #include "espvar.h" 115 116 #ifdef DEBUG 117 #define ESP_DEBUG 118 #endif 119 120 #ifdef ESP_DEBUG 121 int esp_debug = 0; 122 #define DPRINTF(x) if (esp_debug) printf x; 123 #else 124 #define DPRINTF(x) 125 #endif 126 127 128 void espattach_intio __P((struct device *, struct device *, void *)); 129 int espmatch_intio __P((struct device *, struct cfdata *, void *)); 130 131 /* DMA callbacks */ 132 bus_dmamap_t esp_dmacb_continue __P((void *arg)); 133 void esp_dmacb_completed __P((bus_dmamap_t map, void *arg)); 134 void esp_dmacb_shutdown __P((void *arg)); 135 136 #ifdef ESP_DEBUG 137 char esp_dma_dump[5*1024] = ""; 138 struct ncr53c9x_softc *esp_debug_sc = 0; 139 void esp_dma_store __P((struct ncr53c9x_softc *sc)); 140 void esp_dma_print __P((struct ncr53c9x_softc *sc)); 141 int esp_dma_nest = 0; 142 #endif 143 144 145 /* Linkup to the rest of the kernel */ 146 struct cfattach esp_ca = { 147 sizeof(struct esp_softc), espmatch_intio, espattach_intio 148 }; 149 150 /* 151 * Functions and the switch for the MI code. 152 */ 153 u_char esp_read_reg __P((struct ncr53c9x_softc *, int)); 154 void esp_write_reg __P((struct ncr53c9x_softc *, int, u_char)); 155 int esp_dma_isintr __P((struct ncr53c9x_softc *)); 156 void esp_dma_reset __P((struct ncr53c9x_softc *)); 157 int esp_dma_intr __P((struct ncr53c9x_softc *)); 158 int esp_dma_setup __P((struct ncr53c9x_softc *, caddr_t *, 159 size_t *, int, size_t *)); 160 void esp_dma_go __P((struct ncr53c9x_softc *)); 161 void esp_dma_stop __P((struct ncr53c9x_softc *)); 162 int esp_dma_isactive __P((struct ncr53c9x_softc *)); 163 164 struct ncr53c9x_glue esp_glue = { 165 esp_read_reg, 166 esp_write_reg, 167 esp_dma_isintr, 168 esp_dma_reset, 169 esp_dma_intr, 170 esp_dma_setup, 171 esp_dma_go, 172 esp_dma_stop, 173 esp_dma_isactive, 174 NULL, /* gl_clear_latched_intr */ 175 }; 176 177 #ifdef ESP_DEBUG 178 #define XCHR(x) "0123456789abcdef"[(x) & 0xf] 179 static void 180 esp_hex_dump(unsigned char *pkt, size_t len) 181 { 182 size_t i, j; 183 184 printf("00000000 "); 185 for(i=0; i<len; i++) { 186 printf("%c%c ", XCHR(pkt[i]>>4), XCHR(pkt[i])); 187 if ((i+1) % 16 == 8) { 188 printf(" "); 189 } 190 if ((i+1) % 16 == 0) { 191 printf(" %c", '|'); 192 for(j=0; j<16; j++) { 193 printf("%c", pkt[i-15+j]>=32 && pkt[i-15+j]<127?pkt[i-15+j]:'.'); 194 } 195 printf("%c\n%c%c%c%c%c%c%c%c ", '|', 196 XCHR((i+1)>>28),XCHR((i+1)>>24),XCHR((i+1)>>20),XCHR((i+1)>>16), 197 XCHR((i+1)>>12), XCHR((i+1)>>8), XCHR((i+1)>>4), XCHR(i+1)); 198 } 199 } 200 printf("\n"); 201 } 202 #endif 203 204 int 205 espmatch_intio(parent, cf, aux) 206 struct device *parent; 207 struct cfdata *cf; 208 void *aux; 209 { 210 /* should probably probe here */ 211 /* Should also probably set up data from config */ 212 213 return(1); 214 } 215 216 void 217 espattach_intio(parent, self, aux) 218 struct device *parent, *self; 219 void *aux; 220 { 221 struct esp_softc *esc = (void *)self; 222 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; 223 224 #ifdef ESP_DEBUG 225 esp_debug_sc = sc; 226 #endif 227 228 esc->sc_bst = NEXT68K_INTIO_BUS_SPACE; 229 if (bus_space_map(esc->sc_bst, NEXT_P_SCSI, 230 ESP_DEVICE_SIZE, 0, &esc->sc_bsh)) { 231 panic("\n%s: can't map ncr53c90 registers", 232 sc->sc_dev.dv_xname); 233 } 234 235 sc->sc_id = 7; 236 sc->sc_freq = 20; /* Mhz */ 237 238 /* 239 * Set up glue for MI code early; we use some of it here. 240 */ 241 sc->sc_glue = &esp_glue; 242 243 /* 244 * XXX More of this should be in ncr53c9x_attach(), but 245 * XXX should we really poke around the chip that much in 246 * XXX the MI code? Think about this more... 247 */ 248 249 /* 250 * It is necessary to try to load the 2nd config register here, 251 * to find out what rev the esp chip is, else the ncr53c9x_reset 252 * will not set up the defaults correctly. 253 */ 254 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; 255 sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE; 256 sc->sc_cfg3 = NCRCFG3_CDB; 257 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 258 259 if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) != 260 (NCRCFG2_SCSI2 | NCRCFG2_RPE)) { 261 sc->sc_rev = NCR_VARIANT_ESP100; 262 } else { 263 sc->sc_cfg2 = NCRCFG2_SCSI2; 264 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 265 sc->sc_cfg3 = 0; 266 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 267 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK); 268 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 269 if (NCR_READ_REG(sc, NCR_CFG3) != 270 (NCRCFG3_CDB | NCRCFG3_FCLK)) { 271 sc->sc_rev = NCR_VARIANT_ESP100A; 272 } else { 273 /* NCRCFG2_FE enables > 64K transfers */ 274 sc->sc_cfg2 |= NCRCFG2_FE; 275 sc->sc_cfg3 = 0; 276 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 277 sc->sc_rev = NCR_VARIANT_ESP200; 278 } 279 } 280 281 /* 282 * XXX minsync and maxxfer _should_ be set up in MI code, 283 * XXX but it appears to have some dependency on what sort 284 * XXX of DMA we're hooked up to, etc. 285 */ 286 287 /* 288 * This is the value used to start sync negotiations 289 * Note that the NCR register "SYNCTP" is programmed 290 * in "clocks per byte", and has a minimum value of 4. 291 * The SCSI period used in negotiation is one-fourth 292 * of the time (in nanoseconds) needed to transfer one byte. 293 * Since the chip's clock is given in MHz, we have the following 294 * formula: 4 * period = (1000 / freq) * 4 295 */ 296 sc->sc_minsync = 1000 / sc->sc_freq; 297 298 /* 299 * Alas, we must now modify the value a bit, because it's 300 * only valid when can switch on FASTCLK and FASTSCSI bits 301 * in config register 3... 302 */ 303 switch (sc->sc_rev) { 304 case NCR_VARIANT_ESP100: 305 sc->sc_maxxfer = 64 * 1024; 306 sc->sc_minsync = 0; /* No synch on old chip? */ 307 break; 308 309 case NCR_VARIANT_ESP100A: 310 sc->sc_maxxfer = 64 * 1024; 311 /* Min clocks/byte is 5 */ 312 sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5); 313 break; 314 315 case NCR_VARIANT_ESP200: 316 sc->sc_maxxfer = 16 * 1024 * 1024; 317 /* XXX - do actually set FAST* bits */ 318 break; 319 } 320 321 /* @@@ Some ESP_DCTL bits probably need setting */ 322 NCR_WRITE_REG(sc, ESP_DCTL, 323 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_RESET); 324 DELAY(10); 325 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 326 NCR_WRITE_REG(sc, ESP_DCTL, ESPDCTL_20MHZ | ESPDCTL_INTENB); 327 DELAY(10); 328 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 329 330 /* Set up SCSI DMA */ 331 { 332 esc->sc_scsi_dma.nd_bst = NEXT68K_INTIO_BUS_SPACE; 333 334 if (bus_space_map(esc->sc_scsi_dma.nd_bst, NEXT_P_SCSI_CSR, 335 sizeof(struct dma_dev),0, &esc->sc_scsi_dma.nd_bsh)) { 336 panic("\n%s: can't map scsi DMA registers", 337 sc->sc_dev.dv_xname); 338 } 339 340 esc->sc_scsi_dma.nd_intr = NEXT_I_SCSI_DMA; 341 esc->sc_scsi_dma.nd_shutdown_cb = &esp_dmacb_shutdown; 342 esc->sc_scsi_dma.nd_continue_cb = &esp_dmacb_continue; 343 esc->sc_scsi_dma.nd_completed_cb = &esp_dmacb_completed; 344 esc->sc_scsi_dma.nd_cb_arg = sc; 345 nextdma_config(&esc->sc_scsi_dma); 346 nextdma_init(&esc->sc_scsi_dma); 347 348 #if 0 349 /* Turn on target selection using the `dma' method */ 350 ncr53c9x_dmaselect = 1; 351 #else 352 ncr53c9x_dmaselect = 0; 353 #endif 354 355 esc->sc_datain = -1; 356 esc->sc_dmaaddr = 0; 357 esc->sc_dmalen = 0; 358 esc->sc_dmasize = 0; 359 360 esc->sc_loaded = 0; 361 362 esc->sc_begin = 0; 363 esc->sc_begin_size = 0; 364 365 { 366 int error; 367 if ((error = bus_dmamap_create(esc->sc_scsi_dma.nd_dmat, 368 sc->sc_maxxfer, sc->sc_maxxfer/NBPG, sc->sc_maxxfer, 369 0, BUS_DMA_ALLOCNOW, &esc->sc_main_dmamap)) != 0) { 370 panic("%s: can't create main i/o DMA map, error = %d", 371 sc->sc_dev.dv_xname,error); 372 } 373 } 374 esc->sc_main = 0; 375 esc->sc_main_size = 0; 376 377 { 378 int error; 379 if ((error = bus_dmamap_create(esc->sc_scsi_dma.nd_dmat, 380 ESP_DMA_TAILBUFSIZE, 381 1, ESP_DMA_TAILBUFSIZE, 382 0, BUS_DMA_ALLOCNOW, &esc->sc_tail_dmamap)) != 0) { 383 panic("%s: can't create tail i/o DMA map, error = %d", 384 sc->sc_dev.dv_xname,error); 385 } 386 } 387 esc->sc_tail = 0; 388 esc->sc_tail_size = 0; 389 390 } 391 392 /* Establish interrupt channel */ 393 isrlink_autovec(ncr53c9x_intr, sc, NEXT_I_IPL(NEXT_I_SCSI), 0); 394 INTR_ENABLE(NEXT_I_SCSI); 395 396 /* register interrupt stats */ 397 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL, 398 sc->sc_dev.dv_xname, "intr"); 399 400 /* Do the common parts of attachment. */ 401 ncr53c9x_attach(sc, NULL, NULL); 402 } 403 404 /* 405 * Glue functions. 406 */ 407 408 u_char 409 esp_read_reg(sc, reg) 410 struct ncr53c9x_softc *sc; 411 int reg; 412 { 413 struct esp_softc *esc = (struct esp_softc *)sc; 414 415 return(bus_space_read_1(esc->sc_bst, esc->sc_bsh, reg)); 416 } 417 418 void 419 esp_write_reg(sc, reg, val) 420 struct ncr53c9x_softc *sc; 421 int reg; 422 u_char val; 423 { 424 struct esp_softc *esc = (struct esp_softc *)sc; 425 426 bus_space_write_1(esc->sc_bst, esc->sc_bsh, reg, val); 427 } 428 429 int 430 esp_dma_isintr(sc) 431 struct ncr53c9x_softc *sc; 432 { 433 struct esp_softc *esc = (struct esp_softc *)sc; 434 435 int r = (INTR_OCCURRED(NEXT_I_SCSI)); 436 437 if (r) { 438 439 { 440 int flushcount; 441 int s; 442 s = spldma(); 443 444 flushcount = 0; 445 446 #ifdef ESP_DEBUG 447 esp_dma_nest++; 448 #endif 449 450 DPRINTF(("esp_dma_isintr = 0x%b\n", 451 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),NEXT_INTR_BITS)); 452 453 while (esp_dma_isactive(sc)) { 454 flushcount++; 455 456 #ifdef DIAGNOSTIC 457 r = (INTR_OCCURRED(NEXT_I_SCSI)); 458 if (!r) panic("esp intr enabled but dma failed to flush"); 459 #endif 460 #ifdef DIAGNOSTIC 461 #if 0 462 if ((esc->sc_loaded & (ESP_LOADED_TAIL/* |ESP_UNLOADED_MAIN */)) 463 != (ESP_LOADED_TAIL /* |ESP_UNLOADED_MAIN */)) { 464 if (esc->sc_datain) { 465 NCR_WRITE_REG(sc, ESP_DCTL, 466 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 467 } else { 468 NCR_WRITE_REG(sc, ESP_DCTL, 469 ESPDCTL_20MHZ | ESPDCTL_INTENB); 470 } 471 next_dma_print(&esc->sc_scsi_dma); 472 esp_dma_print(sc); 473 printf("%s: unexpected flush: tc=0x%06x\n", 474 sc->sc_dev.dv_xname, 475 (((sc->sc_cfg2 & NCRCFG2_FE) 476 ? NCR_READ_REG(sc, NCR_TCH) : 0)<<16)| 477 (NCR_READ_REG(sc, NCR_TCM)<<8)| 478 NCR_READ_REG(sc, NCR_TCL)); 479 ncr53c9x_readregs(sc); 480 printf("%s: readregs[intr=%02x,stat=%02x,step=%02x]\n", 481 sc->sc_dev.dv_xname, 482 sc->sc_espintr, sc->sc_espstat, sc->sc_espstep); 483 panic("%s: flushing flushing non-tail dma\n", 484 sc->sc_dev.dv_xname); 485 } 486 #endif 487 #endif 488 DPRINTF(("%s: flushing dma, count = %d\n", sc->sc_dev.dv_xname,flushcount)); 489 if (esc->sc_datain) { 490 NCR_WRITE_REG(sc, ESP_DCTL, 491 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD | ESPDCTL_FLUSH); 492 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 493 NCR_WRITE_REG(sc, ESP_DCTL, 494 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD); 495 } else { 496 NCR_WRITE_REG(sc, ESP_DCTL, 497 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_FLUSH); 498 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 499 NCR_WRITE_REG(sc, ESP_DCTL, 500 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD); 501 } 502 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 503 504 { 505 int nr; 506 nr = nextdma_intr(&esc->sc_scsi_dma); 507 if (nr) { 508 DPRINTF(("nextma_intr = %d\n",nr)); 509 #ifdef DIAGNOSTIC 510 #if 0 511 if (flushcount > 16) { 512 printf("%s: unexpected flushcount %d\n",sc->sc_dev.dv_xname,flushcount); 513 } 514 #endif 515 #endif 516 #ifdef DIAGNOSTIC 517 #if 0 518 if (esp_dma_isactive(sc)) { 519 esp_dma_print(sc); 520 printf("%s: dma still active after a flush with count %d\n", 521 sc->sc_dev.dv_xname,flushcount); 522 523 } 524 #endif 525 #endif 526 flushcount = 0; 527 } 528 } 529 } 530 531 #ifdef ESP_DEBUG 532 esp_dma_nest--; 533 #endif 534 535 splx(s); 536 } 537 538 #ifdef DIAGNOSTIC 539 r = (INTR_OCCURRED(NEXT_I_SCSI)); 540 if (!r) panic("esp intr not enabled after dma flush"); 541 #endif 542 543 /* Clear the DMAMOD bit in the DCTL register, since if this 544 * routine returns true, then the ncr53c9x_intr handler will 545 * be called and needs access to the scsi registers. 546 */ 547 if (esc->sc_datain) { 548 NCR_WRITE_REG(sc, ESP_DCTL, 549 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 550 } else { 551 NCR_WRITE_REG(sc, ESP_DCTL, 552 ESPDCTL_20MHZ | ESPDCTL_INTENB); 553 } 554 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 555 556 } 557 558 return (r); 559 } 560 561 void 562 esp_dma_reset(sc) 563 struct ncr53c9x_softc *sc; 564 { 565 struct esp_softc *esc = (struct esp_softc *)sc; 566 567 DPRINTF(("esp dma reset\n")); 568 569 #ifdef ESP_DEBUG 570 if (esp_debug) { 571 printf(" *intrstat = 0x%b\n", 572 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),NEXT_INTR_BITS); 573 printf(" *intrmask = 0x%b\n", 574 (*(volatile u_long *)IIOV(NEXT_P_INTRMASK)),NEXT_INTR_BITS); 575 } 576 #endif 577 578 /* Clear the DMAMOD bit in the DCTL register: */ 579 NCR_WRITE_REG(sc, ESP_DCTL, 580 ESPDCTL_20MHZ | ESPDCTL_INTENB); 581 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 582 583 nextdma_reset(&esc->sc_scsi_dma); 584 585 esc->sc_datain = -1; 586 esc->sc_dmaaddr = 0; 587 esc->sc_dmalen = 0; 588 esc->sc_dmasize = 0; 589 590 esc->sc_loaded = 0; 591 592 esc->sc_begin = 0; 593 esc->sc_begin_size = 0; 594 595 if (esc->sc_main_dmamap->dm_mapsize) { 596 bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap); 597 } 598 esc->sc_main = 0; 599 esc->sc_main_size = 0; 600 601 if (esc->sc_tail_dmamap->dm_mapsize) { 602 bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap); 603 } 604 esc->sc_tail = 0; 605 esc->sc_tail_size = 0; 606 } 607 608 int 609 esp_dma_intr(sc) 610 struct ncr53c9x_softc *sc; 611 { 612 #ifdef DIAGNOSTIC 613 panic("%s: esp_dma_intr shouldn't be invoked.\n", sc->sc_dev.dv_xname); 614 #endif 615 616 return -1; 617 } 618 619 /* it appears that: 620 * addr and len arguments to this need to be kept up to date 621 * with the status of the transfter. 622 * the dmasize of this is the actual length of the transfer 623 * request, which is guaranteed to be less than maxxfer. 624 * (len may be > maxxfer) 625 */ 626 627 int 628 esp_dma_setup(sc, addr, len, datain, dmasize) 629 struct ncr53c9x_softc *sc; 630 caddr_t *addr; 631 size_t *len; 632 int datain; 633 size_t *dmasize; 634 { 635 struct esp_softc *esc = (struct esp_softc *)sc; 636 637 #ifdef DIAGNOSTIC 638 #ifdef ESP_DEBUG 639 /* if this is a read DMA, pre-fill the buffer with 0xdeadbeef 640 * to identify bogus reads 641 */ 642 if (datain) { 643 int *v = (int *)(*addr); 644 int i; 645 for(i=0;i<((*len)/4);i++) v[i] = 0xdeadbeef; 646 v = (int *)(&(esc->sc_tailbuf[0])); 647 for(i=0;i<((sizeof(esc->sc_tailbuf)/4));i++) v[i] = 0xdeaffeed; 648 } else { 649 int *v; 650 int i; 651 v = (int *)(&(esc->sc_tailbuf[0])); 652 for(i=0;i<((sizeof(esc->sc_tailbuf)/4));i++) v[i] = 0xfeeb1eed; 653 } 654 #endif 655 #endif 656 657 DPRINTF(("esp_dma_setup(0x%08lx,0x%08lx,0x%08lx)\n",*addr,*len,*dmasize)); 658 659 #if 0 660 #ifdef DIAGNOSTIC /* @@@ this is ok sometimes. verify that we handle it ok 661 * and then remove this check 662 */ 663 if (*len != *dmasize) { 664 panic("esp dmalen 0x%lx != size 0x%lx",*len,*dmasize); 665 } 666 #endif 667 #endif 668 669 #ifdef DIAGNOSTIC 670 if ((esc->sc_datain != -1) || 671 (esc->sc_main_dmamap->dm_mapsize != 0) || 672 (esc->sc_tail_dmamap->dm_mapsize != 0) || 673 (esc->sc_dmasize != 0)) { 674 panic("%s: map already loaded in esp_dma_setup\n" 675 "\tdatain = %d\n\tmain_mapsize=%d\n\tail_mapsize=%d\n\tdmasize = %d", 676 sc->sc_dev.dv_xname, esc->sc_datain, 677 esc->sc_main_dmamap->dm_mapsize, 678 esc->sc_tail_dmamap->dm_mapsize, 679 esc->sc_dmasize); 680 } 681 #endif 682 683 /* we are sometimes asked to dma zero bytes, that's easy */ 684 if (*dmasize <= 0) { 685 return(0); 686 } 687 688 /* Save these in case we have to abort DMA */ 689 esc->sc_datain = datain; 690 esc->sc_dmaaddr = addr; 691 esc->sc_dmalen = len; 692 esc->sc_dmasize = *dmasize; 693 694 esc->sc_loaded = 0; 695 696 #define DMA_SCSI_ALIGNMENT 16 697 #define DMA_SCSI_ALIGN(type, addr) \ 698 ((type)(((unsigned)(addr)+DMA_SCSI_ALIGNMENT-1) \ 699 &~(DMA_SCSI_ALIGNMENT-1))) 700 #define DMA_SCSI_ALIGNED(addr) \ 701 (((unsigned)(addr)&(DMA_SCSI_ALIGNMENT-1))==0) 702 703 { 704 size_t slop_bgn_size; /* # bytes to be fifo'd at beginning */ 705 size_t slop_end_size; /* # bytes to be transferred in tail buffer */ 706 707 { 708 u_long bgn = (u_long)(*esc->sc_dmaaddr); 709 u_long end = (u_long)(*esc->sc_dmaaddr+esc->sc_dmasize); 710 711 slop_bgn_size = DMA_SCSI_ALIGNMENT-(bgn % DMA_SCSI_ALIGNMENT); 712 if (slop_bgn_size == DMA_SCSI_ALIGNMENT) slop_bgn_size = 0; 713 slop_end_size = (end % DMA_ENDALIGNMENT); 714 } 715 716 /* Force a minimum slop end size. This ensures that write 717 * requests will overrun, as required to get completion interrupts. 718 * In addition, since the tail buffer is guaranteed to be mapped 719 * in a single dma segment, the overrun won't accidentally 720 * end up in its own segment. 721 */ 722 if (!esc->sc_datain) { 723 #if 0 724 slop_end_size += ESP_DMA_MAXTAIL; 725 #else 726 slop_end_size += 0x10; 727 #endif 728 } 729 730 /* Check to make sure we haven't counted extra slop 731 * as would happen for a very short dma buffer, also 732 * for short buffers, just stuff the entire thing in the tail 733 */ 734 if ((slop_bgn_size+slop_end_size >= esc->sc_dmasize) 735 #if 0 736 || (esc->sc_dmasize <= ESP_DMA_MAXTAIL) 737 #endif 738 ) 739 { 740 slop_bgn_size = 0; 741 slop_end_size = esc->sc_dmasize; 742 } 743 744 /* initialize the fifo buffer */ 745 if (slop_bgn_size) { 746 esc->sc_begin = *esc->sc_dmaaddr; 747 esc->sc_begin_size = slop_bgn_size; 748 } else { 749 esc->sc_begin = 0; 750 esc->sc_begin_size = 0; 751 } 752 753 /* Load the normal DMA map */ 754 { 755 esc->sc_main = *esc->sc_dmaaddr+slop_bgn_size; 756 esc->sc_main_size = (esc->sc_dmasize)-(slop_end_size+slop_bgn_size); 757 758 if (esc->sc_main_size) { 759 int error; 760 error = bus_dmamap_load(esc->sc_scsi_dma.nd_dmat, 761 esc->sc_main_dmamap, 762 esc->sc_main, esc->sc_main_size, 763 NULL, BUS_DMA_NOWAIT); 764 if (error) { 765 panic("%s: can't load main dma map. error = %d, addr=0x%08x, size=0x%08x", 766 sc->sc_dev.dv_xname, error,esc->sc_main,esc->sc_main_size); 767 } 768 #if 0 769 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap, 770 0, esc->sc_main_dmamap->dm_mapsize, 771 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 772 #endif 773 } else { 774 esc->sc_main = 0; 775 } 776 } 777 778 /* Load the tail DMA map */ 779 if (slop_end_size) { 780 esc->sc_tail = DMA_ENDALIGN(caddr_t,esc->sc_tailbuf+slop_end_size)-slop_end_size; 781 /* If the beginning of the tail is not correctly aligned, 782 * we have no choice but to align the start, which might then unalign the end. 783 */ 784 esc->sc_tail = DMA_SCSI_ALIGN(caddr_t,esc->sc_tail); 785 /* So therefore, we change the tail size to be end aligned again. */ 786 esc->sc_tail_size = DMA_ENDALIGN(caddr_t,esc->sc_tail+slop_end_size)-esc->sc_tail; 787 788 /* @@@ next dma overrun lossage */ 789 if (!esc->sc_datain) { 790 esc->sc_tail_size += ESP_DMA_OVERRUN; 791 } 792 793 { 794 int error; 795 error = bus_dmamap_load(esc->sc_scsi_dma.nd_dmat, 796 esc->sc_tail_dmamap, 797 esc->sc_tail, esc->sc_tail_size, 798 NULL, BUS_DMA_NOWAIT); 799 if (error) { 800 panic("%s: can't load tail dma map. error = %d, addr=0x%08x, size=0x%08x", 801 sc->sc_dev.dv_xname, error,esc->sc_tail,esc->sc_tail_size); 802 } 803 #if 0 804 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap, 805 0, esc->sc_tail_dmamap->dm_mapsize, 806 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 807 #endif 808 } 809 } 810 } 811 812 return (0); 813 } 814 815 #ifdef ESP_DEBUG 816 /* For debugging */ 817 void 818 esp_dma_store(sc) 819 struct ncr53c9x_softc *sc; 820 { 821 struct esp_softc *esc = (struct esp_softc *)sc; 822 char *p = &esp_dma_dump[0]; 823 824 p += sprintf(p,"%s: sc_datain=%d\n",sc->sc_dev.dv_xname,esc->sc_datain); 825 p += sprintf(p,"%s: sc_loaded=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_loaded); 826 827 if (esc->sc_dmaaddr) { 828 p += sprintf(p,"%s: sc_dmaaddr=0x%08lx\n",sc->sc_dev.dv_xname,*esc->sc_dmaaddr); 829 } else { 830 p += sprintf(p,"%s: sc_dmaaddr=NULL\n",sc->sc_dev.dv_xname); 831 } 832 if (esc->sc_dmalen) { 833 p += sprintf(p,"%s: sc_dmalen=0x%08lx\n",sc->sc_dev.dv_xname,*esc->sc_dmalen); 834 } else { 835 p += sprintf(p,"%s: sc_dmalen=NULL\n",sc->sc_dev.dv_xname); 836 } 837 p += sprintf(p,"%s: sc_dmasize=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_dmasize); 838 839 p += sprintf(p,"%s: sc_begin = 0x%08x, sc_begin_size = 0x%08x\n", 840 sc->sc_dev.dv_xname, esc->sc_begin, esc->sc_begin_size); 841 p += sprintf(p,"%s: sc_main = 0x%08x, sc_main_size = 0x%08x\n", 842 sc->sc_dev.dv_xname, esc->sc_main, esc->sc_main_size); 843 { 844 int i; 845 bus_dmamap_t map = esc->sc_main_dmamap; 846 p += sprintf(p,"%s: sc_main_dmamap. mapsize = 0x%08x, nsegs = %d\n", 847 sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs); 848 for(i=0;i<map->dm_nsegs;i++) { 849 p += sprintf(p,"%s: map->dm_segs[%d]->ds_addr = 0x%08x, len = 0x%08x\n", 850 sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len); 851 } 852 } 853 p += sprintf(p,"%s: sc_tail = 0x%08x, sc_tail_size = 0x%08x\n", 854 sc->sc_dev.dv_xname, esc->sc_tail, esc->sc_tail_size); 855 { 856 int i; 857 bus_dmamap_t map = esc->sc_tail_dmamap; 858 p += sprintf(p,"%s: sc_tail_dmamap. mapsize = 0x%08x, nsegs = %d\n", 859 sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs); 860 for(i=0;i<map->dm_nsegs;i++) { 861 p += sprintf(p,"%s: map->dm_segs[%d]->ds_addr = 0x%08x, len = 0x%08x\n", 862 sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len); 863 } 864 } 865 } 866 867 void 868 esp_dma_print(sc) 869 struct ncr53c9x_softc *sc; 870 { 871 esp_dma_store(sc); 872 printf("%s",esp_dma_dump); 873 } 874 #endif 875 876 void 877 esp_dma_go(sc) 878 struct ncr53c9x_softc *sc; 879 { 880 struct esp_softc *esc = (struct esp_softc *)sc; 881 882 DPRINTF(("%s: esp_dma_go(datain = %d)\n", 883 sc->sc_dev.dv_xname, esc->sc_datain)); 884 885 #ifdef ESP_DEBUG 886 if (esp_debug) esp_dma_print(sc); 887 else esp_dma_store(sc); 888 #endif 889 890 #ifdef ESP_DEBUG 891 { 892 int n = NCR_READ_REG(sc, NCR_FFLAG); 893 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n", 894 sc->sc_dev.dv_xname, 895 n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5)); 896 } 897 #endif 898 899 /* zero length dma transfers are boring */ 900 if (esc->sc_dmasize == 0) { 901 return; 902 } 903 904 #if defined(DIAGNOSTIC) 905 if ((esc->sc_begin_size == 0) && 906 (esc->sc_main_dmamap->dm_mapsize == 0) && 907 (esc->sc_tail_dmamap->dm_mapsize == 0)) { 908 esp_dma_print(sc); 909 panic("%s: No DMA requested!",sc->sc_dev.dv_xname); 910 } 911 #endif 912 913 /* Stuff the fifo with the begin buffer */ 914 if (esc->sc_datain) { 915 int i; 916 DPRINTF(("%s: FIFO read of %d bytes:", 917 sc->sc_dev.dv_xname,esc->sc_begin_size)); 918 for(i=0;i<esc->sc_begin_size;i++) { 919 esc->sc_begin[i]=NCR_READ_REG(sc, NCR_FIFO); 920 DPRINTF((" %02x",esc->sc_begin[i]&0xff)); 921 } 922 DPRINTF(("\n")); 923 } else { 924 int i; 925 DPRINTF(("%s: FIFO write of %d bytes:", 926 sc->sc_dev.dv_xname,esc->sc_begin_size)); 927 for(i=0;i<esc->sc_begin_size;i++) { 928 NCR_WRITE_REG(sc, NCR_FIFO, esc->sc_begin[i]); 929 DPRINTF((" %02x",esc->sc_begin[i]&0xff)); 930 } 931 DPRINTF(("\n")); 932 } 933 934 /* if we are a dma write cycle, copy the end slop */ 935 if (esc->sc_datain == 0) { 936 memcpy(esc->sc_tail, 937 (*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size), 938 (esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size))); 939 } 940 941 if (esc->sc_main_dmamap->dm_mapsize) { 942 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap, 943 0, esc->sc_main_dmamap->dm_mapsize, 944 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 945 } 946 947 if (esc->sc_tail_dmamap->dm_mapsize) { 948 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap, 949 0, esc->sc_tail_dmamap->dm_mapsize, 950 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 951 } 952 953 nextdma_start(&esc->sc_scsi_dma, 954 (esc->sc_datain ? DMACSR_SETREAD : DMACSR_SETWRITE)); 955 956 if (esc->sc_datain) { 957 NCR_WRITE_REG(sc, ESP_DCTL, 958 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD); 959 } else { 960 NCR_WRITE_REG(sc, ESP_DCTL, 961 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD); 962 } 963 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 964 } 965 966 void 967 esp_dma_stop(sc) 968 struct ncr53c9x_softc *sc; 969 { 970 panic("Not yet implemented"); 971 } 972 973 int 974 esp_dma_isactive(sc) 975 struct ncr53c9x_softc *sc; 976 { 977 struct esp_softc *esc = (struct esp_softc *)sc; 978 int r = !nextdma_finished(&esc->sc_scsi_dma); 979 DPRINTF(("esp_dma_isactive = %d\n",r)); 980 return(r); 981 } 982 983 /****************************************************************/ 984 985 /* Internal dma callback routines */ 986 bus_dmamap_t 987 esp_dmacb_continue(arg) 988 void *arg; 989 { 990 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 991 struct esp_softc *esc = (struct esp_softc *)sc; 992 993 DPRINTF(("%s: dma continue\n",sc->sc_dev.dv_xname)); 994 995 #ifdef DIAGNOSTIC 996 if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) { 997 panic("%s: map not loaded in dma continue callback, datain = %d", 998 sc->sc_dev.dv_xname,esc->sc_datain); 999 } 1000 #endif 1001 1002 if ((!(esc->sc_loaded & ESP_LOADED_MAIN)) && 1003 (esc->sc_main_dmamap->dm_mapsize)) { 1004 DPRINTF(("%s: Loading main map\n",sc->sc_dev.dv_xname)); 1005 #if 0 1006 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap, 1007 0, esc->sc_main_dmamap->dm_mapsize, 1008 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1009 #endif 1010 esc->sc_loaded |= ESP_LOADED_MAIN; 1011 return(esc->sc_main_dmamap); 1012 } 1013 1014 if ((!(esc->sc_loaded & ESP_LOADED_TAIL)) && 1015 (esc->sc_tail_dmamap->dm_mapsize)) { 1016 DPRINTF(("%s: Loading tail map\n",sc->sc_dev.dv_xname)); 1017 #if 0 1018 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap, 1019 0, esc->sc_tail_dmamap->dm_mapsize, 1020 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1021 #endif 1022 esc->sc_loaded |= ESP_LOADED_TAIL; 1023 return(esc->sc_tail_dmamap); 1024 } 1025 1026 DPRINTF(("%s: not loading map\n",sc->sc_dev.dv_xname)); 1027 return(0); 1028 } 1029 1030 1031 void 1032 esp_dmacb_completed(map, arg) 1033 bus_dmamap_t map; 1034 void *arg; 1035 { 1036 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1037 struct esp_softc *esc = (struct esp_softc *)sc; 1038 1039 DPRINTF(("%s: dma completed\n",sc->sc_dev.dv_xname)); 1040 1041 #ifdef DIAGNOSTIC 1042 if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) { 1043 panic("%s: invalid dma direction in completed callback, datain = %d", 1044 sc->sc_dev.dv_xname,esc->sc_datain); 1045 } 1046 #endif 1047 1048 if (map == esc->sc_main_dmamap) { 1049 #ifdef DIAGNOSTIC 1050 if ((esc->sc_loaded & ESP_UNLOADED_MAIN) || 1051 !(esc->sc_loaded & ESP_LOADED_MAIN)) { 1052 panic("%s: unexpected completed call for main map\n",sc->sc_dev.dv_xname); 1053 } 1054 #endif 1055 esc->sc_loaded |= ESP_UNLOADED_MAIN; 1056 } else if (map == esc->sc_tail_dmamap) { 1057 #ifdef DIAGNOSTIC 1058 if ((esc->sc_loaded & ESP_UNLOADED_TAIL) || 1059 !(esc->sc_loaded & ESP_LOADED_TAIL)) { 1060 panic("%s: unexpected completed call for tail map\n",sc->sc_dev.dv_xname); 1061 } 1062 #endif 1063 esc->sc_loaded |= ESP_UNLOADED_TAIL; 1064 } 1065 #ifdef DIAGNOSTIC 1066 else { 1067 panic("%s: unexpected completed map", sc->sc_dev.dv_xname); 1068 } 1069 #endif 1070 1071 #ifdef ESP_DEBUG 1072 if (esp_debug) { 1073 if (map == esc->sc_main_dmamap) { 1074 printf("%s: completed main map\n",sc->sc_dev.dv_xname); 1075 } else if (map == esc->sc_tail_dmamap) { 1076 printf("%s: completed tail map\n",sc->sc_dev.dv_xname); 1077 } 1078 } 1079 #endif 1080 1081 #if 0 1082 if ((map == esc->sc_tail_dmamap) || 1083 ((esc->sc_tail_size == 0) && (map == esc->sc_main_dmamap))) { 1084 1085 /* Clear the DMAMOD bit in the DCTL register to give control 1086 * back to the scsi chip. 1087 */ 1088 if (esc->sc_datain) { 1089 NCR_WRITE_REG(sc, ESP_DCTL, 1090 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 1091 } else { 1092 NCR_WRITE_REG(sc, ESP_DCTL, 1093 ESPDCTL_20MHZ | ESPDCTL_INTENB); 1094 } 1095 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 1096 } 1097 #endif 1098 1099 1100 #if 0 1101 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, map, 1102 0, map->dm_mapsize, 1103 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1104 #endif 1105 1106 } 1107 1108 void 1109 esp_dmacb_shutdown(arg) 1110 void *arg; 1111 { 1112 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1113 struct esp_softc *esc = (struct esp_softc *)sc; 1114 1115 DPRINTF(("%s: dma shutdown\n",sc->sc_dev.dv_xname)); 1116 1117 #if 0 1118 { 1119 /* Clear the DMAMOD bit in the DCTL register to give control 1120 * back to the scsi chip. 1121 */ 1122 if (esc->sc_datain) { 1123 NCR_WRITE_REG(sc, ESP_DCTL, 1124 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 1125 } else { 1126 NCR_WRITE_REG(sc, ESP_DCTL, 1127 ESPDCTL_20MHZ | ESPDCTL_INTENB); 1128 } 1129 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 1130 } 1131 #endif 1132 1133 DPRINTF(("%s: esp_dma_nest == %d\n",sc->sc_dev.dv_xname,esp_dma_nest)); 1134 1135 /* Stuff the end slop into fifo */ 1136 1137 #ifdef ESP_DEBUG 1138 if (esp_debug) { 1139 1140 int n = NCR_READ_REG(sc, NCR_FFLAG); 1141 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n", 1142 sc->sc_dev.dv_xname,n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5)); 1143 } 1144 #endif 1145 1146 if (esc->sc_main_dmamap->dm_mapsize) { 1147 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap, 1148 0, esc->sc_main_dmamap->dm_mapsize, 1149 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1150 bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap); 1151 } 1152 1153 if (esc->sc_tail_dmamap->dm_mapsize) { 1154 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap, 1155 0, esc->sc_tail_dmamap->dm_mapsize, 1156 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1157 bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap); 1158 } 1159 1160 /* copy the tail dma buffer data for read transfers */ 1161 if (esc->sc_datain == 1) { 1162 memcpy((*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size), 1163 esc->sc_tail, 1164 (esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size))); 1165 } 1166 1167 #ifdef ESP_DEBUG 1168 if (esp_debug) { 1169 printf("%s: dma_shutdown: addr=0x%08lx,len=0x%08lx,size=0x%08lx\n", 1170 sc->sc_dev.dv_xname, 1171 *esc->sc_dmaaddr, *esc->sc_dmalen, esc->sc_dmasize); 1172 if (esp_debug > 10) { 1173 esp_hex_dump(*(esc->sc_dmaaddr),esc->sc_dmasize); 1174 printf("%s: tail=0x%08lx,tailbuf=0x%08lx,tail_size=0x%08lx\n", 1175 sc->sc_dev.dv_xname, 1176 esc->sc_tail, &(esc->sc_tailbuf[0]), esc->sc_tail_size); 1177 esp_hex_dump(&(esc->sc_tailbuf[0]),sizeof(esc->sc_tailbuf)); 1178 } 1179 } 1180 #endif 1181 1182 *(esc->sc_dmaaddr) += esc->sc_dmasize; 1183 *(esc->sc_dmalen) -= esc->sc_dmasize; 1184 1185 esc->sc_main = 0; 1186 esc->sc_main_size = 0; 1187 esc->sc_tail = 0; 1188 esc->sc_tail_size = 0; 1189 1190 esc->sc_datain = -1; 1191 esc->sc_dmaaddr = 0; 1192 esc->sc_dmalen = 0; 1193 esc->sc_dmasize = 0; 1194 1195 esc->sc_loaded = 0; 1196 1197 esc->sc_begin = 0; 1198 esc->sc_begin_size = 0; 1199 1200 #ifdef ESP_DEBUG 1201 if (esp_debug) { 1202 printf(" *intrstat = 0x%b\n", 1203 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),NEXT_INTR_BITS); 1204 printf(" *intrmask = 0x%b\n", 1205 (*(volatile u_long *)IIOV(NEXT_P_INTRMASK)),NEXT_INTR_BITS); 1206 } 1207 #endif 1208 } 1209