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