|
|
1.1 ! root 1: /* ! 2: * This is the host adaptor specific portion of the ! 3: * Adaptec AHA154x driver. ! 4: * ! 5: * $Log: aha.c,v $ ! 6: * Revision 1.2 92/08/04 12:51:18 bin ! 7: * update for ker59 ! 8: * ! 9: * Revision 1.2 91/05/01 04:54:43 root ! 10: * Debug code and kalloc arg fixes. ! 11: * ! 12: * Revision 1.1 91/04/30 11:01:41 root ! 13: * Shipped with COH 3.1.0 ! 14: * ! 15: */ ! 16: #include <sys/coherent.h> ! 17: #include <sys/buf.h> ! 18: #include <sys/sched.h> ! 19: ! 20: #include <sys/scsiwork.h> ! 21: #include <sys/aha154x.h> ! 22: ! 23: #ifdef _I386 ! 24: extern char *palloc(); ! 25: #endif /* _I386 */ ! 26: ! 27: #ifndef _I386 ! 28: extern saddr_t sds; /* System Data Selector */ ! 29: static paddr_t sds_physical; /* as physical address */ ! 30: #endif /* _I386 */ ! 31: static short aha_i_o_base; ! 32: static char aha_loaded; /* did load() find a host adaptor? */ ! 33: static char dev_bit_map[8]; /* one byte per SCSI-ID; one bit per LUN */ ! 34: char drive_info[MAX_SCSI_ID * MAX_LUN]; /* "per drive" info/flags */ ! 35: ! 36: void aha_intr(); /* interrupt service routine */ ! 37: ! 38: #define MIN_MAILBOX 1 ! 39: int MAX_MAILBOX = { 8 }; /* tunable value */ ! 40: ! 41: static scsi_work_t *scsi_work_queue; ! 42: static mailentry *mailbox_in, *mailbox_out; ! 43: static char *aha_err_msg = { "no message" }; ! 44: ! 45: static long aha_timeout[] = { ! 46: #define TIMEOUT_PRESENT 0 ! 47: 0x30000L, ! 48: #define TIMEOUT_SENDCMD 1 ! 49: 0x10000L, ! 50: #define TIMEOUT_POLL 2 ! 51: 0x100L ! 52: }; ! 53: ! 54: #if 0 ! 55: static ! 56: OUTB( port, value ) ! 57: short port; ! 58: { printf( "<O(%x,%x)>", port, value ); ! 59: outb( port, value ); } ! 60: INB( port ) ! 61: short port; ! 62: { register int i = inb(port); ! 63: printf( "<I(%x)=%x>", port, i ); ! 64: return i; } ! 65: #else ! 66: #define OUTB( port, value ) outb( port, value ) ! 67: #define INB(port) inb(port) ! 68: #endif ! 69: ! 70: #ifdef TRACER ! 71: #define SETMSG(msg) aha_err_msg = msg ! 72: ! 73: static char * ! 74: aha_last_msg() ! 75: { ! 76: T_PIGGY( 0x8000, return aha_err_msg; ); ! 77: ! 78: return "error messages not verbose"; ! 79: } ! 80: ! 81: #else /* TRACER */ ! 82: ! 83: #define SETMSG(msg) ! 84: static char * ! 85: aha_last_msg() ! 86: { ! 87: return "error messages not verbose"; ! 88: } ! 89: #endif /* TRACER */ ! 90: ! 91: static ! 92: int ! 93: no_mem() ! 94: { ! 95: printf("aha154x: out of kernel memory\n"); ! 96: } ! 97: ! 98: int ! 99: aha_set_base( base ) ! 100: { ! 101: register int i; ! 102: ! 103: i = aha_i_o_base; ! 104: aha_i_o_base = base; ! 105: return i; ! 106: } ! 107: ! 108: int ! 109: aha_get_base() ! 110: { ! 111: return aha_i_o_base; ! 112: } ! 113: ! 114: aha_process( ccb ) ! 115: ccb_t *ccb; ! 116: { ! 117: register scsi_work_t *sw = ccb->ccb_sw; ! 118: register BUF *bp; ! 119: ! 120: T_PIGGY( 0x8000, { ! 121: printf( "aha_process: ccb %x ", ccb ); ! 122: printf("sw=%x", ccb->ccb_sw); ! 123: if (0 != ccb->ccb_sw) { ! 124: printf(" bp=%x", ccb->ccb_sw->sw_bp); ! 125: } ! 126: printf("\n"); ! 127: aha_ccb_print( ccb ); ! 128: } ); ! 129: if( ccb->ccb_sw == 0 ) { ! 130: T_PIGGY( 0x8000, ! 131: printf( "process: ccb %x with NULL sw\n", ccb ); ! 132: ); ! 133: ccb->opcode = AHA_OP_INVALID; ! 134: wakeup( ccb ); ! 135: return; ! 136: } ! 137: ! 138: bp = sw->sw_bp; ! 139: ! 140: T_PIGGY( 0x8000, printf( "bp = %x\n", bp ); ); ! 141: ! 142: if( (ccb->hoststatus != 0) || (ccb->targetstatus != 0) ) { ! 143: if( --sw->sw_retry > 0 ! 144: || (ccb->targetstatus == CHECK_TARGET_STATUS ! 145: && ccb->cmd_status[12] == SENSE_UNIT_ATTENTION)) { ! 146: int s = sphi(); ! 147: if( scsi_work_queue->sw_actf == NULL ) { ! 148: scsi_work_queue->sw_actf = sw; ! 149: } else { ! 150: scsi_work_queue->sw_actl->sw_actf = sw; ! 151: } ! 152: scsi_work_queue->sw_actl = sw; ! 153: spl(s); ! 154: aha_start(); ! 155: return; ! 156: } ! 157: bp->b_flag |= BFERR; ! 158: } else { ! 159: bp->b_resid = 0; ! 160: } ! 161: T_PIGGY( 0x8000, printf( "bp flag = %x\n", bp->b_flag ); ); ! 162: ! 163: bdone( bp ); ! 164: #ifdef _I386 ! 165: T_PIGGY( 0x80000, printf( "pf(sw)" ); ); ! 166: pfree( sw ); ! 167: T_PIGGY( 0x80000, printf( "df(d)" ); ); ! 168: dsl_free( ccb->dataptr ); ! 169: T_PIGGY( 0x80000, printf( "pf(ccb)" ); ); ! 170: pfree( ccb ); ! 171: ccb_forget( ccb ); ! 172: #else /* _I386 */ ! 173: kfree( sw ); ! 174: kfree( ccb ); ! 175: #endif /* _I386 */ ! 176: } ! 177: ! 178: static ! 179: int aha_1out( value ) ! 180: { ! 181: register int i; ! 182: ! 183: while( (i = INB(aha_i_o_base + AHA_STATUS) & AHA_CDOPFULL) != 0 ) ! 184: if( (i & AHA_INVDCMD) ! 185: || (INB(aha_i_o_base+AHA_INTERRUPT) & AHA_CMD_DONE) ) ! 186: return -1; ! 187: OUTB( aha_i_o_base + AHA_WRITE, value ); ! 188: return 0; ! 189: } ! 190: ! 191: static ! 192: int aha_1in() ! 193: { ! 194: register int i; ! 195: ! 196: while( (i = INB(aha_i_o_base + AHA_STATUS) & AHA_DIPFULL) == 0 ) ! 197: if( (i & AHA_INVDCMD) ! 198: || (INB(aha_i_o_base+AHA_INTERRUPT) & AHA_CMD_DONE) ) ! 199: return -1; ! 200: return INB( aha_i_o_base + AHA_READ ) & 0xFF; ! 201: } ! 202: ! 203: static ! 204: void aha_cmd_out( value ) ! 205: { ! 206: register long l; ! 207: register int i; ! 208: ! 209: for( l = aha_timeout[TIMEOUT_SENDCMD]; --l > 0; ) { ! 210: if( ((i=INB(aha_i_o_base + AHA_STATUS)) ! 211: & AHA_SCSIIDLE ) != 0 ) { ! 212: aha_1out( value ); ! 213: return; ! 214: } else { ! 215: T_PIGGY( 0x8000, ! 216: printf( "aha: cmd_out status = %x\r", i ); ! 217: ); ! 218: } ! 219: } ! 220: SETMSG( "timeout sending cmd byte" ); ! 221: printf( "aha154x: timeout sending cmd byte\n" ); ! 222: } ! 223: ! 224: static ! 225: int aha_poll() ! 226: { ! 227: register int i; ! 228: register int l = aha_timeout[TIMEOUT_POLL]; ! 229: while( (--l > 0 ) ! 230: && ((i = INB(aha_i_o_base + AHA_INTERRUPT)) & AHA_CMD_DONE) == 0 ) ! 231: ; ! 232: if( l == 0 ) ! 233: printf( "aha154x: aha_poll timed out\n" ); ! 234: ! 235: i = INB(aha_i_o_base + AHA_STATUS); ! 236: OUTB( aha_i_o_base + AHA_CONTROL, AHA_INTRRESET ); ! 237: return i; ! 238: } ! 239: ! 240: static ! 241: void aha_get_data( vec, cnt ) ! 242: char *vec; ! 243: int cnt; ! 244: { ! 245: while( --cnt >= 0 ) ! 246: *vec++ = aha_1in(); ! 247: aha_poll(); ! 248: } ! 249: ! 250: static ! 251: int aha_present() ! 252: { ! 253: long l; ! 254: ! 255: if( INB(aha_i_o_base) == 0xFF ) { ! 256: SETMSG( "no adapter found at io base" ); ! 257: return -3; ! 258: } ! 259: for( l = aha_timeout[TIMEOUT_PRESENT]; ! 260: (--l > 0) && (INB(aha_i_o_base + AHA_STATUS) & AHA_SELFTEST); ) ! 261: ; ! 262: if( l == 0 ) { ! 263: SETMSG( "selftest not completed" ); ! 264: return -1; ! 265: } ! 266: if( INB(aha_i_o_base + AHA_STATUS) & AHA_DIAGFAIL ) { ! 267: SETMSG( "diagnostics failed" ); ! 268: return -2; ! 269: } ! 270: if( INB(aha_i_o_base + AHA_STATUS) & AHA_INITMAIL ) { ! 271: SETMSG( "mailbox initialization needed" ); ! 272: return 1; ! 273: } ! 274: if( INB(aha_i_o_base + AHA_STATUS) & AHA_SCSIIDLE ) { ! 275: SETMSG( "adaptor okay, idle" ); ! 276: return 0; ! 277: } ! 278: SETMSG( "unknown status at start" ); ! 279: return -4; ! 280: } ! 281: ! 282: void ! 283: aha_l_to_p3( value, vec ) ! 284: paddr_t value; ! 285: P3 vec; ! 286: { ! 287: register int i; ! 288: ! 289: for( i = 3; --i >= 0; ) { ! 290: vec[i] = value & 0xFF; ! 291: value >>= 8; ! 292: } ! 293: } ! 294: ! 295: long ! 296: aha_p3_to_l( vec ) ! 297: P3 vec; ! 298: { ! 299: register int i; ! 300: register long retval; ! 301: ! 302: retval = 0; ! 303: for( i = 0; i < 3; ++i) { ! 304: retval <<= 8; ! 305: retval |= vec[i]; ! 306: } ! 307: ! 308: return( retval ); ! 309: } /* aha_p3_to_l() */ ! 310: ! 311: #ifndef _I386 /* All of aha_p3_to_v(). */ ! 312: static char * ! 313: aha_p3_to_v( vec ) ! 314: P3 vec; ! 315: { ! 316: paddr_t adr; ! 317: ! 318: adr = vec[0]; ! 319: adr <<= 16; ! 320: adr |= (vec[1]<<8) | vec[2]; ! 321: adr -= sds_physical; ! 322: return (char *)adr; ! 323: } ! 324: #endif /* _I386 */ ! 325: ! 326: aha_device_info() ! 327: { ! 328: register int i; ! 329: static char buf[256]; ! 330: ! 331: aha_cmd_out( AHA_DO_GET_DEVICES ); ! 332: aha_get_data( &buf[0], 8 ); ! 333: for( i = 0; i < 8; ++i ) ! 334: if( buf[i] != 0 ) ! 335: printf( "[%d] %x ", i, buf[i] ); ! 336: printf( "\n" ); ! 337: } ! 338: ! 339: int aha_unload( ireq ) ! 340: { ! 341: T_PIGGY( 0x8000, printf( "aha_unload: %x\n", ireq ); ); ! 342: /* ! 343: * we should really verify that everything ! 344: * out there gets flushed. ! 345: */ ! 346: if (!aha_loaded) ! 347: return; ! 348: if( mailbox_out ) { ! 349: #ifdef _I386 ! 350: T_PIGGY( 0x80000, printf( "pf(mbo)" ); ); ! 351: pfree( mailbox_out ); ! 352: #else /* _I386 */ ! 353: kfree( mailbox_out ); ! 354: #endif /* _I386 */ ! 355: mailbox_out = 0; ! 356: } ! 357: clrivec( ireq ); ! 358: } ! 359: ! 360: int aha_load( dma, ireq, base, head ) ! 361: scsi_work_t *head; ! 362: { ! 363: register int i; ! 364: unsigned char adr[4]; ! 365: ! 366: T_PIGGY( 0x8000, ! 367: printf( "aha_load( %d, %d, 0x%x );\n", dma, ireq, base ); ! 368: ); ! 369: aha_set_base(base); ! 370: if( mailbox_out == 0 ) { ! 371: if( (mailbox_out = ! 372: #ifdef _I386 ! 373: palloc(2 * MAX_MAILBOX * sizeof(mailentry))) == 0 ) { ! 374: #else /* _I386 */ ! 375: kalloc(2 * MAX_MAILBOX * sizeof(mailentry))) == 0 ) { ! 376: #endif /* _I386 */ ! 377: no_mem(); ! 378: return -1; ! 379: } else { ! 380: mailbox_in = &mailbox_out[MAX_MAILBOX]; ! 381: } ! 382: } ! 383: ! 384: for( i = 0; i < MAX_MAILBOX; ++i ) ! 385: mailbox_out[i].cmd = mailbox_in[i].cmd = 0; ! 386: ! 387: #ifdef _I386 ! 388: aha_l_to_p3( vtop( mailbox_out ), &adr[1] ); ! 389: #else /* _I386 */ ! 390: sds_physical = VTOP2( 0, sds ); ! 391: aha_l_to_p3( VTOP2( mailbox_out, sds ), &adr[1] ); ! 392: #endif /* _I386 */ ! 393: ! 394: adr[0] = MAX_MAILBOX; ! 395: ! 396: /* ! 397: * setup HW ! 398: */ ! 399: setivec( ireq, aha_intr ); ! 400: ! 401: outb( 0xD6, 0xC1 ); /* DMA is currently hard coded for */ ! 402: outb( 0xD4, 0x01 ); /* DMA channel 5 */ ! 403: ! 404: ! 405: OUTB( aha_i_o_base+AHA_CONTROL, AHA_HARDRESET ); ! 406: if (aha_present() < 0) { ! 407: printf("aha154x: initialization error or host adaptor not "); ! 408: printf("found at 0x%x\n", aha_i_o_base); ! 409: return -1; ! 410: } ! 411: aha_cmd_out( AHA_DO_MAILBOX_INIT ); ! 412: for( i = 0; i < 4; ++i ) ! 413: aha_1out( adr[i] ); ! 414: scsi_work_queue = head; ! 415: ++aha_loaded; ! 416: return MAX_MAILBOX; ! 417: } ! 418: ! 419: aha_command( sc ) ! 420: register scsi_cmd_t *sc; ! 421: { ! 422: register int i; ! 423: /* register */ ccb_t *ccb; ! 424: ! 425: short count = sc->blklen; ! 426: long block = sc->block; ! 427: ! 428: #ifdef _I386 ! 429: T_PIGGY(0x100000, printf("pa(ac)"); ); ! 430: ccb = (ccb_t *) palloc(sizeof (ccb_t)); ! 431: #else /* _I386 */ ! 432: ccb = (ccb_t *) kalloc(sizeof (ccb_t)); ! 433: #endif /* _I386 */ ! 434: if (ccb == (ccb_t *) 0) { ! 435: no_mem(); ! 436: return -1; ! 437: } ! 438: T_PIGGY( 0x8000, { ! 439: printf( "aha_command( SCSI ID %d, LUN %d, c %x, b %x", ! 440: sc->unit >> 2, sc->unit & 0x3, sc->cmd, sc->block ); ! 441: printf( " [%d] @%x:%x )\n", ! 442: sc->buflen, sc->buffer ); ! 443: } ); ! 444: ! 445: ccb->ccb_sw = 0; ! 446: #ifdef _I386 ! 447: ccb->opcode = AHA_OP_SIC_SG; /* SCSI_INITIATOR*/ ! 448: #else /* _I386 */ ! 449: ccb->opcode = AHA_OP_SIC; /* SCSI_INITIATOR*/ ! 450: #endif /* _I386 */ ! 451: ccb->target = (sc->unit & 0x1C) << 3; /* SCSI ID */ ! 452: ccb->target |= sc->unit & 0x3; /* LUN */ ! 453: if( (ccb->cmd_status[0] = sc->cmd) == ScmdWRITEXTENDED ) { ! 454: ccb->target |= AHA_CCB_DATA_OUT; ! 455: } else { /* READEXT, READCAP, INQUIRY */ ! 456: ccb->target |= AHA_CCB_DATA_IN; ! 457: } ! 458: ccb->cmd_status[1] = 0; ! 459: ccb->cmd_status[2] = block; ! 460: ccb->cmd_status[3] = block >>16; ! 461: ccb->cmd_status[4] = block >> 8; ! 462: ccb->cmd_status[5] = block; ! 463: ccb->cmd_status[6] = 0; ! 464: ccb->cmd_status[7] = count / 512; ! 465: ccb->cmd_status[8] = count; ! 466: ccb->cmd_status[9] = 0; ! 467: ccb->cmdlen = 10; ! 468: ccb->senselen = MAX_SENSEDATA; ! 469: ! 470: #ifdef _I386 ! 471: dsl_gen( ccb->dataptr, ccb->datalen, sc->buffer, (long)sc->buflen ); ! 472: aha_l_to_p3( vtop( ccb ), mailbox_out[0].adr ); ! 473: ccb_remember( ccb, mailbox_out[0].adr ); ! 474: #else /* _I386 */ ! 475: aha_l_to_p3( (long)sc->buflen, ccb->datalen ); ! 476: aha_l_to_p3( sc->buffer, ccb->dataptr ); ! 477: aha_l_to_p3( VTOP2( ccb, sds ), mailbox_out[0].adr ); ! 478: #endif /* _I386 */ ! 479: ! 480: T_PIGGY( 0x8000, aha_ccb_print( ccb ); ); ! 481: mailbox_out[0].cmd = MBO_TO_START; ! 482: ! 483: /* Start the AHA-154x scanning the mailboxes. */ ! 484: aha_1out( AHA_DO_SCSI_START ); ! 485: ! 486: /* Wait for this ccb to finish. */ ! 487: while( ccb->opcode != AHA_OP_INVALID ) { ! 488: v_sleep( ccb, CVBLKIO, IVBLKIO, SVBLKIO, "aha:ccb" ); ! 489: /* The AHA-154x driver is waiting for a ccb to complete. */ ! 490: } ! 491: ! 492: T_PIGGY( 0x8000, ! 493: printf( "done with status = %d, %d\n\n", ! 494: ccb->hoststatus, ccb->targetstatus ); ! 495: ); ! 496: ! 497: if( (ccb->targetstatus == CHECK_TARGET_STATUS) ! 498: && (ccb->cmd_status[12] != SENSE_UNIT_ATTENTION) ) { ! 499: printf( "aha: SCSI ID %d LUN %d. SCSI sense =", ! 500: (sc->unit >> 2), sc->unit & 0x3 ); ! 501: for( i = 0; i < ccb->senselen; ++i ) ! 502: printf( " %x", ccb->cmd_status[10+i] ); ! 503: printf( "\n" ); ! 504: } ! 505: i = ccb->hoststatus | ccb->targetstatus; ! 506: #ifdef _I386 ! 507: T_PIGGY( 0x80000, printf( "df(d2)" ); ); ! 508: dsl_free( ccb->dataptr ); ! 509: T_PIGGY( 0x80000, printf( "pf(ccb2)" ); ); ! 510: pfree( ccb ); ! 511: ccb_forget( ccb ); ! 512: #else /* _I386 */ ! 513: kfree( ccb ); ! 514: #endif /* _I386 */ ! 515: return i; ! 516: } ! 517: ! 518: ccb_t *buildccb( sw ) ! 519: register scsi_work_t *sw; ! 520: { ! 521: register ccb_t *ccb; ! 522: #ifdef _I386 ! 523: T_PIGGY(0x100000, printf("pa(bld)"); ); ! 524: ccb = (ccb_t *)palloc(sizeof(ccb_t)); ! 525: #else /* _I386 */ ! 526: ccb = (ccb_t *)kalloc(sizeof(ccb_t)); ! 527: #endif /* _I386 */ ! 528: ! 529: T_PIGGY( 0x8000, ! 530: printf( "build: sw:%x, drv:%x, bno:%D ", ! 531: sw, sw->sw_drv, sw->sw_bno ); ! 532: ); ! 533: ! 534: ccb->ccb_sw = sw; ! 535: #ifdef _I386 ! 536: ccb->opcode = AHA_OP_SIC_SG; /* SCSI_INITIATOR*/ ! 537: #else /* _I386 */ ! 538: ccb->opcode = AHA_OP_SIC; /* SCSI_INITIATOR*/ ! 539: #endif /* _I386 */ ! 540: ! 541: ccb->target = (sw->sw_drv & 0x1C) << 3; /* SCSI ID */ ! 542: ccb->target |= (sw->sw_drv) & 0x3; /* LUN */ ! 543: if( sw->sw_bp->b_req == BREAD ) { ! 544: ccb->target |= AHA_CCB_DATA_IN; ! 545: ccb->cmd_status[0] = ScmdREADEXTENDED; ! 546: } else { ! 547: ccb->target |= AHA_CCB_DATA_OUT; ! 548: ccb->cmd_status[0] = ScmdWRITEXTENDED; ! 549: } ! 550: ccb->cmd_status[2] = 0; ! 551: ccb->cmd_status[3] = sw->sw_bno >>16; ! 552: ccb->cmd_status[4] = sw->sw_bno >> 8; ! 553: ccb->cmd_status[5] = sw->sw_bno; ! 554: ccb->cmd_status[6] = 0; ! 555: ccb->cmd_status[7] = sw->sw_bp->b_count / (512*256L); ! 556: ccb->cmd_status[8] = sw->sw_bp->b_count / 512; ! 557: ccb->cmd_status[9] = 0; ! 558: ccb->cmdlen = 10; ! 559: ccb->senselen = MAX_SENSEDATA; ! 560: ! 561: #ifdef _I386 ! 562: dsl_gen( ccb->dataptr, ccb->datalen, ! 563: sw->sw_bp->b_paddr, (long)sw->sw_bp->b_count); ! 564: #else /* _I386 */ ! 565: aha_l_to_p3( (long)sw->sw_bp->b_count, ccb->datalen ); ! 566: aha_l_to_p3( vtop(sw->sw_bp->b_faddr), ccb->dataptr ); ! 567: #endif /* _I386 */ ! 568: return ccb; ! 569: #if 0 ! 570: /* start of ioctl code */ ! 571: if( f == SASI_CMD_IN ) ! 572: ccb->target |= AHA_CCB_DATA_IN; ! 573: else if( f == SASI_CMD_OUT ) ! 574: ccb->target |= AHA_CCB_DATA_OUT; ! 575: else ! 576: ccb->target |= AHA_CCB_DATA_IN ! 577: |AHA_CCB_DATA_OUT; ! 578: #endif ! 579: } ! 580: ! 581: aha_start() ! 582: { ! 583: register int i, s, n = 0; ! 584: scsi_work_t *sw; ! 585: static char locked; ! 586: ! 587: s = sphi(); ! 588: if( locked ) { ! 589: spl(s); ! 590: return; ! 591: } ! 592: ++locked; ! 593: spl(s); ! 594: ! 595: while( (sw = scsi_work_queue->sw_actf) != NULL ) { ! 596: for( i = MIN_MAILBOX; i < MAX_MAILBOX; ++i ) ! 597: if( mailbox_out[i].cmd == MBO_IS_FREE ) { ! 598: register ccb_t *ccb; ! 599: int s; ! 600: ! 601: ++n; ! 602: ccb = buildccb( sw ); ! 603: T_PIGGY( 0x8000, aha_ccb_print( ccb ); ); ! 604: #ifdef _I386 ! 605: aha_l_to_p3( vtop( ccb ), ! 606: mailbox_out[i].adr ); ! 607: ccb_remember( ccb, mailbox_out[i].adr ); ! 608: #else /* _I386 */ ! 609: aha_l_to_p3( VTOP2( ccb, sds ), ! 610: mailbox_out[i].adr ); ! 611: #endif /* _I386 */ ! 612: mailbox_out[i].cmd = MBO_TO_START; ! 613: ! 614: T_PIGGY( 0x8000, { ! 615: printf( "MBO[%d] = %x:%x:%x:%x, ccb = %x ", ! 616: i, mailbox_out[i].cmd, ! 617: mailbox_out[i].adr[0], ! 618: mailbox_out[i].adr[1], ! 619: mailbox_out[i].adr[2], ccb ); ! 620: printf("sw=%x bp=%x\n", ccb->ccb_sw, ccb->ccb_sw->sw_bp); ! 621: } ); /* T_PIGGY() */ ! 622: ! 623: aha_1out( AHA_DO_SCSI_START ); ! 624: ! 625: s = sphi(); ! 626: sw = scsi_work_queue->sw_actf = sw->sw_actf; ! 627: if( sw == NULL ) ! 628: scsi_work_queue->sw_actl = NULL; ! 629: spl(s); ! 630: ! 631: if( sw == NULL ) ! 632: break; ! 633: } ! 634: if( i == MAX_MAILBOX ) ! 635: break; ! 636: } ! 637: --locked; ! 638: return n; ! 639: } ! 640: ! 641: int aha_completed() ! 642: { ! 643: register int i, n; ! 644: ! 645: for( n = 0, i = 0; i < MAX_MAILBOX; ++i ) ! 646: if( mailbox_in[i].cmd != MBI_IS_FREE ) { ! 647: T_PIGGY( 0x8000 , ! 648: printf( "aha: mail[%d] = %x:%x:%x:%x\n", ! 649: i, mailbox_in[i].cmd, ! 650: mailbox_in[i].adr[0], ! 651: mailbox_in[i].adr[1], ! 652: mailbox_in[i].adr[2] ); ! 653: ); ! 654: #ifdef _I386 ! 655: aha_process ( ccb_recall( mailbox_in[i].adr ) ); ! 656: #else /* _I386 */ ! 657: defer( aha_process, ! 658: aha_p3_to_v( mailbox_in[i].adr ) ); ! 659: #endif /* _I386 */ ! 660: mailbox_in[i].cmd = MBI_IS_FREE; ! 661: ++n; ! 662: } ! 663: return n; ! 664: } ! 665: ! 666: void aha_intr() ! 667: { ! 668: register int i; ! 669: ! 670: T_PIGGY( 0x8000, printf( "aha_interrupt routine\n" ); ); ! 671: ! 672: if( ((i = INB(aha_i_o_base+AHA_INTERRUPT)) & AHA_ANY_INTER) == 0 ) ! 673: printf( "aha: spurious interrupt %x\n", i ); ! 674: ! 675: T_PIGGY( 0x8000, printf( "aha_interrupt: %x\n", i ); ); ! 676: ! 677: switch( i & AHA_ALL_INTERRUPTS ) { ! 678: case AHA_RESETED: ! 679: T_PIGGY( 0x8000, printf( "aha: reseted\n" ); ); ! 680: break; ! 681: case AHA_CMD_DONE: ! 682: T_PIGGY( 0x8000, printf( "aha: adapter command completed\n" ); ); ! 683: break; ! 684: case AHA_MBO_EMPTY: ! 685: T_PIGGY( 0x8000, printf( "aha: MAILBOX emptied\n" ); ); ! 686: defer( aha_start, (char *)0 ); ! 687: break; ! 688: case AHA_MBI_STORED: ! 689: T_PIGGY( 0x8000, printf( "aha: MAILBOX in stored\n" ); ); ! 690: aha_completed(); ! 691: break; ! 692: default: ! 693: printf( "aha: multiple interrupts not yet handled\n" ); ! 694: } ! 695: outb( aha_i_o_base+AHA_CONTROL, AHA_INTRRESET ); ! 696: } ! 697: ! 698: aha_ioctl() ! 699: { ! 700: printf( "aha_ioctl: Not implemented\n" ); ! 701: } ! 702: ! 703: #ifdef TRACER ! 704: static unsigned char vec[256]; ! 705: ! 706: static aha_ports_are() { ! 707: printf( "aha_ports_are: %x %x %x\n", ! 708: INB(aha_i_o_base+0), ! 709: INB(aha_i_o_base+1), ! 710: INB(aha_i_o_base+2) ); ! 711: } ! 712: ! 713: static aha_inquiry_is() { ! 714: printf( "aha_inquiry:" ); ! 715: printf( "... aha_present = %d, ", aha_present() ); ! 716: printf( "%s\n", aha_last_msg() ); ! 717: aha_cmd_out( AHA_DO_INQUIRY ); ! 718: ! 719: aha_get_data( &vec[0], 4 ); ! 720: printf( " board id '%c'", vec[0] ); ! 721: printf( ", options '%c'", vec[1] ); ! 722: printf( ", HW '%c'", vec[2] ); ! 723: printf( ", FW '%c'\n", vec[3] ); ! 724: } ! 725: ! 726: void aha_setup_is() { ! 727: register int i; ! 728: ! 729: printf( "Setup and Data:\n" ); ! 730: aha_cmd_out( AHA_DO_GET_SETUP ); ! 731: aha_cmd_out( 16 ); ! 732: aha_get_data( &vec[0], 16 ); ! 733: printf( " Data Xfer %s Sync (J1)\n", (vec[0]&1) ? "is" : "not" ); ! 734: printf( " Parity %s Enabled (J1)\n", (vec[0]&2) ? "is" : "not" ); ! 735: switch( vec[1] ) { ! 736: case AHA_SPEED_5_0_MB: ! 737: printf( " 5.0 Mb/sec.\n" ); break; ! 738: case AHA_SPEED_6_7_MB: ! 739: printf( " 6.7 Mb/sec.\n" ); break; ! 740: case AHA_SPEED_8_0_MB: ! 741: printf( " 8.0 Mb/sec.\n" ); break; ! 742: case AHA_SPEED_10_MB: ! 743: printf( " 10 Mb/sec.\n" ); break; ! 744: case AHA_SPEED_5_7_MB: ! 745: printf( " 5.7 Mb/sec.\n" ); break; ! 746: default: ! 747: if( vec[1] & 0x80 ) ! 748: printf( " Pulse Read %d, Write %d, Strobe off %d\n", ! 749: 50*(2+(vec[1]>>4)&0x7), 50*(2+(vec[1]&7)), ! 750: vec[1] & 0x80 ? 150 : 100 ); ! 751: } ! 752: printf( " Bus Time ON %d, OFF %d\n", vec[2], vec[3] ); ! 753: printf( " %d Mailboxes at %x|%x|%x\n", vec[4], ! 754: vec[5], vec[6], vec[7] ); ! 755: for( i = 0; i < 8; ++i ) ! 756: if( vec[i+8] ) ! 757: printf( " Target [%d] = Sync Neg %x\n", i, vec[i+8] ); ! 758: } ! 759: ! 760: static aha_mailboxes_are( n, adr ) ! 761: mailentry *adr; ! 762: { ! 763: register int i; ! 764: ! 765: printf( "addresses for mailbox is %x:%x\n", (long)adr ); ! 766: for( i = 0; i < n; ++i, ++adr ) ! 767: printf( " mbo[%x] = %x %x|%x|%x\n", ! 768: i, adr->cmd, adr->adr[0], adr->adr[1], adr->adr[2] ); ! 769: for( i = 0; i < n; ++i, ++adr ) ! 770: printf( " mbi[%x] = %x %x|%x|%x\n", ! 771: i, adr->cmd, adr->adr[0], adr->adr[1], adr->adr[2] ); ! 772: } ! 773: ! 774: void aha_status() ! 775: { ! 776: aha_ports_are(); ! 777: aha_inquiry_is(); ! 778: /* aha_devices_are(); */ /* This appears to have never existed. */ ! 779: aha_setup_is(); ! 780: aha_mailboxes_are( MAX_MAILBOX, mailbox_out ); ! 781: } ! 782: ! 783: aha_ccb_print( ccb ) ! 784: ccb_t *ccb; ! 785: { ! 786: register int i; ! 787: register unsigned char *cp; ! 788: ! 789: printf("aha_ccb_print(ccb: %x)", ccb); ! 790: if (0 != ccb) { ! 791: printf(", sw: %x", ccb->ccb_sw); ! 792: if (0 != ccb->ccb_sw) { ! 793: printf(", bp: %x", ccb->ccb_sw->sw_bp); ! 794: if (0 != ccb->ccb_sw->sw_bp) { ! 795: printf(", flag: %x", ! 796: ccb->ccb_sw->sw_bp->b_flag ); ! 797: } ! 798: } ! 799: printf( ", op %d, ", ccb->opcode ); ! 800: printf( "target ID=%d, ", (ccb->target>>5) & 0x7 ); ! 801: printf( "LUN=%d, ", (ccb->target & 0x7) ); ! 802: printf( "dir=%s%s\n", (ccb->target&AHA_CCB_DATA_IN)?"IN":"", ! 803: (ccb->target&AHA_CCB_DATA_OUT)?"OUT":"" ); ! 804: printf( "data len %x|%x|%x, adr %x|%x|%x\n", ! 805: ccb->datalen[0],ccb->datalen[1],ccb->datalen[2], ! 806: ccb->dataptr[0],ccb->dataptr[1],ccb->dataptr[2] ); ! 807: printf( "status host=%x, target=%x\n", ! 808: ccb->hoststatus, ccb->targetstatus ); ! 809: printf( "cmddata[%d]:", ccb->cmdlen ); ! 810: for( i = 0, cp = ccb->cmd_status; i < ccb->cmdlen; ++i ) ! 811: printf( " %x", *cp++ ); ! 812: printf( "\nrequest sense[%d]:", ccb->senselen ); ! 813: for( i = 0; i < ccb->senselen; ++i ) ! 814: printf( " %x", *cp++ ); ! 815: if( i = cp[-1] ) { ! 816: printf( "\n + " ); ! 817: while( --i >= 0 ) ! 818: printf( " %x", *cp++ ); ! 819: } ! 820: printf( "\n" ); ! 821: } ! 822: } ! 823: ! 824: #endif /* TRACER */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.