1 /* $NetBSD: flsc.c,v 1.27 2001/04/25 17:53:07 bouyer Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Michael L. Hitch 5 * Copyright (c) 1995 Daniel Widenfalk 6 * Copyright (c) 1994 Christian E. Hopps 7 * Copyright (c) 1982, 1990 The Regents of the University of California. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by Daniel Widenfalk 21 * and Michael L. Hitch. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39 /* 40 * Initial amiga Fastlane driver by Daniel Widenfalk. Conversion to 41 * 53c9x MI driver by Michael L. Hitch (mhitch@montana.edu). 42 */ 43 44 #include "opt_ddb.h" 45 46 #include <sys/types.h> 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/kernel.h> 50 #include <sys/errno.h> 51 #include <sys/ioctl.h> 52 #include <sys/device.h> 53 #include <sys/buf.h> 54 #include <sys/proc.h> 55 #include <sys/user.h> 56 #include <sys/queue.h> 57 58 #include <dev/scsipi/scsi_all.h> 59 #include <dev/scsipi/scsipi_all.h> 60 #include <dev/scsipi/scsiconf.h> 61 #include <dev/scsipi/scsi_message.h> 62 63 #include <machine/cpu.h> 64 #include <machine/param.h> 65 66 #include <dev/ic/ncr53c9xreg.h> 67 #include <dev/ic/ncr53c9xvar.h> 68 69 #include <amiga/amiga/isr.h> 70 #include <amiga/dev/flscvar.h> 71 #include <amiga/dev/zbusvar.h> 72 73 void flscattach __P((struct device *, struct device *, void *)); 74 int flscmatch __P((struct device *, struct cfdata *, void *)); 75 76 /* Linkup to the rest of the kernel */ 77 struct cfattach flsc_ca = { 78 sizeof(struct flsc_softc), flscmatch, flscattach 79 }; 80 81 /* 82 * Functions and the switch for the MI code. 83 */ 84 u_char flsc_read_reg __P((struct ncr53c9x_softc *, int)); 85 void flsc_write_reg __P((struct ncr53c9x_softc *, int, u_char)); 86 int flsc_dma_isintr __P((struct ncr53c9x_softc *)); 87 void flsc_dma_reset __P((struct ncr53c9x_softc *)); 88 int flsc_dma_intr __P((struct ncr53c9x_softc *)); 89 int flsc_dma_setup __P((struct ncr53c9x_softc *, caddr_t *, 90 size_t *, int, size_t *)); 91 void flsc_dma_go __P((struct ncr53c9x_softc *)); 92 void flsc_dma_stop __P((struct ncr53c9x_softc *)); 93 int flsc_dma_isactive __P((struct ncr53c9x_softc *)); 94 void flsc_clear_latched_intr __P((struct ncr53c9x_softc *)); 95 96 struct ncr53c9x_glue flsc_glue = { 97 flsc_read_reg, 98 flsc_write_reg, 99 flsc_dma_isintr, 100 flsc_dma_reset, 101 flsc_dma_intr, 102 flsc_dma_setup, 103 flsc_dma_go, 104 flsc_dma_stop, 105 flsc_dma_isactive, 106 flsc_clear_latched_intr, 107 }; 108 109 /* Maximum DMA transfer length to reduce impact on high-speed serial input */ 110 u_long flsc_max_dma = 1024; 111 extern int ser_open_speed; 112 113 extern int ncr53c9x_debug; 114 extern u_long scsi_nosync; 115 extern int shift_nosync; 116 117 /* 118 * if we are an Advanced Systems & Software FastlaneZ3 119 */ 120 int 121 flscmatch(parent, cf, aux) 122 struct device *parent; 123 struct cfdata *cf; 124 void *aux; 125 { 126 struct zbus_args *zap; 127 128 if (!is_a4000() && !is_a3000()) 129 return(0); 130 131 zap = aux; 132 if (zap->manid == 0x2140 && zap->prodid == 11 133 && iszthreepa(zap->pa)) 134 return(1); 135 136 return(0); 137 } 138 139 /* 140 * Attach this instance, and then all the sub-devices 141 */ 142 void 143 flscattach(parent, self, aux) 144 struct device *parent, *self; 145 void *aux; 146 { 147 struct flsc_softc *fsc = (void *)self; 148 struct ncr53c9x_softc *sc = &fsc->sc_ncr53c9x; 149 struct zbus_args *zap; 150 151 /* 152 * Set up the glue for MI code early; we use some of it here. 153 */ 154 sc->sc_glue = &flsc_glue; 155 156 /* 157 * Save the regs 158 */ 159 zap = aux; 160 fsc->sc_dmabase = (volatile u_char *)zap->va; 161 fsc->sc_reg = &((volatile u_char *)zap->va)[0x1000001]; 162 163 sc->sc_freq = 40; /* Clocked at 40Mhz */ 164 165 printf(": address %p", fsc->sc_reg); 166 167 sc->sc_id = 7; 168 169 /* 170 * It is necessary to try to load the 2nd config register here, 171 * to find out what rev the flsc chip is, else the flsc_reset 172 * will not set up the defaults correctly. 173 */ 174 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; 175 sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_FE; 176 sc->sc_cfg3 = 0x08 /*FCLK*/ | NCRESPCFG3_FSCSI | NCRESPCFG3_CDB; 177 sc->sc_rev = NCR_VARIANT_FAS216; 178 179 /* 180 * This is the value used to start sync negotiations 181 * Note that the NCR register "SYNCTP" is programmed 182 * in "clocks per byte", and has a minimum value of 4. 183 * The SCSI period used in negotiation is one-fourth 184 * of the time (in nanoseconds) needed to transfer one byte. 185 * Since the chip's clock is given in MHz, we have the following 186 * formula: 4 * period = (1000 / freq) * 4 187 */ 188 sc->sc_minsync = 1000 / sc->sc_freq; 189 190 if (((scsi_nosync >> shift_nosync) & 0xff00) == 0xff00) 191 sc->sc_minsync = 0; 192 193 /* Really no limit, but since we want to fit into the TCR... */ 194 sc->sc_maxxfer = 64 * 1024; 195 196 fsc->sc_portbits = 0xa0 | FLSC_PB_EDI | FLSC_PB_ESI; 197 fsc->sc_hardbits = fsc->sc_reg[0x40]; 198 199 fsc->sc_alignbuf = (char *)((u_long)fsc->sc_unalignbuf & -4); 200 201 sc->sc_dev.dv_cfdata->cf_flags |= (scsi_nosync >> shift_nosync) & 0xffff; 202 shift_nosync += 16; 203 ncr53c9x_debug |= (scsi_nosync >> shift_nosync) & 0xffff; 204 shift_nosync += 16; 205 206 /* 207 * Configure interrupts. 208 */ 209 fsc->sc_isr.isr_intr = ncr53c9x_intr; 210 fsc->sc_isr.isr_arg = sc; 211 fsc->sc_isr.isr_ipl = 2; 212 add_isr(&fsc->sc_isr); 213 214 fsc->sc_reg[0x40] = fsc->sc_portbits; 215 216 /* 217 * Now try to attach all the sub-devices 218 */ 219 sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request; 220 sc->sc_adapter.adapt_minphys = minphys; 221 ncr53c9x_attach(sc); 222 } 223 224 /* 225 * Glue functions. 226 */ 227 228 u_char 229 flsc_read_reg(sc, reg) 230 struct ncr53c9x_softc *sc; 231 int reg; 232 { 233 struct flsc_softc *fsc = (struct flsc_softc *)sc; 234 235 return fsc->sc_reg[reg * 4]; 236 } 237 238 void 239 flsc_write_reg(sc, reg, val) 240 struct ncr53c9x_softc *sc; 241 int reg; 242 u_char val; 243 { 244 struct flsc_softc *fsc = (struct flsc_softc *)sc; 245 struct ncr53c9x_tinfo *ti; 246 u_char v = val; 247 248 if (fsc->sc_piomode && reg == NCR_CMD && 249 v == (NCRCMD_TRANS|NCRCMD_DMA)) { 250 v = NCRCMD_TRANS; 251 } 252 /* 253 * Can't do synchronous transfers in XS_CTL_POLL mode: 254 * If starting XS_CTL_POLL command, clear defer sync negotiation 255 * by clearing the T_NEGOTIATE flag. If starting XS_CTL_POLL and 256 * the device is currently running synchronous, force another 257 * T_NEGOTIATE with 0 offset. 258 */ 259 if (reg == NCR_SELID) { 260 ti = &sc->sc_tinfo[ 261 sc->sc_nexus->xs->xs_periph->periph_target]; 262 if (sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 263 if (ti->flags & T_SYNCMODE) { 264 ti->flags ^= T_SYNCMODE | T_NEGOTIATE; 265 } else if (ti->flags & T_NEGOTIATE) { 266 ti->flags ^= T_NEGOTIATE | T_SYNCHOFF; 267 /* save T_NEGOTIATE in private flags? */ 268 } 269 } else { 270 /* 271 * If we haven't attempted sync negotiation yet, 272 * do it now. 273 */ 274 if ((ti->flags & (T_SYNCMODE | T_SYNCHOFF)) == 275 T_SYNCHOFF && 276 sc->sc_minsync != 0) /* XXX */ 277 ti->flags ^= T_NEGOTIATE | T_SYNCHOFF; 278 } 279 } 280 if (reg == NCR_CMD && v == NCRCMD_SETATN && 281 sc->sc_flags & NCR_SYNCHNEGO && 282 sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 283 ti = &sc->sc_tinfo[ 284 sc->sc_nexus->xs->xs_periph->periph_target]; 285 ti->offset = 0; 286 } 287 fsc->sc_reg[reg * 4] = v; 288 } 289 290 int 291 flsc_dma_isintr(sc) 292 struct ncr53c9x_softc *sc; 293 { 294 struct flsc_softc *fsc = (struct flsc_softc *)sc; 295 unsigned hardbits; 296 297 hardbits = fsc->sc_reg[0x40]; 298 if (hardbits & FLSC_HB_IACT) 299 return (fsc->sc_csr = 0); 300 301 if (sc->sc_state == NCR_CONNECTED || sc->sc_state == NCR_SELECTING) 302 fsc->sc_portbits |= FLSC_PB_LED; 303 else 304 fsc->sc_portbits &= ~FLSC_PB_LED; 305 306 if ((hardbits & FLSC_HB_CREQ) && !(hardbits & FLSC_HB_MINT) && 307 fsc->sc_reg[NCR_STAT * 4] & NCRSTAT_INT) { 308 return 1; 309 } 310 /* Do I still need this? */ 311 if (fsc->sc_piomode && fsc->sc_reg[NCR_STAT * 4] & NCRSTAT_INT && 312 !(hardbits & FLSC_HB_MINT)) 313 return 1; 314 315 fsc->sc_reg[0x40] = fsc->sc_portbits & ~FLSC_PB_INT_BITS; 316 fsc->sc_reg[0x40] = fsc->sc_portbits; 317 return 0; 318 } 319 320 void 321 flsc_clear_latched_intr(sc) 322 struct ncr53c9x_softc *sc; 323 { 324 struct flsc_softc *fsc = (struct flsc_softc *)sc; 325 326 fsc->sc_reg[0x40] = fsc->sc_portbits & ~FLSC_PB_INT_BITS; 327 fsc->sc_reg[0x40] = fsc->sc_portbits; 328 } 329 330 void 331 flsc_dma_reset(sc) 332 struct ncr53c9x_softc *sc; 333 { 334 struct flsc_softc *fsc = (struct flsc_softc *)sc; 335 struct ncr53c9x_tinfo *ti; 336 337 if (sc->sc_nexus) 338 ti = &sc->sc_tinfo[sc->sc_nexus->xs->xs_periph->periph_target]; 339 else 340 ti = &sc->sc_tinfo[1]; /* XXX */ 341 if (fsc->sc_active) { 342 printf("dmaaddr %p dmasize %d stat %x flags %x off %d per %d ff %x", 343 *fsc->sc_dmaaddr, fsc->sc_dmasize, fsc->sc_reg[NCR_STAT * 4], 344 ti->flags, ti->offset, ti->period, fsc->sc_reg[NCR_FFLAG * 4]); 345 printf(" intr %x\n", fsc->sc_reg[NCR_INTR * 4]); 346 #ifdef DDB 347 Debugger(); 348 #endif 349 } 350 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 351 fsc->sc_reg[0x40] = fsc->sc_portbits; 352 fsc->sc_reg[0x80] = 0; 353 *((u_long *)fsc->sc_dmabase) = 0; 354 fsc->sc_active = 0; 355 fsc->sc_piomode = 0; 356 } 357 358 int 359 flsc_dma_intr(sc) 360 struct ncr53c9x_softc *sc; 361 { 362 register struct flsc_softc *fsc = (struct flsc_softc *)sc; 363 register u_char *p; 364 volatile u_char *cmdreg, *intrreg, *statreg, *fiforeg; 365 register u_int flscphase, flscstat, flscintr; 366 register int cnt; 367 368 NCR_DMA(("flsc_dma_intr: pio %d cnt %d int %x stat %x fifo %d ", 369 fsc->sc_piomode, fsc->sc_dmasize, sc->sc_espintr, sc->sc_espstat, 370 fsc->sc_reg[NCR_FFLAG * 4] & NCRFIFO_FF)); 371 if (!(fsc->sc_reg[0x40] & FLSC_HB_CREQ)) 372 printf("flsc_dma_intr: csr %x stat %x intr %x\n", fsc->sc_csr, 373 sc->sc_espstat, sc->sc_espintr); 374 if (fsc->sc_active == 0) { 375 printf("flsc_intr--inactive DMA\n"); 376 return -1; 377 } 378 379 /* if DMA transfer, update sc_dmaaddr and sc_pdmalen, else PIO xfer */ 380 if (fsc->sc_piomode == 0) { 381 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 382 fsc->sc_reg[0x40] = fsc->sc_portbits; 383 fsc->sc_reg[0x80] = 0; 384 *((u_long *)fsc->sc_dmabase) = 0; 385 cnt = fsc->sc_reg[NCR_TCL * 4]; 386 cnt += fsc->sc_reg[NCR_TCM * 4] << 8; 387 cnt += fsc->sc_reg[NCR_TCH * 4] << 16; 388 if (!fsc->sc_datain) { 389 cnt += fsc->sc_reg[NCR_FFLAG * 4] & NCRFIFO_FF; 390 fsc->sc_reg[NCR_CMD * 4] = NCRCMD_FLUSH; 391 } 392 cnt = fsc->sc_dmasize - cnt; /* number of bytes transferred */ 393 NCR_DMA(("DMA xferred %d\n", cnt)); 394 if (fsc->sc_xfr_align) { 395 int i; 396 for (i = 0; i < cnt; ++i) 397 (*fsc->sc_dmaaddr)[i] = fsc->sc_alignbuf[i]; 398 fsc->sc_xfr_align = 0; 399 } 400 *fsc->sc_dmaaddr += cnt; 401 *fsc->sc_pdmalen -= cnt; 402 fsc->sc_active = 0; 403 return 0; 404 } 405 406 if ((sc->sc_espintr & NCRINTR_BS) == 0) { 407 fsc->sc_active = 0; 408 fsc->sc_piomode = 0; 409 NCR_DMA(("no NCRINTR_BS\n")); 410 return 0; 411 } 412 413 cnt = fsc->sc_dmasize; 414 #if 0 415 if (cnt == 0) { 416 printf("data interrupt, but no count left."); 417 } 418 #endif 419 420 p = *fsc->sc_dmaaddr; 421 flscphase = sc->sc_phase; 422 flscstat = (u_int) sc->sc_espstat; 423 flscintr = (u_int) sc->sc_espintr; 424 cmdreg = fsc->sc_reg + NCR_CMD * 4; 425 fiforeg = fsc->sc_reg + NCR_FIFO * 4; 426 statreg = fsc->sc_reg + NCR_STAT * 4; 427 intrreg = fsc->sc_reg + NCR_INTR * 4; 428 NCR_DMA(("PIO %d datain %d phase %d stat %x intr %x\n", 429 cnt, fsc->sc_datain, flscphase, flscstat, flscintr)); 430 do { 431 if (fsc->sc_datain) { 432 *p++ = *fiforeg; 433 cnt--; 434 if (flscphase == DATA_IN_PHASE) { 435 *cmdreg = NCRCMD_TRANS; 436 } else { 437 fsc->sc_active = 0; 438 } 439 } else { 440 NCR_DMA(("flsc_dma_intr: PIO out- phase %d cnt %d active %d\n", flscphase, cnt, 441 fsc->sc_active)); 442 if ( (flscphase == DATA_OUT_PHASE) 443 || (flscphase == MESSAGE_OUT_PHASE)) { 444 int n; 445 n = 16 - (fsc->sc_reg[NCR_FFLAG * 4] & NCRFIFO_FF); 446 if (n > cnt) 447 n = cnt; 448 cnt -= n; 449 while (n-- > 0) 450 *fiforeg = *p++; 451 *cmdreg = NCRCMD_TRANS; 452 } else { 453 fsc->sc_active = 0; 454 } 455 } 456 457 if (fsc->sc_active && cnt) { 458 while (!(*statreg & 0x80)); 459 flscstat = *statreg; 460 flscintr = *intrreg; 461 flscphase = (flscintr & NCRINTR_DIS) 462 ? /* Disconnected */ BUSFREE_PHASE 463 : flscstat & PHASE_MASK; 464 } 465 } while (cnt && fsc->sc_active && (flscintr & NCRINTR_BS)); 466 #if 1 467 if (fsc->sc_dmasize < 8 && cnt) 468 printf("flsc_dma_intr: short transfer: dmasize %d cnt %d\n", 469 fsc->sc_dmasize, cnt); 470 #endif 471 NCR_DMA(("flsc_dma_intr: PIO transfer [%d], %d->%d phase %d stat %x intr %x\n", 472 *fsc->sc_pdmalen, fsc->sc_dmasize, cnt, flscphase, flscstat, flscintr)); 473 sc->sc_phase = flscphase; 474 sc->sc_espstat = (u_char) flscstat; 475 sc->sc_espintr = (u_char) flscintr; 476 *fsc->sc_dmaaddr = p; 477 *fsc->sc_pdmalen -= fsc->sc_dmasize - cnt; 478 fsc->sc_dmasize = cnt; 479 480 if (*fsc->sc_pdmalen == 0) { 481 sc->sc_espstat |= NCRSTAT_TC; 482 fsc->sc_piomode = 0; 483 } 484 return 0; 485 } 486 487 int 488 flsc_dma_setup(sc, addr, len, datain, dmasize) 489 struct ncr53c9x_softc *sc; 490 caddr_t *addr; 491 size_t *len; 492 int datain; 493 size_t *dmasize; 494 { 495 struct flsc_softc *fsc = (struct flsc_softc *)sc; 496 paddr_t pa; 497 u_char *ptr; 498 size_t xfer; 499 500 fsc->sc_dmaaddr = addr; 501 fsc->sc_pdmalen = len; 502 fsc->sc_datain = datain; 503 fsc->sc_dmasize = *dmasize; 504 if (sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 505 /* polling mode, use PIO */ 506 *dmasize = fsc->sc_dmasize; 507 NCR_DMA(("pfsc_dma_setup: PIO %p/%d [%d]\n", *addr, 508 fsc->sc_dmasize, *len)); 509 fsc->sc_piomode = 1; 510 if (datain == 0) { 511 int n; 512 n = fsc->sc_dmasize; 513 if (n > 16) 514 n = 16; 515 while (n-- > 0) { 516 fsc->sc_reg[NCR_FIFO * 4] = **fsc->sc_dmaaddr; 517 (*fsc->sc_pdmalen)--; 518 (*fsc->sc_dmaaddr)++; 519 --fsc->sc_dmasize; 520 } 521 } 522 return 0; 523 } 524 /* 525 * DMA can be nasty for high-speed serial input, so limit the 526 * size of this DMA operation if the serial port is running at 527 * a high speed (higher than 19200 for now - should be adjusted 528 * based on cpu type and speed?). 529 * XXX - add serial speed check XXX 530 */ 531 if (ser_open_speed > 19200 && flsc_max_dma != 0 && 532 fsc->sc_dmasize > flsc_max_dma) 533 fsc->sc_dmasize = flsc_max_dma; 534 ptr = *addr; /* Kernel virtual address */ 535 pa = kvtop(ptr); /* Physical address of DMA */ 536 xfer = min(fsc->sc_dmasize, NBPG - (pa & (NBPG - 1))); 537 fsc->sc_xfr_align = 0; 538 fsc->sc_piomode = 0; 539 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 540 fsc->sc_reg[0x40] = fsc->sc_portbits; 541 fsc->sc_reg[0x80] = 0; 542 *((u_long *)fsc->sc_dmabase) = 0; 543 544 /* 545 * If output and length < 16, copy to fifo 546 */ 547 if (datain == 0 && fsc->sc_dmasize < 16) { 548 int n; 549 for (n = 0; n < fsc->sc_dmasize; ++n) 550 fsc->sc_reg[NCR_FIFO * 4] = *ptr++; 551 NCR_DMA(("flsc_dma_setup: %d bytes written to fifo\n", n)); 552 fsc->sc_piomode = 1; 553 fsc->sc_active = 1; 554 *fsc->sc_pdmalen -= fsc->sc_dmasize; 555 *fsc->sc_dmaaddr += fsc->sc_dmasize; 556 *dmasize = fsc->sc_dmasize; 557 fsc->sc_dmasize = 0; 558 return 0; /* All done */ 559 } 560 /* 561 * If output and unaligned, copy unaligned data to fifo 562 */ 563 else if (datain == 0 && (int)ptr & 3) { 564 int n = 4 - ((int)ptr & 3); 565 NCR_DMA(("flsc_dma_setup: align %d bytes written to fifo\n", n)); 566 pa += n; 567 xfer -= n; 568 while (n--) 569 fsc->sc_reg[NCR_FIFO * 4] = *ptr++; 570 } 571 /* 572 * If unaligned address, read unaligned bytes into alignment buffer 573 */ 574 else if ((int)ptr & 3 || xfer & 3) { 575 pa = kvtop((caddr_t)fsc->sc_alignbuf); 576 xfer = fsc->sc_dmasize = min(xfer, sizeof (fsc->sc_unalignbuf)); 577 NCR_DMA(("flsc_dma_setup: align read by %d bytes\n", xfer)); 578 fsc->sc_xfr_align = 1; 579 } 580 /* 581 * If length smaller than longword, read into alignment buffer 582 * XXX doesn't work for 1 or 2 bytes !!!! 583 */ 584 else if (fsc->sc_dmasize < 4) { 585 NCR_DMA(("flsc_dma_setup: read remaining %d bytes\n", 586 fsc->sc_dmasize)); 587 pa = kvtop((caddr_t)fsc->sc_alignbuf); 588 fsc->sc_xfr_align = 1; 589 } 590 /* 591 * Finally, limit transfer length to multiple of 4 bytes. 592 */ 593 else { 594 fsc->sc_dmasize &= -4; 595 xfer &= -4; 596 } 597 598 while (xfer < fsc->sc_dmasize) { 599 if ((pa + xfer) != kvtop(*addr + xfer)) 600 break; 601 if ((fsc->sc_dmasize - xfer) < NBPG) 602 xfer = fsc->sc_dmasize; 603 else 604 xfer += NBPG; 605 } 606 607 fsc->sc_dmasize = xfer; 608 *dmasize = fsc->sc_dmasize; 609 fsc->sc_pa = pa; 610 #if defined(M68040) || defined(M68060) 611 if (mmutype == MMU_68040) { 612 if (fsc->sc_xfr_align) { 613 int n; 614 for (n = 0; n < sizeof (fsc->sc_unalignbuf); ++n) 615 fsc->sc_alignbuf[n] = n | 0x80; 616 dma_cachectl(fsc->sc_alignbuf, 617 sizeof(fsc->sc_unalignbuf)); 618 } 619 else 620 dma_cachectl(*fsc->sc_dmaaddr, fsc->sc_dmasize); 621 } 622 #endif 623 fsc->sc_reg[0x80] = 0; 624 *((u_long *)(fsc->sc_dmabase + (pa & 0x00fffffc))) = pa; 625 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 626 fsc->sc_portbits |= FLSC_PB_ENABLE_DMA | 627 (fsc->sc_datain ? FLSC_PB_DMA_READ : FLSC_PB_DMA_WRITE); 628 fsc->sc_reg[0x40] = fsc->sc_portbits; 629 NCR_DMA(("flsc_dma_setup: DMA %p->%lx/%d [%d]\n", 630 ptr, pa, fsc->sc_dmasize, *len)); 631 fsc->sc_active = 1; 632 return 0; 633 } 634 635 void 636 flsc_dma_go(sc) 637 struct ncr53c9x_softc *sc; 638 { 639 struct flsc_softc *fsc = (struct flsc_softc *)sc; 640 641 NCR_DMA(("flsc_dma_go: datain %d size %d\n", fsc->sc_datain, 642 fsc->sc_dmasize)); 643 if (sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 644 fsc->sc_active = 1; 645 return; 646 } else if (fsc->sc_piomode == 0) { 647 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 648 fsc->sc_portbits |= FLSC_PB_ENABLE_DMA | 649 (fsc->sc_datain ? FLSC_PB_DMA_READ : FLSC_PB_DMA_WRITE); 650 fsc->sc_reg[0x40] = fsc->sc_portbits; 651 } 652 } 653 654 void 655 flsc_dma_stop(sc) 656 struct ncr53c9x_softc *sc; 657 { 658 struct flsc_softc *fsc = (struct flsc_softc *)sc; 659 660 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 661 fsc->sc_reg[0x40] = fsc->sc_portbits; 662 663 fsc->sc_reg[0x80] = 0; 664 *((u_long *)fsc->sc_dmabase) = 0; 665 fsc->sc_piomode = 0; 666 } 667 668 int 669 flsc_dma_isactive(sc) 670 struct ncr53c9x_softc *sc; 671 { 672 struct flsc_softc *fsc = (struct flsc_softc *)sc; 673 674 return fsc->sc_active; 675 } 676