1 /* $NetBSD: flsc.c,v 1.47 2019/01/08 19:41:09 jdolecek 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 #ifdef __m68k__ 46 #include "opt_m68k_arch.h" 47 #endif 48 49 #include <sys/cdefs.h> 50 __KERNEL_RCSID(0, "$NetBSD: flsc.c,v 1.47 2019/01/08 19:41:09 jdolecek Exp $"); 51 52 #include <sys/types.h> 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/kernel.h> 56 #include <sys/errno.h> 57 #include <sys/ioctl.h> 58 #include <sys/device.h> 59 #include <sys/buf.h> 60 #include <sys/proc.h> 61 #include <sys/queue.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 70 #include <dev/ic/ncr53c9xreg.h> 71 #include <dev/ic/ncr53c9xvar.h> 72 73 #include <amiga/amiga/isr.h> 74 #include <amiga/dev/flscvar.h> 75 #include <amiga/dev/zbusvar.h> 76 77 int flscmatch(device_t, cfdata_t, void *); 78 void flscattach(device_t, device_t, void *); 79 80 /* Linkup to the rest of the kernel */ 81 CFATTACH_DECL_NEW(flsc, sizeof(struct flsc_softc), 82 flscmatch, flscattach, NULL, NULL); 83 84 /* 85 * Functions and the switch for the MI code. 86 */ 87 uint8_t flsc_read_reg(struct ncr53c9x_softc *, int); 88 void flsc_write_reg(struct ncr53c9x_softc *, int, uint8_t); 89 int flsc_dma_isintr(struct ncr53c9x_softc *); 90 void flsc_dma_reset(struct ncr53c9x_softc *); 91 int flsc_dma_intr(struct ncr53c9x_softc *); 92 int flsc_dma_setup(struct ncr53c9x_softc *, uint8_t **, 93 size_t *, int, size_t *); 94 void flsc_dma_go(struct ncr53c9x_softc *); 95 void flsc_dma_stop(struct ncr53c9x_softc *); 96 int flsc_dma_isactive(struct ncr53c9x_softc *); 97 void flsc_clear_latched_intr(struct ncr53c9x_softc *); 98 99 struct ncr53c9x_glue flsc_glue = { 100 flsc_read_reg, 101 flsc_write_reg, 102 flsc_dma_isintr, 103 flsc_dma_reset, 104 flsc_dma_intr, 105 flsc_dma_setup, 106 flsc_dma_go, 107 flsc_dma_stop, 108 flsc_dma_isactive, 109 flsc_clear_latched_intr, 110 }; 111 112 /* Maximum DMA transfer length to reduce impact on high-speed serial input */ 113 u_long flsc_max_dma = 1024; 114 extern int ser_open_speed; 115 116 extern int ncr53c9x_debug; 117 extern u_long scsi_nosync; 118 extern int shift_nosync; 119 120 /* 121 * if we are an Advanced Systems & Software FastlaneZ3 122 */ 123 int 124 flscmatch(device_t parent, cfdata_t cf, 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(device_t parent, device_t self, void *aux) 144 { 145 struct flsc_softc *fsc = device_private(self); 146 struct ncr53c9x_softc *sc = &fsc->sc_ncr53c9x; 147 struct zbus_args *zap; 148 149 /* 150 * Set up the glue for MI code early; we use some of it here. 151 */ 152 sc->sc_dev = self; 153 sc->sc_glue = &flsc_glue; 154 155 /* 156 * Save the regs 157 */ 158 zap = aux; 159 fsc->sc_dmabase = (volatile uint8_t *)zap->va; 160 fsc->sc_reg = &((volatile uint8_t *)zap->va)[0x1000001]; 161 162 sc->sc_freq = 40; /* Clocked at 40 MHz */ 163 164 aprint_normal(": 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 = (uint8_t *)((u_long)fsc->sc_unalignbuf & -4); 199 200 device_cfdata(self)->cf_flags |= 201 (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 uint8_t 229 flsc_read_reg(struct ncr53c9x_softc *sc, int reg) 230 { 231 struct flsc_softc *fsc = (struct flsc_softc *)sc; 232 233 return fsc->sc_reg[reg * 4]; 234 } 235 236 void 237 flsc_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t val) 238 { 239 struct flsc_softc *fsc = (struct flsc_softc *)sc; 240 struct ncr53c9x_tinfo *ti; 241 uint8_t v = val; 242 243 if (fsc->sc_piomode && reg == NCR_CMD && 244 v == (NCRCMD_TRANS | NCRCMD_DMA)) { 245 v = NCRCMD_TRANS; 246 } 247 /* 248 * Can't do synchronous transfers in XS_CTL_POLL mode: 249 * If starting XS_CTL_POLL command, clear defer sync negotiation 250 * by clearing the T_NEGOTIATE flag. If starting XS_CTL_POLL and 251 * the device is currently running synchronous, force another 252 * T_NEGOTIATE with 0 offset. 253 */ 254 if (reg == NCR_SELID) { 255 ti = &sc->sc_tinfo[ 256 sc->sc_nexus->xs->xs_periph->periph_target]; 257 if (sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 258 if (ti->flags & T_SYNCMODE) { 259 ti->flags ^= T_SYNCMODE | T_NEGOTIATE; 260 } else if (ti->flags & T_NEGOTIATE) { 261 ti->flags ^= T_NEGOTIATE | T_SYNCHOFF; 262 /* save T_NEGOTIATE in private flags? */ 263 } 264 } else { 265 /* 266 * If we haven't attempted sync negotiation yet, 267 * do it now. 268 */ 269 if ((ti->flags & (T_SYNCMODE | T_SYNCHOFF)) == 270 T_SYNCHOFF && 271 sc->sc_minsync != 0) /* XXX */ 272 ti->flags ^= T_NEGOTIATE | T_SYNCHOFF; 273 } 274 } 275 if (reg == NCR_CMD && v == NCRCMD_SETATN && 276 sc->sc_flags & NCR_SYNCHNEGO && 277 sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 278 ti = &sc->sc_tinfo[ 279 sc->sc_nexus->xs->xs_periph->periph_target]; 280 ti->offset = 0; 281 } 282 fsc->sc_reg[reg * 4] = v; 283 } 284 285 int 286 flsc_dma_isintr(struct ncr53c9x_softc *sc) 287 { 288 struct flsc_softc *fsc = (struct flsc_softc *)sc; 289 unsigned int hardbits; 290 291 hardbits = fsc->sc_reg[0x40]; 292 if ((hardbits & FLSC_HB_IACT) != 0) 293 return (fsc->sc_csr = 0); 294 295 if (sc->sc_state == NCR_CONNECTED || sc->sc_state == NCR_SELECTING) 296 fsc->sc_portbits |= FLSC_PB_LED; 297 else 298 fsc->sc_portbits &= ~FLSC_PB_LED; 299 300 if ((hardbits & FLSC_HB_CREQ) != 0 && (hardbits & FLSC_HB_MINT) == 0 && 301 (fsc->sc_reg[NCR_STAT * 4] & NCRSTAT_INT) != 0) { 302 return 1; 303 } 304 /* Do I still need this? */ 305 if (fsc->sc_piomode && (fsc->sc_reg[NCR_STAT * 4] & NCRSTAT_INT) != 0 && 306 (hardbits & FLSC_HB_MINT) == 0) 307 return 1; 308 309 fsc->sc_reg[0x40] = fsc->sc_portbits & ~FLSC_PB_INT_BITS; 310 fsc->sc_reg[0x40] = fsc->sc_portbits; 311 return 0; 312 } 313 314 void 315 flsc_clear_latched_intr(struct ncr53c9x_softc *sc) 316 { 317 struct flsc_softc *fsc = (struct flsc_softc *)sc; 318 319 fsc->sc_reg[0x40] = fsc->sc_portbits & ~FLSC_PB_INT_BITS; 320 fsc->sc_reg[0x40] = fsc->sc_portbits; 321 } 322 323 void 324 flsc_dma_reset(struct ncr53c9x_softc *sc) 325 { 326 struct flsc_softc *fsc = (struct flsc_softc *)sc; 327 struct ncr53c9x_tinfo *ti; 328 329 if (sc->sc_nexus) 330 ti = &sc->sc_tinfo[sc->sc_nexus->xs->xs_periph->periph_target]; 331 else 332 ti = &sc->sc_tinfo[1]; /* XXX */ 333 if (fsc->sc_active) { 334 printf("dmaaddr %p dmasize %d stat %x flags %x off %d ", 335 *fsc->sc_dmaaddr, fsc->sc_dmasize, 336 fsc->sc_reg[NCR_STAT * 4], ti->flags, ti->offset); 337 printf("per %d ff %x intr %x\n", 338 ti->period, fsc->sc_reg[NCR_FFLAG * 4], 339 fsc->sc_reg[NCR_INTR * 4]); 340 #ifdef DDB 341 Debugger(); 342 #endif 343 } 344 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 345 fsc->sc_reg[0x40] = fsc->sc_portbits; 346 fsc->sc_reg[0x80] = 0; 347 *((volatile uint32_t *)fsc->sc_dmabase) = 0; 348 fsc->sc_active = 0; 349 fsc->sc_piomode = 0; 350 } 351 352 int 353 flsc_dma_intr(struct ncr53c9x_softc *sc) 354 { 355 register struct flsc_softc *fsc = (struct flsc_softc *)sc; 356 uint8_t *p; 357 volatile uint8_t *cmdreg, *intrreg, *statreg, *fiforeg; 358 u_int flscphase, flscstat, flscintr; 359 int cnt; 360 361 NCR_DMA(("flsc_dma_intr: pio %d cnt %d int %x stat %x fifo %d ", 362 fsc->sc_piomode, fsc->sc_dmasize, sc->sc_espintr, sc->sc_espstat, 363 fsc->sc_reg[NCR_FFLAG * 4] & NCRFIFO_FF)); 364 if ((fsc->sc_reg[0x40] & FLSC_HB_CREQ) == 0) 365 printf("flsc_dma_intr: csr %x stat %x intr %x\n", fsc->sc_csr, 366 sc->sc_espstat, sc->sc_espintr); 367 if (fsc->sc_active == 0) { 368 printf("flsc_intr--inactive DMA\n"); 369 return -1; 370 } 371 372 /* if DMA transfer, update sc_dmaaddr and sc_pdmalen, else PIO xfer */ 373 if (fsc->sc_piomode == 0) { 374 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 375 fsc->sc_reg[0x40] = fsc->sc_portbits; 376 fsc->sc_reg[0x80] = 0; 377 *((volatile uint32_t *)fsc->sc_dmabase) = 0; 378 cnt = fsc->sc_reg[NCR_TCL * 4]; 379 cnt += fsc->sc_reg[NCR_TCM * 4] << 8; 380 cnt += fsc->sc_reg[NCR_TCH * 4] << 16; 381 if (!fsc->sc_datain) { 382 cnt += fsc->sc_reg[NCR_FFLAG * 4] & NCRFIFO_FF; 383 fsc->sc_reg[NCR_CMD * 4] = NCRCMD_FLUSH; 384 } 385 cnt = fsc->sc_dmasize - cnt; /* number of bytes transferred */ 386 NCR_DMA(("DMA xferred %d\n", cnt)); 387 if (fsc->sc_xfr_align) { 388 int i; 389 for (i = 0; i < cnt; ++i) 390 (*fsc->sc_dmaaddr)[i] = fsc->sc_alignbuf[i]; 391 fsc->sc_xfr_align = 0; 392 } 393 *fsc->sc_dmaaddr += cnt; 394 *fsc->sc_pdmalen -= cnt; 395 fsc->sc_active = 0; 396 return 0; 397 } 398 399 if ((sc->sc_espintr & NCRINTR_BS) == 0) { 400 fsc->sc_active = 0; 401 fsc->sc_piomode = 0; 402 NCR_DMA(("no NCRINTR_BS\n")); 403 return 0; 404 } 405 406 cnt = fsc->sc_dmasize; 407 #if 0 408 if (cnt == 0) { 409 printf("data interrupt, but no count left."); 410 } 411 #endif 412 413 p = *fsc->sc_dmaaddr; 414 flscphase = sc->sc_phase; 415 flscstat = (u_int)sc->sc_espstat; 416 flscintr = (u_int)sc->sc_espintr; 417 cmdreg = fsc->sc_reg + NCR_CMD * 4; 418 fiforeg = fsc->sc_reg + NCR_FIFO * 4; 419 statreg = fsc->sc_reg + NCR_STAT * 4; 420 intrreg = fsc->sc_reg + NCR_INTR * 4; 421 NCR_DMA(("PIO %d datain %d phase %d stat %x intr %x\n", 422 cnt, fsc->sc_datain, flscphase, flscstat, flscintr)); 423 do { 424 if (fsc->sc_datain) { 425 *p++ = *fiforeg; 426 cnt--; 427 if (flscphase == DATA_IN_PHASE) { 428 *cmdreg = NCRCMD_TRANS; 429 } else { 430 fsc->sc_active = 0; 431 } 432 } else { 433 NCR_DMA(("flsc_dma_intr: PIO out- phase %d cnt %d active %d\n", flscphase, cnt, 434 fsc->sc_active)); 435 if ( (flscphase == DATA_OUT_PHASE) 436 || (flscphase == MESSAGE_OUT_PHASE)) { 437 int n; 438 n = 16 - (fsc->sc_reg[NCR_FFLAG * 4] & NCRFIFO_FF); 439 if (n > cnt) 440 n = cnt; 441 cnt -= n; 442 while (n-- > 0) 443 *fiforeg = *p++; 444 *cmdreg = NCRCMD_TRANS; 445 } else { 446 fsc->sc_active = 0; 447 } 448 } 449 450 if (fsc->sc_active && cnt) { 451 while ((*statreg & 0x80) == 0) 452 ; 453 flscstat = *statreg; 454 flscintr = *intrreg; 455 flscphase = (flscintr & NCRINTR_DIS) 456 ? /* Disconnected */ BUSFREE_PHASE 457 : flscstat & PHASE_MASK; 458 } 459 } while (cnt && fsc->sc_active && (flscintr & NCRINTR_BS) != 0); 460 #if 1 461 if (fsc->sc_dmasize < 8 && cnt) 462 printf("flsc_dma_intr: short transfer: dmasize %d cnt %d\n", 463 fsc->sc_dmasize, cnt); 464 #endif 465 NCR_DMA(("flsc_dma_intr: PIO transfer [%d], %d->%d phase %d stat %x intr %x\n", 466 *fsc->sc_pdmalen, fsc->sc_dmasize, cnt, flscphase, flscstat, flscintr)); 467 sc->sc_phase = flscphase; 468 sc->sc_espstat = (uint8_t)flscstat; 469 sc->sc_espintr = (uint8_t)flscintr; 470 *fsc->sc_dmaaddr = p; 471 *fsc->sc_pdmalen -= fsc->sc_dmasize - cnt; 472 fsc->sc_dmasize = cnt; 473 474 if (*fsc->sc_pdmalen == 0) { 475 sc->sc_espstat |= NCRSTAT_TC; 476 fsc->sc_piomode = 0; 477 } 478 return 0; 479 } 480 481 int 482 flsc_dma_setup(struct ncr53c9x_softc *sc, uint8_t **addr, size_t *len, 483 int datain, size_t *dmasize) 484 { 485 struct flsc_softc *fsc = (struct flsc_softc *)sc; 486 paddr_t pa; 487 uint8_t *ptr; 488 size_t xfer; 489 490 fsc->sc_dmaaddr = addr; 491 fsc->sc_pdmalen = len; 492 fsc->sc_datain = datain; 493 fsc->sc_dmasize = *dmasize; 494 if (sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 495 /* polling mode, use PIO */ 496 *dmasize = fsc->sc_dmasize; 497 NCR_DMA(("pfsc_dma_setup: PIO %p/%d [%d]\n", *addr, 498 fsc->sc_dmasize, *len)); 499 fsc->sc_piomode = 1; 500 if (datain == 0) { 501 int n; 502 n = fsc->sc_dmasize; 503 if (n > 16) 504 n = 16; 505 while (n-- > 0) { 506 fsc->sc_reg[NCR_FIFO * 4] = **fsc->sc_dmaaddr; 507 (*fsc->sc_pdmalen)--; 508 (*fsc->sc_dmaaddr)++; 509 --fsc->sc_dmasize; 510 } 511 } 512 return 0; 513 } 514 /* 515 * DMA can be nasty for high-speed serial input, so limit the 516 * size of this DMA operation if the serial port is running at 517 * a high speed (higher than 19200 for now - should be adjusted 518 * based on CPU type and speed?). 519 * XXX - add serial speed check XXX 520 */ 521 if (ser_open_speed > 19200 && flsc_max_dma != 0 && 522 fsc->sc_dmasize > flsc_max_dma) 523 fsc->sc_dmasize = flsc_max_dma; 524 ptr = *addr; /* Kernel virtual address */ 525 pa = kvtop(ptr); /* Physical address of DMA */ 526 xfer = uimin(fsc->sc_dmasize, PAGE_SIZE - (pa & (PAGE_SIZE - 1))); 527 fsc->sc_xfr_align = 0; 528 fsc->sc_piomode = 0; 529 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 530 fsc->sc_reg[0x40] = fsc->sc_portbits; 531 fsc->sc_reg[0x80] = 0; 532 *((volatile uint32_t *)fsc->sc_dmabase) = 0; 533 534 /* 535 * If output and length < 16, copy to fifo 536 */ 537 if (datain == 0 && fsc->sc_dmasize < 16) { 538 int n; 539 for (n = 0; n < fsc->sc_dmasize; ++n) 540 fsc->sc_reg[NCR_FIFO * 4] = *ptr++; 541 NCR_DMA(("flsc_dma_setup: %d bytes written to fifo\n", n)); 542 fsc->sc_piomode = 1; 543 fsc->sc_active = 1; 544 *fsc->sc_pdmalen -= fsc->sc_dmasize; 545 *fsc->sc_dmaaddr += fsc->sc_dmasize; 546 *dmasize = fsc->sc_dmasize; 547 fsc->sc_dmasize = 0; 548 return 0; /* All done */ 549 } 550 /* 551 * If output and unaligned, copy unaligned data to fifo 552 */ 553 else if (datain == 0 && (int)ptr & 3) { 554 int n = 4 - ((int)ptr & 3); 555 NCR_DMA(("flsc_dma_setup: align %d bytes written to fifo\n", n)); 556 pa += n; 557 xfer -= n; 558 while (n--) 559 fsc->sc_reg[NCR_FIFO * 4] = *ptr++; 560 } 561 /* 562 * If unaligned address, read unaligned bytes into alignment buffer 563 */ 564 else if ((int)ptr & 3 || xfer & 3) { 565 pa = kvtop((void *)fsc->sc_alignbuf); 566 xfer = fsc->sc_dmasize = uimin(xfer, sizeof(fsc->sc_unalignbuf)); 567 NCR_DMA(("flsc_dma_setup: align read by %d bytes\n", xfer)); 568 fsc->sc_xfr_align = 1; 569 } 570 /* 571 * If length smaller than longword, read into alignment buffer 572 * XXX doesn't work for 1 or 2 bytes !!!! 573 */ 574 else if (fsc->sc_dmasize < 4) { 575 NCR_DMA(("flsc_dma_setup: read remaining %d bytes\n", 576 fsc->sc_dmasize)); 577 pa = kvtop((void *)fsc->sc_alignbuf); 578 fsc->sc_xfr_align = 1; 579 } 580 /* 581 * Finally, limit transfer length to multiple of 4 bytes. 582 */ 583 else { 584 fsc->sc_dmasize &= -4; 585 xfer &= -4; 586 } 587 588 while (xfer < fsc->sc_dmasize) { 589 if ((pa + xfer) != kvtop(*addr + xfer)) 590 break; 591 if ((fsc->sc_dmasize - xfer) < PAGE_SIZE) 592 xfer = fsc->sc_dmasize; 593 else 594 xfer += PAGE_SIZE; 595 } 596 597 fsc->sc_dmasize = xfer; 598 *dmasize = fsc->sc_dmasize; 599 fsc->sc_pa = pa; 600 #if defined(M68040) || defined(M68060) 601 if (mmutype == MMU_68040) { 602 if (fsc->sc_xfr_align) { 603 int n; 604 for (n = 0; n < sizeof(fsc->sc_unalignbuf); ++n) 605 fsc->sc_alignbuf[n] = n | 0x80; 606 dma_cachectl(fsc->sc_alignbuf, 607 sizeof(fsc->sc_unalignbuf)); 608 } 609 else 610 dma_cachectl(*fsc->sc_dmaaddr, fsc->sc_dmasize); 611 } 612 #endif 613 fsc->sc_reg[0x80] = 0; 614 *((volatile uint32_t *)(fsc->sc_dmabase + (pa & 0x00fffffc))) = pa; 615 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 616 fsc->sc_portbits |= FLSC_PB_ENABLE_DMA | 617 (fsc->sc_datain ? FLSC_PB_DMA_READ : FLSC_PB_DMA_WRITE); 618 fsc->sc_reg[0x40] = fsc->sc_portbits; 619 NCR_DMA(("flsc_dma_setup: DMA %p->%lx/%d [%d]\n", 620 ptr, pa, fsc->sc_dmasize, *len)); 621 fsc->sc_active = 1; 622 return 0; 623 } 624 625 void 626 flsc_dma_go(struct ncr53c9x_softc *sc) 627 { 628 struct flsc_softc *fsc = (struct flsc_softc *)sc; 629 630 NCR_DMA(("flsc_dma_go: datain %d size %d\n", fsc->sc_datain, 631 fsc->sc_dmasize)); 632 if (sc->sc_nexus->xs->xs_control & XS_CTL_POLL) { 633 fsc->sc_active = 1; 634 return; 635 } else if (fsc->sc_piomode == 0) { 636 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 637 fsc->sc_portbits |= FLSC_PB_ENABLE_DMA | 638 (fsc->sc_datain ? FLSC_PB_DMA_READ : FLSC_PB_DMA_WRITE); 639 fsc->sc_reg[0x40] = fsc->sc_portbits; 640 } 641 } 642 643 void 644 flsc_dma_stop(struct ncr53c9x_softc *sc) 645 { 646 struct flsc_softc *fsc = (struct flsc_softc *)sc; 647 648 fsc->sc_portbits &= ~FLSC_PB_DMA_BITS; 649 fsc->sc_reg[0x40] = fsc->sc_portbits; 650 651 fsc->sc_reg[0x80] = 0; 652 *((volatile uint32_t *)fsc->sc_dmabase) = 0; 653 fsc->sc_piomode = 0; 654 } 655 656 int 657 flsc_dma_isactive(struct ncr53c9x_softc *sc) 658 { 659 struct flsc_softc *fsc = (struct flsc_softc *)sc; 660 661 return fsc->sc_active; 662 } 663