xref: /original-bsd/sys/vax/uba/up.c (revision d25e1985)
1 /*	up.c	3.24	09/27/80	*/
2 
3 /*
4  * UNIBUS disk driver with overlapped seeks and ECC recovery.
5  *
6  * This driver works marginally on an Emulex SC-11B controller with rev
7  * level J microcode, defining:
8  *	int	olducode = 1;
9  * to force CPU stalling delays.
10  *
11  * It has worked with no delays and no problems on a prototype
12  * SC-21 controller.  Emulex intends to upgrade all SC-11s on VAXes to SC-21s.
13  * You should get a SC-21 to replace any SC-11 on a VAX.
14  *
15  * SC-11B Controller switch settings:
16  *	SW1-1	5/19 surfaces	(off, 19 surfaces on Ampex 9300)
17  *	SW1-2	chksum enable	(off, checksum disabled)
18  *	SW1-3	volume select	(off, 815 cylinders)
19  *	SW1-4	sector select	(on, 32 sectors)
20  *	SW1-5	unused		(off)
21  *	SW1-6	port select	(on, single port)
22  *	SW1-7	npr delay	(off, disable)
23  *	SW1-8	ecc test mode	(off, disable)
24  * and top mounted switches:
25  *	SW2-1	extend opcodes	(off=open, disable)
26  *	SW2-2	extend diag	(off=open, disable)
27  *	SW2-3	4 wd dma burst	(on=closed, enable)
28  *	SW2-4	unused		(off=open)
29  */
30 
31 #include "../h/param.h"
32 #include "../h/systm.h"
33 #include "../h/dk.h"
34 #include "../h/buf.h"
35 #include "../h/conf.h"
36 #include "../h/dir.h"
37 #include "../h/user.h"
38 #include "../h/map.h"
39 #include "../h/pte.h"
40 #include "../h/mba.h"
41 #include "../h/mtpr.h"
42 #include "../h/uba.h"
43 #include "../h/vm.h"
44 
45 /*
46  * Define number of drives, and range of sampling information to be used.
47  *
48  * Normally, DK_N .. DK_N+NUP-1 gather individual drive stats,
49  * and DK_N+NUP gathers controller transferring stats.
50  *
51  * If DK_N+NUP > DK_NMAX, then transfer stats are divided per drive.
52  * If DK_NMAX is yet smaller, some drives are not monitored.
53  */
54 #define	DK_N	2
55 #define	DK_NMAX	3
56 
57 #define	ushort	unsigned short
58 
59 struct	device
60 {
61 	ushort	upcs1;		/* control and status register 1 */
62 	short	upwc;		/* word count register */
63 	ushort	upba;		/* UNIBUS address register */
64 	ushort	upda;		/* desired address register */
65 	ushort	upcs2;		/* control and status register 2 */
66 	ushort	upds;		/* drive Status */
67 	ushort	uper1;		/* error register 1 */
68 	ushort	upas;		/* attention summary */
69 	ushort	upla;		/* look ahead */
70 	ushort	updb;		/* data buffer */
71 	ushort	upmr;		/* maintenance */
72 	ushort	updt;		/* drive type */
73 	ushort	upsn;		/* serial number */
74 	ushort	upof;		/* offset register */
75 	ushort	updc;		/* desired cylinder address register */
76 	ushort	upcc;		/* current cylinder */
77 	ushort	uper2;		/* error register 2 */
78 	ushort	uper3;		/* error register 3 */
79 	ushort	upec1;		/* burst error bit position */
80 	ushort	upec2;		/* burst error bit pattern */
81 };
82 
83 /*
84  * Software extension to the upas register, so we can
85  * postpone starting SEARCH commands until the controller
86  * is not transferring.
87  */
88 int	upsoftas;
89 
90 /*
91  * If upseek then we don't issue SEARCH commands but rather just
92  * settle for a SEEK to the correct cylinder.
93  */
94 int	upseek;
95 
96 #define	UPADDR	((struct device *)(UBA0_DEV + 0176700))
97 
98 #define	NUP	2		/* Number of drives this installation */
99 
100 #define	NSECT	32
101 #define	NTRAC	19
102 
103 /*
104  * Constants controlling on-cylinder SEARCH usage.
105  *
106  * 	upSDIST/2 msec		time needed to start transfer
107  * 	upRDIST/2 msec		tolerable rotational latency when on-cylinder
108  *
109  * If we are no closer than upSDIST sectors and no further than upSDIST+upRDIST
110  * and in the driver then we take it as it is.  Otherwise we do a SEARCH
111  * requesting an interrupt upSDIST sectors in advance.
112  */
113 #define	_upSDIST	6		/* 3.0 msec */
114 #define	_upRDIST	6		/* 3.0 msec */
115 
116 int	upSDIST = _upSDIST;
117 int	upRDIST = _upRDIST;
118 
119 /*
120  * To fill a 300M drive:
121  *	A is designed to be used as a root.
122  *	B is suitable for a swap area.
123  *	H is the primary storage area.
124  * On systems with RP06'es, we normally use only 291346 blocks of the H
125  * area, and use DEF or G to cover the rest of the drive.  The C system
126  * covers the whole drive and can be used for pack-pack copying.
127  */
128 struct	size
129 {
130 	daddr_t	nblocks;
131 	int	cyloff;
132 } up_sizes[8] = {
133 	15884,	0,		/* A=cyl 0 thru 26 */
134 	33440,	27,		/* B=cyl 27 thru 81 */
135 	495520,	0,		/* C=cyl 0 thru 814 */
136 	15884,	562,		/* D=cyl 562 thru 588 */
137 	55936,	589,		/* E=cyl 589 thru 680 */
138 	81472,	681,		/* F=cyl 681 thru 814 */
139 	153824,	562,		/* G=cyl 562 thru 814 */
140 	445664,	82,		/* H=cyl 82 thru 814 */
141 /* Later, and more safely for H area...
142 	291346,	82,		/* H=cyl 82 thru 561 */
143 };
144 
145 /*
146  * The following defines are used in offset positioning
147  * when trying to recover disk errors, with the constants being
148  * +/- microinches.  Note that header compare inhibit (HCI) is not
149  * tried (this makes sense only during read, in any case.)
150  *
151  * NOT ALL OF THESE ARE IMPLEMENTED ON 9300!?!
152  */
153 #define	P400	020
154 #define	M400	0220
155 #define	P800	040
156 #define	M800	0240
157 #define	P1200	060
158 #define	M1200	0260
159 #define	HCI	020000
160 
161 int	up_offset[16] =
162 {
163 	P400, M400, P400, M400,
164 	P800, M800, P800, M800,
165 	P1200, M1200, P1200, M1200,
166 	0, 0, 0, 0,
167 };
168 
169 /*
170  * Each drive has a table uputab[i].  On this table are sorted the
171  * pending requests implementing an elevator algorithm (see dsort.c.)
172  * In the upustart() routine, each drive is independently advanced
173  * until it is on the desired cylinder for the next transfer and near
174  * the desired sector.  The drive is then chained onto the uptab
175  * table, and the transfer is initiated by the upstart() routine.
176  * When the transfer is completed the driver reinvokes the upustart()
177  * routine to set up the next transfer.
178  */
179 struct	buf	uptab;
180 struct	buf	uputab[NUP];
181 
182 struct	buf	rupbuf;			/* Buffer for raw i/o */
183 
184 /* Drive commands, placed in upcs1 */
185 #define	GO	01		/* Go bit, set in all commands */
186 #define	PRESET	020		/* Preset drive at init or after errors */
187 #define	OFFSET	014		/* Offset heads to try to recover error */
188 #define	RTC	016		/* Return to center-line after OFFSET */
189 #define	SEARCH	030		/* Search for cylinder+sector */
190 #define	SEEK	04		/* Seek to cylinder */
191 #define	RECAL	06		/* Recalibrate, needed after seek error */
192 #define	DCLR	010		/* Drive clear, after error */
193 #define	WCOM	060		/* Write */
194 #define	RCOM	070		/* Read */
195 
196 /* Other bits of upcs1 */
197 #define	IE	0100		/* Controller wide interrupt enable */
198 #define	TRE	040000		/* Transfer error */
199 #define	RDY	0200		/* Transfer terminated */
200 
201 /* Drive status bits of upds */
202 #define	PIP	020000		/* Positioning in progress */
203 #define	ERR	040000		/* Error has occurred, DCLR necessary */
204 #define	VV	0100		/* Volume is valid, set by PRESET */
205 #define	DPR	0400		/* Drive has been preset */
206 #define	MOL	010000		/* Drive is online, heads loaded, etc */
207 #define	DRY	0200		/* Drive ready */
208 
209 /* Bits of upcs2 */
210 #define	CLR	040		/* Controller clear */
211 /* Bits of uper1 */
212 #define	DCK	0100000		/* Ecc error occurred */
213 #define	ECH	0100		/* Ecc error was unrecoverable */
214 #define	WLE	04000		/* Attempt to write read-only drive */
215 
216 /* Bits of upof; the offset bits above are also in this register */
217 #define	FMT22	010000		/* 16 bits/word, must be always set */
218 
219 #define	b_cylin b_resid
220 
221 int	up_ubinfo;		/* Information about UBA usage saved here */
222 /*
223  * The EMULEX controller balks if accessed quickly after
224  * certain operations.  With rev J delays seem to be needed only
225  * when selecting a new unit, and in drive initialization type
226  * like PRESET and DCLR.  The following variables control the delay
227  * DELAY(n) is approximately n usec.
228  */
229 int	olducode = 1;
230 int	idelay = 500;		/* Delay after PRESET or DCLR */
231 int	osdelay = 150;		/* Old delay after selecting drive in upcs2 */
232 int	ordelay = 100;		/* Old delay after SEARCH */
233 int	oasdel = 100;		/* Old delay after clearing bit in upas */
234 int	nsdelay = 25;
235 
236 #define	DELAY(N)		{ register int d; d = N; while (--d > 0); }
237 
238 int	nwaitcs2;		/* How many sdelay loops ? */
239 int	neasycs2;		/* How many sdelay loops not needed ? */
240 
241 int	up_wticks;		/* Ticks waiting for interrupt */
242 int	upwstart;		/* Have started guardian */
243 int	upwatch();
244 
245 #ifdef INTRLVE
246 daddr_t dkblock();
247 #endif
248 
249 /*
250  * Queue an i/o request for a drive, checking first that it is in range.
251  *
252  * A unit start is issued if the drive is inactive, causing
253  * a SEARCH for the correct cylinder/sector.  If the drive is
254  * already nearly on the money and the controller is not transferring
255  * we kick it to start the transfer.
256  */
257 upstrategy(bp)
258 register struct buf *bp;
259 {
260 	register struct buf *dp;
261 	register unit, xunit;
262 	long sz, bn;
263 
264 	if (upwstart == 0) {
265 		timeout((caddr_t)upwatch, 0, HZ);
266 		upwstart++;
267 	}
268 	xunit = minor(bp->b_dev) & 077;
269 	sz = bp->b_bcount;
270 	sz = (sz+511) >> 9;		/* transfer size in 512 byte sectors */
271 	unit = dkunit(bp);
272 	if (unit >= NUP ||
273 	    bp->b_blkno < 0 ||
274 	    (bn = dkblock(bp))+sz > up_sizes[xunit&07].nblocks) {
275 		bp->b_flags |= B_ERROR;
276 		iodone(bp);
277 		return;
278 	}
279 	bp->b_cylin = bn/(NSECT*NTRAC) + up_sizes[xunit&07].cyloff;
280 	dp = &uputab[unit];
281 	(void) spl5();
282 	disksort(dp, bp);
283 	if (dp->b_active == 0) {
284 		(void) upustart(unit);
285 		if (uptab.b_actf && uptab.b_active == 0)
286 			(void) upstart();
287 	}
288 	(void) spl0();
289 }
290 
291 /*
292  * Start activity on specified drive; called when drive is inactive
293  * and new transfer request arrives and also when upas indicates that
294  * a SEARCH command is complete.
295  */
296 upustart(unit)
297 register unit;
298 {
299 	register struct buf *bp, *dp;
300 	register struct device *upaddr = UPADDR;
301 	daddr_t bn;
302 	int sn, cn, csn;
303 	int didie = 0;
304 
305 	/*
306 	 * Other drivers tend to say something like
307 	 *	upaddr->upcs1 = IE;
308 	 *	upaddr->upas = 1<<unit;
309 	 * here, but the SC-11B will cancel a command which
310 	 * happens to be sitting in the cs1 if you clear the go
311 	 * bit by storing there (so the first is not safe),
312 	 * and it also does not like being bothered with operations
313 	 * such as clearing upas when a transfer is active (as
314 	 * it may well be.)
315 	 *
316 	 * Thus we keep careful track of when we re-enable IE
317 	 * after an interrupt and do it only if we didn't issue
318 	 * a command which re-enabled it as a matter of course.
319 	 * We clear bits in upas in the interrupt routine, when
320 	 * no transfers are active.
321 	 */
322 	if (unit >= NUP)
323 		goto out;
324 	if (unit+DK_N <= DK_NMAX)
325 		dk_busy &= ~(1<<(unit+DK_N));
326 	dp = &uputab[unit];
327 	if ((bp = dp->b_actf) == NULL)
328 		goto out;
329 	/*
330 	 * The SC-11B doesn't start SEARCH commands when transfers are
331 	 * in progress.  In fact, it tends to get confused when given
332 	 * SEARCH'es during transfers, generating interrupts with neither
333 	 * RDY nor a bit in the upas register.  Thus we defer
334 	 * until an interrupt when a transfer is pending.
335 	 */
336 	if (uptab.b_active) {
337 		upsoftas |= 1<<unit;
338 		return (0);
339 	}
340 	if (dp->b_active)
341 		goto done;
342 	dp->b_active = 1;
343 	if ((upaddr->upcs2 & 07) != unit) {
344 		upaddr->upcs2 = unit;
345 		DELAY(olducode ? osdelay : nsdelay);
346 		nwaitcs2++;
347 	} else
348 		neasycs2++;
349 	/*
350 	 * If we have changed packs or just initialized,
351 	 * then the volume will not be valid; if so, clear
352 	 * the drive, preset it and put in 16bit/word mode.
353 	 */
354 	if ((upaddr->upds & VV) == 0) {
355 		upaddr->upcs1 = IE|DCLR|GO;
356 		DELAY(idelay);
357 		upaddr->upcs1 = IE|PRESET|GO;
358 		DELAY(idelay);
359 		upaddr->upof = FMT22;
360 		didie = 1;
361 	}
362 	if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL))
363 		goto done;
364 	/*
365 	 * Do enough of the disk address decoding to determine
366 	 * which cylinder and sector the request is on.
367 	 * If we are on the correct cylinder and the desired sector
368 	 * lies between upSDIST and upSDIST+upRDIST sectors ahead of us, then
369 	 * we don't bother to SEARCH but just begin the transfer asap.
370 	 * Otherwise ask for a interrupt upSDIST sectors ahead.
371 	 */
372 	bn = dkblock(bp);
373 	cn = bp->b_cylin;
374 	sn = bn%(NSECT*NTRAC);
375 	sn = (sn+NSECT-upSDIST)%NSECT;
376 
377 	if (cn - upaddr->updc)
378 		goto search;		/* Not on-cylinder */
379 	else if (upseek)
380 		goto done;		/* Ok just to be on-cylinder */
381 	csn = (upaddr->upla>>6) - sn - 1;
382 	if (csn < 0)
383 		csn += NSECT;
384 	if (csn > NSECT-upRDIST)
385 		goto done;
386 
387 search:
388 	upaddr->updc = cn;
389 	if (upseek)
390 		upaddr->upcs1 = IE|SEEK|GO;
391 	else {
392 		upaddr->upda = sn;
393 		upaddr->upcs1 = IE|SEARCH|GO;
394 	}
395 	didie = 1;
396 	/*
397 	 * Mark this unit busy.
398 	 */
399 	unit += DK_N;
400 	if (unit <= DK_NMAX && DK_N+NUP <= DK_NMAX) {
401 		dk_busy |= 1<<unit;
402 		dk_numb[unit]++;
403 	}
404 	if (olducode)
405 		DELAY(ordelay);
406 	goto out;
407 
408 done:
409 	/*
410 	 * This unit is ready to go so
411 	 * link it onto the chain of ready disks.
412 	 */
413 	dp->b_forw = NULL;
414 	if (uptab.b_actf == NULL)
415 		uptab.b_actf = dp;
416 	else
417 		uptab.b_actl->b_forw = dp;
418 	uptab.b_actl = dp;
419 
420 out:
421 	return (didie);
422 }
423 
424 /*
425  * Start a transfer; call from top level at spl5() or on interrupt.
426  */
427 upstart()
428 {
429 	register struct buf *bp, *dp;
430 	register unit;
431 	register struct device *upaddr;
432 	daddr_t bn;
433 	int dn, sn, tn, cn, cmd;
434 
435 loop:
436 	/*
437 	 * Pick a drive off the queue of ready drives, and
438 	 * perform the first transfer on its queue.
439 	 *
440 	 * Looping here is completely for the sake of drives which
441 	 * are not present and on-line, for which we completely clear the
442 	 * request queue.
443 	 */
444 	if ((dp = uptab.b_actf) == NULL)
445 		return (0);
446 	if ((bp = dp->b_actf) == NULL) {
447 		uptab.b_actf = dp->b_forw;
448 		goto loop;
449 	}
450 	/*
451 	 * Mark the controller busy, and multi-part disk address.
452 	 * Select the unit on which the i/o is to take place.
453 	 */
454 	uptab.b_active++;
455 	unit = minor(bp->b_dev) & 077;
456 	dn = dkunit(bp);
457 	bn = dkblock(bp);
458 	cn = up_sizes[unit&07].cyloff;
459 	cn += bn/(NSECT*NTRAC);
460 	sn = bn%(NSECT*NTRAC);
461 	tn = sn/NSECT;
462 	sn %= NSECT;
463 	upaddr = UPADDR;
464 	if ((upaddr->upcs2 & 07) != dn) {
465 		upaddr->upcs2 = dn;
466 		/* DELAY(sdelay);		Provided by ubasetup() */
467 		nwaitcs2++;
468 	} else
469 		neasycs2++;
470 	up_ubinfo = ubasetup(bp, 1);	/* Providing delay */
471 	/*
472 	 * If drive is not present and on-line, then
473 	 * get rid of this with an error and loop to get
474 	 * rid of the rest of its queued requests.
475 	 * (Then on to any other ready drives.)
476 	 */
477 	if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) {
478 		printf("!DPR || !MOL, unit %d, ds %o", dn, upaddr->upds);
479 		if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) {
480 			printf("-- hard\n");
481 			uptab.b_active = 0;
482 			uptab.b_errcnt = 0;
483 			dp->b_actf = bp->av_forw;
484 			dp->b_active = 0;
485 			bp->b_flags |= B_ERROR;
486 			iodone(bp);
487 			/* A funny place to do this ... */
488 			ubafree(up_ubinfo), up_ubinfo = 0;
489 			goto loop;
490 		}
491 		printf("-- came back\n");
492 	}
493 	/*
494 	 * If this is a retry, then with the 16'th retry we
495 	 * begin to try offsetting the heads to recover the data.
496 	 */
497 	if (uptab.b_errcnt >= 16 && (bp->b_flags&B_WRITE) == 0) {
498 		upaddr->upof = up_offset[uptab.b_errcnt & 017] | FMT22;
499 		upaddr->upcs1 = IE|OFFSET|GO;
500 		DELAY(idelay);
501 		while (upaddr->upds & PIP)
502 			DELAY(25);
503 	}
504 	/*
505 	 * Now set up the transfer, retrieving the high
506 	 * 2 bits of the UNIBUS address from the information
507 	 * returned by ubasetup() for the cs1 register bits 8 and 9.
508 	 */
509 	upaddr->updc = cn;
510 	upaddr->upda = (tn << 8) + sn;
511 	upaddr->upba = up_ubinfo;
512 	upaddr->upwc = -bp->b_bcount / sizeof (short);
513 	cmd = (up_ubinfo >> 8) & 0x300;
514 	if (bp->b_flags & B_READ)
515 		cmd |= IE|RCOM|GO;
516 	else
517 		cmd |= IE|WCOM|GO;
518 	upaddr->upcs1 = cmd;
519 	/*
520 	 * This is a controller busy situation.
521 	 * Record in dk slot NUP+DK_N (after last drive)
522 	 * unless there aren't that many slots reserved for
523 	 * us in which case we record this as a drive busy
524 	 * (if there is room for that).
525 	 */
526 	unit = dn+DK_N;
527 	if (NUP+DK_N == DK_NMAX)
528 		unit = NUP+DK_N;
529 	if (unit <= DK_NMAX) {
530 		dk_busy |= 1<<unit;
531 		dk_numb[unit]++;
532 		dk_wds[unit] += bp->b_bcount>>6;
533 	}
534 	return (1);
535 }
536 
537 /*
538  * Handle a device interrupt.
539  *
540  * If the transferring drive needs attention, service it
541  * retrying on error or beginning next transfer.
542  * Service all other ready drives, calling ustart to transfer
543  * their blocks to the ready queue in uptab, and then restart
544  * the controller if there is anything to do.
545  */
546 upintr()
547 {
548 	register struct buf *bp, *dp;
549 	register unit;
550 	register struct device *upaddr = UPADDR;
551 	int as = upaddr->upas & 0377;
552 	int oupsoftas;
553 	int needie = 1;
554 
555 	(void) spl6();
556 	up_wticks = 0;
557 	if (uptab.b_active) {
558 		/*
559 		 * The drive is transferring, thus the hardware
560 		 * (say the designers) will only interrupt when the transfer
561 		 * completes; check for it anyways.
562 		 */
563 		if ((upaddr->upcs1 & RDY) == 0) {
564 			printf("!RDY: cs1 %o, ds %o, wc %d\n", upaddr->upcs1,
565 			    upaddr->upds, upaddr->upwc);
566 			printf("as=%d act %d %d %d\n", as, uptab.b_active,
567 			    uputab[0].b_active, uputab[1].b_active);
568 		}
569 		/*
570 		 * Mark controller or drive not busy, and check for an
571 		 * error condition which may have resulted from the transfer.
572 		 */
573 		dp = uptab.b_actf;
574 		bp = dp->b_actf;
575 		unit = dkunit(bp);
576 		if (DK_N+NUP == DK_NMAX)
577 			dk_busy &= ~(1<<(DK_N+NUP));
578 		else if (DK_N+unit <= DK_NMAX)
579 			dk_busy &= ~(1<<(DK_N+unit));
580 		if ((upaddr->upcs2 & 07) != unit) {
581 			upaddr->upcs2 = unit;
582 			DELAY(olducode ? osdelay : nsdelay);
583 			nwaitcs2++;
584 		} else
585 			neasycs2++;
586 		if ((upaddr->upds&ERR) || (upaddr->upcs1&TRE)) {
587 			/*
588 			 * An error occurred, indeed.  Select this unit
589 			 * to get at the drive status (a SEARCH may have
590 			 * intervened to change the selected unit), and
591 			 * wait for the command which caused the interrupt
592 			 * to complete (DRY).
593 			 */
594 			while ((upaddr->upds & DRY) == 0)
595 				DELAY(25);
596 			/*
597 			 * After 28 retries (16 w/o servo offsets, and then
598 			 * 12 with servo offsets), or if we encountered
599 			 * an error because the drive is write-protected,
600 			 * give up.  Print an error message on the last 2
601 			 * retries before a hard failure.
602 			 */
603 			if (++uptab.b_errcnt > 28 || upaddr->uper1&WLE)
604 				bp->b_flags |= B_ERROR;
605 			else
606 				uptab.b_active = 0;	/* To force retry */
607 			if (uptab.b_errcnt > 27)
608 				deverror(bp, upaddr->upcs2, upaddr->uper1);
609 			/*
610 			 * If this was a correctible ECC error, let upecc
611 			 * do the dirty work to correct it.  If upecc
612 			 * starts another READ for the rest of the data
613 			 * then it returns 1 (having set uptab.b_active).
614 			 * Otherwise we are done and fall through to
615 			 * finish up.
616 			 */
617 			if ((upaddr->uper1&(DCK|ECH))==DCK && upecc(upaddr, bp))
618 				return;
619 			/*
620 			 * Clear the drive and, every 4 retries, recalibrate
621 			 * to hopefully help clear up seek positioning problems.
622 			 */
623 			upaddr->upcs1 = TRE|IE|DCLR|GO;
624 			DELAY(idelay);
625 			needie = 0;
626 			if ((uptab.b_errcnt&07) == 4) {
627 				upaddr->upcs1 = RECAL|GO|IE;
628 				DELAY(idelay);
629 				while(upaddr->upds & PIP)
630 					DELAY(25);
631 			}
632 		}
633 		/*
634 		 * If we are still noted as active, then no
635 		 * (further) retries are necessary.
636 		 *
637 		 * Make sure the correct unit is selected,
638 		 * return it to centerline if necessary, and mark
639 		 * this i/o complete, starting the next transfer
640 		 * on this drive with the upustart routine (if any).
641 		 */
642 		if (uptab.b_active) {
643 			if (uptab.b_errcnt >= 16) {
644 				upaddr->upcs1 = RTC|GO|IE;
645 				DELAY(idelay);
646 				while (upaddr->upds & PIP)
647 					DELAY(25);
648 				needie = 0;
649 			}
650 			uptab.b_active = 0;
651 			uptab.b_errcnt = 0;
652 			uptab.b_actf = dp->b_forw;
653 			dp->b_active = 0;
654 			dp->b_errcnt = 0;
655 			dp->b_actf = bp->av_forw;
656 			bp->b_resid = (-upaddr->upwc * sizeof(short));
657 			if (bp->b_resid)
658 				printf("resid %d ds %o er? %o %o %o\n",
659 				    bp->b_resid, upaddr->upds,
660 				    upaddr->uper1, upaddr->uper2, upaddr->uper3);
661 			iodone(bp);
662 			if(dp->b_actf)
663 				if (upustart(unit))
664 					needie = 0;
665 		}
666 		as &= ~(1<<unit);
667 		upsoftas &= ~(1<<unit);
668 		ubafree(up_ubinfo), up_ubinfo = 0;
669 	} else {
670 		if (upaddr->upcs1 & TRE) {
671 			upaddr->upcs1 = TRE;
672 			DELAY(idelay);
673 		}
674 	}
675 	/*
676 	 * If we have a unit with an outstanding SEARCH,
677 	 * and the hardware indicates the unit requires attention,
678 	 * the bring the drive to the ready queue.
679 	 * Finally, if the controller is not transferring
680 	 * start it if any drives are now ready to transfer.
681 	 */
682 	as |= upsoftas;
683 	oupsoftas = upsoftas;
684 	upsoftas = 0;
685 	for (unit = 0; unit < NUP; unit++)
686 		if ((as|oupsoftas) & (1<<unit)) {
687 			if (as & (1<<unit)) {
688 				upaddr->upas = 1<<unit;
689 				if (olducode)
690 					DELAY(oasdel);
691 			}
692 			if (upustart(unit))
693 				needie = 0;
694 		}
695 	if (uptab.b_actf && uptab.b_active == 0)
696 		if (upstart())
697 			needie = 0;
698 out:
699 	if (needie)
700 		upaddr->upcs1 = IE;
701 }
702 
703 upread(dev)
704 {
705 
706 	physio(upstrategy, &rupbuf, dev, B_READ, minphys);
707 }
708 
709 upwrite(dev)
710 {
711 
712 	physio(upstrategy, &rupbuf, dev, B_WRITE, minphys);
713 }
714 
715 /*
716  * Correct an ECC error, and restart the i/o to complete
717  * the transfer if necessary.  This is quite complicated because
718  * the transfer may be going to an odd memory address base and/or
719  * across a page boundary.
720  */
721 upecc(up, bp)
722 register struct device *up;
723 register struct buf *bp;
724 {
725 	struct uba_regs *ubp = (struct uba_regs *)UBA0;
726 	register int i;
727 	caddr_t addr;
728 	int reg, bit, byte, npf, mask, o, cmd, ubaddr;
729 	int bn, cn, tn, sn;
730 
731 	/*
732 	 * Npf is the number of sectors transferred before the sector
733 	 * containing the ECC error, and reg is the UBA register
734 	 * mapping (the first part of) the transfer.
735 	 * O is offset within a memory page of the first byte transferred.
736 	 */
737 	npf = btop((up->upwc * sizeof(short)) + bp->b_bcount) - 1;
738 	reg = btop(up_ubinfo&0x3ffff) + npf;
739 	o = (int)bp->b_un.b_addr & PGOFSET;
740 	printf("%D ", bp->b_blkno+npf);
741 	prdev("ECC", bp->b_dev);
742 	mask = up->upec2;
743 	if (mask == 0) {
744 		up->upof = FMT22;		/* == RTC ???? */
745 		DELAY(idelay);
746 		return (0);
747 	}
748 	/*
749 	 * Flush the buffered data path, and compute the
750 	 * byte and bit position of the error.  The variable i
751 	 * is the byte offset in the transfer, the variable byte
752 	 * is the offset from a page boundary in main memory.
753 	 */
754 	ubp->uba_dpr[(up_ubinfo>>28)&0x0f] |= BNE;
755 	i = up->upec1 - 1;		/* -1 makes 0 origin */
756 	bit = i&07;
757 	i = (i&~07)>>3;
758 	byte = i + o;
759 	/*
760 	 * Correct while possible bits remain of mask.  Since mask
761 	 * contains 11 bits, we continue while the bit offset is > -11.
762 	 * Also watch out for end of this block and the end of the whole
763 	 * transfer.
764 	 */
765 	while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
766 		addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+
767 		    (byte & PGOFSET);
768 		putmemc(addr, getmemc(addr)^(mask<<bit));
769 		byte++;
770 		i++;
771 		bit -= 8;
772 	}
773 	uptab.b_active++;	/* Either complete or continuing... */
774 	if (up->upwc == 0)
775 		return (0);
776 	/*
777 	 * Have to continue the transfer... clear the drive,
778 	 * and compute the position where the transfer is to continue.
779 	 * We have completed npf+1 sectors of the transfer already;
780 	 * restart at offset o of next sector (i.e. in UBA register reg+1).
781 	 */
782 	up->upcs1 = TRE|IE|DCLR|GO;
783 	DELAY(idelay);
784 	bn = dkblock(bp);
785 	cn = bp->b_cylin;
786 	sn = bn%(NSECT*NTRAC) + npf + 1;
787 	tn = sn/NSECT;
788 	sn %= NSECT;
789 	cn += tn/NTRAC;
790 	tn %= NTRAC;
791 	up->updc = cn;
792 	up->upda = (tn << 8) | sn;
793 	ubaddr = (int)ptob(reg+1) + o;
794 	up->upba = ubaddr;
795 	cmd = (ubaddr >> 8) & 0x300;
796 	cmd |= IE|GO|RCOM;
797 	up->upcs1 = cmd;
798 	return (1);
799 }
800 
801 /*
802  * Reset driver after UBA init.
803  * Cancel software state of all pending transfers
804  * and restart all units and the controller.
805  */
806 upreset()
807 {
808 	int unit;
809 
810 	printf(" up");
811 	uptab.b_active = 0;
812 	uptab.b_actf = uptab.b_actl = 0;
813 	if (DK_N+NUP == DK_NMAX)
814 		dk_busy &= ~(1<<(DK_N+NUP));
815 	if (up_ubinfo) {
816 		printf("<%d>", (up_ubinfo>>28)&0xf);
817 		ubafree(up_ubinfo), up_ubinfo = 0;
818 	}
819 	UPADDR->upcs2 = CLR;		/* clear controller */
820 	DELAY(idelay);
821 	for (unit = 0; unit < NUP; unit++) {
822 		uputab[unit].b_active = 0;
823 		(void) upustart(unit);
824 	}
825 	(void) upstart();
826 }
827 
828 /*
829  * Wake up every second and if an interrupt is pending
830  * but nothing has happened increment a counter.
831  * If nothing happens for 20 seconds, reset the controller
832  * and begin anew.
833  */
834 upwatch()
835 {
836 	int i;
837 
838 	timeout((caddr_t)upwatch, 0, HZ);
839 	if (uptab.b_active == 0) {
840 		for (i = 0; i < NUP; i++)
841 			if (uputab[i].b_active)
842 				goto active;
843 		up_wticks = 0;		/* idling */
844 		return;
845 	}
846 active:
847 	up_wticks++;
848 	if (up_wticks >= 20) {
849 		up_wticks = 0;
850 		printf("LOST INTERRUPT RESET");
851 		upreset();
852 		printf("\n");
853 	}
854 }
855