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