1 /* $NetBSD: esp.c,v 1.35 2001/05/23 02:14:07 chs 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 DD_SIZE,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 sc->sc_features |= NCR_F_DMASELECT; 351 #endif 352 353 esc->sc_datain = -1; 354 esc->sc_dmaaddr = 0; 355 esc->sc_dmalen = 0; 356 esc->sc_dmasize = 0; 357 358 esc->sc_loaded = 0; 359 360 esc->sc_begin = 0; 361 esc->sc_begin_size = 0; 362 363 { 364 int error; 365 if ((error = bus_dmamap_create(esc->sc_scsi_dma.nd_dmat, 366 sc->sc_maxxfer, sc->sc_maxxfer/NBPG+1, sc->sc_maxxfer, 367 0, BUS_DMA_ALLOCNOW, &esc->sc_main_dmamap)) != 0) { 368 panic("%s: can't create main i/o DMA map, error = %d", 369 sc->sc_dev.dv_xname,error); 370 } 371 } 372 esc->sc_main = 0; 373 esc->sc_main_size = 0; 374 375 { 376 int error; 377 if ((error = bus_dmamap_create(esc->sc_scsi_dma.nd_dmat, 378 ESP_DMA_TAILBUFSIZE, 379 1, ESP_DMA_TAILBUFSIZE, 380 0, BUS_DMA_ALLOCNOW, &esc->sc_tail_dmamap)) != 0) { 381 panic("%s: can't create tail i/o DMA map, error = %d", 382 sc->sc_dev.dv_xname,error); 383 } 384 } 385 esc->sc_tail = 0; 386 esc->sc_tail_size = 0; 387 388 } 389 390 /* Establish interrupt channel */ 391 isrlink_autovec(ncr53c9x_intr, sc, NEXT_I_IPL(NEXT_I_SCSI), 0); 392 INTR_ENABLE(NEXT_I_SCSI); 393 394 /* register interrupt stats */ 395 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL, 396 sc->sc_dev.dv_xname, "intr"); 397 398 /* Do the common parts of attachment. */ 399 ncr53c9x_attach(sc); 400 } 401 402 /* 403 * Glue functions. 404 */ 405 406 u_char 407 esp_read_reg(sc, reg) 408 struct ncr53c9x_softc *sc; 409 int reg; 410 { 411 struct esp_softc *esc = (struct esp_softc *)sc; 412 413 return(bus_space_read_1(esc->sc_bst, esc->sc_bsh, reg)); 414 } 415 416 void 417 esp_write_reg(sc, reg, val) 418 struct ncr53c9x_softc *sc; 419 int reg; 420 u_char val; 421 { 422 struct esp_softc *esc = (struct esp_softc *)sc; 423 424 bus_space_write_1(esc->sc_bst, esc->sc_bsh, reg, val); 425 } 426 427 int 428 esp_dma_isintr(sc) 429 struct ncr53c9x_softc *sc; 430 { 431 struct esp_softc *esc = (struct esp_softc *)sc; 432 433 int r = (INTR_OCCURRED(NEXT_I_SCSI)); 434 435 if (r) { 436 437 { 438 int flushcount; 439 int s; 440 s = spldma(); 441 442 flushcount = 0; 443 444 #ifdef ESP_DEBUG 445 esp_dma_nest++; 446 447 if (esp_debug) { 448 char sbuf[256]; 449 450 bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)), 451 NEXT_INTR_BITS, sbuf, sizeof(sbuf)); 452 printf("esp_dma_isintr = 0x%s\n", sbuf); 453 } 454 #endif 455 456 while (esp_dma_isactive(sc)) { 457 flushcount++; 458 459 #ifdef DIAGNOSTIC 460 r = (INTR_OCCURRED(NEXT_I_SCSI)); 461 if (!r) panic("esp intr enabled but dma failed to flush"); 462 #endif 463 #ifdef DIAGNOSTIC 464 #if 0 465 if ((esc->sc_loaded & (ESP_LOADED_TAIL/* |ESP_UNLOADED_MAIN */)) 466 != (ESP_LOADED_TAIL /* |ESP_UNLOADED_MAIN */)) { 467 if (esc->sc_datain) { 468 NCR_WRITE_REG(sc, ESP_DCTL, 469 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 470 } else { 471 NCR_WRITE_REG(sc, ESP_DCTL, 472 ESPDCTL_20MHZ | ESPDCTL_INTENB); 473 } 474 next_dma_print(&esc->sc_scsi_dma); 475 esp_dma_print(sc); 476 printf("%s: unexpected flush: tc=0x%06x\n", 477 sc->sc_dev.dv_xname, 478 (((sc->sc_cfg2 & NCRCFG2_FE) 479 ? NCR_READ_REG(sc, NCR_TCH) : 0)<<16)| 480 (NCR_READ_REG(sc, NCR_TCM)<<8)| 481 NCR_READ_REG(sc, NCR_TCL)); 482 ncr53c9x_readregs(sc); 483 printf("%s: readregs[intr=%02x,stat=%02x,step=%02x]\n", 484 sc->sc_dev.dv_xname, 485 sc->sc_espintr, sc->sc_espstat, sc->sc_espstep); 486 panic("%s: flushing flushing non-tail dma\n", 487 sc->sc_dev.dv_xname); 488 } 489 #endif 490 #endif 491 DPRINTF(("%s: flushing dma, count = %d\n", sc->sc_dev.dv_xname,flushcount)); 492 if (esc->sc_datain) { 493 NCR_WRITE_REG(sc, ESP_DCTL, 494 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD | ESPDCTL_FLUSH); 495 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 496 NCR_WRITE_REG(sc, ESP_DCTL, 497 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD); 498 } else { 499 NCR_WRITE_REG(sc, ESP_DCTL, 500 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_FLUSH); 501 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 502 NCR_WRITE_REG(sc, ESP_DCTL, 503 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD); 504 } 505 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 506 507 { 508 int nr; 509 nr = nextdma_intr(&esc->sc_scsi_dma); 510 if (nr) { 511 DPRINTF(("nextma_intr = %d\n",nr)); 512 #ifdef DIAGNOSTIC 513 if (flushcount > 4) { 514 printf("%s: unexpected flushcount %d\n",sc->sc_dev.dv_xname,flushcount); 515 } 516 #endif 517 #ifdef DIAGNOSTIC 518 #if 0 519 if (esp_dma_isactive(sc)) { 520 esp_dma_print(sc); 521 printf("%s: dma still active after a flush with count %d\n", 522 sc->sc_dev.dv_xname,flushcount); 523 524 } 525 #endif 526 #endif 527 flushcount = 0; 528 } 529 } 530 } 531 532 #ifdef ESP_DEBUG 533 esp_dma_nest--; 534 #endif 535 536 splx(s); 537 } 538 539 #ifdef DIAGNOSTIC 540 r = (INTR_OCCURRED(NEXT_I_SCSI)); 541 if (!r) panic("esp intr not enabled after dma flush"); 542 #endif 543 544 /* Clear the DMAMOD bit in the DCTL register, since if this 545 * routine returns true, then the ncr53c9x_intr handler will 546 * be called and needs access to the scsi registers. 547 */ 548 if (esc->sc_datain) { 549 NCR_WRITE_REG(sc, ESP_DCTL, 550 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 551 } else { 552 NCR_WRITE_REG(sc, ESP_DCTL, 553 ESPDCTL_20MHZ | ESPDCTL_INTENB); 554 } 555 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 556 557 } 558 559 return (r); 560 } 561 562 void 563 esp_dma_reset(sc) 564 struct ncr53c9x_softc *sc; 565 { 566 struct esp_softc *esc = (struct esp_softc *)sc; 567 568 DPRINTF(("esp dma reset\n")); 569 570 #ifdef ESP_DEBUG 571 if (esp_debug) { 572 char sbuf[256]; 573 574 bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)), 575 NEXT_INTR_BITS, sbuf, sizeof(sbuf)); 576 printf(" *intrstat = 0x%s\n", sbuf); 577 578 bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRMASK)), 579 NEXT_INTR_BITS, sbuf, sizeof(sbuf)); 580 printf(" *intrmask = 0x%s\n", sbuf); 581 } 582 #endif 583 584 /* Clear the DMAMOD bit in the DCTL register: */ 585 NCR_WRITE_REG(sc, ESP_DCTL, 586 ESPDCTL_20MHZ | ESPDCTL_INTENB); 587 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 588 589 nextdma_reset(&esc->sc_scsi_dma); 590 591 esc->sc_datain = -1; 592 esc->sc_dmaaddr = 0; 593 esc->sc_dmalen = 0; 594 esc->sc_dmasize = 0; 595 596 esc->sc_loaded = 0; 597 598 esc->sc_begin = 0; 599 esc->sc_begin_size = 0; 600 601 if (esc->sc_main_dmamap->dm_mapsize) { 602 bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap); 603 } 604 esc->sc_main = 0; 605 esc->sc_main_size = 0; 606 607 if (esc->sc_tail_dmamap->dm_mapsize) { 608 bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap); 609 } 610 esc->sc_tail = 0; 611 esc->sc_tail_size = 0; 612 } 613 614 int 615 esp_dma_intr(sc) 616 struct ncr53c9x_softc *sc; 617 { 618 #ifdef DIAGNOSTIC 619 panic("%s: esp_dma_intr shouldn't be invoked.\n", sc->sc_dev.dv_xname); 620 #endif 621 622 return -1; 623 } 624 625 /* it appears that: 626 * addr and len arguments to this need to be kept up to date 627 * with the status of the transfter. 628 * the dmasize of this is the actual length of the transfer 629 * request, which is guaranteed to be less than maxxfer. 630 * (len may be > maxxfer) 631 */ 632 633 int 634 esp_dma_setup(sc, addr, len, datain, dmasize) 635 struct ncr53c9x_softc *sc; 636 caddr_t *addr; 637 size_t *len; 638 int datain; 639 size_t *dmasize; 640 { 641 struct esp_softc *esc = (struct esp_softc *)sc; 642 643 #ifdef DIAGNOSTIC 644 #ifdef ESP_DEBUG 645 /* if this is a read DMA, pre-fill the buffer with 0xdeadbeef 646 * to identify bogus reads 647 */ 648 if (datain) { 649 int *v = (int *)(*addr); 650 int i; 651 for(i=0;i<((*len)/4);i++) v[i] = 0xdeadbeef; 652 v = (int *)(&(esc->sc_tailbuf[0])); 653 for(i=0;i<((sizeof(esc->sc_tailbuf)/4));i++) v[i] = 0xdeaffeed; 654 } else { 655 int *v; 656 int i; 657 v = (int *)(&(esc->sc_tailbuf[0])); 658 for(i=0;i<((sizeof(esc->sc_tailbuf)/4));i++) v[i] = 0xfeeb1eed; 659 } 660 #endif 661 #endif 662 663 DPRINTF(("esp_dma_setup(%p,0x%08x,0x%08x)\n",*addr,*len,*dmasize)); 664 665 #if 0 666 #ifdef DIAGNOSTIC /* @@@ this is ok sometimes. verify that we handle it ok 667 * and then remove this check 668 */ 669 if (*len != *dmasize) { 670 panic("esp dmalen 0x%lx != size 0x%lx",*len,*dmasize); 671 } 672 #endif 673 #endif 674 675 #ifdef DIAGNOSTIC 676 if ((esc->sc_datain != -1) || 677 (esc->sc_main_dmamap->dm_mapsize != 0) || 678 (esc->sc_tail_dmamap->dm_mapsize != 0) || 679 (esc->sc_dmasize != 0)) { 680 panic("%s: map already loaded in esp_dma_setup\n" 681 "\tdatain = %d\n\tmain_mapsize=%ld\n\tail_mapsize=%ld\n\tdmasize = %d", 682 sc->sc_dev.dv_xname, esc->sc_datain, 683 esc->sc_main_dmamap->dm_mapsize, 684 esc->sc_tail_dmamap->dm_mapsize, 685 esc->sc_dmasize); 686 } 687 #endif 688 689 /* we are sometimes asked to dma zero bytes, that's easy */ 690 if (*dmasize <= 0) { 691 return(0); 692 } 693 694 /* Save these in case we have to abort DMA */ 695 esc->sc_datain = datain; 696 esc->sc_dmaaddr = addr; 697 esc->sc_dmalen = len; 698 esc->sc_dmasize = *dmasize; 699 700 esc->sc_loaded = 0; 701 702 #define DMA_SCSI_ALIGNMENT 16 703 #define DMA_SCSI_ALIGN(type, addr) \ 704 ((type)(((unsigned)(addr)+DMA_SCSI_ALIGNMENT-1) \ 705 &~(DMA_SCSI_ALIGNMENT-1))) 706 #define DMA_SCSI_ALIGNED(addr) \ 707 (((unsigned)(addr)&(DMA_SCSI_ALIGNMENT-1))==0) 708 709 { 710 size_t slop_bgn_size; /* # bytes to be fifo'd at beginning */ 711 size_t slop_end_size; /* # bytes to be transferred in tail buffer */ 712 713 { 714 u_long bgn = (u_long)(*esc->sc_dmaaddr); 715 u_long end = (u_long)(*esc->sc_dmaaddr+esc->sc_dmasize); 716 717 slop_bgn_size = DMA_SCSI_ALIGNMENT-(bgn % DMA_SCSI_ALIGNMENT); 718 if (slop_bgn_size == DMA_SCSI_ALIGNMENT) slop_bgn_size = 0; 719 slop_end_size = (end % DMA_ENDALIGNMENT); 720 } 721 722 /* Force a minimum slop end size. This ensures that write 723 * requests will overrun, as required to get completion interrupts. 724 * In addition, since the tail buffer is guaranteed to be mapped 725 * in a single dma segment, the overrun won't accidentally 726 * end up in its own segment. 727 */ 728 if (!esc->sc_datain) { 729 #if 0 730 slop_end_size += ESP_DMA_MAXTAIL; 731 #else 732 slop_end_size += 0x10; 733 #endif 734 } 735 736 /* Check to make sure we haven't counted extra slop 737 * as would happen for a very short dma buffer, also 738 * for short buffers, just stuff the entire thing in the tail 739 */ 740 if ((slop_bgn_size+slop_end_size >= esc->sc_dmasize) 741 #if 0 742 || (esc->sc_dmasize <= ESP_DMA_MAXTAIL) 743 #endif 744 ) 745 { 746 slop_bgn_size = 0; 747 slop_end_size = esc->sc_dmasize; 748 } 749 750 /* initialize the fifo buffer */ 751 if (slop_bgn_size) { 752 esc->sc_begin = *esc->sc_dmaaddr; 753 esc->sc_begin_size = slop_bgn_size; 754 } else { 755 esc->sc_begin = 0; 756 esc->sc_begin_size = 0; 757 } 758 759 /* Load the normal DMA map */ 760 { 761 esc->sc_main = *esc->sc_dmaaddr+slop_bgn_size; 762 esc->sc_main_size = (esc->sc_dmasize)-(slop_end_size+slop_bgn_size); 763 764 if (esc->sc_main_size) { 765 int error; 766 error = bus_dmamap_load(esc->sc_scsi_dma.nd_dmat, 767 esc->sc_main_dmamap, 768 esc->sc_main, esc->sc_main_size, 769 NULL, BUS_DMA_NOWAIT); 770 if (error) { 771 #ifdef ESP_DEBUG 772 printf("%s: esc->sc_main_dmamap->_dm_size = %ld\n", 773 sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_size); 774 printf("%s: esc->sc_main_dmamap->_dm_segcnt = %d\n", 775 sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_segcnt); 776 printf("%s: esc->sc_main_dmamap->_dm_maxsegsz = %ld\n", 777 sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_maxsegsz); 778 printf("%s: esc->sc_main_dmamap->_dm_boundary = %ld\n", 779 sc->sc_dev.dv_xname,esc->sc_main_dmamap->_dm_boundary); 780 esp_dma_print(sc); 781 #endif 782 panic("%s: can't load main dma map. error = %d, addr=%p, size=0x%08x", 783 sc->sc_dev.dv_xname, error,esc->sc_main,esc->sc_main_size); 784 } 785 #if 0 786 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap, 787 0, esc->sc_main_dmamap->dm_mapsize, 788 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 789 esc->sc_main_dmamap->dm_xfer_len = 0; 790 #endif 791 } else { 792 esc->sc_main = 0; 793 } 794 } 795 796 /* Load the tail DMA map */ 797 if (slop_end_size) { 798 esc->sc_tail = DMA_ENDALIGN(caddr_t,esc->sc_tailbuf+slop_end_size)-slop_end_size; 799 /* If the beginning of the tail is not correctly aligned, 800 * we have no choice but to align the start, which might then unalign the end. 801 */ 802 esc->sc_tail = DMA_SCSI_ALIGN(caddr_t,esc->sc_tail); 803 /* So therefore, we change the tail size to be end aligned again. */ 804 esc->sc_tail_size = DMA_ENDALIGN(caddr_t,esc->sc_tail+slop_end_size)-esc->sc_tail; 805 806 /* @@@ next dma overrun lossage */ 807 if (!esc->sc_datain) { 808 esc->sc_tail_size += ESP_DMA_OVERRUN; 809 } 810 811 { 812 int error; 813 error = bus_dmamap_load(esc->sc_scsi_dma.nd_dmat, 814 esc->sc_tail_dmamap, 815 esc->sc_tail, esc->sc_tail_size, 816 NULL, BUS_DMA_NOWAIT); 817 if (error) { 818 panic("%s: can't load tail dma map. error = %d, addr=%p, size=0x%08x", 819 sc->sc_dev.dv_xname, error,esc->sc_tail,esc->sc_tail_size); 820 } 821 #if 0 822 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap, 823 0, esc->sc_tail_dmamap->dm_mapsize, 824 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 825 esc->sc_tail_dmamap->dm_xfer_len = 0; 826 #endif 827 } 828 } 829 } 830 831 return (0); 832 } 833 834 #ifdef ESP_DEBUG 835 /* For debugging */ 836 void 837 esp_dma_store(sc) 838 struct ncr53c9x_softc *sc; 839 { 840 struct esp_softc *esc = (struct esp_softc *)sc; 841 char *p = &esp_dma_dump[0]; 842 843 p += sprintf(p,"%s: sc_datain=%d\n",sc->sc_dev.dv_xname,esc->sc_datain); 844 p += sprintf(p,"%s: sc_loaded=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_loaded); 845 846 if (esc->sc_dmaaddr) { 847 p += sprintf(p,"%s: sc_dmaaddr=%p\n",sc->sc_dev.dv_xname,*esc->sc_dmaaddr); 848 } else { 849 p += sprintf(p,"%s: sc_dmaaddr=NULL\n",sc->sc_dev.dv_xname); 850 } 851 if (esc->sc_dmalen) { 852 p += sprintf(p,"%s: sc_dmalen=0x%08x\n",sc->sc_dev.dv_xname,*esc->sc_dmalen); 853 } else { 854 p += sprintf(p,"%s: sc_dmalen=NULL\n",sc->sc_dev.dv_xname); 855 } 856 p += sprintf(p,"%s: sc_dmasize=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_dmasize); 857 858 p += sprintf(p,"%s: sc_begin = %p, sc_begin_size = 0x%08x\n", 859 sc->sc_dev.dv_xname, esc->sc_begin, esc->sc_begin_size); 860 p += sprintf(p,"%s: sc_main = %p, sc_main_size = 0x%08x\n", 861 sc->sc_dev.dv_xname, esc->sc_main, esc->sc_main_size); 862 { 863 int i; 864 bus_dmamap_t map = esc->sc_main_dmamap; 865 p += sprintf(p,"%s: sc_main_dmamap. mapsize = 0x%08lx, nsegs = %d\n", 866 sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs); 867 for(i=0;i<map->dm_nsegs;i++) { 868 p += sprintf(p,"%s: map->dm_segs[%d].ds_addr = 0x%08lx, len = 0x%08lx\n", 869 sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len); 870 } 871 } 872 p += sprintf(p,"%s: sc_tail = %p, sc_tail_size = 0x%08x\n", 873 sc->sc_dev.dv_xname, esc->sc_tail, esc->sc_tail_size); 874 { 875 int i; 876 bus_dmamap_t map = esc->sc_tail_dmamap; 877 p += sprintf(p,"%s: sc_tail_dmamap. mapsize = 0x%08lx, nsegs = %d\n", 878 sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs); 879 for(i=0;i<map->dm_nsegs;i++) { 880 p += sprintf(p,"%s: map->dm_segs[%d].ds_addr = 0x%08lx, len = 0x%08lx\n", 881 sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len); 882 } 883 } 884 } 885 886 void 887 esp_dma_print(sc) 888 struct ncr53c9x_softc *sc; 889 { 890 esp_dma_store(sc); 891 printf("%s",esp_dma_dump); 892 } 893 #endif 894 895 void 896 esp_dma_go(sc) 897 struct ncr53c9x_softc *sc; 898 { 899 struct esp_softc *esc = (struct esp_softc *)sc; 900 901 DPRINTF(("%s: esp_dma_go(datain = %d)\n", 902 sc->sc_dev.dv_xname, esc->sc_datain)); 903 904 #ifdef ESP_DEBUG 905 if (esp_debug) esp_dma_print(sc); 906 else esp_dma_store(sc); 907 #endif 908 909 #ifdef ESP_DEBUG 910 { 911 int n = NCR_READ_REG(sc, NCR_FFLAG); 912 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n", 913 sc->sc_dev.dv_xname, 914 n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5)); 915 } 916 #endif 917 918 /* zero length dma transfers are boring */ 919 if (esc->sc_dmasize == 0) { 920 return; 921 } 922 923 #if defined(DIAGNOSTIC) 924 if ((esc->sc_begin_size == 0) && 925 (esc->sc_main_dmamap->dm_mapsize == 0) && 926 (esc->sc_tail_dmamap->dm_mapsize == 0)) { 927 esp_dma_print(sc); 928 panic("%s: No DMA requested!",sc->sc_dev.dv_xname); 929 } 930 #endif 931 932 /* Stuff the fifo with the begin buffer */ 933 if (esc->sc_datain) { 934 int i; 935 DPRINTF(("%s: FIFO read of %d bytes:", 936 sc->sc_dev.dv_xname,esc->sc_begin_size)); 937 for(i=0;i<esc->sc_begin_size;i++) { 938 esc->sc_begin[i]=NCR_READ_REG(sc, NCR_FIFO); 939 DPRINTF((" %02x",esc->sc_begin[i]&0xff)); 940 } 941 DPRINTF(("\n")); 942 } else { 943 int i; 944 DPRINTF(("%s: FIFO write of %d bytes:", 945 sc->sc_dev.dv_xname,esc->sc_begin_size)); 946 for(i=0;i<esc->sc_begin_size;i++) { 947 NCR_WRITE_REG(sc, NCR_FIFO, esc->sc_begin[i]); 948 DPRINTF((" %02x",esc->sc_begin[i]&0xff)); 949 } 950 DPRINTF(("\n")); 951 } 952 953 /* if we are a dma write cycle, copy the end slop */ 954 if (esc->sc_datain == 0) { 955 memcpy(esc->sc_tail, 956 (*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size), 957 (esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size))); 958 } 959 960 if (esc->sc_main_dmamap->dm_mapsize) { 961 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap, 962 0, esc->sc_main_dmamap->dm_mapsize, 963 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 964 esc->sc_main_dmamap->dm_xfer_len = 0; 965 } 966 967 if (esc->sc_tail_dmamap->dm_mapsize) { 968 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap, 969 0, esc->sc_tail_dmamap->dm_mapsize, 970 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 971 esc->sc_tail_dmamap->dm_xfer_len = 0; 972 } 973 974 nextdma_start(&esc->sc_scsi_dma, 975 (esc->sc_datain ? DMACSR_SETREAD : DMACSR_SETWRITE)); 976 977 if (esc->sc_datain) { 978 NCR_WRITE_REG(sc, ESP_DCTL, 979 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD); 980 } else { 981 NCR_WRITE_REG(sc, ESP_DCTL, 982 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD); 983 } 984 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 985 } 986 987 void 988 esp_dma_stop(sc) 989 struct ncr53c9x_softc *sc; 990 { 991 struct esp_softc *esc = (struct esp_softc *)sc; 992 next_dma_print(&esc->sc_scsi_dma); 993 esp_dma_print(sc); 994 panic("%s: stop not yet implemented\n",sc->sc_dev.dv_xname); 995 } 996 997 int 998 esp_dma_isactive(sc) 999 struct ncr53c9x_softc *sc; 1000 { 1001 struct esp_softc *esc = (struct esp_softc *)sc; 1002 int r = !nextdma_finished(&esc->sc_scsi_dma); 1003 DPRINTF(("esp_dma_isactive = %d\n",r)); 1004 return(r); 1005 } 1006 1007 /****************************************************************/ 1008 1009 /* Internal dma callback routines */ 1010 bus_dmamap_t 1011 esp_dmacb_continue(arg) 1012 void *arg; 1013 { 1014 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1015 struct esp_softc *esc = (struct esp_softc *)sc; 1016 1017 DPRINTF(("%s: dma continue\n",sc->sc_dev.dv_xname)); 1018 1019 #ifdef DIAGNOSTIC 1020 if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) { 1021 panic("%s: map not loaded in dma continue callback, datain = %d", 1022 sc->sc_dev.dv_xname,esc->sc_datain); 1023 } 1024 #endif 1025 1026 if ((!(esc->sc_loaded & ESP_LOADED_MAIN)) && 1027 (esc->sc_main_dmamap->dm_mapsize)) { 1028 DPRINTF(("%s: Loading main map\n",sc->sc_dev.dv_xname)); 1029 #if 0 1030 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap, 1031 0, esc->sc_main_dmamap->dm_mapsize, 1032 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1033 esc->sc_main_dmamap->dm_xfer_len = 0; 1034 #endif 1035 esc->sc_loaded |= ESP_LOADED_MAIN; 1036 return(esc->sc_main_dmamap); 1037 } 1038 1039 if ((!(esc->sc_loaded & ESP_LOADED_TAIL)) && 1040 (esc->sc_tail_dmamap->dm_mapsize)) { 1041 DPRINTF(("%s: Loading tail map\n",sc->sc_dev.dv_xname)); 1042 #if 0 1043 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap, 1044 0, esc->sc_tail_dmamap->dm_mapsize, 1045 (esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1046 esc->sc_tail_dmamap->dm_xfer_len = 0; 1047 #endif 1048 esc->sc_loaded |= ESP_LOADED_TAIL; 1049 return(esc->sc_tail_dmamap); 1050 } 1051 1052 DPRINTF(("%s: not loading map\n",sc->sc_dev.dv_xname)); 1053 return(0); 1054 } 1055 1056 1057 void 1058 esp_dmacb_completed(map, arg) 1059 bus_dmamap_t map; 1060 void *arg; 1061 { 1062 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1063 struct esp_softc *esc = (struct esp_softc *)sc; 1064 1065 DPRINTF(("%s: dma completed\n",sc->sc_dev.dv_xname)); 1066 1067 #ifdef DIAGNOSTIC 1068 if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) { 1069 panic("%s: invalid dma direction in completed callback, datain = %d", 1070 sc->sc_dev.dv_xname,esc->sc_datain); 1071 } 1072 #endif 1073 1074 #if defined(DIAGNOSTIC) && 0 1075 { 1076 int i; 1077 for(i=0;i<map->dm_nsegs;i++) { 1078 if (map->dm_xfer_len != map->dm_mapsize) { 1079 printf("%s: map->dm_mapsize = %d\n", sc->sc_dev.dv_xname,map->dm_mapsize); 1080 printf("%s: map->dm_nsegs = %d\n", sc->sc_dev.dv_xname,map->dm_nsegs); 1081 printf("%s: map->dm_xfer_len = %d\n", sc->sc_dev.dv_xname,map->dm_xfer_len); 1082 for(i=0;i<map->dm_nsegs;i++) { 1083 printf("%s: map->dm_segs[%d].ds_addr = 0x%08lx\n", 1084 sc->sc_dev.dv_xname,i,map->dm_segs[i].ds_addr); 1085 printf("%s: map->dm_segs[%d].ds_len = %d\n", 1086 sc->sc_dev.dv_xname,i,map->dm_segs[i].ds_len); 1087 } 1088 panic("%s: incomplete dma transfer\n",sc->sc_dev.dv_xname); 1089 } 1090 } 1091 } 1092 #endif 1093 1094 if (map == esc->sc_main_dmamap) { 1095 #ifdef DIAGNOSTIC 1096 if ((esc->sc_loaded & ESP_UNLOADED_MAIN) || 1097 !(esc->sc_loaded & ESP_LOADED_MAIN)) { 1098 panic("%s: unexpected completed call for main map\n",sc->sc_dev.dv_xname); 1099 } 1100 #endif 1101 esc->sc_loaded |= ESP_UNLOADED_MAIN; 1102 } else if (map == esc->sc_tail_dmamap) { 1103 #ifdef DIAGNOSTIC 1104 if ((esc->sc_loaded & ESP_UNLOADED_TAIL) || 1105 !(esc->sc_loaded & ESP_LOADED_TAIL)) { 1106 panic("%s: unexpected completed call for tail map\n",sc->sc_dev.dv_xname); 1107 } 1108 #endif 1109 esc->sc_loaded |= ESP_UNLOADED_TAIL; 1110 } 1111 #ifdef DIAGNOSTIC 1112 else { 1113 panic("%s: unexpected completed map", sc->sc_dev.dv_xname); 1114 } 1115 #endif 1116 1117 #ifdef ESP_DEBUG 1118 if (esp_debug) { 1119 if (map == esc->sc_main_dmamap) { 1120 printf("%s: completed main map\n",sc->sc_dev.dv_xname); 1121 } else if (map == esc->sc_tail_dmamap) { 1122 printf("%s: completed tail map\n",sc->sc_dev.dv_xname); 1123 } 1124 } 1125 #endif 1126 1127 #if 0 1128 if ((map == esc->sc_tail_dmamap) || 1129 ((esc->sc_tail_size == 0) && (map == esc->sc_main_dmamap))) { 1130 1131 /* Clear the DMAMOD bit in the DCTL register to give control 1132 * back to the scsi chip. 1133 */ 1134 if (esc->sc_datain) { 1135 NCR_WRITE_REG(sc, ESP_DCTL, 1136 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 1137 } else { 1138 NCR_WRITE_REG(sc, ESP_DCTL, 1139 ESPDCTL_20MHZ | ESPDCTL_INTENB); 1140 } 1141 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 1142 } 1143 #endif 1144 1145 1146 #if 0 1147 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, map, 1148 0, map->dm_mapsize, 1149 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1150 #endif 1151 1152 } 1153 1154 void 1155 esp_dmacb_shutdown(arg) 1156 void *arg; 1157 { 1158 struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg; 1159 struct esp_softc *esc = (struct esp_softc *)sc; 1160 bus_size_t xfer_len = 0; 1161 1162 DPRINTF(("%s: dma shutdown\n",sc->sc_dev.dv_xname)); 1163 1164 #if 0 1165 { 1166 /* Clear the DMAMOD bit in the DCTL register to give control 1167 * back to the scsi chip. 1168 */ 1169 if (esc->sc_datain) { 1170 NCR_WRITE_REG(sc, ESP_DCTL, 1171 ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD); 1172 } else { 1173 NCR_WRITE_REG(sc, ESP_DCTL, 1174 ESPDCTL_20MHZ | ESPDCTL_INTENB); 1175 } 1176 DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL))); 1177 } 1178 #endif 1179 1180 DPRINTF(("%s: esp_dma_nest == %d\n",sc->sc_dev.dv_xname,esp_dma_nest)); 1181 1182 /* Stuff the end slop into fifo */ 1183 1184 #ifdef ESP_DEBUG 1185 if (esp_debug) { 1186 1187 int n = NCR_READ_REG(sc, NCR_FFLAG); 1188 DPRINTF(("%s: fifo size = %d, seq = 0x%x\n", 1189 sc->sc_dev.dv_xname,n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5)); 1190 } 1191 #endif 1192 1193 xfer_len += esc->sc_begin_size; 1194 1195 if (esc->sc_main_dmamap->dm_mapsize) { 1196 xfer_len += esc->sc_main_dmamap->dm_xfer_len; 1197 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap, 1198 0, esc->sc_main_dmamap->dm_mapsize, 1199 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1200 bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap); 1201 } 1202 1203 if (esc->sc_tail_dmamap->dm_mapsize) { 1204 xfer_len += esc->sc_tail_dmamap->dm_xfer_len; 1205 bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap, 1206 0, esc->sc_tail_dmamap->dm_mapsize, 1207 (esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1208 bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap); 1209 } 1210 1211 /* truncate in case tail overran */ 1212 if (xfer_len > esc->sc_dmasize) { 1213 xfer_len = esc->sc_dmasize; 1214 } 1215 1216 /* copy the tail dma buffer data for read transfers */ 1217 if (esc->sc_datain == 1) { 1218 memcpy((*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size), 1219 esc->sc_tail, 1220 (esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size))); 1221 } 1222 1223 #ifdef ESP_DEBUG 1224 if (esp_debug) { 1225 printf("%s: dma_shutdown: addr=%p,len=0x%08x,size=0x%08x\n", 1226 sc->sc_dev.dv_xname, 1227 *esc->sc_dmaaddr, *esc->sc_dmalen, esc->sc_dmasize); 1228 if (esp_debug > 10) { 1229 esp_hex_dump(*(esc->sc_dmaaddr),esc->sc_dmasize); 1230 printf("%s: tail=%p,tailbuf=%p,tail_size=0x%08x\n", 1231 sc->sc_dev.dv_xname, 1232 esc->sc_tail, &(esc->sc_tailbuf[0]), esc->sc_tail_size); 1233 esp_hex_dump(&(esc->sc_tailbuf[0]),sizeof(esc->sc_tailbuf)); 1234 } 1235 } 1236 #endif 1237 1238 #if 0 1239 KASSERT(xfer_len == esc->sc_dmasize); 1240 #endif 1241 1242 *(esc->sc_dmaaddr) += xfer_len; 1243 *(esc->sc_dmalen) -= xfer_len; 1244 1245 esc->sc_main = 0; 1246 esc->sc_main_size = 0; 1247 esc->sc_tail = 0; 1248 esc->sc_tail_size = 0; 1249 1250 esc->sc_datain = -1; 1251 esc->sc_dmaaddr = 0; 1252 esc->sc_dmalen = 0; 1253 esc->sc_dmasize = 0; 1254 1255 esc->sc_loaded = 0; 1256 1257 esc->sc_begin = 0; 1258 esc->sc_begin_size = 0; 1259 1260 #ifdef ESP_DEBUG 1261 if (esp_debug) { 1262 char sbuf[256]; 1263 1264 bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)), 1265 NEXT_INTR_BITS, sbuf, sizeof(sbuf)); 1266 printf(" *intrstat = 0x%s\n", sbuf); 1267 1268 bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRMASK)), 1269 NEXT_INTR_BITS, sbuf, sizeof(sbuf)); 1270 printf(" *intrmask = 0x%s\n", sbuf); 1271 } 1272 #endif 1273 } 1274