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