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