1 /* $NetBSD: si_obio.c,v 1.33 2007/02/03 18:02:57 tsutsui Exp $ */ 2 3 /*- 4 * Copyright (c) 1996 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Adam Glass, David Jones, and Gordon W. Ross. 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 the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * This file contains only the machine-dependent parts of the 41 * Sun3 SCSI driver. (Autoconfig stuff and DMA functions.) 42 * The machine-independent parts are in ncr5380sbc.c 43 * 44 * Supported hardware includes: 45 * Sun SCSI-3 on OBIO (Sun3/50,Sun3/60) 46 * Sun SCSI-3 on VME (Sun3/160,Sun3/260) 47 * 48 * Could be made to support the Sun3/E if someone wanted to. 49 * 50 * Note: Both supported variants of the Sun SCSI-3 adapter have 51 * some really unusual "features" for this driver to deal with, 52 * generally related to the DMA engine. The OBIO variant will 53 * ignore any attempt to write the FIFO count register while the 54 * SCSI bus is in DATA_IN or DATA_OUT phase. This is dealt with 55 * by setting the FIFO count early in COMMAND or MSG_IN phase. 56 * 57 * The VME variant has a bit to enable or disable the DMA engine, 58 * but that bit also gates the interrupt line from the NCR5380! 59 * Therefore, in order to get any interrupt from the 5380, (i.e. 60 * for reselect) one must clear the DMA engine transfer count and 61 * then enable DMA. This has the further complication that you 62 * CAN NOT touch the NCR5380 while the DMA enable bit is set, so 63 * we have to turn DMA back off before we even look at the 5380. 64 * 65 * What wonderfully whacky hardware this is! 66 * 67 * Credits, history: 68 * 69 * David Jones wrote the initial version of this module, which 70 * included support for the VME adapter only. (no reselection). 71 * 72 * Gordon Ross added support for the OBIO adapter, and re-worked 73 * both the VME and OBIO code to support disconnect/reselect. 74 * (Required figuring out the hardware "features" noted above.) 75 * 76 * The autoconfiguration boilerplate came from Adam Glass. 77 */ 78 79 /***************************************************************** 80 * OBIO functions for DMA 81 ****************************************************************/ 82 83 #include <sys/cdefs.h> 84 __KERNEL_RCSID(0, "$NetBSD: si_obio.c,v 1.33 2007/02/03 18:02:57 tsutsui Exp $"); 85 86 #include <sys/param.h> 87 #include <sys/systm.h> 88 #include <sys/errno.h> 89 #include <sys/kernel.h> 90 #include <sys/malloc.h> 91 #include <sys/device.h> 92 #include <sys/buf.h> 93 #include <sys/proc.h> 94 #include <sys/user.h> 95 96 #include <dev/scsipi/scsi_all.h> 97 #include <dev/scsipi/scsipi_all.h> 98 #include <dev/scsipi/scsipi_debug.h> 99 #include <dev/scsipi/scsiconf.h> 100 101 #include <machine/autoconf.h> 102 #include <machine/dvma.h> 103 104 /* #define DEBUG XXX */ 105 106 #include <dev/ic/ncr5380reg.h> 107 #include <dev/ic/ncr5380var.h> 108 109 #include "sireg.h" 110 #include "sivar.h" 111 #include "am9516.h" 112 113 /* 114 * How many uS. to delay after touching the am9516 UDC. 115 */ 116 #define UDC_WAIT_USEC 5 117 118 void si_obio_dma_setup(struct ncr5380_softc *); 119 void si_obio_dma_start(struct ncr5380_softc *); 120 void si_obio_dma_eop(struct ncr5380_softc *); 121 void si_obio_dma_stop(struct ncr5380_softc *); 122 123 static void si_obio_reset(struct ncr5380_softc *); 124 125 static inline void si_obio_udc_write(volatile struct si_regs *, int, int); 126 static inline int si_obio_udc_read(volatile struct si_regs *, int); 127 128 129 /* 130 * New-style autoconfig attachment 131 */ 132 133 static int si_obio_match(struct device *, struct cfdata *, void *); 134 static void si_obio_attach(struct device *, struct device *, void *); 135 136 CFATTACH_DECL(si_obio, sizeof(struct si_softc), 137 si_obio_match, si_obio_attach, NULL, NULL); 138 139 /* 140 * Options for disconnect/reselect, DMA, and interrupts. 141 * By default, allow disconnect/reselect on targets 4-6. 142 * Those are normally tapes that really need it enabled. 143 */ 144 int si_obio_options = 0x0f; 145 146 147 static int 148 si_obio_match(struct device *parent, struct cfdata *cf, void *aux) 149 { 150 struct confargs *ca = aux; 151 152 /* Make sure something is there... */ 153 if (bus_peek(ca->ca_bustype, ca->ca_paddr + 1, 1) == -1) 154 return (0); 155 156 /* Default interrupt priority. */ 157 if (ca->ca_intpri == -1) 158 ca->ca_intpri = 2; 159 160 return (1); 161 } 162 163 static void 164 si_obio_attach(struct device *parent, struct device *self, void *args) 165 { 166 struct si_softc *sc = (struct si_softc *) self; 167 struct ncr5380_softc *ncr_sc = &sc->ncr_sc; 168 struct cfdata *cf = device_cfdata(self); 169 struct confargs *ca = args; 170 171 sc->sc_bst = ca->ca_bustag; 172 sc->sc_dmat = ca->ca_dmatag; 173 174 if (bus_space_map(sc->sc_bst, ca->ca_paddr, sizeof(struct si_regs), 0, 175 &sc->sc_bsh) != 0) { 176 printf(": can't map register\n"); 177 return; 178 } 179 sc->sc_regs = bus_space_vaddr(sc->sc_bst, sc->sc_bsh); 180 181 if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, 1, MAXPHYS, 0, 182 BUS_DMA_NOWAIT, &sc->sc_dmap) != 0) { 183 printf(": can't create DMA map\n"); 184 return; 185 } 186 187 /* Get options from config flags if specified. */ 188 if (cf->cf_flags) 189 sc->sc_options = cf->cf_flags; 190 else 191 sc->sc_options = si_obio_options; 192 193 printf(": options=0x%x\n", sc->sc_options); 194 195 sc->sc_adapter_type = ca->ca_bustype; 196 197 /* 198 * MD function pointers used by the MI code. 199 */ 200 ncr_sc->sc_pio_out = ncr5380_pio_out; 201 ncr_sc->sc_pio_in = ncr5380_pio_in; 202 ncr_sc->sc_dma_alloc = si_dma_alloc; 203 ncr_sc->sc_dma_free = si_dma_free; 204 ncr_sc->sc_dma_setup = si_obio_dma_setup; 205 ncr_sc->sc_dma_start = si_obio_dma_start; 206 ncr_sc->sc_dma_poll = si_dma_poll; 207 ncr_sc->sc_dma_eop = si_obio_dma_eop; 208 ncr_sc->sc_dma_stop = si_obio_dma_stop; 209 ncr_sc->sc_intr_on = NULL; 210 ncr_sc->sc_intr_off = NULL; 211 212 /* Need DVMA-capable memory for the UDC command block. */ 213 sc->sc_dmacmd = dvma_malloc(sizeof (struct udc_table)); 214 215 /* Attach interrupt handler. */ 216 isr_add_autovect(si_intr, (void *)sc, ca->ca_intpri); 217 218 /* Reset the hardware. */ 219 si_obio_reset(ncr_sc); 220 221 /* Do the common attach stuff. */ 222 si_attach(sc); 223 } 224 225 static void 226 si_obio_reset(struct ncr5380_softc *ncr_sc) 227 { 228 struct si_softc *sc = (struct si_softc *)ncr_sc; 229 volatile struct si_regs *si = sc->sc_regs; 230 231 #ifdef DEBUG 232 if (si_debug) { 233 printf("si_obio_reset\n"); 234 } 235 #endif 236 237 /* 238 * The SCSI3 controller has an 8K FIFO to buffer data between the 239 * 5380 and the DMA. Make sure it starts out empty. 240 * 241 * The reset bits in the CSR are active low. 242 */ 243 si->si_csr = 0; 244 delay(10); 245 si->si_csr = SI_CSR_FIFO_RES | SI_CSR_SCSI_RES | SI_CSR_INTR_EN; 246 delay(10); 247 si->fifo_count = 0; 248 } 249 250 static inline void 251 si_obio_udc_write(volatile struct si_regs *si, int regnum, int value) 252 { 253 si->udc_addr = regnum; 254 delay(UDC_WAIT_USEC); 255 si->udc_data = value; 256 delay(UDC_WAIT_USEC); 257 } 258 259 static inline int 260 si_obio_udc_read(volatile struct si_regs *si, int regnum) 261 { 262 int value; 263 264 si->udc_addr = regnum; 265 delay(UDC_WAIT_USEC); 266 value = si->udc_data; 267 delay(UDC_WAIT_USEC); 268 269 return (value); 270 } 271 272 273 /* 274 * This function is called during the COMMAND or MSG_IN phase 275 * that precedes a DATA_IN or DATA_OUT phase, in case we need 276 * to setup the DMA engine before the bus enters a DATA phase. 277 * 278 * The OBIO "si" IGNORES any attempt to set the FIFO count 279 * register after the SCSI bus goes into any DATA phase, so 280 * this function has to setup the evil FIFO logic. 281 */ 282 void 283 si_obio_dma_setup(struct ncr5380_softc *ncr_sc) 284 { 285 struct si_softc *sc = (struct si_softc *)ncr_sc; 286 struct sci_req *sr = ncr_sc->sc_current; 287 struct si_dma_handle *dh = sr->sr_dma_hand; 288 volatile struct si_regs *si = sc->sc_regs; 289 struct udc_table *cmd; 290 long data_pa, cmd_pa; 291 int xlen; 292 293 /* 294 * Get the DVMA mapping for this segment. 295 * XXX - Should separate allocation and mapin. 296 */ 297 data_pa = dh->dh_dmaaddr; 298 if (data_pa & 1) 299 panic("si_dma_start: bad pa=0x%lx", data_pa); 300 xlen = dh->dh_dmalen; 301 sc->sc_reqlen = xlen; /* XXX: or less? */ 302 303 #ifdef DEBUG 304 if (si_debug & 2) { 305 printf("si_dma_setup: dh=%p, pa=0x%lx, xlen=0x%x\n", 306 dh, data_pa, xlen); 307 } 308 #endif 309 310 /* Reset the UDC. (In case not already reset?) */ 311 si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_RESET); 312 313 /* Reset the FIFO */ 314 si->si_csr &= ~SI_CSR_FIFO_RES; /* active low */ 315 si->si_csr |= SI_CSR_FIFO_RES; 316 317 /* Set direction (send/recv) */ 318 if (dh->dh_flags & SIDH_OUT) { 319 si->si_csr |= SI_CSR_SEND; 320 } else { 321 si->si_csr &= ~SI_CSR_SEND; 322 } 323 324 /* Set the FIFO counter. */ 325 si->fifo_count = xlen; 326 327 /* Reset the UDC. */ 328 si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_RESET); 329 330 /* 331 * XXX: Reset the FIFO again! Comment from Sprite: 332 * Go through reset again because of the bug on the 3/50 333 * where bytes occasionally linger in the DMA fifo. 334 */ 335 si->si_csr &= ~SI_CSR_FIFO_RES; /* active low */ 336 si->si_csr |= SI_CSR_FIFO_RES; 337 338 #ifdef DEBUG 339 /* Make sure the extra FIFO reset did not hit the count. */ 340 if (si->fifo_count != xlen) { 341 printf("si_dma_setup: fifo_count=0x%x, xlen=0x%x\n", 342 si->fifo_count, xlen); 343 Debugger(); 344 } 345 #endif 346 347 /* 348 * Set up the DMA controller. The DMA controller on 349 * OBIO needs a command block in DVMA space. 350 */ 351 cmd = sc->sc_dmacmd; 352 cmd->addrh = ((data_pa & 0xFF0000) >> 8) | UDC_ADDR_INFO; 353 cmd->addrl = data_pa & 0xFFFF; 354 cmd->count = xlen / 2; /* bytes -> words */ 355 cmd->cmrh = UDC_CMR_HIGH; 356 if (dh->dh_flags & SIDH_OUT) { 357 if (xlen & 1) 358 cmd->count++; 359 cmd->cmrl = UDC_CMR_LSEND; 360 cmd->rsel = UDC_RSEL_SEND; 361 } else { 362 cmd->cmrl = UDC_CMR_LRECV; 363 cmd->rsel = UDC_RSEL_RECV; 364 } 365 366 /* Tell the DMA chip where the control block is. */ 367 cmd_pa = dvma_kvtopa(cmd, BUS_OBIO); 368 si_obio_udc_write(si, UDC_ADR_CAR_HIGH, 369 (cmd_pa & 0xff0000) >> 8); 370 si_obio_udc_write(si, UDC_ADR_CAR_LOW, 371 (cmd_pa & 0xffff)); 372 373 /* Tell the chip to be a DMA master. */ 374 si_obio_udc_write(si, UDC_ADR_MODE, UDC_MODE); 375 376 /* Tell the chip to interrupt on error. */ 377 si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_CIE); 378 379 /* Will do "start chain" command in _dma_start. */ 380 } 381 382 383 void 384 si_obio_dma_start(struct ncr5380_softc *ncr_sc) 385 { 386 struct si_softc *sc = (struct si_softc *)ncr_sc; 387 struct sci_req *sr = ncr_sc->sc_current; 388 struct si_dma_handle *dh = sr->sr_dma_hand; 389 volatile struct si_regs *si = sc->sc_regs; 390 int s; 391 392 #ifdef DEBUG 393 if (si_debug & 2) { 394 printf("si_dma_start: sr=%p\n", sr); 395 } 396 #endif 397 398 /* This MAY be time critical (not sure). */ 399 s = splhigh(); 400 401 /* Finally, give the UDC a "start chain" command. */ 402 si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_STRT_CHN); 403 404 /* 405 * Acknowledge the phase change. (After DMA setup!) 406 * Put the SBIC into DMA mode, and start the transfer. 407 */ 408 if (dh->dh_flags & SIDH_OUT) { 409 *ncr_sc->sci_tcmd = PHASE_DATA_OUT; 410 SCI_CLR_INTR(ncr_sc); 411 *ncr_sc->sci_icmd = SCI_ICMD_DATA; 412 *ncr_sc->sci_mode |= (SCI_MODE_DMA | SCI_MODE_DMA_IE); 413 *ncr_sc->sci_dma_send = 0; /* start it */ 414 } else { 415 *ncr_sc->sci_tcmd = PHASE_DATA_IN; 416 SCI_CLR_INTR(ncr_sc); 417 *ncr_sc->sci_icmd = 0; 418 *ncr_sc->sci_mode |= (SCI_MODE_DMA | SCI_MODE_DMA_IE); 419 *ncr_sc->sci_irecv = 0; /* start it */ 420 } 421 422 splx(s); 423 ncr_sc->sc_state |= NCR_DOINGDMA; 424 425 #ifdef DEBUG 426 if (si_debug & 2) { 427 printf("si_dma_start: started, flags=0x%x\n", 428 ncr_sc->sc_state); 429 } 430 #endif 431 } 432 433 434 void 435 si_obio_dma_eop(struct ncr5380_softc *ncr_sc) 436 { 437 438 /* Not needed - DMA was stopped prior to examining sci_csr */ 439 } 440 441 442 void 443 si_obio_dma_stop(struct ncr5380_softc *ncr_sc) 444 { 445 struct si_softc *sc = (struct si_softc *)ncr_sc; 446 struct sci_req *sr = ncr_sc->sc_current; 447 struct si_dma_handle *dh = sr->sr_dma_hand; 448 volatile struct si_regs *si = sc->sc_regs; 449 int resid, ntrans, tmo, udc_cnt; 450 451 if ((ncr_sc->sc_state & NCR_DOINGDMA) == 0) { 452 #ifdef DEBUG 453 printf("si_dma_stop: DMA not running\n"); 454 #endif 455 return; 456 } 457 ncr_sc->sc_state &= ~NCR_DOINGDMA; 458 459 NCR_TRACE("si_dma_stop: top, csr=0x%x\n", si->si_csr); 460 461 /* OK, have either phase mis-match or end of DMA. */ 462 /* Set an impossible phase to prevent data movement? */ 463 *ncr_sc->sci_tcmd = PHASE_INVALID; 464 465 /* Check for DMA errors. */ 466 if (si->si_csr & (SI_CSR_DMA_CONFLICT | SI_CSR_DMA_BUS_ERR)) { 467 printf("si: DMA error, csr=0x%x, reset\n", si->si_csr); 468 sr->sr_xs->error = XS_DRIVER_STUFFUP; 469 ncr_sc->sc_state |= NCR_ABORTING; 470 si_obio_reset(ncr_sc); 471 goto out; 472 } 473 474 /* Note that timeout may have set the error flag. */ 475 if (ncr_sc->sc_state & NCR_ABORTING) 476 goto out; 477 478 /* 479 * After a read, wait for the FIFO to empty. 480 * Note: this only works on the OBIO version. 481 */ 482 if ((dh->dh_flags & SIDH_OUT) == 0) { 483 tmo = 200000; /* X10 = 2 sec. */ 484 for (;;) { 485 if (si->si_csr & SI_CSR_FIFO_EMPTY) 486 break; 487 if (--tmo <= 0) { 488 printf("si: DMA FIFO did not empty, reset\n"); 489 ncr_sc->sc_state |= NCR_ABORTING; 490 /* si_obio_reset(ncr_sc); */ 491 goto out; 492 } 493 delay(10); 494 } 495 } 496 497 /* 498 * Now try to figure out how much actually transferred. 499 * The fifo_count might not reflect how many bytes were 500 * actually transferred. 501 */ 502 resid = si->fifo_count & 0xFFFF; 503 ntrans = sc->sc_reqlen - resid; 504 505 #ifdef DEBUG 506 if (si_debug & 2) { 507 printf("si_dma_stop: resid=0x%x ntrans=0x%x\n", 508 resid, ntrans); 509 } 510 #endif 511 512 /* XXX: Treat (ntrans==0) as a special, non-error case? */ 513 if (ntrans < MIN_DMA_LEN) { 514 printf("si: fifo count: 0x%x\n", resid); 515 ncr_sc->sc_state |= NCR_ABORTING; 516 goto out; 517 } 518 if (ntrans > ncr_sc->sc_datalen) 519 panic("si_dma_stop: excess transfer"); 520 521 /* Adjust data pointer */ 522 ncr_sc->sc_dataptr += ntrans; 523 ncr_sc->sc_datalen -= ntrans; 524 525 /* 526 * After a read, we may need to clean-up 527 * "Left-over bytes" (yuck!) 528 */ 529 if ((dh->dh_flags & SIDH_OUT) == 0) { 530 /* If odd transfer count, grab last byte by hand. */ 531 if (ntrans & 1) { 532 NCR_TRACE("si_dma_stop: leftover 1 at 0x%x\n", 533 (int) ncr_sc->sc_dataptr - 1); 534 ncr_sc->sc_dataptr[-1] = 535 (si->fifo_data & 0xff00) >> 8; 536 goto out; 537 } 538 /* UDC might not have transfered the last word. */ 539 udc_cnt = si_obio_udc_read(si, UDC_ADR_COUNT); 540 if (((udc_cnt * 2) - resid) == 2) { 541 NCR_TRACE("si_dma_stop: leftover 2 at 0x%x\n", 542 (int) ncr_sc->sc_dataptr - 2); 543 ncr_sc->sc_dataptr[-2] = 544 (si->fifo_data & 0xff00) >> 8; 545 ncr_sc->sc_dataptr[-1] = 546 (si->fifo_data & 0x00ff); 547 } 548 } 549 550 out: 551 /* Reset the UDC. */ 552 si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_RESET); 553 si->fifo_count = 0; 554 si->si_csr &= ~SI_CSR_SEND; 555 556 /* Reset the FIFO */ 557 si->si_csr &= ~SI_CSR_FIFO_RES; /* active low */ 558 si->si_csr |= SI_CSR_FIFO_RES; 559 560 /* Put SBIC back in PIO mode. */ 561 /* XXX: set tcmd to PHASE_INVALID? */ 562 *ncr_sc->sci_mode &= ~(SCI_MODE_DMA | SCI_MODE_DMA_IE); 563 *ncr_sc->sci_icmd = 0; 564 } 565 566