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