|
|
1.1 root 1: /* rk.c 6.2 83/10/11 */
2:
3: #include "rk.h"
4: #if NHK > 0
5: int rkpip; /* DEBUG */
6: int rknosval; /* DEBUG */
7: #ifdef RKDEBUG
8: int rkdebug;
9: #endif
10: #ifdef RKBDEBUG
11: int rkbdebug;
12: #endif
13: /*
14: * RK611/RK0[67] disk driver
15: *
16: * This driver mimics up.c; see it for an explanation of common code.
17: *
18: * TODO:
19: * Learn why we lose an interrupt sometime when spinning drives down
20: */
21: #include "../machine/pte.h"
22:
23: #include "../h/param.h"
24: #include "../h/systm.h"
25: #include "../h/buf.h"
26: #include "../h/conf.h"
27: #include "../h/dir.h"
28: #include "../h/user.h"
29: #include "../h/map.h"
30: #include "../h/vm.h"
31: #include "../h/dk.h"
32: #include "../h/cmap.h"
33: #include "../h/dkbad.h"
34: #include "../h/uio.h"
35: #include "../h/kernel.h"
36:
37: #include "../vax/cpu.h"
38: #include "../vaxuba/ubareg.h"
39: #include "../vaxuba/ubavar.h"
40: #include "../vaxuba/rkreg.h"
41:
42: struct rk_softc {
43: int sc_softas;
44: int sc_ndrive;
45: int sc_wticks;
46: int sc_recal;
47: } rk_softc[NHK];
48:
49: /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
50: struct size {
51: daddr_t nblocks;
52: int cyloff;
53: } rk7_sizes[8] ={
54: 15884, 0, /* A=cyl 0 thru 240 */
55: 10032, 241, /* B=cyl 241 thru 392 */
56: 53790, 0, /* C=cyl 0 thru 814 */
57: 0, 0,
58: 0, 0,
59: 0, 0,
60: 27786, 393, /* G=cyl 393 thru 813 */
61: 0, 0,
62: }, rk6_sizes[8] ={
63: 15884, 0, /* A=cyl 0 thru 240 */
64: 11154, 241, /* B=cyl 241 thru 409 */
65: 27126, 0, /* C=cyl 0 thru 410 */
66: 0, 0,
67: 0, 0,
68: 0, 0,
69: 0, 0,
70: 0, 0,
71: };
72: /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
73:
74: short rktypes[] = { RK_CDT, 0 };
75:
76: int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr();
77: struct uba_ctlr *rkminfo[NHK];
78: struct uba_device *rkdinfo[NRK];
79: struct uba_device *rkip[NHK][4];
80:
81: u_short rkstd[] = { 0777440, 0 };
82: struct uba_driver hkdriver =
83: { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 };
84: struct buf rkutab[NRK];
85: short rkcyl[NRK];
86: struct dkbad rkbad[NRK];
87: struct buf brkbuf[NRK];
88:
89: struct rkst {
90: short nsect;
91: short ntrak;
92: short nspc;
93: short ncyl;
94: struct size *sizes;
95: } rkst[] = {
96: NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes,
97: NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK6CYL, rk6_sizes,
98: };
99:
100: u_char rk_offset[16] =
101: { RKAS_P400,RKAS_M400,RKAS_P400,RKAS_M400,RKAS_P800,RKAS_M800,RKAS_P800,
102: RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0
103: };
104:
105: struct buf rrkbuf[NRK];
106:
107: #define b_cylin b_resid
108:
109: #ifdef INTRLVE
110: daddr_t dkblock();
111: #endif
112:
113: int rkwstart, rkwatch();
114:
115: rkprobe(reg)
116: caddr_t reg;
117: {
118: register int br, cvec;
119:
120: #ifdef lint
121: br = 0; cvec = br; br = cvec;
122: rkintr(0);
123: #endif
124: ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY;
125: DELAY(10);
126: ((struct rkdevice *)reg)->rkcs1 = RK_CDT;
127: return (sizeof (struct rkdevice));
128: }
129:
130: rkslave(ui, reg)
131: struct uba_device *ui;
132: caddr_t reg;
133: {
134: register struct rkdevice *rkaddr = (struct rkdevice *)reg;
135:
136: ui->ui_type = 0;
137: rkaddr->rkcs1 = RK_CCLR;
138: rkaddr->rkcs2 = ui->ui_slave;
139: rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
140: rkwait(rkaddr);
141: DELAY(50);
142: if (rkaddr->rkcs2&RKCS2_NED || (rkaddr->rkds&RKDS_SVAL) == 0) {
143: rkaddr->rkcs1 = RK_CCLR;
144: return (0);
145: }
146: if (rkaddr->rkcs1&RK_CERR && rkaddr->rker&RKER_DTYE) {
147: ui->ui_type = 1;
148: rkaddr->rkcs1 = RK_CCLR;
149: }
150: return (1);
151: }
152:
153: rkattach(ui)
154: register struct uba_device *ui;
155: {
156:
157: if (rkwstart == 0) {
158: timeout(rkwatch, (caddr_t)0, hz);
159: rkwstart++;
160: }
161: if (ui->ui_dk >= 0)
162: dk_mspw[ui->ui_dk] = 1.0 / (60 * NRKSECT * 256);
163: rkip[ui->ui_ctlr][ui->ui_slave] = ui;
164: rk_softc[ui->ui_ctlr].sc_ndrive++;
165: rkcyl[ui->ui_unit] = -1;
166: ui->ui_flags = 0;
167: }
168:
169: rkopen(dev)
170: dev_t dev;
171: {
172: register int unit = minor(dev) >> 3;
173: register struct uba_device *ui;
174:
175: if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0)
176: return (ENXIO);
177: return (0);
178: }
179:
180: rkstrategy(bp)
181: register struct buf *bp;
182: {
183: register struct uba_device *ui;
184: register struct rkst *st;
185: register int unit;
186: register struct buf *dp;
187: int xunit = minor(bp->b_dev) & 07;
188: long bn, sz;
189: int s;
190:
191: sz = (bp->b_bcount+511) >> 9;
192: unit = dkunit(bp);
193: if (unit >= NRK)
194: goto bad;
195: ui = rkdinfo[unit];
196: if (ui == 0 || ui->ui_alive == 0)
197: goto bad;
198: st = &rkst[ui->ui_type];
199: if (bp->b_blkno < 0 ||
200: (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks)
201: goto bad;
202: bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
203: s = spl5();
204: dp = &rkutab[ui->ui_unit];
205: disksort(dp, bp);
206: if (dp->b_active == 0) {
207: (void) rkustart(ui);
208: bp = &ui->ui_mi->um_tab;
209: if (bp->b_actf && bp->b_active == 0)
210: (void) rkstart(ui->ui_mi);
211: }
212: splx(s);
213: return;
214:
215: bad:
216: bp->b_flags |= B_ERROR;
217: iodone(bp);
218: return;
219: }
220:
221: rkustart(ui)
222: register struct uba_device *ui;
223: {
224: register struct buf *bp, *dp;
225: register struct uba_ctlr *um;
226: register struct rkdevice *rkaddr;
227:
228: if (ui == 0)
229: return;
230: dk_busy &= ~(1<<ui->ui_dk);
231: dp = &rkutab[ui->ui_unit];
232: um = ui->ui_mi;
233: rkaddr = (struct rkdevice *)um->um_addr;
234: if (um->um_tab.b_active) {
235: rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave;
236: return;
237: }
238: if ((bp = dp->b_actf) == NULL)
239: return;
240: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_CERR;
241: rkaddr->rkcs2 = ui->ui_slave;
242: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
243: rkwait(rkaddr);
244: if ((rkaddr->rkds & RKDS_VV) == 0 || ui->ui_flags == 0) {
245: /* SHOULD WARN SYSTEM THAT THIS HAPPENED */
246: struct rkst *st = &rkst[ui->ui_type];
247: struct buf *bbp = &brkbuf[ui->ui_unit];
248:
249: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_PACK|RK_GO;
250: ui->ui_flags = 1;
251: bbp->b_flags = B_READ|B_BUSY;
252: bbp->b_dev = bp->b_dev;
253: bbp->b_bcount = 512;
254: bbp->b_un.b_addr = (caddr_t)&rkbad[ui->ui_unit];
255: bbp->b_blkno = st->ncyl*st->nspc - st->nsect;
256: bbp->b_cylin = st->ncyl - 1;
257: dp->b_actf = bbp;
258: bbp->av_forw = bp;
259: bp = bbp;
260: rkwait(rkaddr);
261: }
262: if (dp->b_active)
263: goto done;
264: dp->b_active = 1;
265: if ((rkaddr->rkds & RKDS_DREADY) != RKDS_DREADY)
266: goto done;
267: if (rk_softc[um->um_ctlr].sc_ndrive == 1)
268: goto done;
269: if (bp->b_cylin == rkcyl[ui->ui_unit])
270: goto done;
271: rkaddr->rkcyl = bp->b_cylin;
272: rkcyl[ui->ui_unit] = bp->b_cylin;
273: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO;
274: if (ui->ui_dk >= 0) {
275: dk_busy |= 1<<ui->ui_dk;
276: dk_seek[ui->ui_dk]++;
277: }
278: goto out;
279: done:
280: if (dp->b_active != 2) {
281: dp->b_forw = NULL;
282: if (um->um_tab.b_actf == NULL)
283: um->um_tab.b_actf = dp;
284: else
285: um->um_tab.b_actl->b_forw = dp;
286: um->um_tab.b_actl = dp;
287: dp->b_active = 2;
288: }
289: out:
290: return;
291: }
292:
293: rkstart(um)
294: register struct uba_ctlr *um;
295: {
296: register struct buf *bp, *dp;
297: register struct uba_device *ui;
298: register struct rkdevice *rkaddr;
299: struct rkst *st;
300: daddr_t bn;
301: int sn, tn, cmd;
302:
303: loop:
304: if ((dp = um->um_tab.b_actf) == NULL)
305: return;
306: if ((bp = dp->b_actf) == NULL) {
307: um->um_tab.b_actf = dp->b_forw;
308: goto loop;
309: }
310: um->um_tab.b_active++;
311: ui = rkdinfo[dkunit(bp)];
312: bn = dkblock(bp);
313: st = &rkst[ui->ui_type];
314: sn = bn%st->nspc;
315: tn = sn/st->nsect;
316: sn %= st->nsect;
317: rkaddr = (struct rkdevice *)ui->ui_addr;
318: retry:
319: rkaddr->rkcs1 = RK_CCLR;
320: rkaddr->rkcs2 = ui->ui_slave;
321: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
322: rkwait(rkaddr);
323: if ((rkaddr->rkds&RKDS_SVAL) == 0) {
324: rknosval++;
325: goto nosval;
326: }
327: if (rkaddr->rkds&RKDS_PIP) {
328: rkpip++;
329: goto retry;
330: }
331: if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) {
332: printf("rk%d: not ready", dkunit(bp));
333: if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) {
334: printf("\n");
335: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
336: rkwait(rkaddr);
337: rkaddr->rkcs1 = RK_CCLR;
338: rkwait(rkaddr);
339: um->um_tab.b_active = 0;
340: um->um_tab.b_errcnt = 0;
341: dp->b_actf = bp->av_forw;
342: dp->b_active = 0;
343: bp->b_flags |= B_ERROR;
344: iodone(bp);
345: goto loop;
346: }
347: printf(" (came back!)\n");
348: }
349: nosval:
350: rkaddr->rkcyl = bp->b_cylin;
351: rkcyl[ui->ui_unit] = bp->b_cylin;
352: rkaddr->rkda = (tn << 8) + sn;
353: rkaddr->rkwc = -bp->b_bcount / sizeof (short);
354: if (bp->b_flags & B_READ)
355: cmd = rktypes[ui->ui_type]|RK_IE|RK_READ|RK_GO;
356: else
357: cmd = rktypes[ui->ui_type]|RK_IE|RK_WRITE|RK_GO;
358: um->um_cmd = cmd;
359: (void) ubago(ui);
360: }
361:
362: rkdgo(um)
363: register struct uba_ctlr *um;
364: {
365: register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr;
366:
367: um->um_tab.b_active = 2; /* should now be 2 */
368: rkaddr->rkba = um->um_ubinfo;
369: rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300);
370: }
371:
372: rkintr(rk11)
373: int rk11;
374: {
375: register struct uba_ctlr *um = rkminfo[rk11];
376: register struct uba_device *ui;
377: register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr;
378: register struct buf *bp, *dp;
379: int unit;
380: struct rk_softc *sc = &rk_softc[um->um_ctlr];
381: int as = (rkaddr->rkatt >> 8) | sc->sc_softas;
382:
383: sc->sc_wticks = 0;
384: sc->sc_softas = 0;
385: if (um->um_tab.b_active == 2 || sc->sc_recal) {
386: um->um_tab.b_active = 1;
387: dp = um->um_tab.b_actf;
388: bp = dp->b_actf;
389: ui = rkdinfo[dkunit(bp)];
390: dk_busy &= ~(1 << ui->ui_dk);
391: if (bp->b_flags&B_BAD)
392: if (rkecc(ui, CONT))
393: return;
394: if (rkaddr->rkcs1 & RK_CERR) {
395: int recal;
396: u_short ds = rkaddr->rkds;
397: u_short cs2 = rkaddr->rkcs2;
398: u_short er = rkaddr->rker;
399: #ifdef RKDEBUG
400: if (rkdebug) {
401: printf("cs2=%b ds=%b er=%b\n",
402: cs2, RKCS2_BITS, ds,
403: RKDS_BITS, er, RKER_BITS);
404: }
405: #endif
406: if (er & RKER_WLE) {
407: printf("rk%d: write locked\n", dkunit(bp));
408: bp->b_flags |= B_ERROR;
409: } else if (++um->um_tab.b_errcnt > 28 ||
410: ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) {
411: hard:
412: harderr(bp, "rk");
413: printf("cs2=%b ds=%b er=%b\n",
414: cs2, RKCS2_BITS, ds,
415: RKDS_BITS, er, RKER_BITS);
416: bp->b_flags |= B_ERROR;
417: sc->sc_recal = 0;
418: } else if (er & RKER_BSE) {
419: if (rkecc(ui, BSE))
420: return;
421: else
422: goto hard;
423: } else {
424: if ((er & (RKER_DCK|RKER_ECH)) == RKER_DCK) {
425: if (rkecc(ui, ECC))
426: return;
427: } else
428: um->um_tab.b_active = 0;
429: }
430: if (cs2&RKCS2_MDS) {
431: rkaddr->rkcs2 = RKCS2_SCLR;
432: goto retry;
433: }
434: recal = 0;
435: if (ds&RKDS_DROT || er&(RKER_OPI|RKER_SKI|RKER_UNS) ||
436: (um->um_tab.b_errcnt&07) == 4)
437: recal = 1;
438: rkaddr->rkcs1 = RK_CCLR;
439: rkaddr->rkcs2 = ui->ui_slave;
440: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
441: rkwait(rkaddr);
442: if (recal && um->um_tab.b_active == 0) {
443: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_RECAL|RK_GO;
444: rkcyl[ui->ui_unit] = -1;
445: sc->sc_recal = 0;
446: goto nextrecal;
447: }
448: }
449: retry:
450: switch (sc->sc_recal) {
451:
452: case 1:
453: rkaddr->rkcyl = bp->b_cylin;
454: rkcyl[ui->ui_unit] = bp->b_cylin;
455: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO;
456: goto nextrecal;
457: case 2:
458: if (um->um_tab.b_errcnt < 16 ||
459: (bp->b_flags&B_READ) == 0)
460: goto donerecal;
461: rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017];
462: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_OFFSET|RK_GO;
463: /* fall into ... */
464: nextrecal:
465: sc->sc_recal++;
466: rkwait(rkaddr);
467: um->um_tab.b_active = 1;
468: return;
469: donerecal:
470: case 3:
471: sc->sc_recal = 0;
472: um->um_tab.b_active = 0;
473: break;
474: }
475: ubadone(um);
476: if (um->um_tab.b_active) {
477: um->um_tab.b_active = 0;
478: um->um_tab.b_errcnt = 0;
479: um->um_tab.b_actf = dp->b_forw;
480: dp->b_active = 0;
481: dp->b_errcnt = 0;
482: dp->b_actf = bp->av_forw;
483: bp->b_resid = -rkaddr->rkwc * sizeof(short);
484: iodone(bp);
485: if (dp->b_actf)
486: rkustart(ui);
487: }
488: as &= ~(1<<ui->ui_slave);
489: }
490: for (unit = 0; as; as >>= 1, unit++)
491: if (as & 1) {
492: ui = rkip[rk11][unit];
493: if (ui) {
494: rkustart(rkip[rk11][unit]);
495: } else {
496: rkaddr->rkcs1 = RK_CCLR;
497: rkaddr->rkcs2 = unit;
498: rkaddr->rkcs1 = RK_DCLR|RK_GO;
499: rkwait(rkaddr);
500: rkaddr->rkcs1 = RK_CCLR;
501: }
502: }
503: if (um->um_tab.b_actf && um->um_tab.b_active == 0)
504: rkstart(um);
505: if (((rkaddr->rkcs1) & RK_IE) == 0)
506: rkaddr->rkcs1 = RK_IE;
507: }
508:
509: rkwait(addr)
510: register struct rkdevice *addr;
511: {
512:
513: while ((addr->rkcs1 & RK_CRDY) == 0)
514: ;
515: }
516:
517: rkread(dev, uio)
518: dev_t dev;
519: struct uio *uio;
520: {
521: register int unit = minor(dev) >> 3;
522:
523: if (unit >= NRK)
524: return (ENXIO);
525: return (physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys, uio));
526: }
527:
528: rkwrite(dev, uio)
529: dev_t dev;
530: struct uio *uio;
531: {
532: register int unit = minor(dev) >> 3;
533:
534: if (unit >= NRK)
535: return (ENXIO);
536: return (physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys, uio));
537: }
538:
539: rkecc(ui, flag)
540: register struct uba_device *ui;
541: {
542: register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr;
543: register struct buf *bp = rkutab[ui->ui_unit].b_actf;
544: register struct uba_ctlr *um = ui->ui_mi;
545: register struct rkst *st;
546: struct uba_regs *ubp = ui->ui_hd->uh_uba;
547: caddr_t addr;
548: int reg, npf, o, cmd, ubaddr;
549: int bn, cn, tn, sn;
550:
551: if (flag == CONT)
552: npf = bp->b_error;
553: else
554: npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount);
555: reg = btop(um->um_ubinfo&0x3ffff) + npf;
556: o = (int)bp->b_un.b_addr & PGOFSET;
557: bn = dkblock(bp);
558: st = &rkst[ui->ui_type];
559: cn = bp->b_cylin;
560: sn = bn%st->nspc + npf;
561: tn = sn/st->nsect;
562: sn %= st->nsect;
563: cn += tn/st->ntrak;
564: tn %= st->ntrak;
565: ubapurge(um);
566: switch (flag) {
567: case ECC:
568: {
569: register int i;
570: int bit, byte, mask;
571:
572: npf--;
573: reg--;
574: printf("rk%d%c: soft ecc sn%d\n", dkunit(bp),
575: 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
576: mask = rk->rkec2;
577: i = rk->rkec1 - 1; /* -1 makes 0 origin */
578: bit = i&07;
579: i = (i&~07)>>3;
580: byte = i + o;
581: while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
582: addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
583: (byte & PGOFSET);
584: putmemc(addr, getmemc(addr)^(mask<<bit));
585: byte++;
586: i++;
587: bit -= 8;
588: }
589: if (rk->rkwc == 0) {
590: um->um_tab.b_active = 0;
591: return (0);
592: }
593: npf++;
594: reg++;
595: break;
596: }
597:
598: case BSE:
599: #ifdef RKBDEBUG
600: if (rkbdebug)
601: printf("rkecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);
602: #endif
603: if ((bn = isbad(&rkbad[ui->ui_unit], cn, tn, sn)) < 0)
604: return(0);
605: bp->b_flags |= B_BAD;
606: bp->b_error = npf + 1;
607: bn = st->ncyl*st->nspc - st->nsect - 1 - bn;
608: cn = bn/st->nspc;
609: sn = bn%st->nspc;
610: tn = sn/st->nsect;
611: sn %= st->nsect;
612: #ifdef RKBDEBUG
613: if (rkbdebug)
614: printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
615: #endif
616: rk->rkwc = -(512 / sizeof (short));
617: break;
618:
619: case CONT:
620: #ifdef RKBDEBUG
621: if (rkbdebug)
622: printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn);
623: #endif
624: bp->b_flags &= ~B_BAD;
625: rk->rkwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof (short));
626: if (rk->rkwc == 0)
627: return (0);
628: break;
629: }
630: rk->rkcs1 = RK_CCLR;
631: rk->rkcs2 = ui->ui_slave;
632: rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
633: rkwait(rk);
634: rk->rkcyl = cn;
635: rk->rkda = (tn << 8) | sn;
636: ubaddr = (int)ptob(reg) + o;
637: rk->rkba = ubaddr;
638: cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO;
639: cmd |= (ubaddr >> 8) & 0x300;
640: cmd |= rktypes[ui->ui_type];
641: rk->rkcs1 = cmd;
642: um->um_tab.b_active = 2; /* continuing */
643: um->um_tab.b_errcnt = 0; /* error has been corrected */
644: return (1);
645: }
646:
647: rkreset(uban)
648: int uban;
649: {
650: register struct uba_ctlr *um;
651: register struct uba_device *ui;
652: register rk11, unit;
653:
654: for (rk11 = 0; rk11 < NHK; rk11++) {
655: if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban ||
656: um->um_alive == 0)
657: continue;
658: printf(" hk%d", rk11);
659: um->um_tab.b_active = 0;
660: um->um_tab.b_actf = um->um_tab.b_actl = 0;
661: rk_softc[um->um_ctlr].sc_recal = 0;
662: rk_softc[um->um_ctlr].sc_wticks = 0;
663: if (um->um_ubinfo) {
664: printf("<%d>", (um->um_ubinfo>>28)&0xf);
665: um->um_ubinfo = 0;
666: }
667: for (unit = 0; unit < NRK; unit++) {
668: if ((ui = rkdinfo[unit]) == 0)
669: continue;
670: if (ui->ui_alive == 0 || ui->ui_mi != um)
671: continue;
672: rkutab[unit].b_active = 0;
673: (void) rkustart(ui);
674: }
675: (void) rkstart(um);
676: }
677: }
678:
679: rkwatch()
680: {
681: register struct uba_ctlr *um;
682: register rk11, unit;
683: register struct rk_softc *sc;
684:
685: timeout(rkwatch, (caddr_t)0, hz);
686: for (rk11 = 0; rk11 < NHK; rk11++) {
687: um = rkminfo[rk11];
688: if (um == 0 || um->um_alive == 0)
689: continue;
690: sc = &rk_softc[rk11];
691: if (um->um_tab.b_active == 0) {
692: for (unit = 0; unit < NRK; unit++)
693: if (rkutab[unit].b_active &&
694: rkdinfo[unit]->ui_mi == um)
695: goto active;
696: sc->sc_wticks = 0;
697: continue;
698: }
699: active:
700: sc->sc_wticks++;
701: if (sc->sc_wticks >= 20) {
702: sc->sc_wticks = 0;
703: printf("hk%d: lost interrupt\n", rk11);
704: ubareset(um->um_ubanum);
705: }
706: }
707: }
708:
709: #define DBSIZE 20
710:
711: rkdump(dev)
712: dev_t dev;
713: {
714: struct rkdevice *rkaddr;
715: char *start;
716: int num, blk, unit;
717: struct size *sizes;
718: register struct uba_regs *uba;
719: register struct uba_device *ui;
720: register short *rp;
721: struct rkst *st;
722:
723: unit = minor(dev) >> 3;
724: if (unit >= NRK)
725: return (ENXIO);
726: #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
727: ui = phys(struct uba_device *, rkdinfo[unit]);
728: if (ui->ui_alive == 0)
729: return (ENXIO);
730: uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
731: ubainit(uba);
732: rkaddr = (struct rkdevice *)ui->ui_physaddr;
733: num = maxfree;
734: start = 0;
735: rkaddr->rkcs1 = RK_CCLR;
736: rkaddr->rkcs2 = unit;
737: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
738: rkwait(rkaddr);
739: if ((rkaddr->rkds & RKDS_VV) == 0) {
740: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO;
741: rkwait(rkaddr);
742: }
743: st = &rkst[ui->ui_type];
744: sizes = phys(struct size *, st->sizes);
745: if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks)
746: return (EINVAL);
747: while (num > 0) {
748: register struct pte *io;
749: register int i;
750: int cn, sn, tn;
751: daddr_t bn;
752:
753: blk = num > DBSIZE ? DBSIZE : num;
754: io = uba->uba_map;
755: for (i = 0; i < blk; i++)
756: *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV;
757: *(int *)io = 0;
758: bn = dumplo + btop(start);
759: cn = bn/st->nspc + sizes[minor(dev)&07].cyloff;
760: sn = bn%st->nspc;
761: tn = sn/st->nsect;
762: sn = sn%st->nsect;
763: rkaddr->rkcyl = cn;
764: rp = (short *) &rkaddr->rkda;
765: *rp = (tn << 8) + sn;
766: *--rp = 0;
767: *--rp = -blk*NBPG / sizeof (short);
768: *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE;
769: rkwait(rkaddr);
770: if (rkaddr->rkcs1 & RK_CERR)
771: return (EIO);
772: start += blk*NBPG;
773: num -= blk;
774: }
775: return (0);
776: }
777:
778: rksize(dev)
779: dev_t dev;
780: {
781: int unit = minor(dev) >> 3;
782: struct uba_device *ui;
783: struct rkst *st;
784:
785: if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0)
786: return (-1);
787: st = &rkst[ui->ui_type];
788: return (st->sizes[minor(dev) & 07].nblocks);
789: }
790: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.