|
|
1.1 root 1: /*
2: * DSA disk class driver
3: * drives RA-class disks
4: * hooked up through an MSCP port
5: */
6:
7: #include "sys/param.h"
8: #include "sys/buf.h"
9: #include "sys/udaioc.h"
10: #include "sys/diskio.h"
11: #include "sys/ra.h"
12: #include "sys/mscp.h"
13: #include "sys/user.h"
14: #include "sys/file.h"
15: #include "sys/conf.h"
16:
17: extern struct msaddr raaddr[];
18: extern struct radisk radisk[];
19: extern int racnt;
20: static long rarefno; /* ref seq num */
21: extern struct buf rabuf[];
22: static struct buf rctbuf; /* for reading replacement table */
23:
24: static rareplace(), raonline(), rasonl(), racinit();
25:
26: int raopen(), raread(), rawrite(), raioctl(), rastrategy(), raclose();
27: struct bdevsw rabdev = bdinit(raopen, raclose, rastrategy, 0);
28: struct cdevsw racdev = cdinit(raopen, raclose, raread, rawrite, raioctl);
29:
30: /*
31: * UNIT(d) == logical unit number;
32: * the physical unit number is in raaddr[UNIT(d)].unit
33: *
34: * 0100 in the minor device is (temporarily?)
35: * usurped to indicate bitmapped file systems
36: * quietly ignore it for now
37: * when things improve, change the UNIT mask to 037
38: */
39: #define UNIT(dev) (((dev)>>3) & 027)
40: #define PART(dev) ((dev)&07)
41: #define HUGE 0x7fffffff /* very large 32-bit number */
42:
43: /*
44: * default partition sizes
45: */
46: static struct size {
47: daddr_t nblocks;
48: daddr_t blkoff;
49:
50: } ra_sizes[NRAPART] = {
51: 11*960, 0*960, /* 0 = cyl 0 thru 10
52: 21*960, 11*960, /* 1 = cyl 11 thru 31
53: 242*960 32*960, /* 2 = cyl 32 thru 273
54: 242*960 274*960, /* 3 = cyl 274 thru 515
55: 242*960 516*960, /* 4 = cyl 516 thru 757
56: 84*960 758*960, /* 5 = cyl 758 thru 841
57: 842*960 0*960, /* 6 = all cyl 0 thru 841
58: };
59:
60: /*
61: *} ra_sizes[NRAPART] = {
62: * 11*960, 0*960, /* A = cyl 0 thru 10 for / */
63: * 22*960, 11*960, /* B = cyl 11 thru 32 for swap */
64: * 842*960, 0*960, /* C = all cyl 0 thru 841 for testing */
65: * 16*960, 33*960, /* D = cyl 33 thru 48 for /usr/guest */
66: * 66*960, 49*960, /* E = cyl 49 thru 114 for /usr/src */
67: * 242*960,115*960, /* F = cyl 115 thru 356 nearly 1/3 */
68: * 242*960,357*960, /* G = cyl 357 thru 598 nearly 1/3 */
69: * 242*960,599*960, /* H = cyl 599 thru 840 nearly 1/3 */
70: *};
71: */
72:
73: /*
74: * reused bits of buf/iobuf struct
75: */
76:
77: #define b_next av_forw /* next buffer in queue */
78: #define b_pkt av_back /* pointer to mscp command */
79: #define b_crf b_resid /* saved refno for pending command */
80:
81: /*
82: * flags in radisk.flags
83: */
84:
85: #define ONLINE 01 /* drive is online */
86: #define WONLINE 02 /* waiting for online */
87: #define GOTDI 04 /* got unit info */
88: #define RPLOCK 010 /* replacement in progress */
89: #define RPWANT 020 /* want RPLOCK */
90: #define RPDONE 040 /* replacement done */
91: #define SPDOWN 0100 /* spin down on last close */
92:
93: /*
94: * random numbers
95: */
96:
97: #define PRIONL (PZERO-1)
98: #define SECTOR 512 /* size of an MSCP sector */
99: #define IDRA 0 /* connection ID for MSCP */
100:
101: /*
102: * open a drive, if necessary
103: */
104:
105: int raseql(), radg();
106:
107: raopen(dev, flag)
108: dev_t dev;
109: {
110: register int unit;
111: register struct radisk *ra;
112: register struct msaddr *rp;
113: register int part;
114:
115: unit = UNIT(dev);
116: if (unit >= racnt) {
117: u.u_error = ENXIO;
118: return;
119: }
120: ra = &radisk[unit];
121: rp = &raaddr[unit];
122: if (ra->open == 0) {
123: if (rp->ctype < 0 || rp->ctype >= nmsport
124: || (ra->port = msportsw[rp->ctype]) == NULL) {
125: u.u_error = ENXIO;
126: return;
127: }
128: ra->di.radsize = HUGE;
129: if ((*ra->port->mp_init)(rp->ctl, rp->ctype, 0, IDRA, raseql, radg) == 0) {
130: u.u_error = ENXIO;
131: return;
132: }
133: racinit(ra, rp);
134: }
135: part = PART(dev);
136: if ((ra->pinit & (1<<part)) == 0) {
137: ra->nblocks[part] = ra_sizes[part].nblocks;
138: ra->blkoff[part] = ra_sizes[part].blkoff;
139: ra->pinit |= (1<<part);
140: }
141: ra->open |= 1<<part;
142: spl6();
143: if ((ra->flags & ONLINE) == 0)
144: raonline(ra, rp);
145: spl0();
146: if ((ra->flags & ONLINE) == 0)
147: u.u_error = ENXIO;
148: }
149:
150: raclose(dev)
151: {
152: register struct radisk *ra;
153: register struct msaddr *rp;
154: register struct mscmd *mp;
155:
156: ra = &radisk[UNIT(dev)];
157: rp = &raaddr[UNIT(dev)];
158: ra->open &=~ (1<<PART(dev));
159: if (ra->open || (ra->flags & ONLINE) == 0)
160: return;
161: mp = (*ra->port->mp_get)(rp->ctl);
162: mp->m_crf = ++rarefno;
163: mp->m_unit = rp->unit;
164: mp->m_opcd = OPAVL; /* put it offline */
165: if ((ra->flags & SPDOWN) == 0)
166: mp->m_mod = 0;
167: else {
168: mp->m_mod = MDSPD;
169: ra->flags &=~ SPDOWN;
170: }
171: mp->m_unfl = 0;
172: mp->m_dvpm = 0; /* ? */
173: ra->flags &=~ ONLINE;
174: (*ra->port->mp_send)(rp->ctl, IDRA, mp);
175: }
176:
177: int rastrategy();
178:
179: raread(dev)
180: {
181: physio(rastrategy, &rabuf[UNIT(dev)], dev, B_READ, minphys);
182: }
183:
184: rawrite(dev)
185: {
186: physio(rastrategy, &rabuf[UNIT(dev)], dev, B_WRITE, minphys);
187: }
188:
189: /*
190: * strategy routine;
191: * used as strategy by all port drivers
192: * send the packet right away
193: */
194:
195: rastrategy(bp)
196: register struct buf *bp;
197: {
198: register struct radisk *ra;
199: register struct mscmd *mp;
200: register int unit;
201: register int part;
202: register struct msaddr *rp;
203: int count;
204: daddr_t limit;
205:
206: unit = UNIT(minor(bp->b_dev));
207: part = PART(minor(bp->b_dev));
208: ra = &radisk[unit];
209: rp = &raaddr[unit];
210: limit = ra->di.radsize - ra->blkoff[part];
211: if (limit > ra->nblocks[part])
212: limit = ra->nblocks[part];
213: if (bp->b_blkno >= limit && bp != &rctbuf) {
214: if (bp->b_blkno == ra->nblocks[part])
215: bp->b_resid = bp->b_bcount;
216: else {
217: bp->b_error = ENOSPC;
218: bp->b_flags |= B_ERROR;
219: }
220: iodone(bp);
221: return;
222: }
223: count = bp->b_bcount;
224: if (count/SECTOR + bp->b_blkno > limit && bp != &rctbuf)
225: count = (limit - bp->b_blkno) * SECTOR;
226: spl6();
227: if ((ra->flags & ONLINE) == 0 && raonline(ra, rp) == 0) {
228: bp->b_flags |= B_ERROR;
229: iodone(bp);
230: spl0();
231: return;
232: }
233: mp = (*ra->port->mp_get)(rp->ctl);
234: mp->m_crf = ++rarefno;
235: mp->m_unit = rp->unit;
236: mp->m_opcd = (bp->b_flags & B_READ) ? OPRD : OPWR;
237: mp->m_mod = 0;
238: mp->m_bcnt = count;
239: mp->m_lbn = bp->b_blkno + ra->blkoff[part];
240: (*ra->port->mp_map)(rp->ctl, mp, bp);
241: bp->b_pkt = (struct buf *)mp;
242: bp->b_crf = mp->m_crf;
243: bp->b_next = NULL;
244: if (ra->actf)
245: ra->actl->b_next = bp;
246: else
247: ra->actf = bp;
248: ra->actl = bp;
249: (*ra->port->mp_send)(rp->ctl, IDRA, mp);
250: spl0();
251: }
252:
253: /*
254: * ioctl
255: * principally for bad block replacement
256: */
257:
258: raioctl(dev, cmd, addr, flag)
259: dev_t dev;
260: caddr_t addr;
261: {
262: register union arg {
263: struct ud_rctbuf r;
264: struct ud_repl b;
265: } *uap;
266: register struct radisk *ra;
267: register int i;
268: long parts[2];
269:
270: ra = &radisk[UNIT(dev)];
271: if ((ra->flags & (ONLINE|GOTDI)) != (ONLINE|GOTDI)) {
272: /* should bring it online here */
273: u.u_error = EIO;
274: return;
275: }
276: uap = (union arg *)addr;
277: switch(cmd) {
278: default:
279: u.u_error = ENOTTY;
280: return;
281:
282: case DIOSSIZ:
283: if ((flag & FWRITE) == 0) {
284: u.u_error = EBADF;
285: return;
286: }
287: if (copyin(addr, (caddr_t)parts, sizeof(parts)) < 0) {
288: u.u_error = EFAULT;
289: return;
290: }
291: ra->blkoff[PART(dev)] = parts[0];
292: ra->nblocks[PART(dev)] = parts[1];
293: return;
294:
295: case DIOGSIZ:
296: parts[0] = ra->blkoff[PART(dev)];
297: parts[1] = ra->nblocks[PART(dev)];
298: if (copyout((caddr_t)parts, addr, sizeof(parts)) < 0)
299: u.u_error = EFAULT;
300: return;
301:
302: case UIOCHAR:
303: if (copyout((caddr_t)&ra->di, addr, sizeof(struct ud_unit)))
304: u.u_error = EFAULT;
305: return;
306:
307: case UIORRCT:
308: if(uap->r.lbn < 0 || uap->r.lbn > ra->di.rctsize) {
309: u.u_error = EIO;
310: return;
311: }
312: /*
313: * try different copies until one works
314: */
315: for (i = 0; i < ra->di.copies; i++) {
316: u.u_count = SECTOR; /* block size on disk */
317: u.u_offset = ltoL((uap->r.lbn + ra->di.radsize) * SECTOR);
318: u.u_offset = Lladd(u.u_offset,i * ra->di.rctsize * SECTOR);
319: u.u_base = uap->r.buf;
320: u.u_segflg = SEGUDATA;
321: u.u_error = 0;
322: physio(rastrategy, &rctbuf, dev, B_READ, minphys);
323: if (u.u_error == 0)
324: break;
325: }
326: return;
327:
328: case UIOWRCT:
329: if ((flag & FWRITE) == 0) {
330: u.u_error = EBADF;
331: return;
332: }
333: if(uap->r.lbn < 0 || uap->r.lbn > ra->di.rctsize) {
334: u.u_error = EIO;
335: return;
336: }
337: /*
338: * write every copy we can
339: * should do read-after-write
340: */
341: for (i = 0; i < ra->di.copies; i++) {
342: u.u_count = SECTOR; /* block size on disk */
343: u.u_offset = ltoL((uap->r.lbn + ra->di.radsize) * SECTOR);
344: u.u_offset = Lladd(u.u_offset, i * ra->di.rctsize * SECTOR);
345: u.u_base = uap->r.buf;
346: u.u_segflg = SEGUDATA;
347: physio(rastrategy, &rctbuf, dev, B_WRITE, minphys);
348: u.u_error = 0;
349: }
350: return;
351:
352: case UIOREPL:
353: if ((flag & FWRITE) == 0) {
354: u.u_error = EBADF;
355: return;
356: }
357: rareplace(dev, uap->b.lbn, uap->b.replbn, uap->b.prim);
358: return;
359:
360: case UIOSPDW:
361: ra->flags |= SPDOWN;
362: return;
363:
364: case UIORST:
365: (*ra->port->mp_init)(raaddr[UNIT(dev)].ctl, raaddr[UNIT(dev)].ctype, 1, IDRA, raseql, radg);
366: return;
367: }
368:
369: }
370:
371: static
372: rareplace(dev, badlbn, replbn, prim)
373: int dev;
374: daddr_t badlbn;
375: daddr_t replbn;
376: int prim;
377: {
378: register struct mscmd *mp;
379: register struct radisk *ra;
380: register struct msaddr *rp;
381: register int unit;
382:
383: unit = UNIT(minor(dev));
384: ra = &radisk[unit];
385: rp = &raaddr[unit];
386: spl6();
387: while (ra->flags & RPLOCK) {
388: ra->flags |= RPWANT;
389: sleep((caddr_t)&ra->flags, PZERO + 1);
390: }
391: ra->flags |= RPLOCK;
392: printf("ra%d replace %D with %D\n", unit, badlbn, replbn);
393: mp = (*ra->port->mp_get)(rp->ctl);
394: bzero((caddr_t)mp, sizeof(struct mscmd)); /* clear reserved fields */
395: mp->m_crf = ++rarefno;
396: mp->m_unit = rp->unit;
397: mp->m_opcd = OPRPL;
398: mp->m_rbn = replbn;
399: mp->m_lbn = badlbn;
400: mp->m_mod = prim ? MDPRI : 0;
401: ra->cmdcrf = mp->m_crf;
402: ra->cmdopc = OPRPL;
403: (*ra->port->mp_send)(rp->ctl, IDRA, mp);
404: while ((ra->flags & RPDONE) == 0)
405: sleep((caddr_t)&ra->rplret, PZERO);
406: u.u_error = ra->rplret;
407: if (ra->flags & RPWANT)
408: wakeup((caddr_t)&ra->flags);
409: ra->flags &=~ (RPWANT|RPLOCK|RPDONE);
410: spl0();
411:
412: }
413:
414: /*
415: * here when the port gets a sequential message
416: */
417: raseql(ctl, type, ep)
418: int ctl, type;
419: register struct msend *ep;
420: {
421: register struct buf *bp;
422: register struct radisk *ra;
423: register int unit;
424: register struct buf *obp;
425: int sts;
426:
427: if (ep->m_opcd == 0 && ep->m_sts == STRST) {
428: rareset(ctl);
429: return;
430: }
431: for (unit = 0; unit < racnt; unit++)
432: if (raaddr[unit].ctl == ctl
433: && raaddr[unit].ctype == type
434: && raaddr[unit].unit == ep->m_unit)
435: break;
436: if (unit >= racnt) {
437: printf("ra%d ctl%d typ%d: stray mscp packet sts x%x opcode %o\n",
438: ep->m_unit, ctl, type, ep->m_sts, ep->m_opcd);
439: return;
440: }
441: ra = &radisk[unit];
442: sts = ep->m_sts & STMSK;
443: if (sts == STAVL || sts == STOFL)
444: ra->flags &=~ ONLINE; /* help! */
445: illcmd:
446: switch (ep->m_opcd & 0377) {
447: case OPEND: /* eg invalid command */
448: if (ep->m_crf == ra->cmdcrf) {
449: ep->m_opcd = ra->cmdopc | OPEND;
450: goto illcmd;
451: }
452: /* else check for pending read or write */
453: case OPRD|OPEND:
454: case OPWR|OPEND:
455: for (bp = ra->actf, obp = NULL; bp; obp = bp, bp = bp->b_next)
456: if (ep->m_crf == bp->b_crf)
457: break;
458: if (bp == NULL) {
459: printf("ra%d stray end: crf %d sts x%x opcode 0%o\n",
460: unit, ep->m_crf, ep->m_sts, ep->m_opcd & 0377);
461: return;
462: }
463: if (((struct mscmd *)(bp->b_pkt))->m_crf != ep->m_crf)
464: printf("ra%d sent %d got %d crf; flg %x dev %x\n",
465: unit, ((struct mscmd *)(bp->b_pkt))->m_crf,
466: ep->m_crf, bp->b_flags, bp->b_dev);
467: if (obp)
468: obp->b_next = bp->b_next;
469: else
470: ra->actf = bp->b_next;
471: if (bp == ra->actl)
472: ra->actl = obp;
473: bp->b_resid = bp->b_bcount - ep->m_bcnt;
474: if (sts != STSUC) {
475: bp->b_flags |= B_ERROR;
476: if (ep->m_sts == STBCK || ep->m_sts == STBK2) /* optical disk blank check */
477: bp->b_error = ENXIO;
478: else
479: printf("err on ra%d block %D: sts x%x\n", unit, bp->b_blkno, ep->m_sts);
480: }
481: (*ra->port->mp_unmap)(ctl, (struct mscmd *)bp->b_pkt);
482: iodone(bp);
483: return;
484:
485: case OPONL|OPEND:
486: rasonl(ra, ep);
487: return;
488:
489: case OPAVL|OPEND:
490: ra->flags &=~ ONLINE;
491: return;
492:
493: case OPGUS|OPEND:
494: if (sts != STSUC) {
495: printf("ra%d: can't get unit sts x%x\n", unit, ep->m_sts);
496: return;
497: }
498: ra->di.medium = ep->m_medi;
499: ra->di.tracksz = ep->m_trck;
500: ra->di.groupsz = ep->m_grp;
501: ra->di.cylsz = ep->m_cyl;
502: ra->di.rctsize = ep->m_rcts;
503: ra->di.rbns = ep->m_rbns;
504: ra->di.copies = ep->m_rctc;
505: ra->flags |= GOTDI;
506: return;
507:
508: case OPSCC|OPEND:
509: if (sts != STSUC)
510: printf("ra ctl%d typ%d: bad init\n", ctl, type);
511: return;
512:
513: case OPRPL|OPEND:
514: ra->rplret = 0;
515: if (sts != STSUC) {
516: printf("ra%d: rpl sts x%x\n", unit, ep->m_sts);
517: ra->rplret = EIO;
518: }
519: ra->flags |= RPDONE;
520: wakeup((caddr_t)&ra->rplret);
521: return;
522:
523: default:
524: printf("ra%d ctl%d typ%d: stray mscp msg opcd 0%o sts x%x\n",
525: ep->m_unit, ctl, type, ep->m_opcd&0377, ep->m_sts);
526: return;
527: }
528: }
529:
530: /*
531: * controller was reset
532: * discard all pending io,
533: * awake all sleepers,
534: * mark everything offline
535: */
536:
537: rareset(ctl)
538: int ctl;
539: {
540: register int unit;
541: register struct radisk *ra;
542: register struct buf *bp, *nbp;
543:
544: for (unit = 0; unit < racnt; unit++) {
545: if (raaddr[unit].ctl != ctl)
546: continue;
547: ra = &radisk[unit];
548: for (bp = ra->actf; bp; bp = nbp) {
549: nbp = bp->b_next;
550: (*ra->port->mp_unmap)(ctl, (struct mscmd *)bp->b_pkt);
551: bp->b_flags |= B_ERROR;
552: iodone(bp);
553: }
554: ra->actf = ra->actl = NULL;
555: ra->flags &=~ (ONLINE|WONLINE);
556: wakeup((caddr_t)ra);
557: }
558: }
559:
560: /*
561: * here with a datagram message
562: * explanations really shouldn't be in the driver
563: *
564: * the hack for event 8 ignores error packets from
565: * the US Design optical disk controller
566: * that really mean `read a blank spot on the disk
567: */
568:
569: static char *raevents[] = {
570: "ok",
571: "inv cmd",
572: "op aborted",
573: "offline",
574: "available",
575: "med fmt",
576: "write prot",
577: "comp err",
578: "data err",
579: "host buf access err",
580: "cntl err",
581: "drive err",
582: };
583: #define MAXEVT 0xb
584:
585: radg(ctl, type, ep)
586: int ctl, type;
587: register struct mserl *ep;
588: {
589: register u_short *sp; /* for sdi crap */
590: register int i; /* for useless design crap */
591: register unsigned char *cp; /* for useless design crap */
592:
593: if (ep->l_fmt == FMDSK && ep->l_evnt == STBCK && ep->l_flgs == 0)
594: return;
595: printf("ra%d ctl%d typ%d seq %d: %s err; fmt x%x ev x%x fl x%x\n",
596: ep->l_unit, ctl, type, ep->l_seq, /* phys unit, not log */
597: ep->l_flgs&(LFSUC|LFCON) ? "soft" : "hard",
598: ep->l_fmt, ep->l_evnt, ep->l_flgs&0377);
599: if ((ep->l_evnt & STMSK) <= MAXEVT)
600: printf("%s; ", raevents[ep->l_evnt & STMSK]);
601: switch (ep->l_fmt) {
602: case FMCNT:
603: /* now the thing should be marked disastrously bad */
604: printf("oops\n");
605: break;
606:
607: case FMBAD:
608: printf("host mem access; addr x%x\n", ep->l_badr);
609: break;
610:
611: case FMDSK:
612: printf("%sbn %d; lev x%x, retry x%x\n",
613: (ep->l_hdcd & 0xf0000000) == 0 ? "l" : "r",
614: ep->l_hdcd & 0x0fffffff, ep->l_lvl, ep->l_rtry);
615: break;
616:
617: case FMSDI:
618: printf("%sbn %d;",
619: (ep->l_hdcd & 0xf0000000) == 0 ? "l" : "r",
620: ep->l_hdcd & 0x0fffffff);
621: /*
622: * print the bytes in the same order used
623: * by the dec diagnostics
624: */
625: sp = (u_short *)&ep->l_sdi[3];
626: while (sp > (u_short *)ep->l_sdi)
627: printf(" %x", *--sp);
628: printf(" xx\n");
629: break;
630:
631: case FMSMD:
632: printf("cyl %d\n", ep->l_sdi[1]);
633: break;
634:
635: case 0x40: /* hack for useless design */
636: printf("scsi:");
637: cp = (unsigned char *)ep->l_sdi;
638: for(i = 0; i < 10; i++)
639: printf(" %x", *cp++);
640: printf(" [%x %x]\n", cp[0], cp[1]);
641: break;
642:
643: default:
644: printf("\n");
645: break;
646: }
647: }
648:
649: /*
650: * unit is believed offline
651: * try to bring it on
652: */
653:
654: static
655: raonline(ra, rp)
656: register struct radisk *ra;
657: register struct msaddr *rp;
658: {
659: register struct mscmd *mp;
660: int s;
661:
662: s = spl6();
663: if ((ra->flags & WONLINE) == 0) {
664: ra->flags &=~ GOTDI;
665: mp = (*ra->port->mp_get)(rp->ctl);
666: bzero((caddr_t)mp, sizeof(struct mscmd)); /* clear reserved fields */
667: mp->m_crf = ++rarefno;
668: mp->m_unit = rp->unit;
669: mp->m_opcd = OPONL;
670: ra->cmdcrf = mp->m_crf;
671: ra->cmdopc = OPONL;
672: (*ra->port->mp_send)(rp->ctl, IDRA, mp);
673: ra->flags |= WONLINE;
674: }
675: while (ra->flags & WONLINE)
676: tsleep((caddr_t)ra, PRIONL, 60);
677: if ((ra->flags & ONLINE) == 0)
678: return (0);
679: if ((ra->flags & GOTDI) == 0) {
680: mp = (*ra->port->mp_get)(rp->ctl);
681: mp->m_crf = ++rarefno;
682: mp->m_unit = rp->unit;
683: mp->m_opcd = OPGUS;
684: mp->m_mod = 0;
685: mp->m_unfl = 0;
686: mp->m_dvpm = 0; /* ? */
687: (*ra->port->mp_send)(rp->ctl, IDRA, mp);
688: }
689: splx(s);
690: return (1);
691: }
692:
693: static
694: rasonl(ra, ep)
695: register struct radisk *ra;
696: register struct msend *ep;
697: {
698:
699: if (ra->flags & WONLINE) {
700: ra->flags &=~ WONLINE;
701: wakeup((caddr_t)ra);
702: }
703: if ((ep->m_sts & STMSK) != STSUC)
704: return;
705: ra->flags |= ONLINE;
706: if (ra->di.radsize != HUGE && ra->di.radsize != ep->m_unsz)
707: printf("ra%d: changed size %d to %d\n", ra-radisk, ra->di.radsize, ep->m_unsz);
708: ra->di.radsize = ep->m_unsz;
709: }
710:
711: /*
712: * controller init
713: * set characteristics to turn off host timeouts
714: */
715:
716: static
717: racinit(ra, rp)
718: struct radisk *ra;
719: struct msaddr *rp;
720: {
721: register struct mscmd *mp;
722: register int s;
723:
724: mp = (*ra->port->mp_get)(rp->ctl);
725: mp->m_crf = ++rarefno;
726: mp->m_unit = rp->unit;
727: mp->m_opcd = OPSCC;
728: mp->m_mod = 0;
729: mp->m_cntf = CFMSC | CFTHS;
730: mp->m_vrsn = MSCPVER;
731: mp->m_htmo = 0; /* no timeout */
732: mp->m_time[0] = mp->m_time[1] = 0L;
733: s = spl6();
734: (*ra->port->mp_send)(rp->ctl, IDRA, mp);
735: splx(s);
736: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.