|
|
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.