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