1 /* $NetBSD: flsc.c,v 1.25 1999/09/30 22:59:52 thorpej 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 struct scsipi_device flsc_dev = { 82 NULL, /* Use default error handler */ 83 NULL, /* have a queue, served by this */ 84 NULL, /* have no async handler */ 85 NULL, /* Use default 'done' routine */ 86 }; 87 88 /* 89 * Functions and the switch for the MI code. 90 */ 91 u_char flsc_read_reg __P((struct ncr53c9x_softc *, int)); 92 void flsc_write_reg __P((struct ncr53c9x_softc *, int, u_char)); 93 int flsc_dma_isintr __P((struct ncr53c9x_softc *)); 94 void flsc_dma_reset __P((struct ncr53c9x_softc *)); 95 int flsc_dma_intr __P((struct ncr53c9x_softc *)); 96 int flsc_dma_setup __P((struct ncr53c9x_softc *, caddr_t *, 97 size_t *, int, size_t *)); 98 void flsc_dma_go __P((struct ncr53c9x_softc *)); 99 void flsc_dma_stop __P((struct ncr53c9x_softc *)); 100 int flsc_dma_isactive __P((struct ncr53c9x_softc *)); 101 void flsc_clear_latched_intr __P((struct ncr53c9x_softc *)); 102 103 struct ncr53c9x_glue flsc_glue = { 104 flsc_read_reg, 105 flsc_write_reg, 106 flsc_dma_isintr, 107 flsc_dma_reset, 108 flsc_dma_intr, 109 flsc_dma_setup, 110 flsc_dma_go, 111 flsc_dma_stop, 112 flsc_dma_isactive, 113 flsc_clear_latched_intr, 114 }; 115 116 /* Maximum DMA transfer length to reduce impact on high-speed serial input */ 117 u_long flsc_max_dma = 1024; 118 extern int ser_open_speed; 119 120 extern int ncr53c9x_debug; 121 extern u_long scsi_nosync; 122 extern int shift_nosync; 123 124 /* 125 * if we are an Advanced Systems & Software FastlaneZ3 126 */ 127 int 128 flscmatch(parent, cf, aux) 129 struct device *parent; 130 struct cfdata *cf; 131 void *aux; 132 { 133 struct zbus_args *zap; 134 135 if (!is_a4000() && !is_a3000()) 136 return(0); 137 138 zap = aux; 139 if (zap->manid == 0x2140 && zap->prodid == 11 140 && iszthreepa(zap->pa)) 141 return(1); 142 143 return(0); 144 } 145 146 /* 147 * Attach this instance, and then all the sub-devices 148 */ 149 void 150 flscattach(parent, self, aux) 151 struct device *parent, *self; 152 void *aux; 153 { 154 struct flsc_softc *fsc = (void *)self; 155 struct ncr53c9x_softc *sc = &fsc->sc_ncr53c9x; 156 struct zbus_args *zap; 157 158 /* 159 * Set up the glue for MI code early; we use some of it here. 160 */ 161 sc->sc_glue = &flsc_glue; 162 163 /* 164 * Save the regs 165 */ 166 zap = aux; 167 fsc->sc_dmabase = (volatile u_char *)zap->va; 168 fsc->sc_reg = &((volatile u_char *)zap->va)[0x1000001]; 169 170 sc->sc_freq = 40; /* Clocked at 40Mhz */ 171 172 printf(": address %p", fsc->sc_reg); 173 174 sc->sc_id = 7; 175 176 /* 177 * It is necessary to try to load the 2nd config register here, 178 * to find out what rev the flsc chip is, else the flsc_reset 179 * will not set up the defaults correctly. 180 */ 181 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; 182 sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_FE; 183 sc->sc_cfg3 = 0x08 /*FCLK*/ | NCRESPCFG3_FSCSI | NCRESPCFG3_CDB; 184 sc->sc_rev = NCR_VARIANT_FAS216; 185 186 /* 187 * This is the value used to start sync negotiations 188 * Note that the NCR register "SYNCTP" is programmed 189 * in "clocks per byte", and has a minimum value of 4. 190 * The SCSI period used in negotiation is one-fourth 191 * of the time (in nanoseconds) needed to transfer one byte. 192 * Since the chip's clock is given in MHz, we have the following 193 * formula: 4 * period = (1000 / freq) * 4 194 */ 195 sc->sc_minsync = 1000 / sc->sc_freq; 196 197 if (((scsi_nosync >> shift_nosync) & 0xff00) == 0xff00) 198 sc->sc_minsync = 0; 199 200 /* Really no limit, but since we want to fit into the TCR... */ 201 sc->sc_maxxfer = 64 * 1024; 202 203 fsc->sc_portbits = 0xa0 | FLSC_PB_EDI | FLSC_PB_ESI; 204 fsc->sc_hardbits = fsc->sc_reg[0x40]; 205 206 fsc->sc_alignbuf = (char *)((u_long)fsc->sc_unalignbuf & -4); 207 208 sc->sc_dev.dv_cfdata->cf_flags |= (scsi_nosync >> shift_nosync) & 0xffff; 209 shift_nosync += 16; 210 ncr53c9x_debug |= (scsi_nosync >> shift_nosync) & 0xffff; 211 shift_nosync += 16; 212 213 /* 214 * Configure interrupts. 215 */ 216 fsc->sc_isr.isr_intr = (int (*)(void *))ncr53c9x_intr; 217 fsc->sc_isr.isr_arg = sc; 218 fsc->sc_isr.isr_ipl = 2; 219 add_isr(&fsc->sc_isr); 220 221 fsc->sc_reg[0x40] = fsc->sc_portbits; 222 223 /* 224 * Now try to attach all the sub-devices 225 */ 226 sc->sc_adapter.scsipi_cmd = ncr53c9x_scsi_cmd; 227 sc->sc_adapter.scsipi_minphys = minphys; 228 ncr53c9x_attach(sc, &flsc_dev); 229 } 230 231 /* 232 * Glue functions. 233 */ 234 235 u_char 236 flsc_read_reg(sc, reg) 237 struct ncr53c9x_softc *sc; 238 int reg; 239 { 240 struct flsc_softc *fsc = (struct flsc_softc *)sc; 241 242 return fsc->sc_reg[reg * 4]; 243 } 244 245 void 246 flsc_write_reg(sc, reg, val) 247 struct ncr53c9x_softc *sc; 248 int reg; 249 u_char val; 250 { 251 struct flsc_softc *fsc = (struct flsc_softc *)sc; 252 struct ncr53c9x_tinfo *ti; 253 u_char v = val; 254 255 if (fsc->sc_piomode && reg == NCR_CMD && 256 v == (NCRCMD_TRANS|NCRCMD_DMA)) { 257 v = NCRCMD_TRANS; 258 } 259 /* 260 * Can't do synchronous transfers in XS_CTL_POLL mode: 261 * If starting XS_CTL_POLL command, clear defer sync negotiation 262 * by clearing the T_NEGOTIATE flag. If starting XS_CTL_POLL and 263 * the device is currently running synchronous, force another 264 * T_NEGOTIATE with 0 offset. 265 */ 266 if (reg == NCR_SELID) { 267 ti = &sc->sc_tinfo[ 268 sc->sc_nexus->xs->sc_link->scsipi_scsi.target]; 269 if (sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 270 if (ti->flags & T_SYNCMODE) { 271 ti->flags ^= T_SYNCMODE | T_NEGOTIATE; 272 } else if (ti->flags & T_NEGOTIATE) { 273 ti->flags ^= T_NEGOTIATE | T_SYNCHOFF; 274 /* save T_NEGOTIATE in private flags? */ 275 } 276 } else { 277 /* 278 * If we haven't attempted sync negotiation yet, 279 * do it now. 280 */ 281 if ((ti->flags & (T_SYNCMODE | T_SYNCHOFF)) == 282 T_SYNCHOFF && 283 sc->sc_minsync != 0) /* XXX */ 284 ti->flags ^= T_NEGOTIATE | T_SYNCHOFF; 285 } 286 } 287 if (reg == NCR_CMD && v == NCRCMD_SETATN && 288 sc->sc_flags & NCR_SYNCHNEGO && 289 sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 290 ti = &sc->sc_tinfo[ 291 sc->sc_nexus->xs->sc_link->scsipi_scsi.target]; 292 ti->offset = 0; 293 } 294 fsc->sc_reg[reg * 4] = v; 295 } 296 297 int 298 flsc_dma_isintr(sc) 299 struct ncr53c9x_softc *sc; 300 { 301 struct flsc_softc *fsc = (struct flsc_softc *)sc; 302 unsigned hardbits; 303 304 hardbits = fsc->sc_reg[0x40]; 305 if (hardbits & FLSC_HB_IACT) 306 return (fsc->sc_csr = 0); 307 308 if (sc->sc_state == NCR_CONNECTED || sc->sc_state == NCR_SELECTING) 309 fsc->sc_portbits |= FLSC_PB_LED; 310 else 311 fsc->sc_portbits &= ~FLSC_PB_LED; 312 313 if ((hardbits & FLSC_HB_CREQ) && !(hardbits & FLSC_HB_MINT) && 314 fsc->sc_reg[NCR_STAT * 4] & NCRSTAT_INT) { 315 return 1; 316 } 317 /* Do I still need this? */ 318 if (fsc->sc_piomode && fsc->sc_reg[NCR_STAT * 4] & NCRSTAT_INT && 319 !(hardbits & FLSC_HB_MINT)) 320 return 1; 321 322 fsc->sc_reg[0x40] = fsc->sc_portbits & ~FLSC_PB_INT_BITS; 323 fsc->sc_reg[0x40] = fsc->sc_portbits; 324 return 0; 325 } 326 327 void 328 flsc_clear_latched_intr(sc) 329 struct ncr53c9x_softc *sc; 330 { 331 struct flsc_softc *fsc = (struct flsc_softc *)sc; 332 333 fsc->sc_reg[0x40] = fsc->sc_portbits & ~FLSC_PB_INT_BITS; 334 fsc->sc_reg[0x40] = fsc->sc_portbits; 335 } 336 337 void 338 flsc_dma_reset(sc) 339 struct ncr53c9x_softc *sc; 340 { 341 struct flsc_softc *fsc = (struct flsc_softc *)sc; 342 struct ncr53c9x_tinfo *ti; 343 344 if (sc->sc_nexus) 345 ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->scsipi_scsi.target]; 346 else 347 ti = &sc->sc_tinfo[1]; /* XXX */ 348 if (fsc->sc_active) { 349 printf("dmaaddr %p dmasize %d stat %x flags %x off %d per %d ff %x", 350 *fsc->sc_dmaaddr, fsc->sc_dmasize, fsc->sc_reg[NCR_STAT * 4], 351 ti->flags, ti->offset, ti->period, fsc->sc_reg[NCR_FFLAG * 4]); 352 printf(" intr %x\n", fsc->sc_reg[NCR_INTR * 4]); 353 #ifdef DDB 354 Debugger(); 355 #endif 356 } 357 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 358 fsc->sc_reg[0x40] = fsc->sc_portbits; 359 fsc->sc_reg[0x80] = 0; 360 *((u_long *)fsc->sc_dmabase) = 0; 361 fsc->sc_active = 0; 362 fsc->sc_piomode = 0; 363 } 364 365 int 366 flsc_dma_intr(sc) 367 struct ncr53c9x_softc *sc; 368 { 369 register struct flsc_softc *fsc = (struct flsc_softc *)sc; 370 register u_char *p; 371 volatile u_char *cmdreg, *intrreg, *statreg, *fiforeg; 372 register u_int flscphase, flscstat, flscintr; 373 register int cnt; 374 375 NCR_DMA(("flsc_dma_intr: pio %d cnt %d int %x stat %x fifo %d ", 376 fsc->sc_piomode, fsc->sc_dmasize, sc->sc_espintr, sc->sc_espstat, 377 fsc->sc_reg[NCR_FFLAG * 4] & NCRFIFO_FF)); 378 if (!(fsc->sc_reg[0x40] & FLSC_HB_CREQ)) 379 printf("flsc_dma_intr: csr %x stat %x intr %x\n", fsc->sc_csr, 380 sc->sc_espstat, sc->sc_espintr); 381 if (fsc->sc_active == 0) { 382 printf("flsc_intr--inactive DMA\n"); 383 return -1; 384 } 385 386 /* if DMA transfer, update sc_dmaaddr and sc_pdmalen, else PIO xfer */ 387 if (fsc->sc_piomode == 0) { 388 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 389 fsc->sc_reg[0x40] = fsc->sc_portbits; 390 fsc->sc_reg[0x80] = 0; 391 *((u_long *)fsc->sc_dmabase) = 0; 392 cnt = fsc->sc_reg[NCR_TCL * 4]; 393 cnt += fsc->sc_reg[NCR_TCM * 4] << 8; 394 cnt += fsc->sc_reg[NCR_TCH * 4] << 16; 395 if (!fsc->sc_datain) { 396 cnt += fsc->sc_reg[NCR_FFLAG * 4] & NCRFIFO_FF; 397 fsc->sc_reg[NCR_CMD * 4] = NCRCMD_FLUSH; 398 } 399 cnt = fsc->sc_dmasize - cnt; /* number of bytes transferred */ 400 NCR_DMA(("DMA xferred %d\n", cnt)); 401 if (fsc->sc_xfr_align) { 402 int i; 403 for (i = 0; i < cnt; ++i) 404 (*fsc->sc_dmaaddr)[i] = fsc->sc_alignbuf[i]; 405 fsc->sc_xfr_align = 0; 406 } 407 *fsc->sc_dmaaddr += cnt; 408 *fsc->sc_pdmalen -= cnt; 409 fsc->sc_active = 0; 410 return 0; 411 } 412 413 if ((sc->sc_espintr & NCRINTR_BS) == 0) { 414 fsc->sc_active = 0; 415 fsc->sc_piomode = 0; 416 NCR_DMA(("no NCRINTR_BS\n")); 417 return 0; 418 } 419 420 cnt = fsc->sc_dmasize; 421 #if 0 422 if (cnt == 0) { 423 printf("data interrupt, but no count left."); 424 } 425 #endif 426 427 p = *fsc->sc_dmaaddr; 428 flscphase = sc->sc_phase; 429 flscstat = (u_int) sc->sc_espstat; 430 flscintr = (u_int) sc->sc_espintr; 431 cmdreg = fsc->sc_reg + NCR_CMD * 4; 432 fiforeg = fsc->sc_reg + NCR_FIFO * 4; 433 statreg = fsc->sc_reg + NCR_STAT * 4; 434 intrreg = fsc->sc_reg + NCR_INTR * 4; 435 NCR_DMA(("PIO %d datain %d phase %d stat %x intr %x\n", 436 cnt, fsc->sc_datain, flscphase, flscstat, flscintr)); 437 do { 438 if (fsc->sc_datain) { 439 *p++ = *fiforeg; 440 cnt--; 441 if (flscphase == DATA_IN_PHASE) { 442 *cmdreg = NCRCMD_TRANS; 443 } else { 444 fsc->sc_active = 0; 445 } 446 } else { 447 NCR_DMA(("flsc_dma_intr: PIO out- phase %d cnt %d active %d\n", flscphase, cnt, 448 fsc->sc_active)); 449 if ( (flscphase == DATA_OUT_PHASE) 450 || (flscphase == MESSAGE_OUT_PHASE)) { 451 int n; 452 n = 16 - (fsc->sc_reg[NCR_FFLAG * 4] & NCRFIFO_FF); 453 if (n > cnt) 454 n = cnt; 455 cnt -= n; 456 while (n-- > 0) 457 *fiforeg = *p++; 458 *cmdreg = NCRCMD_TRANS; 459 } else { 460 fsc->sc_active = 0; 461 } 462 } 463 464 if (fsc->sc_active && cnt) { 465 while (!(*statreg & 0x80)); 466 flscstat = *statreg; 467 flscintr = *intrreg; 468 flscphase = (flscintr & NCRINTR_DIS) 469 ? /* Disconnected */ BUSFREE_PHASE 470 : flscstat & PHASE_MASK; 471 } 472 } while (cnt && fsc->sc_active && (flscintr & NCRINTR_BS)); 473 #if 1 474 if (fsc->sc_dmasize < 8 && cnt) 475 printf("flsc_dma_intr: short transfer: dmasize %d cnt %d\n", 476 fsc->sc_dmasize, cnt); 477 #endif 478 NCR_DMA(("flsc_dma_intr: PIO transfer [%d], %d->%d phase %d stat %x intr %x\n", 479 *fsc->sc_pdmalen, fsc->sc_dmasize, cnt, flscphase, flscstat, flscintr)); 480 sc->sc_phase = flscphase; 481 sc->sc_espstat = (u_char) flscstat; 482 sc->sc_espintr = (u_char) flscintr; 483 *fsc->sc_dmaaddr = p; 484 *fsc->sc_pdmalen -= fsc->sc_dmasize - cnt; 485 fsc->sc_dmasize = cnt; 486 487 if (*fsc->sc_pdmalen == 0) { 488 sc->sc_espstat |= NCRSTAT_TC; 489 fsc->sc_piomode = 0; 490 } 491 return 0; 492 } 493 494 int 495 flsc_dma_setup(sc, addr, len, datain, dmasize) 496 struct ncr53c9x_softc *sc; 497 caddr_t *addr; 498 size_t *len; 499 int datain; 500 size_t *dmasize; 501 { 502 struct flsc_softc *fsc = (struct flsc_softc *)sc; 503 paddr_t pa; 504 u_char *ptr; 505 size_t xfer; 506 507 fsc->sc_dmaaddr = addr; 508 fsc->sc_pdmalen = len; 509 fsc->sc_datain = datain; 510 fsc->sc_dmasize = *dmasize; 511 if (sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 512 /* polling mode, use PIO */ 513 *dmasize = fsc->sc_dmasize; 514 NCR_DMA(("pfsc_dma_setup: PIO %p/%d [%d]\n", *addr, 515 fsc->sc_dmasize, *len)); 516 fsc->sc_piomode = 1; 517 if (datain == 0) { 518 int n; 519 n = fsc->sc_dmasize; 520 if (n > 16) 521 n = 16; 522 while (n-- > 0) { 523 fsc->sc_reg[NCR_FIFO * 4] = **fsc->sc_dmaaddr; 524 (*fsc->sc_pdmalen)--; 525 (*fsc->sc_dmaaddr)++; 526 --fsc->sc_dmasize; 527 } 528 } 529 return 0; 530 } 531 /* 532 * DMA can be nasty for high-speed serial input, so limit the 533 * size of this DMA operation if the serial port is running at 534 * a high speed (higher than 19200 for now - should be adjusted 535 * based on cpu type and speed?). 536 * XXX - add serial speed check XXX 537 */ 538 if (ser_open_speed > 19200 && flsc_max_dma != 0 && 539 fsc->sc_dmasize > flsc_max_dma) 540 fsc->sc_dmasize = flsc_max_dma; 541 ptr = *addr; /* Kernel virtual address */ 542 pa = kvtop(ptr); /* Physical address of DMA */ 543 xfer = min(fsc->sc_dmasize, NBPG - (pa & (NBPG - 1))); 544 fsc->sc_xfr_align = 0; 545 fsc->sc_piomode = 0; 546 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 547 fsc->sc_reg[0x40] = fsc->sc_portbits; 548 fsc->sc_reg[0x80] = 0; 549 *((u_long *)fsc->sc_dmabase) = 0; 550 551 /* 552 * If output and length < 16, copy to fifo 553 */ 554 if (datain == 0 && fsc->sc_dmasize < 16) { 555 int n; 556 for (n = 0; n < fsc->sc_dmasize; ++n) 557 fsc->sc_reg[NCR_FIFO * 4] = *ptr++; 558 NCR_DMA(("flsc_dma_setup: %d bytes written to fifo\n", n)); 559 fsc->sc_piomode = 1; 560 fsc->sc_active = 1; 561 *fsc->sc_pdmalen -= fsc->sc_dmasize; 562 *fsc->sc_dmaaddr += fsc->sc_dmasize; 563 *dmasize = fsc->sc_dmasize; 564 fsc->sc_dmasize = 0; 565 return 0; /* All done */ 566 } 567 /* 568 * If output and unaligned, copy unaligned data to fifo 569 */ 570 else if (datain == 0 && (int)ptr & 3) { 571 int n = 4 - ((int)ptr & 3); 572 NCR_DMA(("flsc_dma_setup: align %d bytes written to fifo\n", n)); 573 pa += n; 574 xfer -= n; 575 while (n--) 576 fsc->sc_reg[NCR_FIFO * 4] = *ptr++; 577 } 578 /* 579 * If unaligned address, read unaligned bytes into alignment buffer 580 */ 581 else if ((int)ptr & 3 || xfer & 3) { 582 pa = kvtop((caddr_t)fsc->sc_alignbuf); 583 xfer = fsc->sc_dmasize = min(xfer, sizeof (fsc->sc_unalignbuf)); 584 NCR_DMA(("flsc_dma_setup: align read by %d bytes\n", xfer)); 585 fsc->sc_xfr_align = 1; 586 } 587 /* 588 * If length smaller than longword, read into alignment buffer 589 * XXX doesn't work for 1 or 2 bytes !!!! 590 */ 591 else if (fsc->sc_dmasize < 4) { 592 NCR_DMA(("flsc_dma_setup: read remaining %d bytes\n", 593 fsc->sc_dmasize)); 594 pa = kvtop((caddr_t)fsc->sc_alignbuf); 595 fsc->sc_xfr_align = 1; 596 } 597 /* 598 * Finally, limit transfer length to multiple of 4 bytes. 599 */ 600 else { 601 fsc->sc_dmasize &= -4; 602 xfer &= -4; 603 } 604 605 while (xfer < fsc->sc_dmasize) { 606 if ((pa + xfer) != kvtop(*addr + xfer)) 607 break; 608 if ((fsc->sc_dmasize - xfer) < NBPG) 609 xfer = fsc->sc_dmasize; 610 else 611 xfer += NBPG; 612 } 613 614 fsc->sc_dmasize = xfer; 615 *dmasize = fsc->sc_dmasize; 616 fsc->sc_pa = pa; 617 #if defined(M68040) || defined(M68060) 618 if (mmutype == MMU_68040) { 619 if (fsc->sc_xfr_align) { 620 int n; 621 for (n = 0; n < sizeof (fsc->sc_unalignbuf); ++n) 622 fsc->sc_alignbuf[n] = n | 0x80; 623 dma_cachectl(fsc->sc_alignbuf, 624 sizeof(fsc->sc_unalignbuf)); 625 } 626 else 627 dma_cachectl(*fsc->sc_dmaaddr, fsc->sc_dmasize); 628 } 629 #endif 630 fsc->sc_reg[0x80] = 0; 631 *((u_long *)(fsc->sc_dmabase + (pa & 0x00fffffc))) = pa; 632 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 633 fsc->sc_portbits |= FLSC_PB_ENABLE_DMA | 634 (fsc->sc_datain ? FLSC_PB_DMA_READ : FLSC_PB_DMA_WRITE); 635 fsc->sc_reg[0x40] = fsc->sc_portbits; 636 NCR_DMA(("flsc_dma_setup: DMA %p->%lx/%d [%d]\n", 637 ptr, pa, fsc->sc_dmasize, *len)); 638 fsc->sc_active = 1; 639 return 0; 640 } 641 642 void 643 flsc_dma_go(sc) 644 struct ncr53c9x_softc *sc; 645 { 646 struct flsc_softc *fsc = (struct flsc_softc *)sc; 647 648 NCR_DMA(("flsc_dma_go: datain %d size %d\n", fsc->sc_datain, 649 fsc->sc_dmasize)); 650 if (sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 651 fsc->sc_active = 1; 652 return; 653 } else if (fsc->sc_piomode == 0) { 654 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 655 fsc->sc_portbits |= FLSC_PB_ENABLE_DMA | 656 (fsc->sc_datain ? FLSC_PB_DMA_READ : FLSC_PB_DMA_WRITE); 657 fsc->sc_reg[0x40] = fsc->sc_portbits; 658 } 659 } 660 661 void 662 flsc_dma_stop(sc) 663 struct ncr53c9x_softc *sc; 664 { 665 struct flsc_softc *fsc = (struct flsc_softc *)sc; 666 667 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 668 fsc->sc_reg[0x40] = fsc->sc_portbits; 669 670 fsc->sc_reg[0x80] = 0; 671 *((u_long *)fsc->sc_dmabase) = 0; 672 fsc->sc_piomode = 0; 673 } 674 675 int 676 flsc_dma_isactive(sc) 677 struct ncr53c9x_softc *sc; 678 { 679 struct flsc_softc *fsc = (struct flsc_softc *)sc; 680 681 return fsc->sc_active; 682 } 683