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