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