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