|
|
1.1 root 1: /***********************************************************************
2: * Module: aha154x.c
3: *
4: * Host Adapter Interface routines for the Adaptec AHA154XX series
5: * of host adapters.
6: *
7: * Much of the information used to create this driver was obtained
8: * from the AHA1540B/1542B Technical Reference Manual available from
9: * Adaptec by phone or snail mail at:
10: *
11: * Adaptec - Literature Department
12: * 691 South Milpitas Blvd.
13: * Milpitas, CA 95035
14: * (408) 945-8600
15: *
16: * Copyright (c), 1993 Christopher Sean Hilton, All Rights Reserved.
17: *
18: * Last Modified: Fri Jun 4 20:03:17 1993 by [chris]
19: */
20:
21: #define _COH_HA_ /* Host Adaptor Module */
22:
23: #include <stddef.h>
24: #include <sys/coherent.h>
25: #include <sys/con.h>
26: #include <sys/types.h>
27:
28: #include <sys/haiscsi.h>
29:
30: /***********************************************************************
31: * Constants - Patch for your own circumstances.
32: */
33:
34: unsigned short AHABASE = 0x330, /* Port Base */
35: AHAINTR = 11, /* Host Adapter Interrupt vector */
36: AHADMACHAN = 0x05; /* DMA Channel */
37:
38: #define CTRLREG (AHABASE + 0) /* Control Register (Write) */
39: #define HRST bit(7) /* Hard Reset */
40: #define SRST bit(6) /* Soft Reset */
41: #define IRST bit(5) /* Interrupt Reset */
42: #define SCRST bit(4) /* SCSI Bus Reset */
43:
44: #define STSREG (AHABASE + 0) /* Status Register (Read) */
45: #define STST bit(7) /* Self Test in progress */
46: #define DIAGF bit(6) /* Internal Diagnostic Failure */
47: #define INIT bit(5) /* Mailbox Initialization Required */
48: #define IDLE bit(4) /* SCSI Host Adapter Idle */
49: #define CDF bit(3) /* Command/Data Out Port Full */
50: #define DF bit(2) /* Data In Port Full */
51: #define INVDCMD bit(0) /* Invalid HA Command */
52:
53: #define CMDDATAOUT (AHABASE + 1) /* Command/Data Out (Write) */
54: #define NOP 0x00 /* No Operation (really?) */
55: #define MBINIT 0x01 /* Mail Box Initialization */
56: #define STARTSCSI 0x02 /* Start a SCSI Command */
57: #define STARTBIOS 0x03 /* Start a BIOS Command */
58: #define HAINQUIRY 0x04 /* HA Inquiry */
59: #define ENBLMBOA 0x05 /* Enable Mailbox Out Available Interrupt */
60: #define STSELTO 0x06 /* Set Selection Timeout */
61: #define SETBUSON 0x07 /* Set Bus on time */
62: #define SETBUSOFF 0x08 /* Set Bus off time */
63: #define SETXFER 0x09 /* Set transfer speed */
64: #define RETINSTDEV 0x0a /* Return Installed Devices */
65: #define RETCFGDATA 0x0b /* Return Configuration Data */
66: #define ENBLTRGTMD 0x0c /* Enable Target Mode */
67: #define RETSUDATA 0x0d /* Return Setup Data */
68:
69: #define DATAIN (AHABASE + 1)
70:
71: #define INTRFLGS (AHABASE + 2)
72: #define ANYINTR bit(7) /* Any Interrupt */
73: #define SCRD bit(3) /* SCSI Reset Detected */
74: #define HACC bit(2) /* HA Command Complete */
75: #define MBOA bit(1) /* MBO Empty */
76: #define MBIF bit(0) /* MBI Full */
77:
78: #define MBOFREE 0x00 /* Mailbox out is free */
79: #define MBOSTART 0x01 /* Start CCB in this Mailbox */
80: #define MBOABORT 0x02 /* Abort CCB in this Mailbox */
81:
82: #define MBIFREE 0x00 /* Mailbox in is free */
83: #define MBISUCCESS 0x01 /* Mailbox's CCB Completed Successfully */
84: #define MBIABORTED 0x02 /* Mailbox's CCB Aborted */
85: #define MBIABRTFLD 0x03 /* CCB to Abort not found */
86: #define MBIERROR 0x04 /* CCB Completed with error */
87:
88: #define TIMEOUT -1 /* Timeout from pollxxx() functions. */
89:
90: #define ST_HAINIT 0x0001 /* Host Adapter being initialized */
91: #define ST_HAIDLE 0x0002 /* Host Adapter is idle */
92:
93: /***********************************************************************
94: * Types
95: */
96:
97: #pragma align 1
98:
99: typedef union addr3_u { /* addr3_u for big/little endian conversions */
100: unsigned long value;
101: unsigned char byteval[sizeof(unsigned long)];
102: } addr3_t;
103:
104: typedef union mbo_u *mbo_p; /* Out Box to host adapter */
105:
106: typedef union mbo_u {
107: unsigned char cmd;
108: paddr_t ccbaddr;
109: } mbo_t;
110:
111: typedef union mbi_u *mbi_p; /* In Box from host adapter */
112:
113: typedef union mbi_u {
114: unsigned char sts;
115: paddr_t ccbaddr;
116: } mbi_t;
117:
118: typedef struct mb_s { /* Host adapter mailbox type */
119: mbo_t o[MAXDEVS]; /* One out box for each device */
120: mbi_t i[MAXDEVS]; /* One in box for each possible reply */
121: } mb_t;
122:
123: typedef struct haccb_s *haccb_p; /* Host Adapter Command/Control Block */
124:
125: typedef struct haccb_s {
126: unsigned char opcode;
127: unsigned char addrctrl;
128: unsigned char cdblen;
129: unsigned char senselen;
130: unsigned char datalen[3];
131: unsigned char bufaddr[3];
132: unsigned char linkaddr[3];
133: unsigned char linkid;
134: unsigned char hoststs;
135: unsigned char trgtsts;
136: unsigned char pad[2];
137: cdb_t cdb;
138: } haccb_t;
139:
140: typedef struct dsentry_s *dsentry_p;
141:
142: typedef struct dsentry_s {
143: unsigned char size[3];
144: unsigned char addr[3];
145: } dsentry_t;
146:
147: typedef struct dslist_s *dslist_p;
148:
149: typedef struct dslist_s {
150: dsentry_t entries[16];
151: } dslist_t;
152:
153: #pragma align
154:
155: /***********************************************************************
156: * Variables
157: */
158:
159: static int hastate; /* Host Adapter State */
160: static mb_t mb;
161: static haccb_t ccb[MAXDEVS];
162: static paddr_t ccbbase;
163: static srb_p actv[MAXDEVS];
164: static dslist_t ds[MAXDEVS];
165:
166: void abortscsi();
167:
168: /***********************************************************************
169: * Support Functions
170: */
171:
172: #define min(a, b) (((a) <= (b)) ? (a) : (b))
173:
174: /***********************************************************************
175: * pollclr()
176: *
177: * Wait for bit(s) to clear in a port.
178: */
179:
180: static int pollclr(port, bits)
181: unsigned port;
182: unsigned bits;
183:
184: {
185: long countdown = 1000000L;
186: unsigned pval;
187:
188: while (countdown-- > 0L) {
189: pval = inb(port) & 0xff;
190: if ((pval & bits) == 0)
191: return (pval & ~bits);
192: }
193: printf("pollclr() port 0x%x stuck at 0x%x waiting for 0x%x\n", port, pval, bits);
194: return TIMEOUT;
195: } /* pollclr() */
196:
197: /***********************************************************************
198: * pollset()
199: *
200: * Wait for bits in port to be set.
201: */
202:
203: static int pollset(port, bits)
204: unsigned port;
205: unsigned bits;
206: {
207: long countdown = 1000000L;
208: unsigned pval;
209:
210: while (countdown-- > 0L) {
211: pval = inb(port) & 0xff;
212: if ((pval & bits) == bits)
213: return pval;
214: }
215: printf("pollset() port 0x%x stuck at 0x%x waiting for 0x%x\n", port, pval, bits);
216: return TIMEOUT;
217: } /* pollset() */
218:
219: /***********************************************************************
220: * hacc()
221: *
222: * Host Adapter Command Completed - Returns 1 if last host adapter
223: * command completed without error.
224: */
225:
226: static int hacc()
227:
228: {
229: unsigned stsreg;
230:
231: if (pollset(INTRFLGS, HACC) == TIMEOUT) {
232: printf("Timeout waiting for Host Adapter Command Complete\n");
233: return 0;
234: }
235: stsreg = inb(STSREG) & (IDLE | INIT | CDF | INVDCMD);
236: if (stsreg != IDLE) {
237: printf("Host Adapter Stuck - STSREG: 0x%x\n", stsreg);
238: return 0;
239: }
240: return 1;
241: } /* hacc() */
242:
243: /***********************************************************************
244: * haidle()
245: *
246: * Returns 1 if the Idle Bit is on in the adapter status register
247: */
248:
249: #define haidle() (pollset(STSREG, IDLE) != TIMEOUT)
250:
251: /***********************************************************************
252: * gethabyte()
253: *
254: * Get a byte from the host adapter Data In register.
255: */
256:
257: static int gethabyte()
258:
259: {
260: return (pollset(STSREG, DF) == TIMEOUT) ? TIMEOUT : (inb(DATAIN) & 0xff);
261: } /* gethabyte() */
262:
263: /***********************************************************************
264: * puthabyte()
265: *
266: * Write a byte to the host adapter Command/Data Out Register.
267: */
268:
269: static int puthabyte(b)
270: unsigned char b;
271:
272: {
273: if (pollclr(STSREG, CDF) == TIMEOUT)
274: return 0;
275: else {
276: outb(CMDDATAOUT, b);
277: return 1;
278: }
279: } /* puthabyte() */
280:
281: /***********************************************************************
282: * isaha154x()
283: *
284: * Returns a string indicating the type and revision of the AHA154x
285: * host adapter on the bus if it is out there. Caveat: if something
286: * else is out there that can respond to this message I don't know
287: * what will happen.
288: */
289:
290: static char *isaha154x(haport)
291: unsigned haport;
292:
293: {
294: /* 0123456789012345678901234 */
295: static char brdid[] = "Adaptec AHA-154x# Rev: ##";
296: char buf[4], *p, *idstr = NULL;
297: int ch, oldhaport, s;
298:
299: oldhaport = AHABASE;
300: s = sphi();
301: AHABASE = haport;
302: if (haidle() && puthabyte(HAINQUIRY)) {
303: for (p = buf; p < buf + sizeof(buf); ++p) {
304: ch = gethabyte();
305: if (ch == TIMEOUT)
306: break;
307: else
308: *p = ch;
309: }
310: if (p >= buf + sizeof(buf)) {
311: outb(CTRLREG, IRST);
312: idstr = (inb(STSREG) & IDLE != IDLE) ? NULL : brdid;
313: brdid[23] = buf[2];
314: brdid[24] = buf[3];
315: switch (buf[0]) { /* Board Type Byte */
316: case 'B': /* AHA-1640 with 64 Head BIOS */
317: brdid[13] = '6';
318: case '\0': /* AHA-1540 with 16 head BIOS */
319: case '0': /* AHA-1540 with 64 head BIOS */
320: brdid[16] = ' ';
321: break;
322: case 'A': /* AHA-1540B with 64 head BIOS */
323: brdid[16] = 'B';
324: break;
325: default:
326: idstr = "AHA-154x Conformant Host Adapter";
327: break;
328: }
329: }
330: }
331: AHABASE = oldhaport;
332: spl(s);
333: return idstr;
334: } /* isaha154x() */
335:
336: /***********************************************************************
337: * hareset()
338: *
339: * Reset the host adapter and leave it ready for operation.
340: */
341:
342: static char *hareset()
343:
344: {
345: addr3_t mbaddr;
346: int mbinitok, stsreg, i, s;
347: char *p;
348:
349: if (p = isaha154x(AHABASE)) {
350: s = sphi();
351: outb(CTRLREG, SRST);
352: if ((stsreg = pollclr(STSREG, STST)) == TIMEOUT)
353: panic("SCSI: Timeout waiting for Host Adapter Initialization\n");
354:
355: if ((stsreg & DIAGF) || (stsreg & (INIT | IDLE)) != (INIT | IDLE))
356: panic("SCSI: Host Adapter Initialization Failed.\n");
357:
358: memset(&mb, 0, sizeof(mb));
359: mbaddr. value = vtop(&mb);
360: mbinitok = 1;
361: mbinitok &= puthabyte(MBINIT);
362: mbinitok &= puthabyte(sizeof(mb) / (sizeof(mbo_t) + sizeof(mbi_t)));
363: mbinitok &= puthabyte(mbaddr. byteval[2]);
364: mbinitok &= puthabyte(mbaddr. byteval[1]);
365: mbinitok &= puthabyte(mbaddr. byteval[0]);
366: if (mbinitok && hacc())
367: for (i = 0; i < MAXDEVS; ++i) {
368: actv[i] = NULL;
369: mb. o[i]. ccbaddr = vtop(ccb + i);
370: flip(mb. o[i]. ccbaddr);
371: mb. o[i]. cmd = MBOFREE;
372: }
373: else
374: panic("SCSI: AHA-154XB Mailbox Initialization Failed.\n");
375:
376: ccbbase = vtop(ccb);
377: spl(s);
378: }
379: return p;
380: } /* hareset() */
381:
382: /***********************************************************************
383: * dmacascade()
384: *
385: * Set the selected (AHADMACHAN) dma channel to cascade mode.
386: */
387:
388: static void dmacascade()
389:
390: {
391: int dmaporta, dmaportb, s;
392:
393: s = sphi();
394: if (AHADMACHAN == 0) {
395: dmaporta = 0x0b;
396: dmaportb = 0x0a;
397: } else {
398: dmaporta = 0xd6;
399: dmaportb = 0xd4;
400: }
401: outb(dmaporta, 0xc0 | (AHADMACHAN & 3));
402: outb(dmaportb, (AHADMACHAN & 3));
403: spl(s);
404: } /* dmacascade() */
405:
406: /***********************************************************************
407: * checkmail()
408: *
409: * Check the incoming mailboxes for messages. Do this on any Mail
410: * Box In Full interrupt and before you fail a command for timeout.
411: * The code to determine which target device finished by tid is a
412: * bit tricky and relies on the following assumptions:
413: *
414: * 1) The host adapter is installed in a Intel (big-endian)
415: * machine. Believe it or not there is (are) non-Intel CPU
416: * ISA bus machines. and the one that I know of is a M68000
417: * machine where this would not work.
418: *
419: * 2) The kernel's data space is physically contiguous and is
420: * never swapped out.
421: */
422:
423: static int checkmail()
424:
425: {
426: static int startid = 0;
427: int msgs = 0;
428: int sts;
429: int s;
430: register int id;
431: register srb_p r;
432: register int i = startid;
433:
434: do {
435: if (mb. i[i]. sts != MBIFREE) {
436: s = sphi();
437: sts = mb. i[i]. sts;
438: flip(mb. i[i]. ccbaddr);
439: id = (unsigned) ((mb. i[i]. ccbaddr & 0x00ffffffL) - ccbbase) / sizeof(haccb_t);
440: if (r = actv[id]) {
441: switch (sts) {
442: case MBISUCCESS:
443: case MBIERROR:
444: case MBIABRTFLD:
445: r->status = ccb[id]. trgtsts;
446: break;
447: case MBIABORTED:
448: r->status = ST_DRVABRT;
449: break;
450: default:
451: panic("Host Adapter Mailbox In value corrupted\n");
452: }
453: actv[id] = NULL;
454: if (r->cleanup)
455: (*(r->cleanup))(r);
456: msgs |= bit(id);
457: }
458: mb. i[i]. ccbaddr = 0;
459: spl(s);
460: }
461: else if (msgs)
462: break;
463: i = (i + 1) & 7;
464: } while (i != startid);
465: startid = i;
466:
467: return msgs;
468: } /* checkmail() */
469:
470: /***********************************************************************
471: * Driver Interface Functions
472: */
473:
474: /***********************************************************************
475: * hatimer()
476: *
477: * Host adapter Timeout handler.
478: */
479:
480: void hatimer()
481:
482: {
483: register int id;
484: register srb_p r;
485: register int active;
486: int s;
487:
488: s = sphi();
489: checkmail(); /* Cleanup any missed interrupts, etc. */
490: active = 0;
491: for (id = 0; id < MAXDEVS; ++id) {
492: if ((r = actv[id]) != NULL && r->timeout != 0) {
493: if (--r->timeout == 0) {
494: abortscsi(r);
495: r->status = ST_DRVABRT;
496: }
497: else
498: active = 1;
499: }
500: }
501: drvl[SCSIMAJOR]. d_time = active;
502: spl(s);
503: } /* hatimer() */
504:
505: /***********************************************************************
506: * haintr()
507: *
508: * SCSI interrupt handler for host adapter.
509: */
510:
511: void haintr()
512:
513: {
514: int intrflgs;
515:
516: intrflgs = inb(INTRFLGS);
517: if (intrflgs & ANYINTR)
518: outb(CTRLREG, IRST);
519:
520: if (hastate == ST_HAINIT)
521: return;
522: if (intrflgs & MBIF) {
523: checkmail();
524: return;
525: }
526: } /* haintr() */
527:
528: /***********************************************************************
529: * hainit()
530: *
531: * Initialize the host adapter for operation.
532: */
533:
534: int hainit()
535:
536: {
537: char *p;
538:
539: hastate = ST_HAINIT;
540: printf("Host Adapter Module: AHA-154x v1.0.0 beta\n");
541: setivec(AHAINTR, haintr);
542: p = hareset();
543: if (!p)
544: panic("AHA154x not found or init failed at port: 0x%x\n", AHABASE);
545: else
546: printf("Initializing %s at port 0x%x, IRQ 0x%x, DMA 0x%x\n", p, AHABASE, AHAINTR, AHADMACHAN);
547:
548: dmacascade();
549: hastate = ST_HAIDLE;
550: return 1;
551: } /* hainit() */
552:
553: /***********************************************************************
554: * mkdslist()
555: *
556: * Make an Adaptec Data Segment list for a Scatter/Gather Request.
557: * Input: d - the memory area for the Scatter/Gather List.
558: * b - the bufaddr structure for the memory block.
559: */
560:
561: static int mkdslist(d, b)
562: register dsentry_p d;
563: bufaddr_p b;
564: {
565: paddr_t p_start;
566: size_t p_size;
567: paddr_t p_next;
568: int segments = 1;
569: register unsigned long start;
570: register unsigned long end;
571: dsentry_p l = d;
572:
573: switch (b->space) {
574: case KRNL_ADDR: /* Kernal Address */
575: case USER_ADDR: /* User Address (Anything goes) */
576: start = b->addr. vaddr;
577: p_start = vtop(start);
578: break;
579: case SYSGLBL_ADDR: /* System Global address (yeah) */
580: start = b->addr. paddr;
581: p_start = P2P(start);
582: break;
583: case PHYS_ADDR: /* Physical Address - (who knows) */
584: default:
585: return 0;
586: }
587: end = start + b->size;
588: p_size = min(NBPC - (p_start & (NBPC - 1)), end - start);
589:
590: for ( ; ; ) {
591: d->size[2] = ((unsigned char *) &p_size)[0];
592: d->size[1] = ((unsigned char *) &p_size)[1];
593: d->size[0] = ((unsigned char *) &p_size)[2];
594: d->addr[2] = ((unsigned char *) &p_start)[0];
595: d->addr[1] = ((unsigned char *) &p_start)[1];
596: d->addr[0] = ((unsigned char *) &p_start)[2];
597: if (start + p_size >= end)
598: return segments;
599:
600: p_next = (b->space == SYSGLBL_ADDR) ? P2P(start + p_size) :
601: vtop(start + p_size);
602: if (p_next == p_start + p_size)
603: /* Continue Last Segment */
604: p_size += min(NBPC, end - start - p_size);
605: else {
606: /* Start New Segment */
607: p_start = p_next;
608: start += p_size;
609: p_size = min(NBPC, end - start);
610: ++d;
611: if (++segments > (sizeof(dslist_t) / sizeof(dsentry_t)))
612: return 0;
613: }
614: }
615: } /* mkdslist() */
616:
617: /***********************************************************************
618: * startscsi()
619: *
620: * Send a SCSI CDB to a target device on the bus.
621: */
622:
623: int startscsi(r)
624: register srb_p r;
625: {
626: register haccb_p c;
627: paddr_t bufaddr;
628: size_t datalen;
629: register int s;
630:
631: if (r->target >= MAXDEVS || r->lun >= MAXUNITS) {
632: printf("Illegal device ID: %d LUN: %d", r->target, r->lun);
633: return 0;
634: }
635:
636: ++r->tries;
637: if (actv[r->target]) {
638: devmsg(r->dev, "Device busy: opcode (0x%x)", r->cdb. g0. opcode);
639: return 0;
640: }
641:
642: s = sphi();
643: r->status = ST_PENDING;
644: c = ccb + r->target;
645: memset(c, 0, sizeof(haccb_t));
646: c->opcode = 0; /* Start SCSI CDB */
647: c->addrctrl = (r->target << 5) | (r->lun & 7);
648: if (r->xferdir & DMAREAD) c->addrctrl |= 0x08;
649: if (r->xferdir & DMAWRITE) c->addrctrl |= 0x10;
650: c->cdblen = cpycdb(&(c->cdb), &(r->cdb));
651: c->senselen = 1;
652:
653: /***********************************************************************
654: * Set up the CCB's Address here. This turned out to be a bit more
655: * complicated than I thought it would be.
656: */
657:
658: if (r->buf. space == PHYS_ADDR) {
659: c->datalen[0] = ((unsigned char *) &(r->buf. size))[2];
660: c->datalen[1] = ((unsigned char *) &(r->buf. size))[1];
661: c->datalen[2] = ((unsigned char *) &(r->buf. size))[0];
662: c->bufaddr[0] = ((unsigned char *) &(r->buf. addr. paddr))[2];
663: c->bufaddr[1] = ((unsigned char *) &(r->buf. addr. paddr))[1];
664: c->bufaddr[2] = ((unsigned char *) &(r->buf. addr. paddr))[0];
665: }
666: else {
667: datalen = mkdslist(ds[r->target]. entries, &(r->buf));
668: if (datalen == 0) {
669: printf("SCSI ID %d - Bad Scatter/Gather list\n", r->target);
670: spl(s);
671: return 0;
672: }
673: else if (datalen == 1)
674: memcpy(c->datalen, ds[r->target]. entries, 6);
675: else {
676: c->opcode = 2;
677: bufaddr = vtop(ds[r->target]. entries);
678: datalen *= 6;
679: c->datalen[0] = ((unsigned char *) &datalen)[2];
680: c->datalen[1] = ((unsigned char *) &datalen)[1];
681: c->datalen[2] = ((unsigned char *) &datalen)[0];
682: c->bufaddr[0] = ((unsigned char *) &bufaddr)[2];
683: c->bufaddr[1] = ((unsigned char *) &bufaddr)[1];
684: c->bufaddr[2] = ((unsigned char *) &bufaddr)[0];
685: }
686: }
687:
688: mb. o[r->target]. cmd = MBOSTART;
689: if (puthabyte(STARTSCSI) && (inb(STSREG) & INVDCMD) == 0) {
690: actv[r->target] = r;
691: if (r->timeout)
692: drvl[SCSIMAJOR]. d_time = 1;
693: }
694: else
695: panic("startscsi(): AHA-154x Command Start Failure\n");
696:
697: spl(s);
698: return 1;
699: } /* startscsi() */
700:
701: /***********************************************************************
702: * abortscsi()
703: *
704: * Abort the SCSI Command at a target device on the bus.
705: */
706:
707: void abortscsi(r)
708: register srb_p r;
709: {
710: int s,
711: spin;
712:
713: printf("abortscsi(id: %d opcode: (0x%x)\n", r->target, r->cdb. g0. opcode);
714: s = sphi();
715: r->timeout = 0;
716: mb. o[r->target]. cmd = MBOABORT;
717: if (!puthabyte(STARTSCSI) || (inb(STSREG) & INVDCMD) != 0)
718: panic("abortscsi(): AHA-154x Command Start Failure\n");
719:
720: spin = 0x200001;
721: while (r->status == ST_PENDING && --spin > 0L)
722: if ((spin & 0xFFF) == 0)
723: checkmail();
724:
725: if (r->status == ST_PENDING) {
726: if (r->xferdir == DMAREAD &&
727: r->buf. space != KRNL_ADDR &&
728: r->buf. size > 0)
729: panic("abortscsi failed at id: %d\n", r->target);
730: else {
731: actv[r->target] = NULL;
732: r->status = ST_DRVABRT;
733: if (r->cleanup)
734: (*r->cleanup)(r);
735: }
736: }
737: spl(s);
738: } /* abortscsi() */
739:
740: /***********************************************************************
741: * resetdevice()
742: *
743: * Reset a SCSI target. This is not used yet so it isn't coded but if
744: * you need to use it all you need to do is set up a CCB with opcode =
745: * 0x81. Then send it to the Host Adapter. It will do the rest.
746: */
747:
748: int resetdevice(id)
749: int id;
750: {
751: panic("resetdevice() Called for ID: %d\n", id);
752: } /* resetdevice() */
753:
754: /* End of file */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.