xref: /original-bsd/sys/vax/uba/rk.c (revision c8089215)
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.9 (Berkeley) 12/16/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 "../include/pte.h"
28 
29 #include "sys/param.h"
30 #include "sys/systm.h"
31 #include "sys/buf.h"
32 #include "sys/conf.h"
33 #include "sys/user.h"
34 #include "sys/map.h"
35 #include "sys/vm.h"
36 #include "sys/dkstat.h"
37 #include "sys/cmap.h"
38 #include "sys/dkbad.h"
39 #include "sys/ioctl.h"
40 #include "sys/disklabel.h"
41 #include "sys/uio.h"
42 #include "sys/kernel.h"
43 #include "sys/syslog.h"
44 
45 #include "../include/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
789