|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)sc.c 1.1 86/02/03 Copyr 1985 Sun Micro"; ! 3: #endif ! 4: ! 5: /* ! 6: * Copyright (c) 1985 by Sun Microsystems, Inc. ! 7: */ ! 8: ! 9: #include "sc.h" ! 10: ! 11: #if NSC > 0 ! 12: /* ! 13: * Generic scsi routines. ! 14: */ ! 15: ! 16: #include "../h/param.h" ! 17: #include "../h/systm.h" ! 18: #include "../h/dk.h" ! 19: #include "../h/buf.h" ! 20: #include "../h/conf.h" ! 21: #include "../h/dir.h" ! 22: #include "../h/user.h" ! 23: #include "../h/map.h" ! 24: #include "../h/vmmac.h" ! 25: /* ! 26: *#include "../h/ioctl.h" ! 27: *#include "../h/uio.h" ! 28: *#include "../h/kernel.h" ! 29: */ ! 30: #include "../h/dkbad.h" ! 31: ! 32: #include "../machine/pte.h" ! 33: #include "../machine/psl.h" ! 34: #include "../machine/mmu.h" ! 35: #include "../machine/cpu.h" ! 36: #include "../machine/scb.h" ! 37: ! 38: #include "../sun/dklabel.h" ! 39: #include "../sun/dkio.h" ! 40: ! 41: #include "../sundev/mbvar.h" ! 42: #include "../sundev/screg.h" ! 43: #include "../sundev/sireg.h" ! 44: #include "../sundev/scsi.h" ! 45: ! 46: struct scsi_ctlr scctlrs[NSC]; ! 47: #define SCNUM(sc) (sc - scctlrs) ! 48: ! 49: int scprobe(), scslave(), scattach(), scgo(), scdone(), scpoll(); ! 50: int scustart(), scstart(), sc_cmd(), sc_getstatus(), sc_cmdwait(); ! 51: int sc_off(), sc_reset(), sc_dmacnt(); ! 52: ! 53: struct mb_ctlr *scinfo[NSC]; ! 54: extern struct mb_device *sdinfo[]; ! 55: struct mb_driver scdriver = { ! 56: scprobe, scslave, scattach, scgo, scdone, scpoll, ! 57: sizeof (struct scsi_ha_reg), "sd", sdinfo, "sc", scinfo, MDR_BIODMA, ! 58: }; ! 59: ! 60: /* routines available to devices for mainbus scsi host adaptor */ ! 61: struct scsi_ctlr_subr scsubr = { ! 62: scustart, scstart, scdone, sc_cmd, sc_getstatus, sc_cmdwait, ! 63: sc_off, sc_reset, sc_dmacnt, scgo, ! 64: }; ! 65: ! 66: extern int scsi_debug; ! 67: extern int scsi_ntype; ! 68: extern struct scsi_unit_subr scsi_unit_subr[]; ! 69: ! 70: /* ! 71: * Determine existence of SCSI host adapter. ! 72: */ ! 73: scprobe(reg, ctlr) ! 74: register struct scsi_ha_reg *reg; ! 75: register int ctlr; ! 76: { ! 77: register struct scsi_ctlr *c; ! 78: ! 79: /* probe for different scsi host adaptor interfaces */ ! 80: c = &scctlrs[ctlr]; ! 81: if (peekc((char *)®->dma_count) == -1) { ! 82: return (0); ! 83: } ! 84: reg->dma_count = 0x6789; ! 85: if (reg->dma_count != 0x6789) { ! 86: return (0); ! 87: } ! 88: ! 89: /* allocate memory for sense information */ ! 90: c->c_sense = (struct scsi_sense *) rmalloc(iopbmap, ! 91: (long) sizeof (struct scsi_sense)); ! 92: if (c->c_sense == NULL) { ! 93: printf("scprobe: no iopb memory for sense.\n"); ! 94: return (0); ! 95: } ! 96: ! 97: /* init controller information */ ! 98: c->c_flags = SCSI_PRESENT; ! 99: c->c_har = reg; ! 100: c->c_ss = &scsubr; ! 101: sc_reset(c); ! 102: return (sizeof (struct scsi_ha_reg)); ! 103: } ! 104: ! 105: /* ! 106: * See if a slave exists. ! 107: * Since it may exist but be powered off, we always say yes. ! 108: */ ! 109: /*ARGSUSED*/ ! 110: scslave(md, reg) ! 111: struct mb_device *md; ! 112: register struct scsi_ha_reg *reg; ! 113: { ! 114: register struct scsi_unit *un; ! 115: register int type; ! 116: ! 117: /* ! 118: * This kludge allows autoconfig to print out "sd" for ! 119: * disks and "st" for tapes. The problem is that there ! 120: * is only one md_driver for scsi devices. ! 121: */ ! 122: type = TYPE(md->md_flags); ! 123: if (type >= scsi_ntype) { ! 124: panic("scslave: unknown type in md_flags"); ! 125: } ! 126: ! 127: /* link unit to its controller */ ! 128: un = (struct scsi_unit *)(*scsi_unit_subr[type].ss_unit_ptr)(md); ! 129: if (un == 0) { ! 130: panic("scslave: md_flags scsi type not configured in\n"); ! 131: } ! 132: un->un_c = &scctlrs[md->md_ctlr]; ! 133: md->md_driver->mdr_dname = scsi_unit_subr[type].ss_devname; ! 134: return (1); ! 135: } ! 136: ! 137: /* ! 138: * Attach device (boot time). ! 139: */ ! 140: scattach(md) ! 141: register struct mb_device *md; ! 142: { ! 143: register struct mb_ctlr *mc = md->md_mc; ! 144: register struct scsi_ctlr *c = &scctlrs[md->md_ctlr]; ! 145: register int type = TYPE(md->md_flags); ! 146: ! 147: if (type >= scsi_ntype) { ! 148: panic("scattach: unknown type in md_flags"); ! 149: } ! 150: (*scsi_unit_subr[type].ss_attach)(md); ! 151: ! 152: /* ! 153: * Initialize interrupt register ! 154: */ ! 155: if (mc->mc_intr) { ! 156: /* set up for vectored interrupts - we will pass ctlr ptr */ ! 157: c->c_har->intvec = mc->mc_intr->v_vec; ! 158: *(mc->mc_intr->v_vptr) = (int)c; ! 159: } else { ! 160: /* use auto-vectoring */ ! 161: c->c_har->intvec = AUTOBASE + mc->mc_intpri; ! 162: } ! 163: } ! 164: ! 165: /* ! 166: * SCSI unit start routine. ! 167: * Called by SCSI device drivers. ! 168: */ ! 169: scustart(un) ! 170: register struct scsi_unit *un; ! 171: { ! 172: register struct buf *dp; ! 173: register struct mb_ctlr *mc; ! 174: ! 175: mc = un->un_mc; ! 176: dp = &un->un_utab; ! 177: /* ! 178: * Caller guarantees: dp->b_actf != NULL && dp->b_active == 0 ! 179: */ ! 180: /* ! 181: * Put device on ready queue for bus. ! 182: */ ! 183: if (mc->mc_tab.b_actf == NULL) { ! 184: mc->mc_tab.b_actf = dp; ! 185: } else { ! 186: mc->mc_tab.b_actl->b_forw = dp; ! 187: } ! 188: dp->b_forw = NULL; ! 189: mc->mc_tab.b_actl = dp; ! 190: dp->b_active = 1; ! 191: dp->b_un.b_addr = (caddr_t) un; ! 192: } ! 193: ! 194: /* ! 195: * Set up a transfer for the bus. ! 196: */ ! 197: scstart(un) ! 198: register struct scsi_unit *un; ! 199: { ! 200: register struct mb_ctlr *mc; ! 201: register struct buf *bp, *dp; ! 202: ! 203: mc = un->un_mc; ! 204: dp = mc->mc_tab.b_actf; /* != NULL guaranteed by caller */ ! 205: un = (struct scsi_unit *) dp->b_un.b_addr; ! 206: bp = dp->b_actf; ! 207: for (;;) { ! 208: if (bp == NULL) { /* no more blocks for this device */ ! 209: un->un_utab.b_active = 0; ! 210: dp = mc->mc_tab.b_actf = dp->b_forw; ! 211: if (dp == NULL) { /* no more devices for this ctlr */ ! 212: return; ! 213: } ! 214: un = (struct scsi_unit *) dp->b_un.b_addr; ! 215: bp = dp->b_actf; ! 216: } else { ! 217: if ((*un->un_ss->ss_start)(bp, un)) { ! 218: mc->mc_tab.b_active = 1; ! 219: un->un_c->c_un = un; ! 220: if (bp == &un->un_sbuf && ! 221: ((un->un_flags & SC_UNF_DVMA) == 0)) { ! 222: scgo(mc); ! 223: } else { ! 224: (void) mbgo(mc); ! 225: } ! 226: return; ! 227: } ! 228: dp->b_actf = bp = bp->av_forw; ! 229: } ! 230: } ! 231: } ! 232: ! 233: /* ! 234: * Start up a transfer ! 235: * Called via mbgo after buffer is in memory ! 236: */ ! 237: scgo(mc) ! 238: register struct mb_ctlr *mc; ! 239: { ! 240: register struct scsi_unit *un; ! 241: register struct scsi_ctlr *c; ! 242: register struct buf *bp, *dp; ! 243: register int unit; ! 244: ! 245: c = &scctlrs[mc->mc_ctlr]; ! 246: dp = mc->mc_tab.b_actf; ! 247: if (dp == NULL || dp->b_actf == NULL) { ! 248: panic("scgo queueing error 1"); ! 249: } ! 250: bp = dp->b_actf; ! 251: un = c->c_un; ! 252: if (dp != &un->un_utab) { ! 253: panic("scgo queueing error 2"); ! 254: } ! 255: un->un_baddr = MBI_ADDR(mc->mc_mbinfo); ! 256: if ((unit = un->un_md->md_dk) >= 0) { ! 257: dk_busy |= 1<<unit; ! 258: dk_xfer[unit]++; ! 259: dk_wds[unit] += bp->b_bcount >> 6; ! 260: } ! 261: (*un->un_ss->ss_mkcdb)(c, un); ! 262: if (sc_cmd(c, un, 1) == 0) { ! 263: (*un->un_ss->ss_intr)(c, 0, SE_RETRYABLE); ! 264: sc_off(un); ! 265: } ! 266: } ! 267: ! 268: /* ! 269: * Pass a command to the SCSI bus. ! 270: */ ! 271: sc_cmd(c, un, intr) ! 272: register struct scsi_ctlr *c; ! 273: register struct scsi_unit *un; ! 274: register int intr; ! 275: { ! 276: register u_char *cp; ! 277: register int i, errct; ! 278: register u_short icr_mode; ! 279: ! 280: errct = 0; ! 281: do { ! 282: /* make sure scsi bus is not continuously busy */ ! 283: for (i = WAIT_COUNT; i > 0; i--) { ! 284: if (!(c->c_har->icr & ICR_BUSY)) ! 285: break; ! 286: DELAY(10); ! 287: } ! 288: if (i == 0) { ! 289: sc_reset(c); ! 290: return (0); ! 291: } ! 292: ! 293: /* select target and wait for response */ ! 294: c->c_har->data = (1 << un->un_target) | HOST_ADDR; ! 295: c->c_har->icr = ICR_SELECT; ! 296: ! 297: /* target never responded to selection */ ! 298: if (sc_wait(c, ICR_BUSY) == 0) { ! 299: c->c_har->data = 0; ! 300: c->c_har->icr = 0; ! 301: return (0); ! 302: } ! 303: /* ! 304: * may need to map between the CPU's kernel context address ! 305: * and the device's DVMA bus address ! 306: */ ! 307: c->c_har->dma_addr = un->un_dma_addr; ! 308: c->c_har->dma_count = ~un->un_dma_count; /* hardware is funny */ ! 309: icr_mode = ICR_DMA_ENABLE; ! 310: if (intr) { ! 311: icr_mode |= ICR_INTERRUPT_ENABLE; ! 312: un->un_wantint = 1; ! 313: } ! 314: if (! (un->un_dma_count & 1)) { ! 315: icr_mode |= ICR_WORD_MODE; ! 316: } ! 317: c->c_har->icr = icr_mode; ! 318: cp = (u_char *) &c->c_cdb; ! 319: if (scsi_debug) { ! 320: printf("sc%d: sc_cmd: target %d issuing command ", ! 321: SCNUM(c), un->un_target); ! 322: for (i = 0; i < sizeof (struct scsi_cdb); i++) { ! 323: printf("%x ", *cp++); ! 324: } ! 325: printf("\n"); ! 326: cp = (u_char *) &c->c_cdb; ! 327: } ! 328: for (i = 0; i < sizeof (struct scsi_cdb); i++) { ! 329: if (sc_putbyte(c, ICR_COMMAND, *cp++) == 0) { ! 330: errct++; ! 331: break; ! 332: } ! 333: } ! 334: if (i == sizeof (struct scsi_cdb)) { ! 335: return (1); ! 336: } ! 337: } while (errct < 5); ! 338: printf("sc_cmd: unrecoverable errors\n"); ! 339: return (0); ! 340: } ! 341: ! 342: /* ! 343: * Handle a scsi bus interrupt for the mainbus scsi. ! 344: */ ! 345: scintr(c) ! 346: register struct scsi_ctlr *c; ! 347: { ! 348: register int resid; ! 349: register struct scsi_unit *un; ! 350: ! 351: un = c->c_un; ! 352: if (un->un_wantint == 0) { ! 353: if (c->c_har->icr & ICR_BUS_ERROR) { ! 354: printf("scsi bus error (unwanted interrupt)\n"); ! 355: } else { ! 356: printf("scsi: unwanted interrupt\n"); ! 357: } ! 358: sc_reset(c); ! 359: return; ! 360: } ! 361: un->un_wantint = 0; ! 362: resid = ~c->c_har->dma_count; ! 363: if (c->c_har->icr & ICR_BUS_ERROR) { ! 364: printf("scsi bus error. icr %x resid %d\n", ! 365: c->c_har->icr, resid); ! 366: sc_reset(c); ! 367: (*c->c_un->un_ss->ss_intr)(c, resid, SE_FATAL); ! 368: return; ! 369: } ! 370: if (c->c_har->icr & ICR_ODD_LENGTH) { ! 371: if ((c->c_cdb.cmd == SC_READ) || ! 372: (c->c_cdb.cmd == SC_REQUEST_SENSE)) { ! 373: DVMA[un->un_baddr + un->un_dma_count - resid] = ! 374: c->c_har->data; ! 375: resid--; ! 376: } else if (c->c_cdb.cmd == SC_WRITE) { ! 377: resid++; ! 378: } else { ! 379: printf("scsi: odd length without xfer\n"); ! 380: } ! 381: } ! 382: if (resid < 0) { ! 383: panic("scsi resid"); ! 384: } ! 385: if (sc_getstatus(c->c_un, 0) == 0) { ! 386: (*c->c_un->un_ss->ss_intr)(c, resid, SE_RETRYABLE); ! 387: } else { ! 388: (*c->c_un->un_ss->ss_intr)(c, resid, SE_NO_ERROR); ! 389: } ! 390: } ! 391: ! 392: /* ! 393: * Handle a polling SCSI bus interrupt. ! 394: */ ! 395: scpoll() ! 396: { ! 397: register struct scsi_ctlr *c; ! 398: register int serviced = 0; ! 399: ! 400: for (c = scctlrs; c < &scctlrs[NSC]; c++) { ! 401: if ((c->c_flags & SCSI_PRESENT) == 0) ! 402: continue; ! 403: if ((c->c_har->icr & (ICR_INTERRUPT_REQUEST | ICR_BUS_ERROR)) ! 404: == 0) { ! 405: continue; ! 406: } ! 407: serviced = 1; ! 408: scintr(c); ! 409: } ! 410: return (serviced); ! 411: } ! 412: ! 413: /* ! 414: * Clean up queues, free resources, and start next I/O ! 415: * all done after I/O finishes ! 416: * Called by mbdone after moving read data from Mainbus ! 417: */ ! 418: scdone(mc) ! 419: register struct mb_ctlr *mc; ! 420: { ! 421: register struct buf *bp, *dp; ! 422: register struct scsi_unit *un; ! 423: register struct scsi_ctlr *c; ! 424: ! 425: bp = mc->mc_tab.b_actf->b_actf; ! 426: c = &scctlrs[mc->mc_ctlr]; ! 427: un = c->c_un; ! 428: ! 429: /* advance controller queue */ ! 430: dp = mc->mc_tab.b_actf; ! 431: mc->mc_tab.b_active = 0; ! 432: mc->mc_tab.b_actf = dp->b_forw; ! 433: ! 434: /* advance unit queue */ ! 435: dp->b_active = 0; ! 436: dp->b_actf = bp->av_forw; ! 437: ! 438: iodone(bp); ! 439: ! 440: /* start next I/O on unit */ ! 441: if (dp->b_actf) ! 442: scustart(un); ! 443: ! 444: /* start next I/O on controller */ ! 445: if (mc->mc_tab.b_actf && mc->mc_tab.b_active == 0) ! 446: scstart(un); ! 447: } ! 448: ! 449: /*ARGSUSED*/ ! 450: sc_off(un) ! 451: struct scsi_unit *un; ! 452: { ! 453: ! 454: #ifdef notdef ! 455: /* if done to root real bad things happen... */ ! 456: un->un_present = 0; ! 457: printf("scsi unit %d/%d offline\n", un->un_target, un->un_lun); ! 458: if (un->un_md->md_dk > 0) { ! 459: dk_mspw[un->un_md->md_dk]=0; ! 460: } ! 461: #endif ! 462: } ! 463: ! 464: /* ! 465: * Wait for a condition on the scsi bus. ! 466: */ ! 467: sc_wait(c, cond) ! 468: register struct scsi_ctlr *c; ! 469: { ! 470: register struct scsi_ha_reg *har = c->c_har; ! 471: register int i, icr; ! 472: ! 473: for (i = 0; i < WAIT_COUNT; i++) { ! 474: icr = har->icr; ! 475: if ((icr & cond) == cond) { ! 476: return (1); ! 477: } ! 478: if (icr & ICR_BUS_ERROR) { ! 479: break; ! 480: } ! 481: DELAY(10); ! 482: } ! 483: return (0); ! 484: } ! 485: ! 486: /* ! 487: * Wait for the completion of a scsi command. ! 488: */ ! 489: sc_cmdwait(c) ! 490: register struct scsi_ctlr *c; ! 491: { ! 492: if (sc_wait(c, ICR_INTERRUPT_REQUEST) == 0) { ! 493: sc_reset(c); ! 494: return(0); ! 495: } else { ! 496: return(1); ! 497: } ! 498: } ! 499: ! 500: /* ! 501: * Put a byte into the scsi command register. ! 502: */ ! 503: sc_putbyte(c, bits, data) ! 504: register struct scsi_ctlr *c; ! 505: register u_short bits; ! 506: register u_char data; ! 507: { ! 508: register struct scsi_ha_reg *har = c->c_har; ! 509: register int icr; ! 510: ! 511: if (sc_wait(c, ICR_REQUEST) == 0) { ! 512: sc_reset(c); ! 513: return (0); ! 514: } ! 515: icr = har->icr; ! 516: if ((icr & ICR_BITS) != bits) { ! 517: #ifdef SCSI_DEBUG ! 518: printf("sc_putbyte error.\n"); ! 519: sc_pr_icr("icr is ", icr); ! 520: sc_pr_icr("waiting for", bits); ! 521: #endif SCSI_DEBUG ! 522: sc_reset(c); ! 523: return (0); ! 524: } ! 525: har->cmd_stat = data; ! 526: return (1); ! 527: } ! 528: ! 529: /* ! 530: * Get a byte from the scsi command/status register. ! 531: */ ! 532: sc_getbyte(c, bits) ! 533: register struct scsi_ctlr *c; ! 534: { ! 535: register struct scsi_ha_reg *har = c->c_har; ! 536: register int icr; ! 537: ! 538: if (sc_wait(c, ICR_REQUEST) == 0) { ! 539: sc_reset(c); ! 540: return (-1); ! 541: } ! 542: icr = har->icr; ! 543: if ((icr & ICR_BITS) != bits) { ! 544: if (bits == ICR_STATUS) { ! 545: return (-1); /* no more status */ ! 546: } ! 547: #ifdef SCSI_DEBUG ! 548: printf("sc_getbyte error.\n"); ! 549: sc_pr_icr("icr is ", icr); ! 550: sc_pr_icr("waiting for", bits); ! 551: #endif SCSI_DEBUG ! 552: sc_reset(c); ! 553: return (-1); ! 554: } ! 555: return (har->cmd_stat); ! 556: } ! 557: ! 558: sc_dmacnt(c) ! 559: register struct scsi_ctlr *c; ! 560: { ! 561: return (~c->c_har->dma_count); ! 562: } ! 563: ! 564: sc_reset(c) ! 565: register struct scsi_ctlr *c; ! 566: { ! 567: register struct scsi_ha_reg *har = c->c_har; ! 568: ! 569: har->icr = ICR_RESET; ! 570: DELAY(50); ! 571: har->icr = 0; ! 572: #ifdef SCSI_DEBUG ! 573: printf("scsi host adapter reset\n"); ! 574: #endif SCSI_DEBUG ! 575: } ! 576: ! 577: /* ! 578: * Get status bytes from scsi bus. ! 579: */ ! 580: sc_getstatus(un, recurse) ! 581: register struct scsi_unit *un; ! 582: { ! 583: register struct scsi_ctlr *c = un->un_c; ! 584: register u_char *cp = (u_char *)&c->c_scb; ! 585: struct scsi_cdb save_cdb; ! 586: struct scsi_scb save_scb; ! 587: register int i; ! 588: register int b; ! 589: register int save_dma_addr; ! 590: register int save_dma_count; ! 591: register int save_reg_dma_count; ! 592: int resid; ! 593: short retval = 1; ! 594: int s; ! 595: ! 596: /* get all the status bytes */ ! 597: for (i = 0;;) { ! 598: b = sc_getbyte(c, ICR_STATUS); ! 599: if (b < 0) { ! 600: break; ! 601: } ! 602: if (i < STATUS_LEN) { ! 603: cp[i++] = b; ! 604: } ! 605: } ! 606: ! 607: /* get command complete message */ ! 608: b = sc_getbyte(c, ICR_MESSAGE_IN); ! 609: if (b != SC_COMMAND_COMPLETE) { ! 610: if (scsi_debug) { ! 611: printf("Invalid SCSI message: %x\n", b); ! 612: printf("Status bytes:"); ! 613: for (b = 0; b < i; b++) { ! 614: printf(" %x", cp[b]); ! 615: } ! 616: printf("\n"); ! 617: } ! 618: return (0); ! 619: } ! 620: if (scsi_debug) { ! 621: printf("sc%d: sc_getstatus: Got status ", SCNUM(c)); ! 622: for (b = 0; b < i; b++) { ! 623: printf(" %x", cp[b]); ! 624: } ! 625: printf("\n"); ! 626: } ! 627: if (c->c_scb.busy) { ! 628: return (0); ! 629: } ! 630: ! 631: /* check for sense data */ ! 632: if (c->c_scb.chk) { ! 633: if (recurse) { ! 634: printf("scsi: chk on sense: invalid\n"); ! 635: return (0); ! 636: } ! 637: ! 638: /* save information while we get sense */ ! 639: save_cdb = c->c_cdb; ! 640: save_scb = c->c_scb; ! 641: save_dma_addr = un->un_dma_addr; ! 642: save_dma_count = un->un_dma_count; ! 643: save_reg_dma_count = c->c_har->dma_count; ! 644: ! 645: /* set up for getting sense */ ! 646: c->c_cdb.cmd = SC_REQUEST_SENSE; ! 647: c->c_cdb.lun = un->un_lun; ! 648: cdbaddr(&c->c_cdb, 0); ! 649: c->c_cdb.count = sizeof(struct scsi_sense); ! 650: un->un_dma_addr = (int)c->c_sense - (int)DVMA; ! 651: un->un_dma_count = sizeof(struct scsi_sense); ! 652: ! 653: /* get sense */ ! 654: if ((s=0),sc_cmd(c, un, 0) == 0 || ! 655: (s=1),sc_cmdwait(c) == 0 || ! 656: (s=2),sc_getstatus(un, 1) == 0) { ! 657: printf("scsi: cannot get sense %d\n", s); ! 658: sc_off(un); ! 659: retval = 0; ! 660: } ! 661: resid = ~c->c_har->dma_count; ! 662: if (resid < 0) { ! 663: printf("scsi: dma_count %x resid %d", ! 664: c->c_har->dma_count, resid); ! 665: panic("scsi sense count too big."); ! 666: } ! 667: ! 668: /* restore pre sense information */ ! 669: c->c_cdb = save_cdb; ! 670: c->c_scb = save_scb; ! 671: un->un_dma_addr = save_dma_addr; ! 672: un->un_dma_count = save_dma_count; ! 673: c->c_har->dma_count = save_reg_dma_count; ! 674: } ! 675: return (retval); ! 676: } ! 677: ! 678: #ifdef SCSI_DEBUG ! 679: /* ! 680: * Print out the scsi host adapter interface control register. ! 681: */ ! 682: sc_pr_icr(cp, i) ! 683: register char *cp; ! 684: { ! 685: printf("\t%s: %x ", cp, i); ! 686: if (i & ICR_PARITY_ERROR) ! 687: printf("Parity err "); ! 688: if (i & ICR_BUS_ERROR) ! 689: printf("Bus err "); ! 690: if (i & ICR_ODD_LENGTH) ! 691: printf("Odd len "); ! 692: if (i & ICR_INTERRUPT_REQUEST) ! 693: printf("Int req "); ! 694: if (i & ICR_REQUEST) { ! 695: printf("Req "); ! 696: switch (i & ICR_BITS) { ! 697: case 0: ! 698: printf("Data out "); ! 699: break; ! 700: case ICR_INPUT_OUTPUT: ! 701: printf("Data in "); ! 702: break; ! 703: case ICR_COMMAND_DATA: ! 704: printf("Command "); ! 705: break; ! 706: case ICR_COMMAND_DATA | ICR_INPUT_OUTPUT: ! 707: printf("Status "); ! 708: break; ! 709: case ICR_MESSAGE | ICR_COMMAND_DATA: ! 710: printf("Msg out "); ! 711: break; ! 712: case ICR_MESSAGE | ICR_COMMAND_DATA | ICR_INPUT_OUTPUT: ! 713: printf("Msg in "); ! 714: break; ! 715: default: ! 716: printf("DCM: %x ", i & ICR_BITS); ! 717: break; ! 718: } ! 719: } ! 720: if (i & ICR_PARITY) ! 721: printf("Parity "); ! 722: if (i & ICR_BUSY) ! 723: printf("Busy "); ! 724: if (i & ICR_SELECT) ! 725: printf("Sel "); ! 726: if (i & ICR_RESET) ! 727: printf("Reset "); ! 728: if (i & ICR_PARITY_ENABLE) ! 729: printf("Par ena "); ! 730: if (i & ICR_WORD_MODE) ! 731: printf("Word mode "); ! 732: if (i & ICR_DMA_ENABLE) ! 733: printf("Dma ena "); ! 734: if (i & ICR_INTERRUPT_ENABLE) ! 735: printf("Int ena "); ! 736: printf("\n"); ! 737: } ! 738: ! 739: /* ! 740: * Print out status completion block. ! 741: */ ! 742: sc_pr_scb(scbp) ! 743: register struct scsi_scb *scbp; ! 744: { ! 745: register u_char *cp; ! 746: ! 747: cp = (u_char *) scbp; ! 748: printf("scb: %x", cp[0]); ! 749: if (scbp->ext_st1) { ! 750: printf(" %x", cp[1]); ! 751: if (scbp->ext_st2) { ! 752: printf(" %x", cp[2]); ! 753: } ! 754: } ! 755: if (scbp->is) { ! 756: printf(" intermediate status"); ! 757: } ! 758: if (scbp->busy) { ! 759: printf(" busy"); ! 760: } ! 761: if (scbp->cm) { ! 762: printf(" condition met"); ! 763: } ! 764: if (scbp->chk) { ! 765: printf(" check"); ! 766: } ! 767: if (scbp->ext_st1 && scbp->ha_er) { ! 768: printf(" host adapter detected error"); ! 769: } ! 770: printf("\n"); ! 771: } ! 772: #endif SCSI_DEBUG ! 773: #endif NSC > 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.