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