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