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