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