xref: /original-bsd/sys/vax/uba/up.c (revision 3c32e3a3)
1 /*	up.c	4.73	83/05/18	*/
2 
3 #include "up.h"
4 #if NSC > 0
5 /*
6  * UNIBUS disk driver with:
7  *	overlapped seeks,
8  *	ECC recovery, and
9  *	bad sector forwarding.
10  *
11  * TODO:
12  *	Check that offset recovery code works
13  */
14 #include "../machine/pte.h"
15 
16 #include "../h/param.h"
17 #include "../h/systm.h"
18 #include "../h/dk.h"
19 #include "../h/dkbad.h"
20 #include "../h/buf.h"
21 #include "../h/conf.h"
22 #include "../h/dir.h"
23 #include "../h/user.h"
24 #include "../h/map.h"
25 #include "../h/vm.h"
26 #include "../h/cmap.h"
27 #include "../h/uio.h"
28 #include "../h/kernel.h"
29 
30 #include "../vax/cpu.h"
31 #include "../vax/nexus.h"
32 #include "../vaxuba/ubavar.h"
33 #include "../vaxuba/ubareg.h"
34 #include "../vaxuba/upreg.h"
35 
36 struct	up_softc {
37 	int	sc_softas;
38 	int	sc_ndrive;
39 	int	sc_wticks;
40 	int	sc_recal;
41 } up_softc[NSC];
42 
43 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
44 struct	size {
45 	daddr_t	nblocks;
46 	int	cyloff;
47 } up9300_sizes[8] = {
48 	15884,	0,		/* A=cyl 0 thru 26 */
49 	33440,	27,		/* B=cyl 27 thru 81 */
50 	495520,	0,		/* C=cyl 0 thru 814 */
51 	15884,	562,		/* D=cyl 562 thru 588 */
52 	55936,	589,		/* E=cyl 589 thru 680 */
53 	81376,	681,		/* F=cyl 681 thru 814 */
54 	153728,	562,		/* G=cyl 562 thru 814 */
55 	291346,	82,		/* H=cyl 82 thru 561 */
56 }, up9766_sizes[8] = {
57 	15884,	0,		/* A=cyl 0 thru 26 */
58 	33440,	27,		/* B=cyl 27 thru 81 */
59 	500384,	0,		/* C=cyl 0 thru 822 */
60 	15884,	562,		/* D=cyl 562 thru 588 */
61 	55936,	589,		/* E=cyl 589 thru 680 */
62 	86240,	681,		/* F=cyl 681 thru 822 */
63 	158592,	562,		/* G=cyl 562 thru 822 */
64 	291346,	82,		/* H=cyl 82 thru 561 */
65 }, up160_sizes[8] = {
66 	15884,	0,		/* A=cyl 0 thru 49 */
67 	33440,	50,		/* B=cyl 50 thru 154 */
68 	263360,	0,		/* C=cyl 0 thru 822 */
69 	15884,	155,		/* D=cyl 155 thru 204 */
70 	55936,	205,		/* E=cyl 205 thru 379 */
71 	141664,	380,		/* F=cyl 380 thru 822 */
72 	213664,	155,		/* G=cyl 155 thru 822 */
73 	0,	0,
74 }, upam_sizes[8] = {
75 	15884,	0,		/* A=cyl 0 thru 31 */
76 	33440,	32,		/* B=cyl 32 thru 97 */
77 	524288,	0,		/* C=cyl 0 thru 1023 */
78 	15884,	668,		/* D=cyl 668 thru 699 */
79 	55936,	700,		/* E=cyl 700 thru 809 */
80 	109472,	810,		/* F=cyl 810 thru 1023 */
81 	182176,	668,		/* G=cyl 668 thru 1023 */
82 	291346,	98,		/* H=cyl 98 thru 667 */
83 };
84 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
85 
86 /*
87  * On a 780 upSDIST could be 2, but
88  * in the interest of 750's...
89  */
90 #define	_upSDIST	3		/* 1.5 msec */
91 #define	_upRDIST	4		/* 2.0 msec */
92 
93 int	upSDIST = _upSDIST;
94 int	upRDIST = _upRDIST;
95 
96 int	upprobe(), upslave(), upattach(), updgo(), upintr();
97 struct	uba_ctlr *upminfo[NSC];
98 struct	uba_device *updinfo[NUP];
99 #define	UPIPUNITS	8
100 struct	uba_device *upip[NSC][UPIPUNITS]; /* fuji w/fixed head gives n,n+4 */
101 
102 u_short	upstd[] = { 0776700, 0774400, 0776300, 0 };
103 struct	uba_driver scdriver =
104     { upprobe, upslave, upattach, updgo, upstd, "up", updinfo, "sc", upminfo };
105 struct	buf	uputab[NUP];
106 char upinit[NUP];
107 
108 struct	upst {
109 	short	nsect;
110 	short	ntrak;
111 	short	nspc;
112 	short	ncyl;
113 	struct	size *sizes;
114 } upst[] = {
115 	32,	19,	32*19,	815,	up9300_sizes,	/* 9300 */
116 	32,	19,	32*19,	823,	up9766_sizes,	/* 9766 */
117 	32,	10,	32*10,	823,	up160_sizes,	/* fujitsu 160m */
118 	32,	16,	32*16,	1024,	upam_sizes,	/* ampex capricorn */
119 	0,	0,	0,	0,	0
120 };
121 
122 u_char	up_offset[16] = {
123 	UPOF_P400, UPOF_M400, UPOF_P400, UPOF_M400,
124 	UPOF_P800, UPOF_M800, UPOF_P800, UPOF_M800,
125 	UPOF_P1200, UPOF_M1200, UPOF_P1200, UPOF_M1200,
126 	0, 0, 0, 0
127 };
128 
129 struct	buf	rupbuf[NUP];
130 struct 	buf	bupbuf[NUP];
131 struct	dkbad	upbad[NUP];
132 
133 #define	b_cylin b_resid
134 
135 #ifdef INTRLVE
136 daddr_t dkblock();
137 #endif
138 
139 int	upwstart, upwatch();		/* Have started guardian */
140 int	upseek;
141 int	upwaitdry;
142 
143 /*ARGSUSED*/
144 upprobe(reg)
145 	caddr_t reg;
146 {
147 	register int br, cvec;
148 
149 #ifdef lint
150 	br = 0; cvec = br; br = cvec;
151 #endif
152 	((struct updevice *)reg)->upcs1 = UP_IE|UP_RDY;
153 	DELAY(10);
154 	((struct updevice *)reg)->upcs1 = 0;
155 	return (sizeof (struct updevice));
156 }
157 
158 upslave(ui, reg)
159 	struct uba_device *ui;
160 	caddr_t reg;
161 {
162 	register struct updevice *upaddr = (struct updevice *)reg;
163 
164 	upaddr->upcs1 = 0;		/* conservative */
165 	upaddr->upcs2 = ui->ui_slave;
166 	upaddr->upcs1 = UP_NOP|UP_GO;
167 	if (upaddr->upcs2&UPCS2_NED) {
168 		upaddr->upcs1 = UP_DCLR|UP_GO;
169 		return (0);
170 	}
171 	return (1);
172 }
173 
174 upattach(ui)
175 	register struct uba_device *ui;
176 {
177 
178 	if (upwstart == 0) {
179 		timeout(upwatch, (caddr_t)0, hz);
180 		upwstart++;
181 	}
182 	if (ui->ui_dk >= 0)
183 		dk_mspw[ui->ui_dk] = .0000020345;
184 	upip[ui->ui_ctlr][ui->ui_slave] = ui;
185 	up_softc[ui->ui_ctlr].sc_ndrive++;
186 	ui->ui_type = upmaptype(ui);
187 }
188 
189 upmaptype(ui)
190 	register struct uba_device *ui;
191 {
192 	register struct updevice *upaddr = (struct updevice *)ui->ui_addr;
193 	int type = ui->ui_type;
194 	register struct upst *st;
195 
196 	upaddr->upcs1 = 0;
197 	upaddr->upcs2 = ui->ui_slave;
198 	upaddr->uphr = UPHR_MAXTRAK;
199 	for (st = upst; st->nsect != 0; st++)
200 		if (upaddr->uphr == st->ntrak - 1) {
201 			type = st - upst;
202 			break;
203 		}
204 	if (st->nsect == 0)
205 		printf("up%d: uphr=%x\n", ui->ui_slave, upaddr->uphr);
206 	if (type == 0) {
207 		upaddr->uphr = UPHR_MAXCYL;
208 		if (upaddr->uphr == 822)
209 			type++;
210 	}
211 	upaddr->upcs2 = UPCS2_CLR;
212 	return (type);
213 }
214 
215 upopen(dev)
216 	dev_t dev;
217 {
218 	register int unit = minor(dev) >> 3;
219 	register struct uba_device *ui;
220 
221 	if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0)
222 		return (ENXIO);
223 	return (0);
224 }
225 
226 upstrategy(bp)
227 	register struct buf *bp;
228 {
229 	register struct uba_device *ui;
230 	register struct upst *st;
231 	register int unit;
232 	register struct buf *dp;
233 	int xunit = minor(bp->b_dev) & 07;
234 	long bn, sz;
235 
236 	sz = (bp->b_bcount+511) >> 9;
237 	unit = dkunit(bp);
238 	if (unit >= NUP)
239 		goto bad;
240 	ui = updinfo[unit];
241 	if (ui == 0 || ui->ui_alive == 0)
242 		goto bad;
243 	st = &upst[ui->ui_type];
244 	if (bp->b_blkno < 0 ||
245 	    (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks)
246 		goto bad;
247 	bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
248 	(void) spl5();
249 	dp = &uputab[ui->ui_unit];
250 	disksort(dp, bp);
251 	if (dp->b_active == 0) {
252 		(void) upustart(ui);
253 		bp = &ui->ui_mi->um_tab;
254 		if (bp->b_actf && bp->b_active == 0)
255 			(void) upstart(ui->ui_mi);
256 	}
257 	(void) spl0();
258 	return;
259 
260 bad:
261 	bp->b_flags |= B_ERROR;
262 	iodone(bp);
263 	return;
264 }
265 
266 /*
267  * Unit start routine.
268  * Seek the drive to be where the data is
269  * and then generate another interrupt
270  * to actually start the transfer.
271  * If there is only one drive on the controller,
272  * or we are very close to the data, don't
273  * bother with the search.  If called after
274  * searching once, don't bother to look where
275  * we are, just queue for transfer (to avoid
276  * positioning forever without transferrring.)
277  */
278 upustart(ui)
279 	register struct uba_device *ui;
280 {
281 	register struct buf *bp, *dp;
282 	register struct uba_ctlr *um;
283 	register struct updevice *upaddr;
284 	register struct upst *st;
285 	daddr_t bn;
286 	int sn, csn;
287 	/*
288 	 * The SC21 cancels commands if you just say
289 	 *	cs1 = UP_IE
290 	 * so we are cautious about handling of cs1.
291 	 * Also don't bother to clear as bits other than in upintr().
292 	 */
293 	int didie = 0;
294 
295 	if (ui == 0)
296 		return (0);
297 	um = ui->ui_mi;
298 	dk_busy &= ~(1<<ui->ui_dk);
299 	dp = &uputab[ui->ui_unit];
300 	if ((bp = dp->b_actf) == NULL)
301 		goto out;
302 	/*
303 	 * If the controller is active, just remember
304 	 * that this device would like to be positioned...
305 	 * if we tried to position now we would confuse the SC21.
306 	 */
307 	if (um->um_tab.b_active) {
308 		up_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave;
309 		return (0);
310 	}
311 	/*
312 	 * If we have already positioned this drive,
313 	 * then just put it on the ready queue.
314 	 */
315 	if (dp->b_active)
316 		goto done;
317 	dp->b_active = 1;
318 	upaddr = (struct updevice *)um->um_addr;
319 	upaddr->upcs2 = ui->ui_slave;
320 	/*
321 	 * If drive has just come up,
322 	 * setup the pack.
323 	 */
324 	if ((upaddr->upds & UPDS_VV) == 0 || upinit[ui->ui_unit] == 0) {
325 		struct buf *bbp = &bupbuf[ui->ui_unit];
326 
327 		/* SHOULD WARN SYSTEM THAT THIS HAPPENED */
328 		upinit[ui->ui_unit] = 1;
329 		upaddr->upcs1 = UP_IE|UP_DCLR|UP_GO;
330 		upaddr->upcs1 = UP_IE|UP_PRESET|UP_GO;
331 		upaddr->upof = UPOF_FMT22;
332 		didie = 1;
333 		st = &upst[ui->ui_type];
334 		bbp->b_flags = B_READ|B_BUSY;
335 		bbp->b_dev = bp->b_dev;
336 		bbp->b_bcount = 512;
337 		bbp->b_un.b_addr = (caddr_t)&upbad[ui->ui_unit];
338 		bbp->b_blkno = st->ncyl * st->nspc - st->nsect;
339 		bbp->b_cylin = st->ncyl - 1;
340 		dp->b_actf = bbp;
341 		bbp->av_forw = bp;
342 		bp = bbp;
343 	}
344 	/*
345 	 * If drive is offline, forget about positioning.
346 	 */
347 	if ((upaddr->upds & (UPDS_DPR|UPDS_MOL)) != (UPDS_DPR|UPDS_MOL))
348 		goto done;
349 	/*
350 	 * If there is only one drive,
351 	 * dont bother searching.
352 	 */
353 	if (up_softc[um->um_ctlr].sc_ndrive == 1)
354 		goto done;
355 	/*
356 	 * Figure out where this transfer is going to
357 	 * and see if we are close enough to justify not searching.
358 	 */
359 	st = &upst[ui->ui_type];
360 	bn = dkblock(bp);
361 	sn = bn%st->nspc;
362 	sn = (sn + st->nsect - upSDIST) % st->nsect;
363 	if (bp->b_cylin - upaddr->updc)
364 		goto search;		/* Not on-cylinder */
365 	else if (upseek)
366 		goto done;		/* Ok just to be on-cylinder */
367 	csn = (upaddr->upla>>6) - sn - 1;
368 	if (csn < 0)
369 		csn += st->nsect;
370 	if (csn > st->nsect - upRDIST)
371 		goto done;
372 search:
373 	upaddr->updc = bp->b_cylin;
374 	/*
375 	 * Not on cylinder at correct position,
376 	 * seek/search.
377 	 */
378 	if (upseek)
379 		upaddr->upcs1 = UP_IE|UP_SEEK|UP_GO;
380 	else {
381 		upaddr->upda = sn;
382 		upaddr->upcs1 = UP_IE|UP_SEARCH|UP_GO;
383 	}
384 	didie = 1;
385 	/*
386 	 * Mark unit busy for iostat.
387 	 */
388 	if (ui->ui_dk >= 0) {
389 		dk_busy |= 1<<ui->ui_dk;
390 		dk_seek[ui->ui_dk]++;
391 	}
392 	goto out;
393 done:
394 	/*
395 	 * Device is ready to go.
396 	 * Put it on the ready queue for the controller
397 	 * (unless its already there.)
398 	 */
399 	if (dp->b_active != 2) {
400 		dp->b_forw = NULL;
401 		if (um->um_tab.b_actf == NULL)
402 			um->um_tab.b_actf = dp;
403 		else
404 			um->um_tab.b_actl->b_forw = dp;
405 		um->um_tab.b_actl = dp;
406 		dp->b_active = 2;
407 	}
408 out:
409 	return (didie);
410 }
411 
412 /*
413  * Start up a transfer on a drive.
414  */
415 upstart(um)
416 	register struct uba_ctlr *um;
417 {
418 	register struct buf *bp, *dp;
419 	register struct uba_device *ui;
420 	register struct updevice *upaddr;
421 	struct upst *st;
422 	daddr_t bn;
423 	int dn, sn, tn, cmd, waitdry;
424 
425 loop:
426 	/*
427 	 * Pull a request off the controller queue
428 	 */
429 	if ((dp = um->um_tab.b_actf) == NULL)
430 		return (0);
431 	if ((bp = dp->b_actf) == NULL) {
432 		um->um_tab.b_actf = dp->b_forw;
433 		goto loop;
434 	}
435 	/*
436 	 * Mark controller busy, and
437 	 * determine destination of this request.
438 	 */
439 	um->um_tab.b_active++;
440 	ui = updinfo[dkunit(bp)];
441 	bn = dkblock(bp);
442 	dn = ui->ui_slave;
443 	st = &upst[ui->ui_type];
444 	sn = bn%st->nspc;
445 	tn = sn/st->nsect;
446 	sn %= st->nsect;
447 	upaddr = (struct updevice *)ui->ui_addr;
448 	/*
449 	 * Select drive if not selected already.
450 	 */
451 	if ((upaddr->upcs2&07) != dn)
452 		upaddr->upcs2 = dn;
453 	/*
454 	 * Check that it is ready and online
455 	 */
456 	waitdry = 0;
457 	while ((upaddr->upds&UPDS_DRY) == 0) {
458 		printf("up%d: ds wait ds=%o\n",dkunit(bp),upaddr->upds);
459 		if (++waitdry > 512)
460 			break;
461 		upwaitdry++;
462 	}
463 	if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
464 		printf("up%d: not ready", dkunit(bp));
465 		if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
466 			printf("\n");
467 			um->um_tab.b_active = 0;
468 			um->um_tab.b_errcnt = 0;
469 			dp->b_actf = bp->av_forw;
470 			dp->b_active = 0;
471 			bp->b_flags |= B_ERROR;
472 			iodone(bp);
473 			goto loop;
474 		}
475 		/*
476 		 * Oh, well, sometimes this
477 		 * happens, for reasons unknown.
478 		 */
479 		printf(" (flakey)\n");
480 	}
481 	/*
482 	 * Setup for the transfer, and get in the
483 	 * UNIBUS adaptor queue.
484 	 */
485 	upaddr->updc = bp->b_cylin;
486 	upaddr->upda = (tn << 8) + sn;
487 	upaddr->upwc = -bp->b_bcount / sizeof (short);
488 	if (bp->b_flags & B_READ)
489 		cmd = UP_IE|UP_RCOM|UP_GO;
490 	else
491 		cmd = UP_IE|UP_WCOM|UP_GO;
492 	um->um_cmd = cmd;
493 	(void) ubago(ui);
494 	return (1);
495 }
496 
497 /*
498  * Now all ready to go, stuff the registers.
499  */
500 updgo(um)
501 	struct uba_ctlr *um;
502 {
503 	register struct updevice *upaddr = (struct updevice *)um->um_addr;
504 
505 	um->um_tab.b_active = 2;	/* should now be 2 */
506 	upaddr->upba = um->um_ubinfo;
507 	upaddr->upcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300);
508 }
509 
510 /*
511  * Handle a disk interrupt.
512  */
513 upintr(sc21)
514 	register sc21;
515 {
516 	register struct buf *bp, *dp;
517 	register struct uba_ctlr *um = upminfo[sc21];
518 	register struct uba_device *ui;
519 	register struct updevice *upaddr = (struct updevice *)um->um_addr;
520 	register unit;
521 	struct up_softc *sc = &up_softc[um->um_ctlr];
522 	int as = (upaddr->upas & 0377) | sc->sc_softas;
523 	int needie = 1, waitdry;
524 
525 	sc->sc_wticks = 0;
526 	sc->sc_softas = 0;
527 	/*
528 	 * If controller wasn't transferring, then this is an
529 	 * interrupt for attention status on seeking drives.
530 	 * Just service them.
531 	 */
532 	if (um->um_tab.b_active != 2 && !sc->sc_recal) {
533 		if (upaddr->upcs1 & UP_TRE)
534 			upaddr->upcs1 = UP_TRE;
535 		goto doattn;
536 	}
537 	um->um_tab.b_active = 1;
538 	/*
539 	 * Get device and block structures, and a pointer
540 	 * to the uba_device for the drive.  Select the drive.
541 	 */
542 	dp = um->um_tab.b_actf;
543 	bp = dp->b_actf;
544 	ui = updinfo[dkunit(bp)];
545 	dk_busy &= ~(1 << ui->ui_dk);
546 	if ((upaddr->upcs2&07) != ui->ui_slave)
547 		upaddr->upcs2 = ui->ui_slave;
548 	if (bp->b_flags&B_BAD) {
549 		if (upecc(ui, CONT))
550 			return;
551 	}
552 	/*
553 	 * Check for and process errors on
554 	 * either the drive or the controller.
555 	 */
556 	if ((upaddr->upds&UPDS_ERR) || (upaddr->upcs1&UP_TRE)) {
557 		waitdry = 0;
558 		while ((upaddr->upds & UPDS_DRY) == 0) {
559 			if (++waitdry > 512)
560 				break;
561 			upwaitdry++;
562 		}
563 		if (upaddr->uper1&UPER1_WLE) {
564 			/*
565 			 * Give up on write locked devices
566 			 * immediately.
567 			 */
568 			printf("up%d: write locked\n", dkunit(bp));
569 			bp->b_flags |= B_ERROR;
570 		} else if (++um->um_tab.b_errcnt > 27) {
571 			/*
572 			 * After 28 retries (16 without offset, and
573 			 * 12 with offset positioning) give up.
574 			 * If the error was header CRC, the header is
575 			 * screwed up, and the sector may in fact exist
576 			 * in the bad sector table, better check...
577 			 */
578 			if (upaddr->uper1&UPER1_HCRC) {
579 				if (upecc(ui, BSE))
580 					return;
581 			}
582 	hard:
583 			harderr(bp, "up");
584 			printf("cn=%d tn=%d sn=%d cs2=%b er1=%b er2=%b\n",
585 			        upaddr->updc, ((upaddr->upda)>>8)&077,
586 			        (upaddr->upda)&037,
587 				upaddr->upcs2, UPCS2_BITS,
588 				upaddr->uper1, UPER1_BITS,
589 				upaddr->uper2, UPER2_BITS);
590 			bp->b_flags |= B_ERROR;
591 		} else if (upaddr->uper2 & UPER2_BSE) {
592 			if (upecc(ui, BSE))
593 				return;
594 			else
595 				goto hard;
596 		} else {
597 			/*
598 			 * Retriable error.
599 			 * If a soft ecc, correct it (continuing
600 			 * by returning if necessary.
601 			 * Otherwise fall through and retry the transfer
602 			 */
603 			if ((upaddr->uper1&(UPER1_DCK|UPER1_ECH))==UPER1_DCK) {
604 				if (upecc(ui, ECC))
605 					return;
606 			} else
607 				um->um_tab.b_active = 0; /* force retry */
608 		}
609 		/*
610 		 * Clear drive error and, every eight attempts,
611 		 * (starting with the fourth)
612 		 * recalibrate to clear the slate.
613 		 */
614 		upaddr->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO;
615 		needie = 0;
616 		if ((um->um_tab.b_errcnt&07) == 4 && um->um_tab.b_active == 0) {
617 			upaddr->upcs1 = UP_RECAL|UP_IE|UP_GO;
618 			sc->sc_recal = 0;
619 			goto nextrecal;
620 		}
621 	}
622 	/*
623 	 * Advance recalibration finite state machine
624 	 * if recalibrate in progress, through
625 	 *	RECAL
626 	 *	SEEK
627 	 *	OFFSET (optional)
628 	 *	RETRY
629 	 */
630 	switch (sc->sc_recal) {
631 
632 	case 1:
633 		upaddr->updc = bp->b_cylin;
634 		upaddr->upcs1 = UP_SEEK|UP_IE|UP_GO;
635 		goto nextrecal;
636 	case 2:
637 		if (um->um_tab.b_errcnt < 16 || (bp->b_flags&B_READ) == 0)
638 			goto donerecal;
639 		upaddr->upof = up_offset[um->um_tab.b_errcnt & 017] | UPOF_FMT22;
640 		upaddr->upcs1 = UP_IE|UP_OFFSET|UP_GO;
641 		goto nextrecal;
642 	nextrecal:
643 		sc->sc_recal++;
644 		um->um_tab.b_active = 1;
645 		return;
646 	donerecal:
647 	case 3:
648 		sc->sc_recal = 0;
649 		um->um_tab.b_active = 0;
650 		break;
651 	}
652 	/*
653 	 * If still ``active'', then don't need any more retries.
654 	 */
655 	if (um->um_tab.b_active) {
656 		/*
657 		 * If we were offset positioning,
658 		 * return to centerline.
659 		 */
660 		if (um->um_tab.b_errcnt >= 16) {
661 			upaddr->upof = UPOF_FMT22;
662 			upaddr->upcs1 = UP_RTC|UP_GO|UP_IE;
663 			while (upaddr->upds & UPDS_PIP)
664 				DELAY(25);
665 			needie = 0;
666 		}
667 		um->um_tab.b_active = 0;
668 		um->um_tab.b_errcnt = 0;
669 		um->um_tab.b_actf = dp->b_forw;
670 		dp->b_active = 0;
671 		dp->b_errcnt = 0;
672 		dp->b_actf = bp->av_forw;
673 		bp->b_resid = (-upaddr->upwc * sizeof(short));
674 		iodone(bp);
675 		/*
676 		 * If this unit has more work to do,
677 		 * then start it up right away.
678 		 */
679 		if (dp->b_actf)
680 			if (upustart(ui))
681 				needie = 0;
682 	}
683 	as &= ~(1<<ui->ui_slave);
684 	/*
685 	 * Release unibus resources and flush data paths.
686 	 */
687 	ubadone(um);
688 doattn:
689 	/*
690 	 * Process other units which need attention.
691 	 * For each unit which needs attention, call
692 	 * the unit start routine to place the slave
693 	 * on the controller device queue.
694 	 */
695 	while (unit = ffs(as)) {
696 		unit--;		/* was 1 origin */
697 		as &= ~(1<<unit);
698 		upaddr->upas = 1<<unit;
699 		if (unit < UPIPUNITS && upustart(upip[sc21][unit]))
700 			needie = 0;
701 	}
702 	/*
703 	 * If the controller is not transferring, but
704 	 * there are devices ready to transfer, start
705 	 * the controller.
706 	 */
707 	if (um->um_tab.b_actf && um->um_tab.b_active == 0)
708 		if (upstart(um))
709 			needie = 0;
710 	if (needie)
711 		upaddr->upcs1 = UP_IE;
712 }
713 
714 upread(dev, uio)
715 	dev_t dev;
716 	struct uio *uio;
717 {
718 	register int unit = minor(dev) >> 3;
719 
720 	if (unit >= NUP)
721 		return (ENXIO);
722 	return (physio(upstrategy, &rupbuf[unit], dev, B_READ, minphys, uio));
723 }
724 
725 upwrite(dev, uio)
726 	dev_t dev;
727 	struct uio *uio;
728 {
729 	register int unit = minor(dev) >> 3;
730 
731 	if (unit >= NUP)
732 		return (ENXIO);
733 	return (physio(upstrategy, &rupbuf[unit], dev, B_WRITE, minphys, uio));
734 }
735 
736 /*
737  * Correct an ECC error, and restart the i/o to complete
738  * the transfer if necessary.  This is quite complicated because
739  * the transfer may be going to an odd memory address base and/or
740  * across a page boundary.
741  */
742 upecc(ui, flag)
743 	register struct uba_device *ui;
744 	int flag;
745 {
746 	register struct updevice *up = (struct updevice *)ui->ui_addr;
747 	register struct buf *bp = uputab[ui->ui_unit].b_actf;
748 	register struct uba_ctlr *um = ui->ui_mi;
749 	register struct upst *st;
750 	struct uba_regs *ubp = ui->ui_hd->uh_uba;
751 	register int i;
752 	caddr_t addr;
753 	int reg, bit, byte, npf, mask, o, cmd, ubaddr;
754 	int bn, cn, tn, sn;
755 
756 	/*
757 	 * Npf is the number of sectors transferred before the sector
758 	 * containing the ECC error, and reg is the UBA register
759 	 * mapping (the first part of) the transfer.
760 	 * O is offset within a memory page of the first byte transferred.
761 	 */
762 	if (flag == CONT)
763 		npf = bp->b_error;
764 	else
765 		npf = btop((up->upwc * sizeof(short)) + bp->b_bcount);
766 	reg = btop(um->um_ubinfo&0x3ffff) + npf;
767 	o = (int)bp->b_un.b_addr & PGOFSET;
768 	mask = up->upec2;
769 #ifdef UPECCDEBUG
770 	printf("npf %d reg %x o %d mask %o pos %d\n", npf, reg, o, mask,
771 	    up->upec1);
772 #endif
773 	bn = dkblock(bp);
774 	st = &upst[ui->ui_type];
775 	cn = bp->b_cylin;
776 	sn = bn%st->nspc + npf;
777 	tn = sn/st->nsect;
778 	sn %= st->nsect;
779 	cn += tn/st->ntrak;
780 	tn %= st->ntrak;
781 	ubapurge(um);
782 	um->um_tab.b_active=2;
783 	/*
784 	 * action taken depends on the flag
785 	 */
786 	switch(flag){
787 	case ECC:
788 		npf--;
789 		reg--;
790 		mask = up->upec2;
791 		printf("up%d%c: soft ecc sn%d\n", dkunit(bp),
792 			'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
793 		/*
794 		 * Flush the buffered data path, and compute the
795 		 * byte and bit position of the error.  The variable i
796 		 * is the byte offset in the transfer, the variable byte
797 		 * is the offset from a page boundary in main memory.
798 		 */
799 		i = up->upec1 - 1;		/* -1 makes 0 origin */
800 		bit = i&07;
801 		i = (i&~07)>>3;
802 		byte = i + o;
803 		/*
804 		 * Correct while possible bits remain of mask.  Since mask
805 		 * contains 11 bits, we continue while the bit offset is > -11.
806 		 * Also watch out for end of this block and the end of the whole
807 		 * transfer.
808 		 */
809 		while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
810 			addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
811 				(byte & PGOFSET);
812 #ifdef UPECCDEBUG
813 			printf("addr %x map reg %x\n",
814 				addr, *(int *)(&ubp->uba_map[reg+btop(byte)]));
815 			printf("old: %x, ", getmemc(addr));
816 #endif
817 			putmemc(addr, getmemc(addr)^(mask<<bit));
818 #ifdef UPECCDEBUG
819 			printf("new: %x\n", getmemc(addr));
820 #endif
821 			byte++;
822 			i++;
823 			bit -= 8;
824 		}
825 		if (up->upwc == 0)
826 			return (0);
827 		npf++;
828 		reg++;
829 		break;
830 	case BSE:
831 		/*
832 		 * if not in bad sector table, return 0
833 		 */
834 		if ((bn = isbad(&upbad[ui->ui_unit], cn, tn, sn)) < 0)
835 			return(0);
836 		/*
837 		 * flag this one as bad
838 		 */
839 		bp->b_flags |= B_BAD;
840 		bp->b_error = npf + 1;
841 #ifdef UPECCDEBUG
842 		printf("BSE: restart at %d\n",npf+1);
843 #endif
844 		bn = st->ncyl * st->nspc -st->nsect - 1 - bn;
845 		cn = bn / st->nspc;
846 		sn = bn % st->nspc;
847 		tn = sn / st->nsect;
848 		sn %= st->nsect;
849 		up->upwc = -(512 / sizeof (short));
850 #ifdef UPECCDEBUG
851 		printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
852 #endif
853 		break;
854 	case CONT:
855 #ifdef UPECCDEBUG
856 		printf("upecc, CONT: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);
857 #endif
858 		bp->b_flags &= ~B_BAD;
859 		up->upwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof(short));
860 		if (up->upwc == 0)
861 			return(0);
862 		break;
863 	}
864 	if (up->upwc == 0) {
865 		um->um_tab.b_active = 0;
866 		return (0);
867 	}
868 	/*
869 	 * Have to continue the transfer... clear the drive,
870 	 * and compute the position where the transfer is to continue.
871 	 * We have completed npf+1 sectors of the transfer already;
872 	 * restart at offset o of next sector (i.e. in UBA register reg+1).
873 	 */
874 #ifdef notdef
875 	up->uper1 = 0;
876 	up->upcs1 |= UP_GO;
877 #else
878 	up->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO;
879 	up->updc = cn;
880 	up->upda = (tn << 8) | sn;
881 	ubaddr = (int)ptob(reg) + o;
882 	up->upba = ubaddr;
883 	cmd = (ubaddr >> 8) & 0x300;
884 	cmd |= ((bp->b_flags&B_READ)?UP_RCOM:UP_WCOM)|UP_IE|UP_GO;
885 	um->um_tab.b_errcnt = 0;
886 	up->upcs1 = cmd;
887 #endif
888 	return (1);
889 }
890 
891 /*
892  * Reset driver after UBA init.
893  * Cancel software state of all pending transfers
894  * and restart all units and the controller.
895  */
896 upreset(uban)
897 	int uban;
898 {
899 	register struct uba_ctlr *um;
900 	register struct uba_device *ui;
901 	register sc21, unit;
902 
903 	for (sc21 = 0; sc21 < NSC; sc21++) {
904 		if ((um = upminfo[sc21]) == 0 || um->um_ubanum != uban ||
905 		    um->um_alive == 0)
906 			continue;
907 		printf(" sc%d", sc21);
908 		um->um_tab.b_active = 0;
909 		um->um_tab.b_actf = um->um_tab.b_actl = 0;
910 		up_softc[sc21].sc_recal = 0;
911 		up_softc[sc21].sc_wticks = 0;
912 		if (um->um_ubinfo) {
913 			printf("<%d>", (um->um_ubinfo>>28)&0xf);
914 			um->um_ubinfo = 0;
915 		}
916 		((struct updevice *)(um->um_addr))->upcs2 = UPCS2_CLR;
917 		for (unit = 0; unit < NUP; unit++) {
918 			if ((ui = updinfo[unit]) == 0)
919 				continue;
920 			if (ui->ui_alive == 0 || ui->ui_mi != um)
921 				continue;
922 			uputab[unit].b_active = 0;
923 			(void) upustart(ui);
924 		}
925 		(void) upstart(um);
926 	}
927 }
928 
929 /*
930  * Wake up every second and if an interrupt is pending
931  * but nothing has happened increment a counter.
932  * If nothing happens for 20 seconds, reset the UNIBUS
933  * and begin anew.
934  */
935 upwatch()
936 {
937 	register struct uba_ctlr *um;
938 	register sc21, unit;
939 	register struct up_softc *sc;
940 
941 	timeout(upwatch, (caddr_t)0, hz);
942 	for (sc21 = 0; sc21 < NSC; sc21++) {
943 		um = upminfo[sc21];
944 		if (um == 0 || um->um_alive == 0)
945 			continue;
946 		sc = &up_softc[sc21];
947 		if (um->um_tab.b_active == 0) {
948 			for (unit = 0; unit < NUP; unit++)
949 				if (uputab[unit].b_active &&
950 				    updinfo[unit]->ui_mi == um)
951 					goto active;
952 			sc->sc_wticks = 0;
953 			continue;
954 		}
955 active:
956 		sc->sc_wticks++;
957 		if (sc->sc_wticks >= 20) {
958 			sc->sc_wticks = 0;
959 			printf("sc%d: lost interrupt\n", sc21);
960 			ubareset(um->um_ubanum);
961 		}
962 	}
963 }
964 
965 #define	DBSIZE	20
966 
967 updump(dev)
968 	dev_t dev;
969 {
970 	struct updevice *upaddr;
971 	char *start;
972 	int num, blk, unit;
973 	struct size *sizes;
974 	register struct uba_regs *uba;
975 	register struct uba_device *ui;
976 	register short *rp;
977 	struct upst *st;
978 	register int retry;
979 
980 	unit = minor(dev) >> 3;
981 	if (unit >= NUP)
982 		return (ENXIO);
983 #define	phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
984 	ui = phys(struct uba_device *, updinfo[unit]);
985 	if (ui->ui_alive == 0)
986 		return (ENXIO);
987 	uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
988 	ubainit(uba);
989 	upaddr = (struct updevice *)ui->ui_physaddr;
990 	DELAY(5000000);
991 	num = maxfree;
992 	upaddr->upcs2 = unit;
993 	DELAY(100);
994 	upaddr->upcs1 = UP_DCLR|UP_GO;
995 	upaddr->upcs1 = UP_PRESET|UP_GO;
996 	upaddr->upof = UPOF_FMT22;
997 	retry = 0;
998 	do {
999 		DELAY(25);
1000 		if (++retry > 527)
1001 			break;
1002 	} while ((upaddr->upds & UP_RDY) == 0);
1003 	if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY)
1004 		return (EFAULT);
1005 	start = 0;
1006 	st = &upst[ui->ui_type];
1007 	sizes = phys(struct size *, st->sizes);
1008 	if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks)
1009 		return (EINVAL);
1010 	while (num > 0) {
1011 		register struct pte *io;
1012 		register int i;
1013 		int cn, sn, tn;
1014 		daddr_t bn;
1015 
1016 		blk = num > DBSIZE ? DBSIZE : num;
1017 		io = uba->uba_map;
1018 		for (i = 0; i < blk; i++)
1019 			*(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV;
1020 		*(int *)io = 0;
1021 		bn = dumplo + btop(start);
1022 		cn = bn/st->nspc + sizes[minor(dev)&07].cyloff;
1023 		sn = bn%st->nspc;
1024 		tn = sn/st->nsect;
1025 		sn = sn%st->nsect;
1026 		upaddr->updc = cn;
1027 		rp = (short *) &upaddr->upda;
1028 		*rp = (tn << 8) + sn;
1029 		*--rp = 0;
1030 		*--rp = -blk*NBPG / sizeof (short);
1031 		*--rp = UP_GO|UP_WCOM;
1032 		retry = 0;
1033 		do {
1034 			DELAY(25);
1035 			if (++retry > 527)
1036 				break;
1037 		} while ((upaddr->upcs1 & UP_RDY) == 0);
1038 		if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
1039 			printf("up%d: not ready", unit);
1040 			if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
1041 				printf("\n");
1042 				return (EIO);
1043 			}
1044 			printf(" (flakey)\n");
1045 		}
1046 		if (upaddr->upds&UPDS_ERR)
1047 			return (EIO);
1048 		start += blk*NBPG;
1049 		num -= blk;
1050 	}
1051 	return (0);
1052 }
1053 
1054 upsize(dev)
1055 	dev_t dev;
1056 {
1057 	int unit = minor(dev) >> 3;
1058 	struct uba_device *ui;
1059 	struct upst *st;
1060 
1061 	if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0)
1062 		return (-1);
1063 	st = &upst[ui->ui_type];
1064 	return (st->sizes[minor(dev) & 07].nblocks);
1065 }
1066 #endif
1067