|
|
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.1 (Berkeley) 6/5/86
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 "dk.h"
38: #include "cmap.h"
39: #include "dkbad.h"
40: #include "uio.h"
41: #include "kernel.h"
42: #include "syslog.h"
43:
44: #include "../vax/cpu.h"
45: #include "ubareg.h"
46: #include "ubavar.h"
47: #include "rkreg.h"
48:
49: struct rk_softc {
50: int sc_softas;
51: int sc_ndrive;
52: int sc_wticks;
53: int sc_recal;
54: } rk_softc[NHK];
55:
56: #define rkunit(dev) (minor(dev) >> 3)
57:
58: /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
59: struct size {
60: daddr_t nblocks;
61: int cyloff;
62: } rk7_sizes[8] = {
63: 15884, 0, /* A=cyl 0 thru 240 */
64: 10032, 241, /* B=cyl 241 thru 392 */
65: 53790, 0, /* C=cyl 0 thru 814 */
66: 15884, 393, /* D=cyl 393 thru 633 */
67: 0, 0,
68: 11792, 634, /* F=cyl 634 thru 814 */
69: 27786, 393, /* G=cyl 393 thru 814, should be 27698 */
70: 0, 0,
71: }, rk6_sizes[8] ={
72: 15884, 0, /* A=cyl 0 thru 240 */
73: 11154, 241, /* B=cyl 241 thru 409 */
74: 27126, 0, /* C=cyl 0 thru 410 */
75: 0, 0,
76: 0, 0,
77: 0, 0,
78: 0, 0,
79: 0, 0,
80: };
81: /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
82:
83: short rktypes[] = { RK_CDT, 0 };
84:
85: int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr();
86: struct uba_ctlr *rkminfo[NHK];
87: struct uba_device *rkdinfo[NRK];
88: struct uba_device *rkip[NHK][4];
89:
90: u_short rkstd[] = { 0777440, 0 };
91: struct uba_driver hkdriver =
92: { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 };
93: struct buf rkutab[NRK];
94: short rkcyl[NRK];
95: struct dkbad rkbad[NRK];
96: struct buf brkbuf[NRK];
97:
98: struct rkst {
99: short nsect;
100: short ntrak;
101: short nspc;
102: short ncyl;
103: struct size *sizes;
104: } rkst[] = {
105: NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes,
106: NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK6CYL, rk6_sizes,
107: };
108:
109: u_char rk_offset[16] =
110: { RKAS_P400,RKAS_M400,RKAS_P400,RKAS_M400,RKAS_P800,RKAS_M800,RKAS_P800,
111: RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0
112: };
113:
114: struct buf rrkbuf[NRK];
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: harderr(bp, "rk");
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: rkread(dev, uio)
535: dev_t dev;
536: struct uio *uio;
537: {
538: register int unit = rkunit(dev);
539:
540: if (unit >= NRK)
541: return (ENXIO);
542: return (physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys, uio));
543: }
544:
545: rkwrite(dev, uio)
546: dev_t dev;
547: struct uio *uio;
548: {
549: register int unit = rkunit(dev);
550:
551: if (unit >= NRK)
552: return (ENXIO);
553: return (physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys, uio));
554: }
555:
556: rkecc(ui, flag)
557: register struct uba_device *ui;
558: {
559: register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr;
560: register struct buf *bp = rkutab[ui->ui_unit].b_actf;
561: register struct uba_ctlr *um = ui->ui_mi;
562: register struct rkst *st;
563: struct uba_regs *ubp = ui->ui_hd->uh_uba;
564: caddr_t addr;
565: int reg, npf, o, cmd, ubaddr;
566: int bn, cn, tn, sn;
567:
568: if (flag == CONT)
569: npf = bp->b_error;
570: else
571: npf = btodb(bp->b_bcount + (rk->rkwc * sizeof(short)) + 511);
572: reg = btop(um->um_ubinfo&0x3ffff) + npf;
573: o = (int)bp->b_un.b_addr & PGOFSET;
574: bn = bp->b_blkno;
575: st = &rkst[ui->ui_type];
576: cn = bp->b_cylin;
577: sn = bn%st->nspc + npf;
578: tn = sn/st->nsect;
579: sn %= st->nsect;
580: cn += tn/st->ntrak;
581: tn %= st->ntrak;
582: ubapurge(um);
583: switch (flag) {
584: case ECC:
585: {
586: register int i;
587: int bit, byte, mask;
588:
589: npf--;
590: reg--;
591: log(LOG_WARNING, "rk%d%c: soft ecc sn%d\n", rkunit(bp->b_dev),
592: 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
593: mask = rk->rkec2;
594: i = rk->rkec1 - 1; /* -1 makes 0 origin */
595: bit = i&07;
596: i = (i&~07)>>3;
597: byte = i + o;
598: while (i < 512 && (int)dbtob(npf)+i < bp->b_bcount && bit > -11) {
599: addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
600: (byte & PGOFSET);
601: putmemc(addr, getmemc(addr)^(mask<<bit));
602: byte++;
603: i++;
604: bit -= 8;
605: }
606: if (rk->rkwc == 0) {
607: um->um_tab.b_active = 0;
608: return (0);
609: }
610: npf++;
611: reg++;
612: break;
613: }
614:
615: case BSE:
616: #ifdef RKBDEBUG
617: if (rkbdebug)
618: printf("rkecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);
619: #endif
620: if ((bn = isbad(&rkbad[ui->ui_unit], cn, tn, sn)) < 0)
621: return(0);
622: bp->b_flags |= B_BAD;
623: bp->b_error = npf + 1;
624: bn = st->ncyl*st->nspc - st->nsect - 1 - bn;
625: cn = bn/st->nspc;
626: sn = bn%st->nspc;
627: tn = sn/st->nsect;
628: sn %= st->nsect;
629: #ifdef RKBDEBUG
630: if (rkbdebug)
631: printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
632: #endif
633: rk->rkwc = -(512 / sizeof (short));
634: break;
635:
636: case CONT:
637: #ifdef RKBDEBUG
638: if (rkbdebug)
639: printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn);
640: #endif
641: bp->b_flags &= ~B_BAD;
642: if ((int)dbtob(npf) >= bp->b_bcount)
643: return (0);
644: rk->rkwc = -((bp->b_bcount - (int)dbtob(npf)) / sizeof (short));
645: break;
646: }
647: rk->rkcs1 = RK_CCLR;
648: rk->rkcs2 = ui->ui_slave;
649: rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
650: rkwait(rk);
651: rk->rkcyl = cn;
652: rk->rkda = (tn << 8) | sn;
653: ubaddr = (int)ptob(reg) + o;
654: rk->rkba = ubaddr;
655: cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO;
656: cmd |= (ubaddr >> 8) & 0x300;
657: cmd |= rktypes[ui->ui_type];
658: rk->rkcs1 = cmd;
659: um->um_tab.b_active = 2; /* continuing */
660: um->um_tab.b_errcnt = 0; /* error has been corrected */
661: return (1);
662: }
663:
664: rkreset(uban)
665: int uban;
666: {
667: register struct uba_ctlr *um;
668: register struct uba_device *ui;
669: register rk11, unit;
670:
671: for (rk11 = 0; rk11 < NHK; rk11++) {
672: if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban ||
673: um->um_alive == 0)
674: continue;
675: printf(" hk%d", rk11);
676: um->um_tab.b_active = 0;
677: um->um_tab.b_actf = um->um_tab.b_actl = 0;
678: rk_softc[um->um_ctlr].sc_recal = 0;
679: rk_softc[um->um_ctlr].sc_wticks = 0;
680: if (um->um_ubinfo) {
681: printf("<%d>", (um->um_ubinfo>>28)&0xf);
682: um->um_ubinfo = 0;
683: }
684: for (unit = 0; unit < NRK; unit++) {
685: if ((ui = rkdinfo[unit]) == 0)
686: continue;
687: if (ui->ui_alive == 0 || ui->ui_mi != um)
688: continue;
689: rkutab[unit].b_active = 0;
690: (void) rkustart(ui);
691: }
692: (void) rkstart(um);
693: }
694: }
695:
696: rkwatch()
697: {
698: register struct uba_ctlr *um;
699: register rk11, unit;
700: register struct rk_softc *sc;
701:
702: timeout(rkwatch, (caddr_t)0, hz);
703: for (rk11 = 0; rk11 < NHK; rk11++) {
704: um = rkminfo[rk11];
705: if (um == 0 || um->um_alive == 0)
706: continue;
707: sc = &rk_softc[rk11];
708: if (um->um_tab.b_active == 0) {
709: for (unit = 0; unit < NRK; unit++)
710: if (rkutab[unit].b_active &&
711: rkdinfo[unit]->ui_mi == um)
712: goto active;
713: sc->sc_wticks = 0;
714: continue;
715: }
716: active:
717: sc->sc_wticks++;
718: if (sc->sc_wticks >= 20) {
719: sc->sc_wticks = 0;
720: printf("hk%d: lost interrupt\n", rk11);
721: ubareset(um->um_ubanum);
722: }
723: }
724: }
725:
726: #define DBSIZE 20
727:
728: rkdump(dev)
729: dev_t dev;
730: {
731: struct rkdevice *rkaddr;
732: char *start;
733: int num, blk, unit;
734: struct size *sizes;
735: register struct uba_regs *uba;
736: register struct uba_device *ui;
737: register short *rp;
738: struct rkst *st;
739:
740: unit = rkunit(dev);
741: if (unit >= NRK)
742: return (ENXIO);
743: #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
744: ui = phys(struct uba_device *, rkdinfo[unit]);
745: if (ui->ui_alive == 0)
746: return (ENXIO);
747: uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
748: ubainit(uba);
749: rkaddr = (struct rkdevice *)ui->ui_physaddr;
750: num = maxfree;
751: start = 0;
752: rkaddr->rkcs1 = RK_CCLR;
753: rkaddr->rkcs2 = unit;
754: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
755: rkwait(rkaddr);
756: if ((rkaddr->rkds & RKDS_VV) == 0) {
757: rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO;
758: rkwait(rkaddr);
759: }
760: st = &rkst[ui->ui_type];
761: sizes = phys(struct size *, st->sizes);
762: if (dumplo < 0)
763: return (EINVAL);
764: if (dumplo + num >= sizes[minor(dev)&07].nblocks)
765: num = sizes[minor(dev)&07].nblocks - dumplo;
766: while (num > 0) {
767: register struct pte *io;
768: register int i;
769: int cn, sn, tn;
770: daddr_t bn;
771:
772: blk = num > DBSIZE ? DBSIZE : num;
773: io = uba->uba_map;
774: for (i = 0; i < blk; i++)
775: *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV;
776: *(int *)io = 0;
777: bn = dumplo + btop(start);
778: cn = bn/st->nspc + sizes[minor(dev)&07].cyloff;
779: sn = bn%st->nspc;
780: tn = sn/st->nsect;
781: sn = sn%st->nsect;
782: rkaddr->rkcyl = cn;
783: rp = (short *) &rkaddr->rkda;
784: *rp = (tn << 8) + sn;
785: *--rp = 0;
786: *--rp = -blk*NBPG / sizeof (short);
787: *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE;
788: rkwait(rkaddr);
789: if (rkaddr->rkcs1 & RK_CERR)
790: return (EIO);
791: start += blk*NBPG;
792: num -= blk;
793: }
794: return (0);
795: }
796:
797: rksize(dev)
798: dev_t dev;
799: {
800: int unit = rkunit(dev);
801: struct uba_device *ui;
802: struct rkst *st;
803:
804: if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0)
805: return (-1);
806: st = &rkst[ui->ui_type];
807: return (st->sizes[minor(dev) & 07].nblocks);
808: }
809: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.