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