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