1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND BSD-2-Clause-NetBSD 3 * 4 * Copyright (c) 2004 Scott Long 5 * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 */ 30 31/* $NetBSD: esp_sbus.c,v 1.51 2009/09/17 16:28:12 tsutsui Exp $ */ 32 33/*- 34 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 35 * All rights reserved. 36 * 37 * This code is derived from software contributed to The NetBSD Foundation 38 * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace 39 * Simulation Facility, NASA Ames Research Center; Paul Kranenburg. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 51 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 52 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 54 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 55 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 56 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 57 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 58 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 59 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 60 * POSSIBILITY OF SUCH DAMAGE. 61 */ 62 63#include <sys/cdefs.h> 64__FBSDID("$FreeBSD$"); 65 66#include <sys/param.h> 67#include <sys/systm.h> 68#include <sys/bus.h> 69#include <sys/kernel.h> 70#include <sys/lock.h> 71#include <sys/module.h> 72#include <sys/mutex.h> 73#include <sys/rman.h> 74 75#include <dev/ofw/ofw_bus.h> 76#include <dev/ofw/openfirm.h> 77#include <machine/bus.h> 78#include <machine/ofw_machdep.h> 79#include <machine/resource.h> 80 81#include <cam/cam.h> 82#include <cam/cam_ccb.h> 83#include <cam/scsi/scsi_all.h> 84#include <cam/scsi/scsi_message.h> 85 86#include <sparc64/sbus/lsi64854reg.h> 87#include <sparc64/sbus/lsi64854var.h> 88#include <sparc64/sbus/sbusvar.h> 89 90#include <dev/esp/ncr53c9xreg.h> 91#include <dev/esp/ncr53c9xvar.h> 92 93/* #define ESP_SBUS_DEBUG */ 94 95struct esp_softc { 96 struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */ 97 device_t sc_dev; 98 99 struct resource *sc_res; 100 101 struct resource *sc_irqres; 102 void *sc_irq; 103 104 struct lsi64854_softc *sc_dma; /* pointer to my DMA */ 105}; 106 107static int esp_probe(device_t); 108static int esp_dma_attach(device_t); 109static int esp_dma_detach(device_t); 110static int esp_sbus_attach(device_t); 111static int esp_sbus_detach(device_t); 112static int esp_suspend(device_t); 113static int esp_resume(device_t); 114 115static device_method_t esp_dma_methods[] = { 116 DEVMETHOD(device_probe, esp_probe), 117 DEVMETHOD(device_attach, esp_dma_attach), 118 DEVMETHOD(device_detach, esp_dma_detach), 119 DEVMETHOD(device_suspend, esp_suspend), 120 DEVMETHOD(device_resume, esp_resume), 121 122 DEVMETHOD_END 123}; 124 125static driver_t esp_dma_driver = { 126 "esp", 127 esp_dma_methods, 128 sizeof(struct esp_softc) 129}; 130 131DRIVER_MODULE(esp, dma, esp_dma_driver, esp_devclass, 0, 0); 132MODULE_DEPEND(esp, dma, 1, 1, 1); 133 134static device_method_t esp_sbus_methods[] = { 135 DEVMETHOD(device_probe, esp_probe), 136 DEVMETHOD(device_attach, esp_sbus_attach), 137 DEVMETHOD(device_detach, esp_sbus_detach), 138 DEVMETHOD(device_suspend, esp_suspend), 139 DEVMETHOD(device_resume, esp_resume), 140 141 DEVMETHOD_END 142}; 143 144static driver_t esp_sbus_driver = { 145 "esp", 146 esp_sbus_methods, 147 sizeof(struct esp_softc) 148}; 149 150DRIVER_MODULE(esp, sbus, esp_sbus_driver, esp_devclass, 0, 0); 151MODULE_DEPEND(esp, sbus, 1, 1, 1); 152 153/* 154 * Functions and the switch for the MI code 155 */ 156static uint8_t esp_read_reg(struct ncr53c9x_softc *sc, int reg); 157static void esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t v); 158static int esp_dma_isintr(struct ncr53c9x_softc *sc); 159static void esp_dma_reset(struct ncr53c9x_softc *sc); 160static int esp_dma_intr(struct ncr53c9x_softc *sc); 161static int esp_dma_setup(struct ncr53c9x_softc *sc, void **addr, 162 size_t *len, int datain, size_t *dmasize); 163static void esp_dma_go(struct ncr53c9x_softc *sc); 164static void esp_dma_stop(struct ncr53c9x_softc *sc); 165static int esp_dma_isactive(struct ncr53c9x_softc *sc); 166static int espattach(struct esp_softc *esc, 167 const struct ncr53c9x_glue *gluep); 168static int espdetach(struct esp_softc *esc); 169 170static const struct ncr53c9x_glue esp_sbus_glue = { 171 esp_read_reg, 172 esp_write_reg, 173 esp_dma_isintr, 174 esp_dma_reset, 175 esp_dma_intr, 176 esp_dma_setup, 177 esp_dma_go, 178 esp_dma_stop, 179 esp_dma_isactive, 180}; 181 182static int 183esp_probe(device_t dev) 184{ 185 const char *name; 186 187 name = ofw_bus_get_name(dev); 188 if (strcmp("SUNW,fas", name) == 0) { 189 device_set_desc(dev, "Sun FAS366 Fast-Wide SCSI"); 190 return (BUS_PROBE_DEFAULT); 191 } else if (strcmp("esp", name) == 0) { 192 device_set_desc(dev, "Sun ESP SCSI/Sun FAS Fast-SCSI"); 193 return (BUS_PROBE_DEFAULT); 194 } 195 196 return (ENXIO); 197} 198 199static int 200esp_sbus_attach(device_t dev) 201{ 202 struct esp_softc *esc; 203 struct ncr53c9x_softc *sc; 204 struct lsi64854_softc *lsc; 205 device_t *children; 206 int error, i, nchildren; 207 208 esc = device_get_softc(dev); 209 sc = &esc->sc_ncr53c9x; 210 211 lsc = NULL; 212 esc->sc_dev = dev; 213 sc->sc_freq = sbus_get_clockfreq(dev); 214 215 if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") == 0) { 216 /* 217 * Allocate space for DMA, in SUNW,fas there are no 218 * separate DMA devices. 219 */ 220 lsc = malloc(sizeof (struct lsi64854_softc), M_DEVBUF, 221 M_NOWAIT | M_ZERO); 222 if (lsc == NULL) { 223 device_printf(dev, "out of memory (lsi64854_softc)\n"); 224 return (ENOMEM); 225 } 226 esc->sc_dma = lsc; 227 228 /* 229 * SUNW,fas have 2 register spaces: DMA (lsi64854) and 230 * SCSI core (ncr53c9x). 231 */ 232 233 /* Allocate DMA registers. */ 234 i = 0; 235 if ((lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 236 &i, RF_ACTIVE)) == NULL) { 237 device_printf(dev, "cannot allocate DMA registers\n"); 238 error = ENXIO; 239 goto fail_sbus_lsc; 240 } 241 242 /* Create a parent DMA tag based on this bus. */ 243 error = bus_dma_tag_create( 244 bus_get_dma_tag(dev), /* parent */ 245 1, 0, /* alignment, boundary */ 246 BUS_SPACE_MAXADDR, /* lowaddr */ 247 BUS_SPACE_MAXADDR, /* highaddr */ 248 NULL, NULL, /* filter, filterarg */ 249 BUS_SPACE_MAXSIZE, /* maxsize */ 250 BUS_SPACE_UNRESTRICTED, /* nsegments */ 251 BUS_SPACE_MAXSIZE, /* maxsegsize */ 252 0, /* flags */ 253 NULL, NULL, /* no locking */ 254 &lsc->sc_parent_dmat); 255 if (error != 0) { 256 device_printf(dev, "cannot allocate parent DMA tag\n"); 257 goto fail_sbus_lres; 258 } 259 260 i = sbus_get_burstsz(dev); 261 262#ifdef ESP_SBUS_DEBUG 263 printf("%s: burst 0x%x\n", __func__, i); 264#endif 265 266 lsc->sc_burst = (i & SBUS_BURST_32) ? 32 : 267 (i & SBUS_BURST_16) ? 16 : 0; 268 269 lsc->sc_channel = L64854_CHANNEL_SCSI; 270 lsc->sc_client = sc; 271 lsc->sc_dev = dev; 272 273 /* 274 * Allocate SCSI core registers. 275 */ 276 i = 1; 277 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 278 &i, RF_ACTIVE)) == NULL) { 279 device_printf(dev, 280 "cannot allocate SCSI core registers\n"); 281 error = ENXIO; 282 goto fail_sbus_lpdma; 283 } 284 } else { 285 /* 286 * Search accompanying DMA engine. It should have been 287 * already attached otherwise there isn't much we can do. 288 */ 289 if (device_get_children(device_get_parent(dev), &children, 290 &nchildren) != 0) { 291 device_printf(dev, "cannot determine siblings\n"); 292 return (ENXIO); 293 } 294 for (i = 0; i < nchildren; i++) { 295 if (device_is_attached(children[i]) && 296 sbus_get_slot(children[i]) == 297 sbus_get_slot(dev) && 298 strcmp(ofw_bus_get_name(children[i]), 299 "dma") == 0) { 300 /* XXX hackery */ 301 esc->sc_dma = (struct lsi64854_softc *) 302 device_get_softc(children[i]); 303 break; 304 } 305 } 306 free(children, M_TEMP); 307 if (esc->sc_dma == NULL) { 308 device_printf(dev, "cannot find DMA engine\n"); 309 return (ENXIO); 310 } 311 esc->sc_dma->sc_client = sc; 312 313 /* 314 * Allocate SCSI core registers. 315 */ 316 i = 0; 317 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 318 &i, RF_ACTIVE)) == NULL) { 319 device_printf(dev, 320 "cannot allocate SCSI core registers\n"); 321 return (ENXIO); 322 } 323 } 324 325 error = espattach(esc, &esp_sbus_glue); 326 if (error != 0) { 327 device_printf(dev, "espattach failed\n"); 328 goto fail_sbus_eres; 329 } 330 331 return (0); 332 333 fail_sbus_eres: 334 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 335 esc->sc_res); 336 if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0) 337 return (error); 338 fail_sbus_lpdma: 339 bus_dma_tag_destroy(lsc->sc_parent_dmat); 340 fail_sbus_lres: 341 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res), 342 lsc->sc_res); 343 fail_sbus_lsc: 344 free(lsc, M_DEVBUF); 345 return (error); 346} 347 348static int 349esp_sbus_detach(device_t dev) 350{ 351 struct esp_softc *esc; 352 struct lsi64854_softc *lsc; 353 int error; 354 355 esc = device_get_softc(dev); 356 lsc = esc->sc_dma; 357 358 error = espdetach(esc); 359 if (error != 0) 360 return (error); 361 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 362 esc->sc_res); 363 if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0) 364 return (0); 365 bus_dma_tag_destroy(lsc->sc_parent_dmat); 366 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res), 367 lsc->sc_res); 368 free(lsc, M_DEVBUF); 369 370 return (0); 371} 372 373static int 374esp_dma_attach(device_t dev) 375{ 376 struct esp_softc *esc; 377 struct ncr53c9x_softc *sc; 378 int error, i; 379 380 esc = device_get_softc(dev); 381 sc = &esc->sc_ncr53c9x; 382 383 esc->sc_dev = dev; 384 if (OF_getprop(ofw_bus_get_node(dev), "clock-frequency", 385 &sc->sc_freq, sizeof(sc->sc_freq)) == -1) { 386 printf("failed to query OFW for clock-frequency\n"); 387 return (ENXIO); 388 } 389 390 /* XXX hackery */ 391 esc->sc_dma = (struct lsi64854_softc *) 392 device_get_softc(device_get_parent(dev)); 393 esc->sc_dma->sc_client = sc; 394 395 /* 396 * Allocate SCSI core registers. 397 */ 398 i = 0; 399 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 400 &i, RF_ACTIVE)) == NULL) { 401 device_printf(dev, "cannot allocate SCSI core registers\n"); 402 return (ENXIO); 403 } 404 405 error = espattach(esc, &esp_sbus_glue); 406 if (error != 0) { 407 device_printf(dev, "espattach failed\n"); 408 goto fail_dma_eres; 409 } 410 411 return (0); 412 413 fail_dma_eres: 414 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 415 esc->sc_res); 416 return (error); 417} 418 419static int 420esp_dma_detach(device_t dev) 421{ 422 struct esp_softc *esc; 423 int error; 424 425 esc = device_get_softc(dev); 426 427 error = espdetach(esc); 428 if (error != 0) 429 return (error); 430 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 431 esc->sc_res); 432 433 return (0); 434} 435 436static int 437esp_suspend(device_t dev) 438{ 439 440 return (ENXIO); 441} 442 443static int 444esp_resume(device_t dev) 445{ 446 447 return (ENXIO); 448} 449 450static int 451espattach(struct esp_softc *esc, const struct ncr53c9x_glue *gluep) 452{ 453 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; 454 unsigned int uid = 0; 455 int error, i; 456 457 NCR_LOCK_INIT(sc); 458 459 sc->sc_id = OF_getscsinitid(esc->sc_dev); 460 461#ifdef ESP_SBUS_DEBUG 462 device_printf(esc->sc_dev, "%s: sc_id %d, freq %d\n", 463 __func__, sc->sc_id, sc->sc_freq); 464#endif 465 466 /* 467 * The `ESC' DMA chip must be reset before we can access 468 * the ESP registers. 469 */ 470 if (esc->sc_dma->sc_rev == DMAREV_ESC) 471 DMA_RESET(esc->sc_dma); 472 473 /* 474 * Set up glue for MI code early; we use some of it here. 475 */ 476 sc->sc_glue = gluep; 477 478 /* gimme MHz */ 479 sc->sc_freq /= 1000000; 480 481 /* 482 * XXX More of this should be in ncr53c9x_attach(), but 483 * XXX should we really poke around the chip that much in 484 * XXX the MI code? Think about this more... 485 */ 486 487 /* 488 * Read the part-unique ID code of the SCSI chip. The contained 489 * value is only valid if all of the following conditions are met: 490 * - After power-up or chip reset. 491 * - Before any value is written to this register. 492 * - The NCRCFG2_FE bit is set. 493 * - A (NCRCMD_NOP | NCRCMD_DMA) command has been issued. 494 */ 495 NCRCMD(sc, NCRCMD_RSTCHIP); 496 NCRCMD(sc, NCRCMD_NOP); 497 sc->sc_cfg2 = NCRCFG2_FE; 498 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 499 NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); 500 uid = NCR_READ_REG(sc, NCR_UID); 501 502 /* 503 * It is necessary to try to load the 2nd config register here, 504 * to find out what rev the esp chip is, else the ncr53c9x_reset 505 * will not set up the defaults correctly. 506 */ 507 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; 508 NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1); 509 sc->sc_cfg2 = 0; 510 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 511 sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE; 512 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 513 514 if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) != 515 (NCRCFG2_SCSI2 | NCRCFG2_RPE)) 516 sc->sc_rev = NCR_VARIANT_ESP100; 517 else { 518 sc->sc_cfg2 = NCRCFG2_SCSI2; 519 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 520 sc->sc_cfg3 = 0; 521 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 522 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK); 523 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 524 if (NCR_READ_REG(sc, NCR_CFG3) != 525 (NCRCFG3_CDB | NCRCFG3_FCLK)) 526 sc->sc_rev = NCR_VARIANT_ESP100A; 527 else { 528 /* NCRCFG2_FE enables > 64K transfers. */ 529 sc->sc_cfg2 |= NCRCFG2_FE; 530 sc->sc_cfg3 = 0; 531 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 532 if (sc->sc_freq <= 25) 533 sc->sc_rev = NCR_VARIANT_ESP200; 534 else { 535 switch ((uid & 0xf8) >> 3) { 536 case 0x00: 537 sc->sc_rev = NCR_VARIANT_FAS100A; 538 break; 539 540 case 0x02: 541 if ((uid & 0x07) == 0x02) 542 sc->sc_rev = 543 NCR_VARIANT_FAS216; 544 else 545 sc->sc_rev = 546 NCR_VARIANT_FAS236; 547 break; 548 549 case 0x0a: 550 sc->sc_rev = NCR_VARIANT_FAS366; 551 break; 552 553 default: 554 /* 555 * We could just treat unknown chips 556 * as ESP200 but then we would most 557 * likely drive them out of specs. 558 */ 559 device_printf(esc->sc_dev, 560 "Unknown chip\n"); 561 error = ENXIO; 562 goto fail_lock; 563 } 564 } 565 } 566 } 567 568#ifdef ESP_SBUS_DEBUG 569 printf("%s: revision %d, uid 0x%x\n", __func__, sc->sc_rev, uid); 570#endif 571 572 /* 573 * This is the value used to start sync negotiations 574 * Note that the NCR register "SYNCTP" is programmed 575 * in "clocks per byte", and has a minimum value of 4. 576 * The SCSI period used in negotiation is one-fourth 577 * of the time (in nanoseconds) needed to transfer one byte. 578 * Since the chip's clock is given in MHz, we have the following 579 * formula: 4 * period = (1000 / freq) * 4 580 */ 581 sc->sc_minsync = 1000 / sc->sc_freq; 582 583 /* 584 * Except for some variants the maximum transfer size is 64k. 585 */ 586 sc->sc_maxxfer = 64 * 1024; 587 sc->sc_maxoffset = 15; 588 sc->sc_extended_geom = 1; 589 590 /* 591 * Alas, we must now modify the value a bit, because it's 592 * only valid when we can switch on FASTCLK and FASTSCSI bits 593 * in the config register 3... 594 */ 595 switch (sc->sc_rev) { 596 case NCR_VARIANT_ESP100: 597 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT; 598 sc->sc_minsync = 0; /* No synch on old chip? */ 599 break; 600 601 case NCR_VARIANT_ESP100A: 602 case NCR_VARIANT_ESP200: 603 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT; 604 /* Min clocks/byte is 5 */ 605 sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5); 606 break; 607 608 case NCR_VARIANT_FAS100A: 609 case NCR_VARIANT_FAS216: 610 case NCR_VARIANT_FAS236: 611 /* 612 * The onboard SCSI chips in Sun Ultra 1 are actually 613 * documented to be NCR53C9X which use NCRCFG3_FCLK and 614 * NCRCFG3_FSCSI. BSD/OS however probes these chips as 615 * FAS100A and uses NCRF9XCFG3_FCLK and NCRF9XCFG3_FSCSI 616 * instead which seems to be correct as otherwise sync 617 * negotiation just doesn't work. Using NCRF9XCFG3_FCLK 618 * and NCRF9XCFG3_FSCSI with these chips in fact also 619 * yields Fast-SCSI speed. 620 */ 621 sc->sc_features = NCR_F_FASTSCSI; 622 sc->sc_cfg3 = NCRF9XCFG3_FCLK; 623 sc->sc_cfg3_fscsi = NCRF9XCFG3_FSCSI; 624 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT; 625 sc->sc_maxxfer = 16 * 1024 * 1024; 626 break; 627 628 case NCR_VARIANT_FAS366: 629 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_16_BIT; 630 sc->sc_maxxfer = 16 * 1024 * 1024; 631 break; 632 } 633 634 /* 635 * Given that we allocate resources based on sc->sc_maxxfer it doesn't 636 * make sense to supply a value higher than the maximum actually used. 637 */ 638 sc->sc_maxxfer = min(sc->sc_maxxfer, MAXPHYS); 639 640 /* Attach the DMA engine. */ 641 error = lsi64854_attach(esc->sc_dma); 642 if (error != 0) { 643 device_printf(esc->sc_dev, "lsi64854_attach failed\n"); 644 goto fail_lock; 645 } 646 647 /* Establish interrupt channel. */ 648 i = 0; 649 if ((esc->sc_irqres = bus_alloc_resource_any(esc->sc_dev, SYS_RES_IRQ, 650 &i, RF_SHAREABLE|RF_ACTIVE)) == NULL) { 651 device_printf(esc->sc_dev, "cannot allocate interrupt\n"); 652 goto fail_lsi; 653 } 654 if (bus_setup_intr(esc->sc_dev, esc->sc_irqres, 655 INTR_MPSAFE | INTR_TYPE_CAM, NULL, ncr53c9x_intr, sc, 656 &esc->sc_irq)) { 657 device_printf(esc->sc_dev, "cannot set up interrupt\n"); 658 error = ENXIO; 659 goto fail_ires; 660 } 661 662 /* Turn on target selection using the `DMA' method. */ 663 if (sc->sc_rev != NCR_VARIANT_FAS366) 664 sc->sc_features |= NCR_F_DMASELECT; 665 666 /* Do the common parts of attachment. */ 667 sc->sc_dev = esc->sc_dev; 668 error = ncr53c9x_attach(sc); 669 if (error != 0) { 670 device_printf(esc->sc_dev, "ncr53c9x_attach failed\n"); 671 goto fail_intr; 672 } 673 674 return (0); 675 676 fail_intr: 677 bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq); 678 fail_ires: 679 bus_release_resource(esc->sc_dev, SYS_RES_IRQ, 680 rman_get_rid(esc->sc_irqres), esc->sc_irqres); 681 fail_lsi: 682 lsi64854_detach(esc->sc_dma); 683 fail_lock: 684 NCR_LOCK_DESTROY(sc); 685 return (error); 686} 687 688static int 689espdetach(struct esp_softc *esc) 690{ 691 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; 692 int error; 693 694 bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq); 695 error = ncr53c9x_detach(sc); 696 if (error != 0) 697 return (error); 698 error = lsi64854_detach(esc->sc_dma); 699 if (error != 0) 700 return (error); 701 NCR_LOCK_DESTROY(sc); 702 bus_release_resource(esc->sc_dev, SYS_RES_IRQ, 703 rman_get_rid(esc->sc_irqres), esc->sc_irqres); 704 705 return (0); 706} 707 708/* 709 * Glue functions 710 */ 711 712#ifdef ESP_SBUS_DEBUG 713static int esp_sbus_debug = 0; 714 715static const struct { 716 const char *r_name; 717 int r_flag; 718} const esp__read_regnames [] = { 719 { "TCL", 0}, /* 0/00 */ 720 { "TCM", 0}, /* 1/04 */ 721 { "FIFO", 0}, /* 2/08 */ 722 { "CMD", 0}, /* 3/0c */ 723 { "STAT", 0}, /* 4/10 */ 724 { "INTR", 0}, /* 5/14 */ 725 { "STEP", 0}, /* 6/18 */ 726 { "FFLAGS", 1}, /* 7/1c */ 727 { "CFG1", 1}, /* 8/20 */ 728 { "STAT2", 0}, /* 9/24 */ 729 { "CFG4", 1}, /* a/28 */ 730 { "CFG2", 1}, /* b/2c */ 731 { "CFG3", 1}, /* c/30 */ 732 { "-none", 1}, /* d/34 */ 733 { "TCH", 1}, /* e/38 */ 734 { "TCX", 1}, /* f/3c */ 735}; 736 737static const const struct { 738 const char *r_name; 739 int r_flag; 740} const esp__write_regnames[] = { 741 { "TCL", 1}, /* 0/00 */ 742 { "TCM", 1}, /* 1/04 */ 743 { "FIFO", 0}, /* 2/08 */ 744 { "CMD", 0}, /* 3/0c */ 745 { "SELID", 1}, /* 4/10 */ 746 { "TIMEOUT", 1}, /* 5/14 */ 747 { "SYNCTP", 1}, /* 6/18 */ 748 { "SYNCOFF", 1}, /* 7/1c */ 749 { "CFG1", 1}, /* 8/20 */ 750 { "CCF", 1}, /* 9/24 */ 751 { "TEST", 1}, /* a/28 */ 752 { "CFG2", 1}, /* b/2c */ 753 { "CFG3", 1}, /* c/30 */ 754 { "-none", 1}, /* d/34 */ 755 { "TCH", 1}, /* e/38 */ 756 { "TCX", 1}, /* f/3c */ 757}; 758#endif 759 760static uint8_t 761esp_read_reg(struct ncr53c9x_softc *sc, int reg) 762{ 763 struct esp_softc *esc = (struct esp_softc *)sc; 764 uint8_t v; 765 766 v = bus_read_1(esc->sc_res, reg * 4); 767 768#ifdef ESP_SBUS_DEBUG 769 if (esp_sbus_debug && (reg < 0x10) && esp__read_regnames[reg].r_flag) 770 printf("RD:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ? 771 esp__read_regnames[reg].r_name : "<***>", v); 772#endif 773 774 return (v); 775} 776 777static void 778esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t v) 779{ 780 struct esp_softc *esc = (struct esp_softc *)sc; 781 782#ifdef ESP_SBUS_DEBUG 783 if (esp_sbus_debug && (reg < 0x10) && esp__write_regnames[reg].r_flag) 784 printf("WR:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ? 785 esp__write_regnames[reg].r_name : "<***>", v); 786#endif 787 788 bus_write_1(esc->sc_res, reg * 4, v); 789} 790 791static int 792esp_dma_isintr(struct ncr53c9x_softc *sc) 793{ 794 struct esp_softc *esc = (struct esp_softc *)sc; 795 796 return (DMA_ISINTR(esc->sc_dma)); 797} 798 799static void 800esp_dma_reset(struct ncr53c9x_softc *sc) 801{ 802 struct esp_softc *esc = (struct esp_softc *)sc; 803 804 DMA_RESET(esc->sc_dma); 805} 806 807static int 808esp_dma_intr(struct ncr53c9x_softc *sc) 809{ 810 struct esp_softc *esc = (struct esp_softc *)sc; 811 812 return (DMA_INTR(esc->sc_dma)); 813} 814 815static int 816esp_dma_setup(struct ncr53c9x_softc *sc, void **addr, size_t *len, 817 int datain, size_t *dmasize) 818{ 819 struct esp_softc *esc = (struct esp_softc *)sc; 820 821 return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize)); 822} 823 824static void 825esp_dma_go(struct ncr53c9x_softc *sc) 826{ 827 struct esp_softc *esc = (struct esp_softc *)sc; 828 829 DMA_GO(esc->sc_dma); 830} 831 832static void 833esp_dma_stop(struct ncr53c9x_softc *sc) 834{ 835 struct esp_softc *esc = (struct esp_softc *)sc; 836 837 L64854_SCSR(esc->sc_dma, L64854_GCSR(esc->sc_dma) & ~D_EN_DMA); 838} 839 840static int 841esp_dma_isactive(struct ncr53c9x_softc *sc) 842{ 843 struct esp_softc *esc = (struct esp_softc *)sc; 844 845 return (DMA_ISACTIVE(esc->sc_dma)); 846} 847