Annotation of sys/dev/ic/adw.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: adw.c,v 1.31 2006/11/28 23:59:45 dlg Exp $ */
! 2: /* $NetBSD: adw.c,v 1.23 2000/05/27 18:24:50 dante Exp $ */
! 3:
! 4: /*
! 5: * Generic driver for the Advanced Systems Inc. SCSI controllers
! 6: *
! 7: * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
! 8: * All rights reserved.
! 9: *
! 10: * Author: Baldassare Dante Profeta <dante@mclink.it>
! 11: *
! 12: * Redistribution and use in source and binary forms, with or without
! 13: * modification, are permitted provided that the following conditions
! 14: * are met:
! 15: * 1. Redistributions of source code must retain the above copyright
! 16: * notice, this list of conditions and the following disclaimer.
! 17: * 2. Redistributions in binary form must reproduce the above copyright
! 18: * notice, this list of conditions and the following disclaimer in the
! 19: * documentation and/or other materials provided with the distribution.
! 20: * 3. All advertising materials mentioning features or use of this software
! 21: * must display the following acknowledgement:
! 22: * This product includes software developed by the NetBSD
! 23: * Foundation, Inc. and its contributors.
! 24: * 4. Neither the name of The NetBSD Foundation nor the names of its
! 25: * contributors may be used to endorse or promote products derived
! 26: * from this software without specific prior written permission.
! 27: *
! 28: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 29: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 30: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 31: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 32: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 33: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 34: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 35: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 36: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 37: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 38: * POSSIBILITY OF SUCH DAMAGE.
! 39: */
! 40:
! 41: #include <sys/types.h>
! 42: #include <sys/param.h>
! 43: #include <sys/systm.h>
! 44: #include <sys/kernel.h>
! 45: #include <sys/errno.h>
! 46: #include <sys/ioctl.h>
! 47: #include <sys/device.h>
! 48: #include <sys/malloc.h>
! 49: #include <sys/buf.h>
! 50: #include <sys/proc.h>
! 51: #include <sys/user.h>
! 52: #include <sys/timeout.h>
! 53:
! 54: #include <machine/bus.h>
! 55: #include <machine/intr.h>
! 56:
! 57: #include <scsi/scsi_all.h>
! 58: #include <scsi/scsiconf.h>
! 59:
! 60: #include <dev/ic/adwlib.h>
! 61: #include <dev/microcode/adw/adwmcode.h>
! 62: #include <dev/ic/adw.h>
! 63:
! 64: #ifndef DDB
! 65: #define Debugger() panic("should call debugger here (adw.c)")
! 66: #endif /* ! DDB */
! 67:
! 68: /******************************************************************************/
! 69:
! 70:
! 71: void adw_enqueue(ADW_SOFTC *, struct scsi_xfer *, int);
! 72: struct scsi_xfer *adw_dequeue(ADW_SOFTC *);
! 73:
! 74: int adw_alloc_controls(ADW_SOFTC *);
! 75: int adw_alloc_carriers(ADW_SOFTC *);
! 76: int adw_create_ccbs(ADW_SOFTC *, ADW_CCB *, int);
! 77: void adw_free_ccb(ADW_SOFTC *, ADW_CCB *);
! 78: void adw_reset_ccb(ADW_CCB *);
! 79: int adw_init_ccb(ADW_SOFTC *, ADW_CCB *);
! 80: ADW_CCB *adw_get_ccb(ADW_SOFTC *, int);
! 81: int adw_queue_ccb(ADW_SOFTC *, ADW_CCB *, int);
! 82:
! 83: int adw_scsi_cmd(struct scsi_xfer *);
! 84: int adw_build_req(struct scsi_xfer *, ADW_CCB *, int);
! 85: void adw_build_sglist(ADW_CCB *, ADW_SCSI_REQ_Q *, ADW_SG_BLOCK *);
! 86: void adw_minphys(struct buf *);
! 87: void adw_isr_callback(ADW_SOFTC *, ADW_SCSI_REQ_Q *);
! 88: void adw_async_callback(ADW_SOFTC *, u_int8_t);
! 89:
! 90: void adw_print_info(ADW_SOFTC *, int);
! 91:
! 92: int adw_poll(ADW_SOFTC *, struct scsi_xfer *, int);
! 93: void adw_timeout(void *);
! 94: void adw_reset_bus(ADW_SOFTC *);
! 95:
! 96:
! 97: /******************************************************************************/
! 98:
! 99:
! 100: struct cfdriver adw_cd = {
! 101: NULL, "adw", DV_DULL
! 102: };
! 103:
! 104: /* the below structure is so we have a default dev struct for our link struct */
! 105: struct scsi_device adw_dev =
! 106: {
! 107: NULL, /* Use default error handler */
! 108: NULL, /* have a queue, served by this */
! 109: NULL, /* have no async handler */
! 110: NULL, /* Use default 'done' routine */
! 111: };
! 112:
! 113:
! 114: /******************************************************************************/
! 115: /* scsi_xfer queue routines */
! 116: /******************************************************************************/
! 117:
! 118: /*
! 119: * Insert a scsi_xfer into the software queue. We overload xs->free_list
! 120: * to avoid having to allocate additional resources (since we're used
! 121: * only during resource shortages anyhow.
! 122: */
! 123: void
! 124: adw_enqueue(sc, xs, infront)
! 125: ADW_SOFTC *sc;
! 126: struct scsi_xfer *xs;
! 127: int infront;
! 128: {
! 129:
! 130: if (infront || LIST_EMPTY(&sc->sc_queue)) {
! 131: if (LIST_EMPTY(&sc->sc_queue))
! 132: sc->sc_queuelast = xs;
! 133: LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
! 134: return;
! 135: }
! 136: LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
! 137: sc->sc_queuelast = xs;
! 138: }
! 139:
! 140:
! 141: /*
! 142: * Pull a scsi_xfer off the front of the software queue.
! 143: */
! 144: struct scsi_xfer *
! 145: adw_dequeue(sc)
! 146: ADW_SOFTC *sc;
! 147: {
! 148: struct scsi_xfer *xs;
! 149:
! 150: xs = LIST_FIRST(&sc->sc_queue);
! 151: LIST_REMOVE(xs, free_list);
! 152:
! 153: if (LIST_EMPTY(&sc->sc_queue))
! 154: sc->sc_queuelast = NULL;
! 155:
! 156: return (xs);
! 157: }
! 158:
! 159: /******************************************************************************/
! 160: /* DMA Mapping for Control Blocks */
! 161: /******************************************************************************/
! 162:
! 163:
! 164: int
! 165: adw_alloc_controls(sc)
! 166: ADW_SOFTC *sc;
! 167: {
! 168: bus_dma_segment_t seg;
! 169: int error, rseg;
! 170:
! 171: /*
! 172: * Allocate the control structure.
! 173: */
! 174: if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct adw_control),
! 175: NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
! 176: printf("%s: unable to allocate control structures,"
! 177: " error = %d\n", sc->sc_dev.dv_xname, error);
! 178: return (error);
! 179: }
! 180: if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
! 181: sizeof(struct adw_control), (caddr_t *) & sc->sc_control,
! 182: BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
! 183: printf("%s: unable to map control structures, error = %d\n",
! 184: sc->sc_dev.dv_xname, error);
! 185: return (error);
! 186: }
! 187:
! 188: /*
! 189: * Create and load the DMA map used for the control blocks.
! 190: */
! 191: if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct adw_control),
! 192: 1, sizeof(struct adw_control), 0, BUS_DMA_NOWAIT,
! 193: &sc->sc_dmamap_control)) != 0) {
! 194: printf("%s: unable to create control DMA map, error = %d\n",
! 195: sc->sc_dev.dv_xname, error);
! 196: return (error);
! 197: }
! 198: if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
! 199: sc->sc_control, sizeof(struct adw_control), NULL,
! 200: BUS_DMA_NOWAIT)) != 0) {
! 201: printf("%s: unable to load control DMA map, error = %d\n",
! 202: sc->sc_dev.dv_xname, error);
! 203: return (error);
! 204: }
! 205:
! 206: return (0);
! 207: }
! 208:
! 209:
! 210: int
! 211: adw_alloc_carriers(sc)
! 212: ADW_SOFTC *sc;
! 213: {
! 214: bus_dma_segment_t seg;
! 215: int error, rseg;
! 216:
! 217: /*
! 218: * Allocate the control structure.
! 219: */
! 220: sc->sc_control->carriers =
! 221: malloc(sizeof(ADW_CARRIER) * ADW_MAX_CARRIER, M_DEVBUF,
! 222: M_NOWAIT);
! 223: if (sc->sc_control->carriers == NULL)
! 224: return (ENOMEM);
! 225:
! 226:
! 227: if ((error = bus_dmamem_alloc(sc->sc_dmat,
! 228: sizeof(ADW_CARRIER) * ADW_MAX_CARRIER,
! 229: 0x10, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
! 230: printf("%s: unable to allocate carrier structures,"
! 231: " error = %d\n", sc->sc_dev.dv_xname, error);
! 232: return (error);
! 233: }
! 234: if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
! 235: sizeof(ADW_CARRIER) * ADW_MAX_CARRIER,
! 236: (caddr_t *) &sc->sc_control->carriers,
! 237: BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
! 238: printf("%s: unable to map carrier structures,"
! 239: " error = %d\n", sc->sc_dev.dv_xname, error);
! 240: return (error);
! 241: }
! 242:
! 243: /*
! 244: * Create and load the DMA map used for the control blocks.
! 245: */
! 246: if ((error = bus_dmamap_create(sc->sc_dmat,
! 247: sizeof(ADW_CARRIER) * ADW_MAX_CARRIER, 1,
! 248: sizeof(ADW_CARRIER) * ADW_MAX_CARRIER, 0,BUS_DMA_NOWAIT,
! 249: &sc->sc_dmamap_carrier)) != 0) {
! 250: printf("%s: unable to create carriers DMA map,"
! 251: " error = %d\n", sc->sc_dev.dv_xname, error);
! 252: return (error);
! 253: }
! 254: if ((error = bus_dmamap_load(sc->sc_dmat,
! 255: sc->sc_dmamap_carrier, sc->sc_control->carriers,
! 256: sizeof(ADW_CARRIER) * ADW_MAX_CARRIER, NULL,
! 257: BUS_DMA_NOWAIT)) != 0) {
! 258: printf("%s: unable to load carriers DMA map,"
! 259: " error = %d\n", sc->sc_dev.dv_xname, error);
! 260: return (error);
! 261: }
! 262:
! 263: return (0);
! 264: }
! 265:
! 266:
! 267: /******************************************************************************/
! 268: /* Control Blocks routines */
! 269: /******************************************************************************/
! 270:
! 271:
! 272: /*
! 273: * Create a set of ccbs and add them to the free list. Called once
! 274: * by adw_init(). We return the number of CCBs successfully created.
! 275: */
! 276: int
! 277: adw_create_ccbs(sc, ccbstore, count)
! 278: ADW_SOFTC *sc;
! 279: ADW_CCB *ccbstore;
! 280: int count;
! 281: {
! 282: ADW_CCB *ccb;
! 283: int i, error;
! 284:
! 285: for (i = 0; i < count; i++) {
! 286: ccb = &ccbstore[i];
! 287: if ((error = adw_init_ccb(sc, ccb)) != 0) {
! 288: printf("%s: unable to initialize ccb, error = %d\n",
! 289: sc->sc_dev.dv_xname, error);
! 290: return (i);
! 291: }
! 292: TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
! 293: }
! 294:
! 295: return (i);
! 296: }
! 297:
! 298:
! 299: /*
! 300: * A ccb is put onto the free list.
! 301: */
! 302: void
! 303: adw_free_ccb(sc, ccb)
! 304: ADW_SOFTC *sc;
! 305: ADW_CCB *ccb;
! 306: {
! 307: int s;
! 308:
! 309: s = splbio();
! 310:
! 311: adw_reset_ccb(ccb);
! 312: TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
! 313:
! 314: /*
! 315: * If there were none, wake anybody waiting for one to come free,
! 316: * starting with queued entries.
! 317: */
! 318: if (TAILQ_NEXT(ccb, chain) == NULL)
! 319: wakeup(&sc->sc_free_ccb);
! 320:
! 321: splx(s);
! 322: }
! 323:
! 324:
! 325: void
! 326: adw_reset_ccb(ccb)
! 327: ADW_CCB *ccb;
! 328: {
! 329:
! 330: ccb->flags = 0;
! 331: }
! 332:
! 333:
! 334: int
! 335: adw_init_ccb(sc, ccb)
! 336: ADW_SOFTC *sc;
! 337: ADW_CCB *ccb;
! 338: {
! 339: int hashnum, error;
! 340:
! 341: /*
! 342: * Create the DMA map for this CCB.
! 343: */
! 344: error = bus_dmamap_create(sc->sc_dmat,
! 345: (ADW_MAX_SG_LIST - 1) * PAGE_SIZE,
! 346: ADW_MAX_SG_LIST, (ADW_MAX_SG_LIST - 1) * PAGE_SIZE,
! 347: 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer);
! 348: if (error) {
! 349: printf("%s: unable to create CCB DMA map, error = %d\n",
! 350: sc->sc_dev.dv_xname, error);
! 351: return (error);
! 352: }
! 353:
! 354: /*
! 355: * put in the phystokv hash table
! 356: * Never gets taken out.
! 357: */
! 358: ccb->hashkey = sc->sc_dmamap_control->dm_segs[0].ds_addr +
! 359: ADW_CCB_OFF(ccb);
! 360: hashnum = CCB_HASH(ccb->hashkey);
! 361: ccb->nexthash = sc->sc_ccbhash[hashnum];
! 362: sc->sc_ccbhash[hashnum] = ccb;
! 363: adw_reset_ccb(ccb);
! 364: return (0);
! 365: }
! 366:
! 367:
! 368: /*
! 369: * Get a free ccb
! 370: *
! 371: * If there are none, see if we can allocate a new one
! 372: */
! 373: ADW_CCB *
! 374: adw_get_ccb(sc, flags)
! 375: ADW_SOFTC *sc;
! 376: int flags;
! 377: {
! 378: ADW_CCB *ccb = 0;
! 379: int s;
! 380:
! 381: s = splbio();
! 382:
! 383: /*
! 384: * If we can and have to, sleep waiting for one to come free
! 385: * but only if we can't allocate a new one.
! 386: */
! 387: for (;;) {
! 388: ccb = TAILQ_FIRST(&sc->sc_free_ccb);
! 389: if (ccb) {
! 390: TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
! 391: break;
! 392: }
! 393: if ((flags & SCSI_NOSLEEP) != 0)
! 394: goto out;
! 395:
! 396: tsleep(&sc->sc_free_ccb, PRIBIO, "adwccb", 0);
! 397: }
! 398:
! 399: ccb->flags |= CCB_ALLOC;
! 400:
! 401: out:
! 402: splx(s);
! 403: return (ccb);
! 404: }
! 405:
! 406:
! 407: /*
! 408: * Given a physical address, find the ccb that it corresponds to.
! 409: */
! 410: ADW_CCB *
! 411: adw_ccb_phys_kv(sc, ccb_phys)
! 412: ADW_SOFTC *sc;
! 413: u_int32_t ccb_phys;
! 414: {
! 415: int hashnum = CCB_HASH(ccb_phys);
! 416: ADW_CCB *ccb = sc->sc_ccbhash[hashnum];
! 417:
! 418: while (ccb) {
! 419: if (ccb->hashkey == ccb_phys)
! 420: break;
! 421: ccb = ccb->nexthash;
! 422: }
! 423: return (ccb);
! 424: }
! 425:
! 426:
! 427: /*
! 428: * Queue a CCB to be sent to the controller, and send it if possible.
! 429: */
! 430: int
! 431: adw_queue_ccb(sc, ccb, retry)
! 432: ADW_SOFTC *sc;
! 433: ADW_CCB *ccb;
! 434: int retry;
! 435: {
! 436: int errcode = ADW_SUCCESS;
! 437:
! 438: if(!retry) {
! 439: TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
! 440: }
! 441:
! 442: while ((ccb = TAILQ_FIRST(&sc->sc_waiting_ccb)) != NULL) {
! 443:
! 444: errcode = AdwExeScsiQueue(sc, &ccb->scsiq);
! 445: switch(errcode) {
! 446: case ADW_SUCCESS:
! 447: break;
! 448:
! 449: case ADW_BUSY:
! 450: printf("ADW_BUSY\n");
! 451: return(ADW_BUSY);
! 452:
! 453: case ADW_ERROR:
! 454: printf("ADW_ERROR\n");
! 455: TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
! 456: return(ADW_ERROR);
! 457: }
! 458:
! 459: TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
! 460: TAILQ_INSERT_TAIL(&sc->sc_pending_ccb, ccb, chain);
! 461:
! 462: /* ALWAYS initialize stimeout, lest it contain garbage! */
! 463: timeout_set(&ccb->xs->stimeout, adw_timeout, ccb);
! 464: if ((ccb->xs->flags & SCSI_POLL) == 0)
! 465: timeout_add(&ccb->xs->stimeout, (ccb->timeout * hz) / 1000);
! 466: }
! 467:
! 468: return(errcode);
! 469: }
! 470:
! 471:
! 472: /******************************************************************************/
! 473: /* SCSI layer interfacing routines */
! 474: /******************************************************************************/
! 475:
! 476:
! 477: int
! 478: adw_init(sc)
! 479: ADW_SOFTC *sc;
! 480: {
! 481: u_int16_t warn_code;
! 482:
! 483:
! 484: sc->cfg.lib_version = (ADW_LIB_VERSION_MAJOR << 8) |
! 485: ADW_LIB_VERSION_MINOR;
! 486: sc->cfg.chip_version =
! 487: ADW_GET_CHIP_VERSION(sc->sc_iot, sc->sc_ioh, sc->bus_type);
! 488:
! 489: /*
! 490: * Reset the chip to start and allow register writes.
! 491: */
! 492: if (ADW_FIND_SIGNATURE(sc->sc_iot, sc->sc_ioh) == 0) {
! 493: panic("adw_init: adw_find_signature failed");
! 494: } else {
! 495: AdwResetChip(sc->sc_iot, sc->sc_ioh);
! 496:
! 497: warn_code = AdwInitFromEEPROM(sc);
! 498:
! 499: if (warn_code & ADW_WARN_EEPROM_CHKSUM)
! 500: printf("%s: Bad checksum found. "
! 501: "Setting default values\n",
! 502: sc->sc_dev.dv_xname);
! 503: if (warn_code & ADW_WARN_EEPROM_TERMINATION)
! 504: printf("%s: Bad bus termination setting."
! 505: "Using automatic termination.\n",
! 506: sc->sc_dev.dv_xname);
! 507: }
! 508:
! 509: sc->isr_callback = (ADW_CALLBACK) adw_isr_callback;
! 510: sc->async_callback = (ADW_CALLBACK) adw_async_callback;
! 511:
! 512: return 0;
! 513: }
! 514:
! 515:
! 516: void
! 517: adw_attach(sc)
! 518: ADW_SOFTC *sc;
! 519: {
! 520: struct scsibus_attach_args saa;
! 521: int i, error;
! 522:
! 523:
! 524: TAILQ_INIT(&sc->sc_free_ccb);
! 525: TAILQ_INIT(&sc->sc_waiting_ccb);
! 526: TAILQ_INIT(&sc->sc_pending_ccb);
! 527: LIST_INIT(&sc->sc_queue);
! 528:
! 529:
! 530: /*
! 531: * Allocate the Control Blocks.
! 532: */
! 533: error = adw_alloc_controls(sc);
! 534: if (error)
! 535: return; /* (error) */ ;
! 536:
! 537: bzero(sc->sc_control, sizeof(struct adw_control));
! 538:
! 539: /*
! 540: * Create and initialize the Control Blocks.
! 541: */
! 542: i = adw_create_ccbs(sc, sc->sc_control->ccbs, ADW_MAX_CCB);
! 543: if (i == 0) {
! 544: printf("%s: unable to create Control Blocks\n",
! 545: sc->sc_dev.dv_xname);
! 546: return; /* (ENOMEM) */ ;
! 547: } else if (i != ADW_MAX_CCB) {
! 548: printf("%s: WARNING: only %d of %d Control Blocks"
! 549: " created\n",
! 550: sc->sc_dev.dv_xname, i, ADW_MAX_CCB);
! 551: }
! 552:
! 553: /*
! 554: * Create and initialize the Carriers.
! 555: */
! 556: error = adw_alloc_carriers(sc);
! 557: if (error)
! 558: return; /* (error) */ ;
! 559:
! 560: /*
! 561: * Zero's the freeze_device status
! 562: */
! 563: bzero(sc->sc_freeze_dev, sizeof(sc->sc_freeze_dev));
! 564:
! 565: /*
! 566: * Initialize the adapter
! 567: */
! 568: switch (AdwInitDriver(sc)) {
! 569: case ADW_IERR_BIST_PRE_TEST:
! 570: panic("%s: BIST pre-test error",
! 571: sc->sc_dev.dv_xname);
! 572: break;
! 573:
! 574: case ADW_IERR_BIST_RAM_TEST:
! 575: panic("%s: BIST RAM test error",
! 576: sc->sc_dev.dv_xname);
! 577: break;
! 578:
! 579: case ADW_IERR_MCODE_CHKSUM:
! 580: panic("%s: Microcode checksum error",
! 581: sc->sc_dev.dv_xname);
! 582: break;
! 583:
! 584: case ADW_IERR_ILLEGAL_CONNECTION:
! 585: panic("%s: All three connectors are in use",
! 586: sc->sc_dev.dv_xname);
! 587: break;
! 588:
! 589: case ADW_IERR_REVERSED_CABLE:
! 590: panic("%s: Cable is reversed",
! 591: sc->sc_dev.dv_xname);
! 592: break;
! 593:
! 594: case ADW_IERR_HVD_DEVICE:
! 595: panic("%s: HVD attached to LVD connector",
! 596: sc->sc_dev.dv_xname);
! 597: break;
! 598:
! 599: case ADW_IERR_SINGLE_END_DEVICE:
! 600: panic("%s: single-ended device is attached to"
! 601: " one of the connectors",
! 602: sc->sc_dev.dv_xname);
! 603: break;
! 604:
! 605: case ADW_IERR_NO_CARRIER:
! 606: panic("%s: unable to create Carriers",
! 607: sc->sc_dev.dv_xname);
! 608: break;
! 609:
! 610: case ADW_WARN_BUSRESET_ERROR:
! 611: printf("%s: WARNING: Bus Reset Error\n",
! 612: sc->sc_dev.dv_xname);
! 613: break;
! 614: }
! 615:
! 616: /*
! 617: * Fill in the adapter.
! 618: */
! 619: sc->sc_adapter.scsi_cmd = adw_scsi_cmd;
! 620: sc->sc_adapter.scsi_minphys = adw_minphys;
! 621:
! 622: /*
! 623: * fill in the prototype scsi_link.
! 624: */
! 625: sc->sc_link.adapter_softc = sc;
! 626: sc->sc_link.adapter_target = sc->chip_scsi_id;
! 627: sc->sc_link.adapter = &sc->sc_adapter;
! 628: sc->sc_link.device = &adw_dev;
! 629: sc->sc_link.openings = 4;
! 630: sc->sc_link.adapter_buswidth = ADW_MAX_TID+1;
! 631:
! 632: bzero(&saa, sizeof(saa));
! 633: saa.saa_sc_link = &sc->sc_link;
! 634:
! 635: config_found(&sc->sc_dev, &saa, scsiprint);
! 636: }
! 637:
! 638:
! 639: void
! 640: adw_minphys(bp)
! 641: struct buf *bp;
! 642: {
! 643:
! 644: if (bp->b_bcount > ((ADW_MAX_SG_LIST - 1) * PAGE_SIZE))
! 645: bp->b_bcount = ((ADW_MAX_SG_LIST - 1) * PAGE_SIZE);
! 646: minphys(bp);
! 647: }
! 648:
! 649:
! 650: /*
! 651: * start a scsi operation given the command and the data address.
! 652: * Also needs the unit, target and lu.
! 653: */
! 654: int
! 655: adw_scsi_cmd(xs)
! 656: struct scsi_xfer *xs;
! 657: {
! 658: struct scsi_link *sc_link = xs->sc_link;
! 659: ADW_SOFTC *sc = sc_link->adapter_softc;
! 660: ADW_CCB *ccb;
! 661: int s, fromqueue = 1, dontqueue = 0, nowait = 0, retry = 0;
! 662: int flags;
! 663:
! 664: s = splbio(); /* protect the queue */
! 665:
! 666: /*
! 667: * If we're running the queue from adw_done(), we've been
! 668: * called with the first queue entry as our argument.
! 669: */
! 670: if (xs == LIST_FIRST(&sc->sc_queue)) {
! 671: if(sc->sc_freeze_dev[xs->sc_link->target]) {
! 672: splx(s);
! 673: return (TRY_AGAIN_LATER);
! 674: }
! 675: xs = adw_dequeue(sc);
! 676: fromqueue = 1;
! 677: nowait = 1;
! 678: } else {
! 679: if(sc->sc_freeze_dev[xs->sc_link->target]) {
! 680: splx(s);
! 681: return (TRY_AGAIN_LATER);
! 682: }
! 683:
! 684: /* Polled requests can't be queued for later. */
! 685: dontqueue = xs->flags & SCSI_POLL;
! 686:
! 687: /*
! 688: * If there are jobs in the queue, run them first.
! 689: */
! 690: if (!LIST_EMPTY(&sc->sc_queue)) {
! 691: /*
! 692: * If we can't queue, we have to abort, since
! 693: * we have to preserve order.
! 694: */
! 695: if (dontqueue) {
! 696: splx(s);
! 697: return (TRY_AGAIN_LATER);
! 698: }
! 699: /*
! 700: * Swap with the first queue entry.
! 701: */
! 702: adw_enqueue(sc, xs, 0);
! 703: xs = adw_dequeue(sc);
! 704: fromqueue = 1;
! 705: }
! 706: }
! 707:
! 708:
! 709: /*
! 710: * get a ccb to use. If the transfer
! 711: * is from a buf (possibly from interrupt time)
! 712: * then we can't allow it to sleep
! 713: */
! 714:
! 715: flags = xs->flags;
! 716: if (nowait)
! 717: flags |= SCSI_NOSLEEP;
! 718: if ((ccb = adw_get_ccb(sc, flags)) == NULL) {
! 719: /*
! 720: * If we can't queue, we lose.
! 721: */
! 722: if (dontqueue) {
! 723: splx(s);
! 724: return (TRY_AGAIN_LATER);
! 725: }
! 726: /*
! 727: * Stuff ourselves into the queue, in front
! 728: * if we came off in the first place.
! 729: */
! 730: adw_enqueue(sc, xs, fromqueue);
! 731: splx(s);
! 732: return (SUCCESSFULLY_QUEUED);
! 733: }
! 734: splx(s); /* done playing with the queue */
! 735:
! 736: ccb->xs = xs;
! 737: ccb->timeout = xs->timeout;
! 738:
! 739: if (adw_build_req(xs, ccb, flags)) {
! 740: retryagain:
! 741: s = splbio();
! 742: retry = adw_queue_ccb(sc, ccb, retry);
! 743: splx(s);
! 744:
! 745: switch(retry) {
! 746: case ADW_BUSY:
! 747: goto retryagain;
! 748:
! 749: case ADW_ERROR:
! 750: xs->error = XS_DRIVER_STUFFUP;
! 751: return (COMPLETE);
! 752: }
! 753:
! 754: /*
! 755: * Usually return SUCCESSFULLY QUEUED
! 756: */
! 757: if ((xs->flags & SCSI_POLL) == 0)
! 758: return (SUCCESSFULLY_QUEUED);
! 759:
! 760: /*
! 761: * If we can't use interrupts, poll on completion
! 762: */
! 763: if (adw_poll(sc, xs, ccb->timeout)) {
! 764: adw_timeout(ccb);
! 765: if (adw_poll(sc, xs, ccb->timeout))
! 766: adw_timeout(ccb);
! 767: }
! 768: }
! 769: return (COMPLETE);
! 770: }
! 771:
! 772:
! 773: /*
! 774: * Build a request structure for the Wide Boards.
! 775: */
! 776: int
! 777: adw_build_req(xs, ccb, flags)
! 778: struct scsi_xfer *xs;
! 779: ADW_CCB *ccb;
! 780: int flags;
! 781: {
! 782: struct scsi_link *sc_link = xs->sc_link;
! 783: ADW_SOFTC *sc = sc_link->adapter_softc;
! 784: bus_dma_tag_t dmat = sc->sc_dmat;
! 785: ADW_SCSI_REQ_Q *scsiqp;
! 786: int error;
! 787:
! 788: scsiqp = &ccb->scsiq;
! 789: bzero(scsiqp, sizeof(ADW_SCSI_REQ_Q));
! 790:
! 791: /*
! 792: * Set the ADW_SCSI_REQ_Q 'ccb_ptr' to point to the
! 793: * physical CCB structure.
! 794: */
! 795: scsiqp->ccb_ptr = ccb->hashkey;
! 796:
! 797: /*
! 798: * Build the ADW_SCSI_REQ_Q request.
! 799: */
! 800:
! 801: /*
! 802: * Set CDB length and copy it to the request structure.
! 803: * For wide boards a CDB length maximum of 16 bytes
! 804: * is supported.
! 805: */
! 806: bcopy(xs->cmd, &scsiqp->cdb, ((scsiqp->cdb_len = xs->cmdlen) <= 12)?
! 807: xs->cmdlen : 12 );
! 808: if(xs->cmdlen > 12)
! 809: bcopy(&(xs->cmd[12]), &scsiqp->cdb16, xs->cmdlen - 12);
! 810:
! 811: scsiqp->target_id = sc_link->target;
! 812: scsiqp->target_lun = sc_link->lun;
! 813:
! 814: scsiqp->vsense_addr = &ccb->scsi_sense;
! 815: scsiqp->sense_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr +
! 816: ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsi_sense);
! 817: scsiqp->sense_len = sizeof(struct scsi_sense_data);
! 818:
! 819: /*
! 820: * Build ADW_SCSI_REQ_Q for a scatter-gather buffer command.
! 821: */
! 822: if (xs->datalen) {
! 823: /*
! 824: * Map the DMA transfer.
! 825: */
! 826: #ifdef TFS
! 827: if (xs->flags & SCSI_DATA_UIO) {
! 828: error = bus_dmamap_load_uio(dmat,
! 829: ccb->dmamap_xfer, (struct uio *) xs->data,
! 830: (flags & SCSI_NOSLEEP) ?
! 831: BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
! 832: } else
! 833: #endif /* TFS */
! 834: {
! 835: error = bus_dmamap_load(dmat,
! 836: ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
! 837: (flags & SCSI_NOSLEEP) ?
! 838: BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
! 839: }
! 840:
! 841: if (error) {
! 842: if (error == EFBIG) {
! 843: printf("%s: adw_scsi_cmd, more than %d dma"
! 844: " segments\n",
! 845: sc->sc_dev.dv_xname, ADW_MAX_SG_LIST);
! 846: } else {
! 847: printf("%s: adw_scsi_cmd, error %d loading"
! 848: " dma map\n",
! 849: sc->sc_dev.dv_xname, error);
! 850: }
! 851:
! 852: xs->error = XS_DRIVER_STUFFUP;
! 853: adw_free_ccb(sc, ccb);
! 854: return (0);
! 855: }
! 856: bus_dmamap_sync(dmat, ccb->dmamap_xfer,
! 857: 0, ccb->dmamap_xfer->dm_mapsize,
! 858: (xs->flags & SCSI_DATA_IN) ?
! 859: BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
! 860:
! 861: /*
! 862: * Build scatter-gather list.
! 863: */
! 864: scsiqp->data_cnt = xs->datalen;
! 865: scsiqp->vdata_addr = xs->data;
! 866: scsiqp->data_addr = ccb->dmamap_xfer->dm_segs[0].ds_addr;
! 867: bzero(ccb->sg_block, sizeof(ADW_SG_BLOCK) * ADW_NUM_SG_BLOCK);
! 868: adw_build_sglist(ccb, scsiqp, ccb->sg_block);
! 869: } else {
! 870: /*
! 871: * No data xfer, use non S/G values.
! 872: */
! 873: scsiqp->data_cnt = 0;
! 874: scsiqp->vdata_addr = 0;
! 875: scsiqp->data_addr = 0;
! 876: }
! 877:
! 878: return (1);
! 879: }
! 880:
! 881:
! 882: /*
! 883: * Build scatter-gather list for Wide Boards.
! 884: */
! 885: void
! 886: adw_build_sglist(ccb, scsiqp, sg_block)
! 887: ADW_CCB *ccb;
! 888: ADW_SCSI_REQ_Q *scsiqp;
! 889: ADW_SG_BLOCK *sg_block;
! 890: {
! 891: u_long sg_block_next_addr; /* block and its next */
! 892: u_int32_t sg_block_physical_addr;
! 893: int i; /* how many SG entries */
! 894: bus_dma_segment_t *sg_list = &ccb->dmamap_xfer->dm_segs[0];
! 895: int sg_elem_cnt = ccb->dmamap_xfer->dm_nsegs;
! 896:
! 897:
! 898: sg_block_next_addr = (u_long) sg_block; /* allow math operation */
! 899: sg_block_physical_addr = ccb->hashkey +
! 900: offsetof(struct adw_ccb, sg_block[0]);
! 901: scsiqp->sg_real_addr = sg_block_physical_addr;
! 902:
! 903: /*
! 904: * If there are more than NO_OF_SG_PER_BLOCK dma segments (hw sg-list)
! 905: * then split the request into multiple sg-list blocks.
! 906: */
! 907:
! 908: do {
! 909: for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
! 910: sg_block->sg_list[i].sg_addr = sg_list->ds_addr;
! 911: sg_block->sg_list[i].sg_count = sg_list->ds_len;
! 912:
! 913: if (--sg_elem_cnt == 0) {
! 914: /* last entry, get out */
! 915: sg_block->sg_cnt = i + 1;
! 916: sg_block->sg_ptr = NULL; /* next link = NULL */
! 917: return;
! 918: }
! 919: sg_list++;
! 920: }
! 921: sg_block_next_addr += sizeof(ADW_SG_BLOCK);
! 922: sg_block_physical_addr += sizeof(ADW_SG_BLOCK);
! 923:
! 924: sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
! 925: sg_block->sg_ptr = sg_block_physical_addr;
! 926: sg_block = (ADW_SG_BLOCK *) sg_block_next_addr; /* virt. addr */
! 927: } while (1);
! 928: }
! 929:
! 930:
! 931: /******************************************************************************/
! 932: /* Interrupts and TimeOut routines */
! 933: /******************************************************************************/
! 934:
! 935:
! 936: int
! 937: adw_intr(arg)
! 938: void *arg;
! 939: {
! 940: ADW_SOFTC *sc = arg;
! 941: struct scsi_xfer *xs;
! 942:
! 943:
! 944: if(AdwISR(sc) != ADW_FALSE) {
! 945: /*
! 946: * If there are queue entries in the software queue, try to
! 947: * run the first one. We should be more or less guaranteed
! 948: * to succeed, since we just freed a CCB.
! 949: *
! 950: * NOTE: adw_scsi_cmd() relies on our calling it with
! 951: * the first entry in the queue.
! 952: */
! 953: if ((xs = LIST_FIRST(&sc->sc_queue)) != NULL)
! 954: (void) adw_scsi_cmd(xs);
! 955:
! 956: return (1);
! 957: }
! 958:
! 959: return (0);
! 960: }
! 961:
! 962:
! 963: /*
! 964: * Poll a particular unit, looking for a particular xs
! 965: */
! 966: int
! 967: adw_poll(sc, xs, count)
! 968: ADW_SOFTC *sc;
! 969: struct scsi_xfer *xs;
! 970: int count;
! 971: {
! 972:
! 973: /* timeouts are in msec, so we loop in 1000 usec cycles */
! 974: while (count > 0) {
! 975: adw_intr(sc);
! 976: if (xs->flags & ITSDONE) {
! 977: if ((xs->cmd->opcode == INQUIRY)
! 978: && (xs->sc_link->lun == 0)
! 979: && (xs->error == XS_NOERROR))
! 980: adw_print_info(sc, xs->sc_link->target);
! 981: return (0);
! 982: }
! 983: delay(1000); /* only happens in boot so ok */
! 984: count--;
! 985: }
! 986: return (1);
! 987: }
! 988:
! 989:
! 990: void
! 991: adw_timeout(arg)
! 992: void *arg;
! 993: {
! 994: ADW_CCB *ccb = arg;
! 995: struct scsi_xfer *xs = ccb->xs;
! 996: struct scsi_link *sc_link = xs->sc_link;
! 997: ADW_SOFTC *sc = sc_link->adapter_softc;
! 998: int s;
! 999:
! 1000: sc_print_addr(sc_link);
! 1001: printf("timed out");
! 1002:
! 1003: s = splbio();
! 1004:
! 1005: if (ccb->flags & CCB_ABORTED) {
! 1006: /*
! 1007: * Abort Timed Out
! 1008: *
! 1009: * No more opportunities. Lets try resetting the bus and
! 1010: * reinitialize the host adapter.
! 1011: */
! 1012: timeout_del(&xs->stimeout);
! 1013: printf(" AGAIN. Resetting SCSI Bus\n");
! 1014: adw_reset_bus(sc);
! 1015: splx(s);
! 1016: return;
! 1017: } else if (ccb->flags & CCB_ABORTING) {
! 1018: /*
! 1019: * Abort the operation that has timed out.
! 1020: *
! 1021: * Second opportunity.
! 1022: */
! 1023: printf("\n");
! 1024: xs->error = XS_TIMEOUT;
! 1025: ccb->flags |= CCB_ABORTED;
! 1026: #if 0
! 1027: /*
! 1028: * - XXX - 3.3a microcode is BROKEN!!!
! 1029: *
! 1030: * We cannot abort a CCB, so we can only hope the command
! 1031: * get completed before the next timeout, otherwise a
! 1032: * Bus Reset will arrive inexorably.
! 1033: */
! 1034: /*
! 1035: * ADW_ABORT_CCB() makes the board to generate an interrupt
! 1036: *
! 1037: * - XXX - The above assertion MUST be verified (and this
! 1038: * code changed as well [callout_*()]), when the
! 1039: * ADW_ABORT_CCB will be working again
! 1040: */
! 1041: ADW_ABORT_CCB(sc, ccb);
! 1042: #endif
! 1043: /*
! 1044: * waiting for multishot callout_reset() let's restart it
! 1045: * by hand so the next time a timeout event will occur
! 1046: * we will reset the bus.
! 1047: */
! 1048: timeout_add(&xs->stimeout, (ccb->timeout * hz) / 1000);
! 1049: } else {
! 1050: /*
! 1051: * Abort the operation that has timed out.
! 1052: *
! 1053: * First opportunity.
! 1054: */
! 1055: printf("\n");
! 1056: xs->error = XS_TIMEOUT;
! 1057: ccb->flags |= CCB_ABORTING;
! 1058: #if 0
! 1059: /*
! 1060: * - XXX - 3.3a microcode is BROKEN!!!
! 1061: *
! 1062: * We cannot abort a CCB, so we can only hope the command
! 1063: * get completed before the next 2 timeout, otherwise a
! 1064: * Bus Reset will arrive inexorably.
! 1065: */
! 1066: /*
! 1067: * ADW_ABORT_CCB() makes the board to generate an interrupt
! 1068: *
! 1069: * - XXX - The above assertion MUST be verified (and this
! 1070: * code changed as well [callout_*()]), when the
! 1071: * ADW_ABORT_CCB will be working again
! 1072: */
! 1073: ADW_ABORT_CCB(sc, ccb);
! 1074: #endif
! 1075: /*
! 1076: * waiting for multishot callout_reset() let's restart it
! 1077: * by hand so to give a second opportunity to the command
! 1078: * which timed-out.
! 1079: */
! 1080: timeout_add(&xs->stimeout, (ccb->timeout * hz) / 1000);
! 1081: }
! 1082:
! 1083: splx(s);
! 1084: }
! 1085:
! 1086:
! 1087: void
! 1088: adw_reset_bus(sc)
! 1089: ADW_SOFTC *sc;
! 1090: {
! 1091: ADW_CCB *ccb;
! 1092: int s;
! 1093:
! 1094: s = splbio();
! 1095: AdwResetSCSIBus(sc); /* XXX - should check return value? */
! 1096: while((ccb = TAILQ_LAST(&sc->sc_pending_ccb,
! 1097: adw_pending_ccb)) != NULL) {
! 1098: timeout_del(&ccb->xs->stimeout);
! 1099: TAILQ_REMOVE(&sc->sc_pending_ccb, ccb, chain);
! 1100: TAILQ_INSERT_HEAD(&sc->sc_waiting_ccb, ccb, chain);
! 1101: }
! 1102:
! 1103: bzero(sc->sc_freeze_dev, sizeof(sc->sc_freeze_dev));
! 1104: adw_queue_ccb(sc, TAILQ_FIRST(&sc->sc_waiting_ccb), 1);
! 1105:
! 1106: splx(s);
! 1107: }
! 1108:
! 1109:
! 1110: /******************************************************************************/
! 1111: /* Host Adapter and Peripherals Information Routines */
! 1112: /******************************************************************************/
! 1113:
! 1114:
! 1115: void
! 1116: adw_print_info(sc, tid)
! 1117: ADW_SOFTC *sc;
! 1118: int tid;
! 1119: {
! 1120: bus_space_handle_t ioh = sc->sc_ioh;
! 1121: bus_space_tag_t iot = sc->sc_iot;
! 1122: u_int16_t hshk_cfg, able_mask, period = 0;
! 1123:
! 1124: /* hshk/HSHK means 'handskake' */
! 1125:
! 1126: ADW_READ_WORD_LRAM(iot, ioh,
! 1127: ADW_MC_DEVICE_HSHK_CFG_TABLE + (2 * tid), hshk_cfg);
! 1128:
! 1129: ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, able_mask);
! 1130: if ((able_mask & ADW_TID_TO_TIDMASK(tid)) == 0)
! 1131: hshk_cfg &= ~HSHK_CFG_WIDE_XFR;
! 1132:
! 1133: ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, able_mask);
! 1134: if ((able_mask & ADW_TID_TO_TIDMASK(tid)) == 0)
! 1135: hshk_cfg &= ~HSHK_CFG_OFFSET;
! 1136:
! 1137: printf("%s: target %d using %d bit ", sc->sc_dev.dv_xname, tid,
! 1138: (hshk_cfg & HSHK_CFG_WIDE_XFR) ? 16 : 8);
! 1139:
! 1140: if ((hshk_cfg & HSHK_CFG_OFFSET) == 0)
! 1141: printf("async ");
! 1142: else {
! 1143: period = (hshk_cfg & 0x1f00) >> 8;
! 1144: switch (period) {
! 1145: case 0x11:
! 1146: printf("80.0 ");
! 1147: break;
! 1148: case 0x10:
! 1149: printf("40.0 ");
! 1150: break;
! 1151: default:
! 1152: period = (period * 25) + 50;
! 1153: printf("%d.%d ", 1000/period, ADW_TENTHS(1000, period));
! 1154: break;
! 1155: }
! 1156: printf("MHz %d REQ/ACK offset ", hshk_cfg & HSHK_CFG_OFFSET);
! 1157: }
! 1158:
! 1159: printf("xfers\n");
! 1160: }
! 1161:
! 1162:
! 1163: /******************************************************************************/
! 1164: /* WIDE boards Interrupt callbacks */
! 1165: /******************************************************************************/
! 1166:
! 1167:
! 1168: /*
! 1169: * adw_isr_callback() - Second Level Interrupt Handler called by AdwISR()
! 1170: *
! 1171: * Interrupt callback function for the Wide SCSI Adw Library.
! 1172: *
! 1173: * Notice:
! 1174: * Interrupts are disabled by the caller (AdwISR() function), and will be
! 1175: * enabled at the end of the caller.
! 1176: */
! 1177: void
! 1178: adw_isr_callback(sc, scsiq)
! 1179: ADW_SOFTC *sc;
! 1180: ADW_SCSI_REQ_Q *scsiq;
! 1181: {
! 1182: bus_dma_tag_t dmat;
! 1183: ADW_CCB *ccb;
! 1184: struct scsi_xfer *xs;
! 1185: struct scsi_sense_data *s1, *s2;
! 1186:
! 1187:
! 1188: ccb = adw_ccb_phys_kv(sc, scsiq->ccb_ptr);
! 1189: TAILQ_REMOVE(&sc->sc_pending_ccb, ccb, chain);
! 1190:
! 1191: if ((ccb->flags & CCB_ALLOC) == 0) {
! 1192: printf("%s: unallocated ccb found on pending list!\n",
! 1193: sc->sc_dev.dv_xname);
! 1194: Debugger();
! 1195: adw_free_ccb(sc, ccb);
! 1196: return;
! 1197: }
! 1198:
! 1199: xs = ccb->xs;
! 1200: timeout_del(&xs->stimeout);
! 1201:
! 1202: /*
! 1203: * If we were a data transfer, unload the map that described
! 1204: * the data buffer.
! 1205: */
! 1206: dmat = sc->sc_dmat;
! 1207: if (xs->datalen) {
! 1208: bus_dmamap_sync(dmat, ccb->dmamap_xfer,
! 1209: 0, ccb->dmamap_xfer->dm_mapsize,
! 1210: ((xs->flags & SCSI_DATA_IN) ?
! 1211: BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
! 1212: bus_dmamap_unload(dmat, ccb->dmamap_xfer);
! 1213: }
! 1214:
! 1215: /*
! 1216: * 'done_status' contains the command's ending status.
! 1217: * 'host_status' contains the host adapter status.
! 1218: * 'scsi_status' contains the scsi peripheral status.
! 1219: */
! 1220:
! 1221: sc->sc_freeze_dev[scsiq->target_id] = 0;
! 1222: xs->status = scsiq->scsi_status;
! 1223:
! 1224: switch (scsiq->done_status) {
! 1225: case QD_NO_ERROR: /* (scsi_status == 0) && (host_status == 0) */
! 1226: NO_ERROR:
! 1227: xs->resid = scsiq->data_cnt;
! 1228: xs->error = XS_NOERROR;
! 1229: break;
! 1230:
! 1231: case QD_WITH_ERROR:
! 1232: switch (scsiq->host_status) {
! 1233: case QHSTA_NO_ERROR:
! 1234: switch (scsiq->scsi_status) {
! 1235: case SCSI_COND_MET:
! 1236: case SCSI_INTERM:
! 1237: case SCSI_INTERM_COND_MET:
! 1238: /*
! 1239: * These non-zero status values are
! 1240: * not really error conditions.
! 1241: *
! 1242: * XXX - would it be too paranoid to
! 1243: * add SCSI_OK here in
! 1244: * case the docs are wrong re
! 1245: * QD_NO_ERROR?
! 1246: */
! 1247: goto NO_ERROR;
! 1248:
! 1249: case SCSI_CHECK:
! 1250: case SCSI_TERMINATED:
! 1251: case SCSI_ACA_ACTIVE:
! 1252: s1 = &ccb->scsi_sense;
! 1253: s2 = &xs->sense;
! 1254: *s2 = *s1;
! 1255: xs->error = XS_SENSE;
! 1256: break;
! 1257:
! 1258: case SCSI_BUSY:
! 1259: case SCSI_QUEUE_FULL:
! 1260: case SCSI_RESV_CONFLICT:
! 1261: sc->sc_freeze_dev[scsiq->target_id] = 1;
! 1262: xs->error = XS_BUSY;
! 1263: break;
! 1264:
! 1265: default: /* scsiq->scsi_status value */
! 1266: printf("%s: bad scsi_status: 0x%02x.\n"
! 1267: ,sc->sc_dev.dv_xname
! 1268: ,scsiq->scsi_status);
! 1269: xs->error = XS_DRIVER_STUFFUP;
! 1270: break;
! 1271: }
! 1272: break;
! 1273:
! 1274: case QHSTA_M_SEL_TIMEOUT:
! 1275: xs->error = XS_SELTIMEOUT;
! 1276: break;
! 1277:
! 1278: case QHSTA_M_DIRECTION_ERR:
! 1279: case QHSTA_M_SXFR_OFF_UFLW:
! 1280: case QHSTA_M_SXFR_OFF_OFLW:
! 1281: case QHSTA_M_SXFR_XFR_OFLW:
! 1282: case QHSTA_M_QUEUE_ABORTED:
! 1283: case QHSTA_M_INVALID_DEVICE:
! 1284: case QHSTA_M_SGBACKUP_ERROR:
! 1285: case QHSTA_M_SXFR_DESELECTED:
! 1286: case QHSTA_M_SXFR_XFR_PH_ERR:
! 1287: case QHSTA_M_BUS_DEVICE_RESET:
! 1288: case QHSTA_M_NO_AUTO_REQ_SENSE:
! 1289: case QHSTA_M_BAD_CMPL_STATUS_IN:
! 1290: case QHSTA_M_SXFR_UNKNOWN_ERROR:
! 1291: case QHSTA_M_AUTO_REQ_SENSE_FAIL:
! 1292: case QHSTA_M_UNEXPECTED_BUS_FREE:
! 1293: printf("%s: host adapter error 0x%02x."
! 1294: " See adw(4).\n"
! 1295: ,sc->sc_dev.dv_xname, scsiq->host_status);
! 1296: xs->error = XS_DRIVER_STUFFUP;
! 1297: break;
! 1298:
! 1299: case QHSTA_M_RDMA_PERR:
! 1300: case QHSTA_M_SXFR_WD_TMO:
! 1301: case QHSTA_M_WTM_TIMEOUT:
! 1302: case QHSTA_M_FROZEN_TIDQ:
! 1303: case QHSTA_M_SXFR_SDMA_ERR:
! 1304: case QHSTA_M_SXFR_SXFR_PERR:
! 1305: case QHSTA_M_SCSI_BUS_RESET:
! 1306: case QHSTA_M_DIRECTION_ERR_HUNG:
! 1307: case QHSTA_M_SCSI_BUS_RESET_UNSOL:
! 1308: /*
! 1309: * XXX - are all these cases really asking
! 1310: * for a card reset? _BUS_RESET and
! 1311: * _BUS_RESET_UNSOL added just to make
! 1312: * sure the pending queue is cleared out
! 1313: * in case card has lost track of them.
! 1314: */
! 1315: printf("%s: host adapter error 0x%02x,"
! 1316: " resetting bus. See adw(4).\n"
! 1317: ,sc->sc_dev.dv_xname, scsiq->host_status);
! 1318: adw_reset_bus(sc);
! 1319: xs->error = XS_RESET;
! 1320: break;
! 1321:
! 1322: default: /* scsiq->host_status value */
! 1323: /*
! 1324: * XXX - is a panic really appropriate here? If
! 1325: * not, would it be better to make the
! 1326: * XS_DRIVER_STUFFUP case above the
! 1327: * default behaviour? Or XS_RESET?
! 1328: */
! 1329: panic("%s: bad host_status: 0x%02x"
! 1330: ,sc->sc_dev.dv_xname, scsiq->host_status);
! 1331: break;
! 1332: }
! 1333: break;
! 1334:
! 1335: case QD_ABORTED_BY_HOST:
! 1336: xs->error = XS_DRIVER_STUFFUP;
! 1337: break;
! 1338:
! 1339: default: /* scsiq->done_status value */
! 1340: /*
! 1341: * XXX - would QD_NO_STATUS really mean the I/O is not
! 1342: * done? and would that mean it should somehow be
! 1343: * put back as a pending I/O?
! 1344: */
! 1345: printf("%s: bad done_status: 0x%02x"
! 1346: " (host_status: 0x%02x, scsi_status: 0x%02x)\n"
! 1347: ,sc->sc_dev.dv_xname
! 1348: ,scsiq->done_status
! 1349: ,scsiq->host_status
! 1350: ,scsiq->scsi_status);
! 1351: xs->error = XS_DRIVER_STUFFUP;
! 1352: break;
! 1353: }
! 1354:
! 1355: adw_free_ccb(sc, ccb);
! 1356:
! 1357: xs->flags |= ITSDONE;
! 1358: scsi_done(xs);
! 1359: }
! 1360:
! 1361:
! 1362: /*
! 1363: * adw_async_callback() - Adw Library asynchronous event callback function.
! 1364: */
! 1365: void
! 1366: adw_async_callback(sc, code)
! 1367: ADW_SOFTC *sc;
! 1368: u_int8_t code;
! 1369: {
! 1370: switch (code) {
! 1371: case ADW_ASYNC_SCSI_BUS_RESET_DET:
! 1372: /* The firmware detected a SCSI Bus reset. */
! 1373: printf("%s: SCSI Bus reset detected\n", sc->sc_dev.dv_xname);
! 1374: break;
! 1375:
! 1376: case ADW_ASYNC_RDMA_FAILURE:
! 1377: /*
! 1378: * Handle RDMA failure by resetting the SCSI Bus and
! 1379: * possibly the chip if it is unresponsive.
! 1380: */
! 1381: printf("%s: RDMA failure. Resetting the SCSI Bus and"
! 1382: " the adapter\n", sc->sc_dev.dv_xname);
! 1383: adw_reset_bus(sc);
! 1384: break;
! 1385:
! 1386: case ADW_HOST_SCSI_BUS_RESET:
! 1387: /* Host generated SCSI bus reset occurred. */
! 1388: printf("%s: Host generated SCSI bus reset occurred\n",
! 1389: sc->sc_dev.dv_xname);
! 1390: break;
! 1391:
! 1392:
! 1393: case ADW_ASYNC_CARRIER_READY_FAILURE:
! 1394: /*
! 1395: * Carrier Ready failure.
! 1396: *
! 1397: * A warning only - RISC too busy to realize it's been
! 1398: * tickled. Occurs in normal operation under heavy
! 1399: * load, so a message is printed only when ADW_DEBUG'ing
! 1400: */
! 1401: #ifdef ADW_DEBUG
! 1402: printf("%s: Carrier Ready failure!\n", sc->sc_dev.dv_xname);
! 1403: #endif
! 1404: break;
! 1405:
! 1406: default:
! 1407: printf("%s: Unknown Async callback code (ignored): 0x%02x\n",
! 1408: sc->sc_dev.dv_xname, code);
! 1409: break;
! 1410: }
! 1411: }
CVSweb