1 /* $NetBSD: sbc.c,v 1.40 1999/11/02 06:42:26 scottr Exp $ */ 2 3 /* 4 * Copyright (C) 1996 Scott Reynolds. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* 30 * This file contains only the machine-dependent parts of the mac68k 31 * NCR 5380 SCSI driver. (Autoconfig stuff and PDMA functions.) 32 * The machine-independent parts are in ncr5380sbc.c 33 * 34 * Supported hardware includes: 35 * Macintosh II family 5380-based controller 36 * 37 * Credits, history: 38 * 39 * Scott Reynolds wrote this module, based on work by Allen Briggs 40 * (mac68k), Gordon W. Ross and David Jones (sun3), and Leo Weppelman 41 * (atari). Thanks to Allen for supplying crucial interpretation of the 42 * NetBSD/mac68k 1.1 'ncrscsi' driver. Also, Allen, Gordon, and Jason 43 * Thorpe all helped to refine this code, and were considerable sources 44 * of moral support. 45 */ 46 #include "opt_ddb.h" 47 48 #include <sys/types.h> 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/kernel.h> 52 #include <sys/errno.h> 53 #include <sys/device.h> 54 #include <sys/buf.h> 55 #include <sys/proc.h> 56 #include <sys/user.h> 57 58 #include <dev/scsipi/scsi_all.h> 59 #include <dev/scsipi/scsipi_all.h> 60 #include <dev/scsipi/scsipi_debug.h> 61 #include <dev/scsipi/scsiconf.h> 62 63 #include <dev/ic/ncr5380reg.h> 64 #include <dev/ic/ncr5380var.h> 65 66 #include <machine/cpu.h> 67 #include <machine/viareg.h> 68 69 #include <mac68k/dev/sbcreg.h> 70 #include <mac68k/dev/sbcvar.h> 71 72 /* SBC_DEBUG -- relies on DDB */ 73 #ifdef SBC_DEBUG 74 # define SBC_DB_INTR 0x01 75 # define SBC_DB_DMA 0x02 76 # define SBC_DB_REG 0x04 77 # define SBC_DB_BREAK 0x08 78 # ifndef DDB 79 # define Debugger() printf("Debug: sbc.c:%d\n", __LINE__) 80 # endif 81 # define SBC_BREAK \ 82 do { if (sbc_debug & SBC_DB_BREAK) Debugger(); } while (0) 83 #else 84 # define SBC_BREAK 85 #endif 86 87 88 int sbc_debug = 0 /* | SBC_DB_INTR | SBC_DB_DMA */; 89 int sbc_link_flags = 0 /* | SDEV_DB2 */; 90 int sbc_options = 0 /* | SBC_PDMA */; 91 92 /* This is copied from julian's bt driver */ 93 /* "so we have a default dev struct for our link struct." */ 94 struct scsipi_device sbc_dev = { 95 NULL, /* Use default error handler. */ 96 NULL, /* Use default start handler. */ 97 NULL, /* Use default async handler. */ 98 NULL, /* Use default "done" routine. */ 99 }; 100 101 extern label_t *nofault; 102 extern caddr_t m68k_fault_addr; 103 104 static int sbc_wait_busy __P((struct ncr5380_softc *)); 105 static int sbc_ready __P((struct ncr5380_softc *)); 106 static int sbc_wait_dreq __P((struct ncr5380_softc *)); 107 108 109 /*** 110 * General support for Mac-specific SCSI logic. 111 ***/ 112 113 /* These are used in the following inline functions. */ 114 int sbc_wait_busy_timo = 1000 * 5000; /* X2 = 10 S. */ 115 int sbc_ready_timo = 1000 * 5000; /* X2 = 10 S. */ 116 int sbc_wait_dreq_timo = 1000 * 5000; /* X2 = 10 S. */ 117 118 /* Return zero on success. */ 119 static __inline__ int 120 sbc_wait_busy(sc) 121 struct ncr5380_softc *sc; 122 { 123 int timo = sbc_wait_busy_timo; 124 for (;;) { 125 if (SCI_BUSY(sc)) { 126 timo = 0; /* return 0 */ 127 break; 128 } 129 if (--timo < 0) 130 break; /* return -1 */ 131 delay(2); 132 } 133 return (timo); 134 } 135 136 static __inline__ int 137 sbc_ready(sc) 138 struct ncr5380_softc *sc; 139 { 140 int timo = sbc_ready_timo; 141 142 for (;;) { 143 if ((*sc->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) 144 == (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 145 timo = 0; 146 break; 147 } 148 if (((*sc->sci_csr & SCI_CSR_PHASE_MATCH) == 0) 149 || (SCI_BUSY(sc) == 0)) { 150 timo = -1; 151 break; 152 } 153 if (--timo < 0) 154 break; /* return -1 */ 155 delay(2); 156 } 157 return (timo); 158 } 159 160 static __inline__ int 161 sbc_wait_dreq(sc) 162 struct ncr5380_softc *sc; 163 { 164 int timo = sbc_wait_dreq_timo; 165 166 for (;;) { 167 if ((*sc->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) 168 == (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 169 timo = 0; 170 break; 171 } 172 if (--timo < 0) 173 break; /* return -1 */ 174 delay(2); 175 } 176 return (timo); 177 } 178 179 void 180 sbc_irq_intr(p) 181 void *p; 182 { 183 struct ncr5380_softc *ncr_sc = p; 184 struct sbc_softc *sc = (struct sbc_softc *)ncr_sc; 185 int claimed = 0; 186 187 /* How we ever arrive here without IRQ set is a mystery... */ 188 if (*ncr_sc->sci_csr & SCI_CSR_INT) { 189 #ifdef SBC_DEBUG 190 if (sbc_debug & SBC_DB_INTR) 191 decode_5380_intr(ncr_sc); 192 #endif 193 if (!cold) 194 claimed = ncr5380_intr(ncr_sc); 195 if (!claimed) { 196 if (((*ncr_sc->sci_csr & ~SCI_CSR_PHASE_MATCH) == SCI_CSR_INT) 197 && ((*ncr_sc->sci_bus_csr & ~SCI_BUS_RST) == 0)) { 198 SCI_CLR_INTR(ncr_sc); /* RST interrupt */ 199 if (sc->sc_clrintr) 200 (*sc->sc_clrintr)(ncr_sc); 201 } 202 #ifdef SBC_DEBUG 203 else { 204 printf("%s: spurious intr\n", 205 ncr_sc->sc_dev.dv_xname); 206 SBC_BREAK; 207 } 208 #endif 209 } 210 } 211 } 212 213 #ifdef SBC_DEBUG 214 void 215 decode_5380_intr(ncr_sc) 216 struct ncr5380_softc *ncr_sc; 217 { 218 u_int8_t csr = *ncr_sc->sci_csr; 219 u_int8_t bus_csr = *ncr_sc->sci_bus_csr; 220 221 if (((csr & ~(SCI_CSR_PHASE_MATCH | SCI_CSR_ATN)) == SCI_CSR_INT) && 222 ((bus_csr & ~(SCI_BUS_MSG | SCI_BUS_CD | SCI_BUS_IO | SCI_BUS_DBP)) == SCI_BUS_SEL)) { 223 if (csr & SCI_BUS_IO) 224 printf("%s: reselect\n", ncr_sc->sc_dev.dv_xname); 225 else 226 printf("%s: select\n", ncr_sc->sc_dev.dv_xname); 227 } else if (((csr & ~SCI_CSR_ACK) == (SCI_CSR_DONE | SCI_CSR_INT)) && 228 ((bus_csr & (SCI_BUS_RST | SCI_BUS_BSY | SCI_BUS_SEL)) == SCI_BUS_BSY)) 229 printf("%s: dma eop\n", ncr_sc->sc_dev.dv_xname); 230 else if (((csr & ~SCI_CSR_PHASE_MATCH) == SCI_CSR_INT) && 231 ((bus_csr & ~SCI_BUS_RST) == 0)) 232 printf("%s: bus reset\n", ncr_sc->sc_dev.dv_xname); 233 else if (((csr & ~(SCI_CSR_DREQ | SCI_CSR_ATN | SCI_CSR_ACK)) == (SCI_CSR_PERR | SCI_CSR_INT | SCI_CSR_PHASE_MATCH)) && 234 ((bus_csr & (SCI_BUS_RST | SCI_BUS_BSY | SCI_BUS_SEL)) == SCI_BUS_BSY)) 235 printf("%s: parity error\n", ncr_sc->sc_dev.dv_xname); 236 else if (((csr & ~SCI_CSR_ATN) == SCI_CSR_INT) && 237 ((bus_csr & (SCI_BUS_RST | SCI_BUS_BSY | SCI_BUS_REQ | SCI_BUS_SEL)) == (SCI_BUS_BSY | SCI_BUS_REQ))) 238 printf("%s: phase mismatch\n", ncr_sc->sc_dev.dv_xname); 239 else if (((csr & ~SCI_CSR_PHASE_MATCH) == (SCI_CSR_INT | SCI_CSR_DISC)) && 240 (bus_csr == 0)) 241 printf("%s: disconnect\n", ncr_sc->sc_dev.dv_xname); 242 else 243 printf("%s: unknown intr: csr=%x, bus_csr=%x\n", 244 ncr_sc->sc_dev.dv_xname, csr, bus_csr); 245 } 246 #endif 247 248 249 /*** 250 * The following code implements polled PDMA. 251 ***/ 252 253 int 254 sbc_pdma_in(ncr_sc, phase, datalen, data) 255 struct ncr5380_softc *ncr_sc; 256 int phase; 257 int datalen; 258 u_char *data; 259 { 260 struct sbc_softc *sc = (struct sbc_softc *)ncr_sc; 261 volatile u_int32_t *long_data = (u_int32_t *)sc->sc_drq_addr; 262 volatile u_int8_t *byte_data = (u_int8_t *)sc->sc_nodrq_addr; 263 int resid, s; 264 265 if (datalen < ncr_sc->sc_min_dma_len || 266 (sc->sc_options & SBC_PDMA) == 0) 267 return ncr5380_pio_in(ncr_sc, phase, datalen, data); 268 269 s = splbio(); 270 if (sbc_wait_busy(ncr_sc)) { 271 splx(s); 272 return 0; 273 } 274 275 *ncr_sc->sci_mode |= SCI_MODE_DMA; 276 *ncr_sc->sci_irecv = 0; 277 278 #define R4 *((u_int32_t *)data)++ = *long_data 279 #define R1 *((u_int8_t *)data)++ = *byte_data 280 for (resid = datalen; resid >= 128; resid -= 128) { 281 if (sbc_ready(ncr_sc)) 282 goto interrupt; 283 R4; R4; R4; R4; R4; R4; R4; R4; 284 R4; R4; R4; R4; R4; R4; R4; R4; 285 R4; R4; R4; R4; R4; R4; R4; R4; 286 R4; R4; R4; R4; R4; R4; R4; R4; /* 128 */ 287 } 288 while (resid) { 289 if (sbc_ready(ncr_sc)) 290 goto interrupt; 291 R1; 292 resid--; 293 } 294 #undef R4 295 #undef R1 296 297 interrupt: 298 SCI_CLR_INTR(ncr_sc); 299 *ncr_sc->sci_mode &= ~SCI_MODE_DMA; 300 *ncr_sc->sci_icmd = 0; 301 splx(s); 302 return (datalen - resid); 303 } 304 305 int 306 sbc_pdma_out(ncr_sc, phase, datalen, data) 307 struct ncr5380_softc *ncr_sc; 308 int phase; 309 int datalen; 310 u_char *data; 311 { 312 struct sbc_softc *sc = (struct sbc_softc *)ncr_sc; 313 volatile u_int32_t *long_data = (u_int32_t *)sc->sc_drq_addr; 314 volatile u_int8_t *byte_data = (u_int8_t *)sc->sc_nodrq_addr; 315 label_t faultbuf; 316 int resid, s; 317 u_int8_t icmd; 318 319 #if 1 320 /* Work around lame gcc initialization bug */ 321 (void)&data; 322 #endif 323 324 if (datalen < ncr_sc->sc_min_dma_len || 325 (sc->sc_options & SBC_PDMA) == 0) 326 return ncr5380_pio_out(ncr_sc, phase, datalen, data); 327 328 s = splbio(); 329 if (sbc_wait_busy(ncr_sc)) { 330 splx(s); 331 return 0; 332 } 333 334 icmd = *(ncr_sc->sci_icmd) & SCI_ICMD_RMASK; 335 *ncr_sc->sci_icmd = icmd | SCI_ICMD_DATA; 336 *ncr_sc->sci_mode |= SCI_MODE_DMA; 337 *ncr_sc->sci_dma_send = 0; 338 339 /* 340 * Setup for a possible bus error caused by SCSI controller 341 * switching out of DATA OUT before we're done with the 342 * current transfer. (See comment before sbc_drq_intr().) 343 */ 344 nofault = &faultbuf; 345 346 if (setjmp(nofault)) { 347 printf("buf = 0x%lx, fault = 0x%lx\n", 348 (u_long)sc->sc_drq_addr, (u_long)m68k_fault_addr); 349 panic("Unexpected bus error in sbc_pdma_out()"); 350 } 351 352 #define W1 *byte_data = *((u_int8_t *)data)++ 353 #define W4 *long_data = *((u_int32_t *)data)++ 354 for (resid = datalen; resid >= 64; resid -= 64) { 355 if (sbc_ready(ncr_sc)) 356 goto interrupt; 357 W1; 358 if (sbc_ready(ncr_sc)) 359 goto interrupt; 360 W1; 361 if (sbc_ready(ncr_sc)) 362 goto interrupt; 363 W1; 364 if (sbc_ready(ncr_sc)) 365 goto interrupt; 366 W1; 367 if (sbc_ready(ncr_sc)) 368 goto interrupt; 369 W4; W4; W4; W4; 370 W4; W4; W4; W4; 371 W4; W4; W4; W4; 372 W4; W4; W4; 373 } 374 while (resid) { 375 if (sbc_ready(ncr_sc)) 376 goto interrupt; 377 W1; 378 resid--; 379 } 380 #undef W1 381 #undef W4 382 if (sbc_wait_dreq(ncr_sc)) 383 printf("%s: timeout waiting for DREQ.\n", 384 ncr_sc->sc_dev.dv_xname); 385 386 *byte_data = 0; 387 goto done; 388 389 interrupt: 390 if ((*ncr_sc->sci_csr & SCI_CSR_PHASE_MATCH) == 0) { 391 *ncr_sc->sci_icmd = icmd & ~SCI_ICMD_DATA; 392 --resid; 393 } 394 395 done: 396 SCI_CLR_INTR(ncr_sc); 397 *ncr_sc->sci_mode &= ~SCI_MODE_DMA; 398 *ncr_sc->sci_icmd = icmd; 399 splx(s); 400 return (datalen - resid); 401 } 402 403 404 /*** 405 * The following code implements interrupt-driven PDMA. 406 ***/ 407 408 /* 409 * This is the meat of the PDMA transfer. 410 * When we get here, we shove data as fast as the mac can take it. 411 * We depend on several things: 412 * * All macs after the Mac Plus that have a 5380 chip should have a general 413 * logic IC that handshakes data for blind transfers. 414 * * If the SCSI controller finishes sending/receiving data before we do, 415 * the same general logic IC will generate a /BERR for us in short order. 416 * * The fault address for said /BERR minus the base address for the 417 * transfer will be the amount of data that was actually written. 418 * 419 * We use the nofault flag and the setjmp/longjmp in locore.s so we can 420 * detect and handle the bus error for early termination of a command. 421 * This is usually caused by a disconnecting target. 422 */ 423 void 424 sbc_drq_intr(p) 425 void *p; 426 { 427 struct sbc_softc *sc = (struct sbc_softc *)p; 428 struct ncr5380_softc *ncr_sc = (struct ncr5380_softc *)p; 429 struct sci_req *sr = ncr_sc->sc_current; 430 struct sbc_pdma_handle *dh = sr->sr_dma_hand; 431 label_t faultbuf; 432 volatile u_int32_t *long_drq; 433 u_int32_t *long_data; 434 volatile u_int8_t *drq; 435 u_int8_t *data; 436 int count, dcount, resid; 437 u_int8_t tmp; 438 439 /* Work around lame gcc initialization bug */ 440 (void)&drq; 441 442 /* 443 * If we're not ready to xfer data, or have no more, just return. 444 */ 445 if ((*ncr_sc->sci_csr & SCI_CSR_DREQ) == 0 || dh->dh_len == 0) 446 return; 447 448 #ifdef SBC_DEBUG 449 if (sbc_debug & SBC_DB_INTR) 450 printf("%s: drq intr, dh_len=0x%x, dh_flags=0x%x\n", 451 ncr_sc->sc_dev.dv_xname, dh->dh_len, dh->dh_flags); 452 #endif 453 454 /* 455 * Setup for a possible bus error caused by SCSI controller 456 * switching out of DATA-IN/OUT before we're done with the 457 * current transfer. 458 */ 459 nofault = &faultbuf; 460 461 if (setjmp(nofault)) { 462 nofault = (label_t *)0; 463 if ((dh->dh_flags & SBC_DH_DONE) == 0) { 464 count = (( (u_long)m68k_fault_addr 465 - (u_long)sc->sc_drq_addr)); 466 467 if ((count < 0) || (count > dh->dh_len)) { 468 printf("%s: complete=0x%x (pending 0x%x)\n", 469 ncr_sc->sc_dev.dv_xname, count, dh->dh_len); 470 panic("something is wrong"); 471 } 472 473 dh->dh_addr += count; 474 dh->dh_len -= count; 475 } else 476 count = 0; 477 478 #ifdef SBC_DEBUG 479 if (sbc_debug & SBC_DB_INTR) 480 printf("%s: drq /berr, complete=0x%x (pending 0x%x)\n", 481 ncr_sc->sc_dev.dv_xname, count, dh->dh_len); 482 #endif 483 m68k_fault_addr = 0; 484 485 return; 486 } 487 488 if (dh->dh_flags & SBC_DH_OUT) { /* Data Out */ 489 dcount = 0; 490 491 /* 492 * Get the source address aligned. 493 */ 494 resid = 495 count = min(dh->dh_len, 4 - (((int)dh->dh_addr) & 0x3)); 496 if (count && count < 4) { 497 drq = (volatile u_int8_t *)sc->sc_drq_addr; 498 data = (u_int8_t *)dh->dh_addr; 499 500 #define W1 *drq++ = *data++ 501 while (count) { 502 W1; count--; 503 } 504 #undef W1 505 dh->dh_addr += resid; 506 dh->dh_len -= resid; 507 } 508 509 /* 510 * Start the transfer. 511 */ 512 while (dh->dh_len) { 513 dcount = count = min(dh->dh_len, MAX_DMA_LEN); 514 long_drq = (volatile u_int32_t *)sc->sc_drq_addr; 515 long_data = (u_int32_t *)dh->dh_addr; 516 517 #define W4 *long_drq++ = *long_data++ 518 while (count >= 64) { 519 W4; W4; W4; W4; W4; W4; W4; W4; 520 W4; W4; W4; W4; W4; W4; W4; W4; /* 64 */ 521 count -= 64; 522 } 523 while (count >= 4) { 524 W4; count -= 4; 525 } 526 #undef W4 527 data = (u_int8_t *)long_data; 528 drq = (u_int8_t *)long_drq; 529 530 #define W1 *drq++ = *data++ 531 while (count) { 532 W1; count--; 533 } 534 #undef W1 535 dh->dh_len -= dcount; 536 dh->dh_addr += dcount; 537 } 538 dh->dh_flags |= SBC_DH_DONE; 539 540 /* 541 * XXX -- Read a byte from the SBC to trigger a /BERR. 542 * This seems to be necessary for us to notice that 543 * the target has disconnected. Ick. 06 jun 1996 (sr) 544 */ 545 if (dcount >= MAX_DMA_LEN) 546 drq = (volatile u_int8_t *)sc->sc_drq_addr; 547 tmp = *drq; 548 } else { /* Data In */ 549 /* 550 * Get the dest address aligned. 551 */ 552 resid = 553 count = min(dh->dh_len, 4 - (((int)dh->dh_addr) & 0x3)); 554 if (count && count < 4) { 555 data = (u_int8_t *)dh->dh_addr; 556 drq = (volatile u_int8_t *)sc->sc_drq_addr; 557 558 #define R1 *data++ = *drq++ 559 while (count) { 560 R1; count--; 561 } 562 #undef R1 563 dh->dh_addr += resid; 564 dh->dh_len -= resid; 565 } 566 567 /* 568 * Start the transfer. 569 */ 570 while (dh->dh_len) { 571 dcount = count = min(dh->dh_len, MAX_DMA_LEN); 572 long_data = (u_int32_t *)dh->dh_addr; 573 long_drq = (volatile u_int32_t *)sc->sc_drq_addr; 574 575 #define R4 *long_data++ = *long_drq++ 576 while (count >= 64) { 577 R4; R4; R4; R4; R4; R4; R4; R4; 578 R4; R4; R4; R4; R4; R4; R4; R4; /* 64 */ 579 count -= 64; 580 } 581 while (count >= 4) { 582 R4; count -= 4; 583 } 584 #undef R4 585 data = (u_int8_t *)long_data; 586 drq = (volatile u_int8_t *)long_drq; 587 588 #define R1 *data++ = *drq++ 589 while (count) { 590 R1; count--; 591 } 592 #undef R1 593 dh->dh_len -= dcount; 594 dh->dh_addr += dcount; 595 } 596 dh->dh_flags |= SBC_DH_DONE; 597 } 598 599 /* 600 * OK. No bus error occurred above. Clear the nofault flag 601 * so we no longer short-circuit bus errors. 602 */ 603 nofault = (label_t *)0; 604 605 #ifdef SBC_DEBUG 606 if (sbc_debug & (SBC_DB_REG | SBC_DB_INTR)) 607 printf("%s: drq intr complete: csr=0x%x, bus_csr=0x%x\n", 608 ncr_sc->sc_dev.dv_xname, *ncr_sc->sci_csr, 609 *ncr_sc->sci_bus_csr); 610 #endif 611 } 612 613 void 614 sbc_dma_alloc(ncr_sc) 615 struct ncr5380_softc *ncr_sc; 616 { 617 struct sbc_softc *sc = (struct sbc_softc *)ncr_sc; 618 struct sci_req *sr = ncr_sc->sc_current; 619 struct scsipi_xfer *xs = sr->sr_xs; 620 struct sbc_pdma_handle *dh; 621 int i, xlen; 622 623 #ifdef DIAGNOSTIC 624 if (sr->sr_dma_hand != NULL) 625 panic("sbc_dma_alloc: already have PDMA handle"); 626 #endif 627 628 /* Polled transfers shouldn't allocate a PDMA handle. */ 629 if (sr->sr_flags & SR_IMMED) 630 return; 631 632 xlen = ncr_sc->sc_datalen; 633 634 /* Make sure our caller checked sc_min_dma_len. */ 635 if (xlen < MIN_DMA_LEN) 636 panic("sbc_dma_alloc: len=0x%x\n", xlen); 637 638 /* 639 * Find free PDMA handle. Guaranteed to find one since we 640 * have as many PDMA handles as the driver has processes. 641 * (instances?) 642 */ 643 for (i = 0; i < SCI_OPENINGS; i++) { 644 if ((sc->sc_pdma[i].dh_flags & SBC_DH_BUSY) == 0) 645 goto found; 646 } 647 panic("sbc: no free PDMA handles"); 648 found: 649 dh = &sc->sc_pdma[i]; 650 dh->dh_flags = SBC_DH_BUSY; 651 dh->dh_addr = ncr_sc->sc_dataptr; 652 dh->dh_len = xlen; 653 654 /* Copy the 'write' flag for convenience. */ 655 if (xs->xs_control & XS_CTL_DATA_OUT) 656 dh->dh_flags |= SBC_DH_OUT; 657 658 sr->sr_dma_hand = dh; 659 } 660 661 void 662 sbc_dma_free(ncr_sc) 663 struct ncr5380_softc *ncr_sc; 664 { 665 struct sci_req *sr = ncr_sc->sc_current; 666 struct sbc_pdma_handle *dh = sr->sr_dma_hand; 667 668 #ifdef DIAGNOSTIC 669 if (sr->sr_dma_hand == NULL) 670 panic("sbc_dma_free: no DMA handle"); 671 #endif 672 673 if (ncr_sc->sc_state & NCR_DOINGDMA) 674 panic("sbc_dma_free: free while in progress"); 675 676 if (dh->dh_flags & SBC_DH_BUSY) { 677 dh->dh_flags = 0; 678 dh->dh_addr = NULL; 679 dh->dh_len = 0; 680 } 681 sr->sr_dma_hand = NULL; 682 } 683 684 void 685 sbc_dma_poll(ncr_sc) 686 struct ncr5380_softc *ncr_sc; 687 { 688 struct sci_req *sr = ncr_sc->sc_current; 689 690 /* 691 * We shouldn't arrive here; if SR_IMMED is set, then 692 * dma_alloc() should have refused to allocate a handle 693 * for the transfer. This forces the polled PDMA code 694 * to handle the request... 695 */ 696 #ifdef SBC_DEBUG 697 if (sbc_debug & SBC_DB_DMA) 698 printf("%s: lost DRQ interrupt?\n", ncr_sc->sc_dev.dv_xname); 699 #endif 700 sr->sr_flags |= SR_OVERDUE; 701 } 702 703 void 704 sbc_dma_setup(ncr_sc) 705 struct ncr5380_softc *ncr_sc; 706 { 707 /* Not needed; we don't have real DMA */ 708 } 709 710 void 711 sbc_dma_start(ncr_sc) 712 struct ncr5380_softc *ncr_sc; 713 { 714 struct sbc_softc *sc = (struct sbc_softc *)ncr_sc; 715 struct sci_req *sr = ncr_sc->sc_current; 716 struct sbc_pdma_handle *dh = sr->sr_dma_hand; 717 718 /* 719 * Match bus phase, clear pending interrupts, set DMA mode, and 720 * assert data bus (for writing only), then start the transfer. 721 */ 722 if (dh->dh_flags & SBC_DH_OUT) { 723 *ncr_sc->sci_tcmd = PHASE_DATA_OUT; 724 SCI_CLR_INTR(ncr_sc); 725 if (sc->sc_clrintr) 726 (*sc->sc_clrintr)(ncr_sc); 727 *ncr_sc->sci_mode |= SCI_MODE_DMA; 728 *ncr_sc->sci_icmd = SCI_ICMD_DATA; 729 *ncr_sc->sci_dma_send = 0; 730 } else { 731 *ncr_sc->sci_tcmd = PHASE_DATA_IN; 732 SCI_CLR_INTR(ncr_sc); 733 if (sc->sc_clrintr) 734 (*sc->sc_clrintr)(ncr_sc); 735 *ncr_sc->sci_mode |= SCI_MODE_DMA; 736 *ncr_sc->sci_icmd = 0; 737 *ncr_sc->sci_irecv = 0; 738 } 739 ncr_sc->sc_state |= NCR_DOINGDMA; 740 741 #ifdef SBC_DEBUG 742 if (sbc_debug & SBC_DB_DMA) 743 printf("%s: PDMA started, va=%p, len=0x%x\n", 744 ncr_sc->sc_dev.dv_xname, dh->dh_addr, dh->dh_len); 745 #endif 746 } 747 748 void 749 sbc_dma_eop(ncr_sc) 750 struct ncr5380_softc *ncr_sc; 751 { 752 /* Not used; the EOP pin is wired high (GMFH, pp. 389-390) */ 753 } 754 755 void 756 sbc_dma_stop(ncr_sc) 757 struct ncr5380_softc *ncr_sc; 758 { 759 struct sbc_softc *sc = (struct sbc_softc *)ncr_sc; 760 struct sci_req *sr = ncr_sc->sc_current; 761 struct sbc_pdma_handle *dh = sr->sr_dma_hand; 762 int ntrans; 763 764 if ((ncr_sc->sc_state & NCR_DOINGDMA) == 0) { 765 #ifdef SBC_DEBUG 766 if (sbc_debug & SBC_DB_DMA) 767 printf("%s: dma_stop: DMA not running\n", 768 ncr_sc->sc_dev.dv_xname); 769 #endif 770 return; 771 } 772 ncr_sc->sc_state &= ~NCR_DOINGDMA; 773 774 if ((ncr_sc->sc_state & NCR_ABORTING) == 0) { 775 ntrans = ncr_sc->sc_datalen - dh->dh_len; 776 777 #ifdef SBC_DEBUG 778 if (sbc_debug & SBC_DB_DMA) 779 printf("%s: dma_stop: ntrans=0x%x\n", 780 ncr_sc->sc_dev.dv_xname, ntrans); 781 #endif 782 783 if (ntrans > ncr_sc->sc_datalen) 784 panic("sbc_dma_stop: excess transfer\n"); 785 786 /* Adjust data pointer */ 787 ncr_sc->sc_dataptr += ntrans; 788 ncr_sc->sc_datalen -= ntrans; 789 790 /* Clear any pending interrupts. */ 791 SCI_CLR_INTR(ncr_sc); 792 if (sc->sc_clrintr) 793 (*sc->sc_clrintr)(ncr_sc); 794 } 795 796 /* Put SBIC back into PIO mode. */ 797 *ncr_sc->sci_mode &= ~SCI_MODE_DMA; 798 *ncr_sc->sci_icmd = 0; 799 800 #ifdef SBC_DEBUG 801 if (sbc_debug & SBC_DB_REG) 802 printf("%s: dma_stop: csr=0x%x, bus_csr=0x%x\n", 803 ncr_sc->sc_dev.dv_xname, *ncr_sc->sci_csr, 804 *ncr_sc->sci_bus_csr); 805 #endif 806 } 807