xref: /csrg-svn/sys/vax/uba/ut.c (revision 11197)
1 /*	ut.c	4.28	83/02/20	*/
2 
3 #include "tj.h"
4 #if NUT > 0
5 /*
6  * System Industries Model 9700 Tape Drive
7  *   emulates a TU45 on the UNIBUS
8  *
9  * TODO:
10  *	check out attention processing
11  *	try reset code and dump code
12  */
13 #include "../machine/pte.h"
14 
15 #include "../h/param.h"
16 #include "../h/systm.h"
17 #include "../h/buf.h"
18 #include "../h/conf.h"
19 #include "../h/dir.h"
20 #include "../h/file.h"
21 #include "../h/user.h"
22 #include "../h/map.h"
23 #include "../h/ioctl.h"
24 #include "../h/mtio.h"
25 #include "../h/cmap.h"
26 #include "../h/uio.h"
27 #include "../h/kernel.h"
28 
29 #include "../vax/cpu.h"
30 #include "../vaxuba/ubareg.h"
31 #include "../vaxuba/ubavar.h"
32 #include "../vaxuba/utreg.h"
33 
34 struct	buf	rutbuf[NUT];	/* bufs for raw i/o */
35 struct	buf	cutbuf[NUT];	/* bufs for control operations */
36 struct	buf	tjutab[NTJ];	/* bufs for slave queue headers */
37 
38 struct uba_ctlr *utminfo[NUT];
39 struct uba_device *tjdinfo[NTJ];
40 int utprobe(), utslave(), utattach(), utdgo(), utintr(), uttimer();
41 u_short utstd[] = { 0772440, 0 };
42 struct uba_driver utdriver =
43   { utprobe, utslave, utattach, utdgo, utstd, "tj", tjdinfo, "ut", utminfo, 0 };
44 
45 #define	MASKREG(reg)	((reg)&0xffff)
46 
47 /* bits in minor device */
48 #define	TJUNIT(dev)	(minor(dev)&03)
49 #define	T_NOREWIND	04
50 #define	T_1600BPI	010
51 #define	T_6250BPI	020
52 short	utdens[] = { UT_NRZI, UT_PE, UT_GCR, UT_NRZI };
53 
54 /* slave to controller mapping table */
55 short	tjtout[NTJ];
56 #define UTUNIT(dev)	(tjtout[TJUNIT(dev)])
57 
58 #define	INF	(daddr_t)1000000L	/* a block number that wont exist */
59 
60 struct	tj_softc {
61 	char	sc_openf;	/* exclusive open */
62 	char	sc_lastiow;	/* last I/O operation was a write */
63 	daddr_t	sc_blkno;	/* next block to transfer */
64 	daddr_t	sc_nxrec;	/* next record on tape */
65 	u_short	sc_erreg;	/* image of uter */
66 	u_short	sc_dsreg;	/* image of utds */
67 	u_short	sc_resid;	/* residual from transfer */
68 	u_short	sc_dens;	/* sticky selected density */
69 	daddr_t	sc_timo;	/* time until timeout expires */
70 	short	sc_tact;	/* timeout is active flag */
71 } tj_softc[NTJ];
72 
73 /*
74  * Internal per/slave states found in sc_state
75  */
76 #define	SSEEK		1	/* seeking */
77 #define	SIO		2	/* doing sequential I/O */
78 #define	SCOM		3	/* sending a control command */
79 #define	SREW		4	/* doing a rewind op */
80 #define	SERASE		5	/* erase inter-record gap */
81 #define	SERASED		6	/* erased inter-record gap */
82 
83 /*ARGSUSED*/
84 utprobe(reg)
85 	caddr_t reg;
86 {
87 	register int br, cvec;
88 #ifdef lint
89 	br=0; cvec=br; br=cvec;
90 	utintr(0);
91 #endif
92 	/*
93 	 * The SI documentation says you must set the RDY bit
94 	 * (even though it's read-only) to force an interrupt.
95 	 */
96 	((struct utdevice *) reg)->utcs1 = UT_IE|UT_NOP|UT_RDY;
97 	DELAY(10000);
98 	return (sizeof (struct utdevice));
99 }
100 
101 /*ARGSUSED*/
102 utslave(ui, reg)
103 	struct uba_device *ui;
104 	caddr_t reg;
105 {
106 	/*
107 	 * A real TU45 would support the slave present bit
108 	 * int the drive type register, but this thing doesn't,
109 	 * so there's no way to determine if a slave is present or not.
110 	 */
111 	 return(1);
112 }
113 
114 utattach(ui)
115 	struct uba_device *ui;
116 {
117 	tjtout[ui->ui_unit] = ui->ui_mi->um_ctlr;
118 }
119 
120 /*
121  * Open the device with exclusive access.
122  */
123 utopen(dev, flag)
124 	dev_t dev;
125 	int flag;
126 {
127 	register int tjunit = TJUNIT(dev);
128 	register struct uba_device *ui;
129 	register struct tj_softc *sc;
130 	int olddens, dens;
131 	register int s;
132 
133 	if (tjunit >= NTJ || (sc = &tj_softc[tjunit])->sc_openf ||
134 	    (ui = tjdinfo[tjunit]) == 0 || ui->ui_alive == 0)
135 		return (ENXIO);
136 	olddens = sc->sc_dens;
137 	dens = sc->sc_dens =
138 	    utdens[(minor(dev)&(T_1600BPI|T_6250BPI))>>3]|
139 	      PDP11FMT|(ui->ui_slave&07);
140 get:
141 	utcommand(dev, UT_SENSE, 1);
142 	if (sc->sc_dsreg&UTDS_PIP) {
143 		sleep((caddr_t)&lbolt, PZERO+1);
144 		goto get;
145 	}
146 	sc->sc_dens = olddens;
147 	if ((sc->sc_dsreg&UTDS_MOL) == 0) {
148 		uprintf("tj%d: not online\n", tjunit);
149 		return (EIO);
150 	}
151 	if ((flag&FWRITE) && (sc->sc_dsreg&UTDS_WRL)) {
152 		uprintf("tj%d: no write ring\n", tjunit);
153 		return (EIO);
154 	}
155 	if ((sc->sc_dsreg&UTDS_BOT) == 0 && (flag&FWRITE) &&
156 	    dens != sc->sc_dens) {
157 		uprintf("tj%d: can't change density in mid-tape\n", tjunit);
158 		return (EIO);
159 	}
160 	sc->sc_openf = 1;
161 	sc->sc_blkno = (daddr_t)0;
162 	sc->sc_nxrec = INF;
163 	sc->sc_lastiow = 0;
164 	sc->sc_dens = dens;
165 	/*
166 	 * For 6250 bpi take exclusive use of the UNIBUS.
167 	 */
168 	ui->ui_driver->ud_xclu = (dens&(T_1600BPI|T_6250BPI)) == T_6250BPI;
169 	s = spl6();
170 	if (sc->sc_tact == 0) {
171 		sc->sc_timo = INF;
172 		sc->sc_tact = 1;
173 		timeout(uttimer, (caddr_t)dev, 5*hz);
174 	}
175 	splx(s);
176 	return (0);
177 }
178 
179 utclose(dev, flag)
180 	register dev_t dev;
181 	register flag;
182 {
183 	register struct tj_softc *sc = &tj_softc[TJUNIT(dev)];
184 
185 	if (flag == FWRITE || ((flag&FWRITE) && sc->sc_lastiow)) {
186 		utcommand(dev, UT_WEOF, 1);
187 		utcommand(dev, UT_WEOF, 1);
188 		utcommand(dev, UT_SREV, 1);
189 	}
190 	if ((minor(dev)&T_NOREWIND) == 0)
191 		utcommand(dev, UT_REW, 0);
192 	sc->sc_openf = 0;
193 }
194 
195 utcommand(dev, com, count)
196 	dev_t dev;
197 	int com, count;
198 {
199 	register struct buf *bp;
200 	register int s;
201 
202 	bp = &cutbuf[UTUNIT(dev)];
203 	s = spl5();
204 	while (bp->b_flags&B_BUSY) {
205 		if(bp->b_repcnt == 0 && (bp->b_flags&B_DONE))
206 			break;
207 		bp->b_flags |= B_WANTED;
208 		sleep((caddr_t)bp, PRIBIO);
209 	}
210 	bp->b_flags = B_BUSY|B_READ;
211 	splx(s);
212 	bp->b_dev = dev;
213 	bp->b_command = com;
214 	bp->b_repcnt = count;
215 	bp->b_blkno = 0;
216 	utstrategy(bp);
217 	if (count == 0)
218 		return;
219 	iowait(bp);
220 	if (bp->b_flags&B_WANTED)
221 		wakeup((caddr_t)bp);
222 	bp->b_flags &= B_ERROR;
223 }
224 
225 /*
226  * Queue a tape operation.
227  */
228 utstrategy(bp)
229 	register struct buf *bp;
230 {
231 	int tjunit = TJUNIT(bp->b_dev);
232 	register struct uba_ctlr *um;
233 	register struct buf *dp;
234 
235 	/*
236 	 * Put transfer at end of unit queue
237 	 */
238 	dp = &tjutab[tjunit];
239 	bp->av_forw = NULL;
240 	(void) spl5();
241 	if (dp->b_actf == NULL) {
242 		dp->b_actf = bp;
243 		/*
244 		 * Transport not active, so...
245 		 * put at end of controller queue
246 		 */
247 		dp->b_forw = NULL;
248 		um = tjdinfo[tjunit]->ui_mi;
249 		if (um->um_tab.b_actf == NULL)
250 			um->um_tab.b_actf = dp;
251 		else
252 			um->um_tab.b_actl->b_forw = dp;
253 		um->um_tab.b_actl = dp;
254 	} else
255 		dp->b_actl->av_forw = bp;
256 	dp->b_actl = bp;
257 	/*
258 	 * If the controller is not busy, set it going.
259 	 */
260 	if (um->um_tab.b_state == 0)
261 		utstart(um);
262 	(void) spl0();
263 }
264 
265 utstart(um)
266 	register struct uba_ctlr *um;
267 {
268 	register struct utdevice *addr;
269 	register struct buf *bp, *dp;
270 	register struct tj_softc *sc;
271 	struct uba_device *ui;
272 	int tjunit;
273 	daddr_t blkno;
274 
275 loop:
276 	/*
277 	 * Scan controller queue looking for units with
278 	 * transaction queues to dispatch
279 	 */
280 	if ((dp = um->um_tab.b_actf) == NULL)
281 		return;
282 	if ((bp = dp->b_actf) == NULL) {
283 		um->um_tab.b_actf = dp->b_forw;
284 		goto loop;
285 	}
286 	addr = (struct utdevice *)um->um_addr;
287 	tjunit = TJUNIT(bp->b_dev);
288 	ui = tjdinfo[tjunit];
289 	sc = &tj_softc[tjunit];
290 	/* note slave select, density, and format were merged on open */
291 	addr->uttc = sc->sc_dens;
292 	sc->sc_dsreg = addr->utds;
293 	sc->sc_erreg = addr->uter;
294 	sc->sc_resid = MASKREG(addr->utfc);
295 	/*
296 	 * Default is that last command was NOT a write command;
297 	 * if we do a write command we will notice this in utintr().
298 	 */
299 	sc->sc_lastiow = 0;
300 	if (sc->sc_openf < 0 || (addr->utds&UTDS_MOL) == 0) {
301 		/*
302 		 * Have had a hard error on a non-raw tape
303 		 * or the tape unit is now unavailable
304 		 * (e.g. taken off line).
305 		 */
306 		bp->b_flags |= B_ERROR;
307 		goto next;
308 	}
309 	if (bp == &cutbuf[UTUNIT(bp->b_dev)]) {
310 		/*
311 		 * Execute a control operation with the specified
312 		 * count.
313 		 */
314 		if (bp->b_command == UT_SENSE)
315 			goto next;
316 		if (bp->b_command == UT_SFORW && (addr->utds & UTDS_EOT)) {
317 			bp->b_resid = bp->b_bcount;
318 			goto next;
319 		}
320 		/*
321 		 * Set next state; handle timeouts
322 		 */
323 		if (bp->b_command == UT_REW) {
324 			um->um_tab.b_state = SREW;
325 			sc->sc_timo = 5*60;
326 		} else {
327 			um->um_tab.b_state = SCOM;
328 			sc->sc_timo = imin(imax(10*(int)-bp->b_repcnt,60),5*60);
329 		}
330 		/* NOTE: this depends on the ut command values */
331 		if (bp->b_command >= UT_SFORW && bp->b_command <= UT_SREVF)
332 			addr->utfc = -bp->b_repcnt;
333 		goto dobpcmd;
334 	}
335 	/*
336 	 * The following checks boundary conditions for operations
337 	 * on non-raw tapes.  On raw tapes the initialization of
338 	 * sc->sc_nxrec by utphys causes them to be skipped normally
339 	 * (except in the case of retries).
340 	 */
341 	if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) {
342 		/* can't read past end of file */
343 		bp->b_flags |= B_ERROR;
344 		bp->b_error = ENXIO;
345 		goto next;
346 	}
347 	if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && (bp->b_flags&B_READ)) {
348 		/* read at eof returns 0 count */
349 		bp->b_resid = bp->b_bcount;
350 		clrbuf(bp);
351 		goto next;
352 	}
353 	if ((bp->b_flags&B_READ) == 0)
354 		sc->sc_nxrec = bdbtofsb(bp->b_blkno)+1;
355 	/*
356 	 * If the tape is correctly positioned, set up all the
357 	 * registers but the csr, and give control over to the
358 	 * UNIBUS adaptor routines, to wait for resources to
359 	 * start I/O.
360 	 */
361 	if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) {
362 		addr->utwc = -(((bp->b_bcount)+1)>>1);
363 		addr->utfc = -bp->b_bcount;
364 		if ((bp->b_flags&B_READ) == 0) {
365 			/*
366 			 * On write error retries erase the
367 			 * inter-record gap before rewriting.
368 			 */
369 			if (um->um_tab.b_errcnt) {
370 				if (um->um_tab.b_state != SERASED) {
371 					um->um_tab.b_state = SERASE;
372 					sc->sc_timo = 60;
373 					addr->utcs1 = UT_ERASE|UT_IE|UT_GO;
374 					return;
375 				}
376 			}
377 			if (addr->utds & UTDS_EOT) {
378 				bp->b_resid = bp->b_bcount;
379 				um->um_tab.b_state = 0;
380 				goto next;
381 			}
382 			um->um_cmd = UT_WCOM;
383 		} else
384 			um->um_cmd = UT_RCOM;
385 		sc->sc_timo = 60;
386 		um->um_tab.b_state = SIO;
387 		(void) ubago(ui);
388 		return;
389 	}
390 	/*
391 	 * Tape positioned incorrectly; seek forwards or
392 	 * backwards to the correct spot.  This happens for
393 	 * raw tapes only on error retries.
394 	 */
395 	um->um_tab.b_state = SSEEK;
396 	if (blkno < bdbtofsb(bp->b_blkno)) {
397 		addr->utfc = blkno - bdbtofsb(bp->b_blkno);
398 		bp->b_command = UT_SFORW;
399 	} else {
400 		addr->utfc = bdbtofsb(bp->b_blkno) - blkno;
401 		bp->b_command = UT_SREV;
402 	}
403 	sc->sc_timo = imin(imax(10 * -addr->utfc, 60), 5*60);
404 
405 dobpcmd:
406 	/*
407 	 * Perform the command setup in bp.
408 	 */
409 	addr->utcs1 = bp->b_command|UT_IE|UT_GO;
410 	return;
411 next:
412 	/*
413 	 * Advance to the next command in the slave queue,
414 	 * posting notice and releasing resources as needed.
415 	 */
416 	if (um->um_ubinfo)
417 		ubadone(um);
418 	um->um_tab.b_errcnt = 0;
419 	dp->b_actf = bp->av_forw;
420 	iodone(bp);
421 	goto loop;
422 }
423 
424 /*
425  * Start operation on controller --
426  * UNIBUS resources have been allocated.
427  */
428 utdgo(um)
429 	register struct uba_ctlr *um;
430 {
431 	register struct utdevice *addr = (struct utdevice *)um->um_addr;
432 
433 	addr->utba = (u_short) um->um_ubinfo;
434 	addr->utcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300)|UT_IE|UT_GO;
435 }
436 
437 /*
438  * Ut interrupt handler
439  */
440 /*ARGSUSED*/
441 utintr(ut11)
442 	int ut11;
443 {
444 	struct buf *dp;
445 	register struct buf *bp;
446 	register struct uba_ctlr *um = utminfo[ut11];
447 	register struct utdevice *addr;
448 	register struct tj_softc *sc;
449 	u_short tjunit, cs2, cs1;
450 	register state;
451 
452 	if ((dp = um->um_tab.b_actf) == NULL)
453 		return;
454 	bp = dp->b_actf;
455 	tjunit = TJUNIT(bp->b_dev);
456 	addr = (struct utdevice *)tjdinfo[tjunit]->ui_addr;
457 	sc = &tj_softc[tjunit];
458 	/*
459 	 * Record status...
460 	 */
461 	sc->sc_timo = INF;
462 	sc->sc_dsreg = addr->utds;
463 	sc->sc_erreg = addr->uter;
464 	sc->sc_resid = MASKREG(addr->utfc);
465 	if ((bp->b_flags&B_READ) == 0)
466 		sc->sc_lastiow = 1;
467 	state = um->um_tab.b_state;
468 	um->um_tab.b_state = 0;
469 	/*
470 	 * Check for errors...
471 	 */
472 	if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE)) {
473 		/*
474 		 * To clear the ERR bit, we must issue a drive clear
475 		 * command, and to clear the TRE bit we must set the
476 		 * controller clear bit.
477 		 */
478 		cs2 = addr->utcs2;
479 		if ((cs1 = addr->utcs1)&UT_TRE)
480 			addr->utcs2 |= UTCS2_CLR;
481 		/* is this dangerous ?? */
482 		while ((addr->utcs1&UT_RDY) == 0)
483 			;
484 		addr->utcs1 = UT_CLEAR|UT_GO;
485 		/*
486 		 * If we were reading at 1600 or 6250 bpi and the error
487 		 * was corrected, then don't consider this an error.
488 		 */
489 		if (sc->sc_erreg & UTER_COR && (bp->b_flags & B_READ) &&
490 		    (addr->uttc & UTTC_DEN) != UT_NRZI) {
491 			printf(
492 			  "ut%d: soft error bn%d cs1=%b er=%b cs2=%b ds=%b\n",
493 			  tjunit, bp->b_blkno, cs1, UT_BITS, sc->sc_erreg,
494 			  UTER_BITS, cs2, UTCS2_BITS, sc->sc_dsreg, UTDS_BITS);
495 			sc->sc_erreg &= ~UTER_COR;
496 		}
497 		/*
498 		 * If we were reading from a raw tape and the only error
499 		 * was that the record was too long, then we don't consider
500 		 * this an error.
501 		 */
502 		if (bp == &rutbuf[UTUNIT(bp->b_dev)] && (bp->b_flags&B_READ) &&
503 		    (sc->sc_erreg&UTER_FCE))
504 			sc->sc_erreg &= ~UTER_FCE;
505 		if (sc->sc_erreg == 0)
506 			goto ignoreerr;
507 		/*
508 		 * Fix up errors which occur due to backspacing
509 		 * "over" the front of the tape.
510 		 */
511 		if ((sc->sc_dsreg & UTDS_BOT) && bp->b_command == UT_SREV &&
512 		    ((sc->sc_erreg &= ~(UTER_NEF|UTER_FCE)) == 0))
513 			goto opdone;
514 		/*
515 		 * Retry soft errors up to 8 times
516 		 */
517 		if ((sc->sc_erreg&UTER_HARD) == 0 && state == SIO) {
518 			if (++um->um_tab.b_errcnt < 7) {
519 				sc->sc_blkno++;
520 				ubadone(um);
521 				goto opcont;
522 			}
523 		}
524 		/*
525 		 * Hard or non-I/O errors on non-raw tape
526 		 * cause it to close.
527 		 */
528 		if (sc->sc_openf > 0 && bp != &rutbuf[UTUNIT(bp->b_dev)])
529 			sc->sc_openf = -1;
530 		/*
531 		 * Couldn't recover error.
532 		 */
533 		printf("ut%d: hard error bn%d cs1=%b er=%b cs2=%b ds=%b\n",
534 			tjunit, bp->b_blkno, cs1, UT_BITS, sc->sc_erreg,
535 			UTER_BITS, cs2, UTCS2_BITS, sc->sc_dsreg, UTDS_BITS);
536 		bp->b_flags |= B_ERROR;
537 		goto opdone;
538 	}
539 
540 ignoreerr:
541 	/*
542 	 * If we hit a tape mark update our position.
543 	 */
544 	if (sc->sc_dsreg & UTDS_TM && bp->b_flags & B_READ) {
545 		/*
546 		 * Set blkno and nxrec
547 		 */
548 		if (bp == &cutbuf[UTUNIT(bp->b_dev)]) {
549 			if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) {
550 				sc->sc_nxrec =
551 				     bdbtofsb(bp->b_blkno) - addr->utfc;
552 				sc->sc_blkno = sc->sc_nxrec;
553 			} else {
554 				sc->sc_blkno =
555 				     bdbtofsb(bp->b_blkno) + addr->utfc;
556 				sc->sc_nxrec = sc->sc_blkno-1;
557 			}
558 		} else
559 			sc->sc_nxrec = bdbtofsb(bp->b_blkno);
560 		/*
561 		 * Note: if we get a tape mark on a read, the
562 		 * frame count register will be zero, so b_resid
563 		 * will be calculated correctly below.
564 		 */
565 		goto opdone;
566 	}
567 	/*
568 	 * Advance tape control FSM.
569 	 */
570 	switch (state) {
571 
572 	case SIO:		/* read/write increments tape block # */
573 		sc->sc_blkno++;
574 		break;
575 
576 	case SCOM:		/* motion commands update current position */
577 		if (bp == &cutbuf[UTUNIT(bp->b_dev)])
578 		switch (bp->b_command) {
579 
580 		case UT_SFORW:
581 			sc->sc_blkno -= bp->b_repcnt;
582 			break;
583 
584 		case UT_SREV:
585 			sc->sc_blkno += bp->b_repcnt;
586 			break;
587 
588 		case UT_REWOFFL:
589 			addr->utcs1 = UT_CLEAR|UT_GO;
590 			break;
591 		}
592 		break;
593 
594 	case SSEEK:
595 		sc->sc_blkno = bdbtofsb(bp->b_blkno);
596 		goto opcont;
597 
598 	case SERASE:
599 		/*
600 		 * Completed erase of the inter-record gap due to a
601 		 * write error; now retry the write operation.
602 		 */
603 		um->um_tab.b_state = SERASED;
604 		goto opcont;
605 
606 	case SREW:			/* clear attention bit */
607 		addr->utcs1 = UT_CLEAR|UT_GO;
608 		break;
609 
610 	default:
611 		printf("bad state %d\n", state);
612 		panic("utintr");
613 	}
614 
615 opdone:
616 	/*
617 	 * Reset error count and remove
618 	 * from device queue
619 	 */
620 	um->um_tab.b_errcnt = 0;
621 	dp->b_actf = bp->av_forw;
622 	/*
623 	 * For read command, frame count register contains
624 	 * actual length of tape record.  Otherwise, it
625 	 * holds negative residual count.
626 	 */
627 	if (state == SIO && um->um_cmd == UT_RCOM) {
628 		bp->b_resid = 0;
629 		if (bp->b_bcount > MASKREG(addr->utfc))
630 			bp->b_resid = bp->b_bcount - MASKREG(addr->utfc);
631 	} else
632 		bp->b_resid = MASKREG(-addr->utfc);
633 	ubadone(um);
634 	iodone(bp);
635 	/*
636 	 * Circulate slave to end of controller queue
637 	 * to give other slaves a chance
638 	 */
639 	um->um_tab.b_actf = dp->b_forw;
640 	if (dp->b_actf) {
641 		dp->b_forw = NULL;
642 		if (um->um_tab.b_actf == NULL)
643 			um->um_tab.b_actf = dp;
644 		else
645 			um->um_tab.b_actl->b_forw = dp;
646 		um->um_tab.b_actl = dp;
647 	}
648 	if (um->um_tab.b_actf == 0)
649 		return;
650 opcont:
651 	utstart(um);
652 }
653 
654 /*
655  * Watchdog timer routine.
656  */
657 uttimer(dev)
658 	int dev;
659 {
660 	register struct tj_softc *sc = &tj_softc[TJUNIT(dev)];
661 	register short x;
662 
663 	if (sc->sc_timo != INF && (sc->sc_timo -= 5) < 0) {
664 		printf("tj%d: lost interrupt\n", TJUNIT(dev));
665 		sc->sc_timo = INF;
666 		x = spl5();
667 		utintr(UTUNIT(dev));
668 		(void) splx(x);
669 	}
670 	timeout(uttimer, (caddr_t)dev, 5*hz);
671 }
672 
673 /*
674  * Raw interface for a read
675  */
676 utread(dev, uio)
677 	dev_t dev;
678 	struct uio *uio;
679 {
680 	int errno;
681 
682 	errno = utphys(dev, uio);
683 	if (errno)
684 		return (errno);
685 	return (physio(utstrategy, &rutbuf[UTUNIT(dev)], dev, B_READ, minphys, uio));
686 }
687 
688 /*
689  * Raw interface for a write
690  */
691 utwrite(dev, uio)
692 	dev_t dev;
693 	struct uio *uio;
694 {
695 	int errno;
696 
697 	errno = utphys(dev, uio);
698 	if (errno)
699 		return (errno);
700 	return (physio(utstrategy, &rutbuf[UTUNIT(dev)], dev, B_WRITE, minphys, uio));
701 }
702 
703 /*
704  * Check for valid device number dev and update our notion
705  * of where we are on the tape
706  */
707 utphys(dev, uio)
708 	dev_t dev;
709 	struct uio *uio;
710 {
711 	register int tjunit = TJUNIT(dev);
712 	register struct tj_softc *sc;
713 	register struct uba_device *ui;
714 
715 	if (tjunit >= NTJ || (ui=tjdinfo[tjunit]) == 0 || ui->ui_alive == 0)
716 		return (ENXIO);
717 	sc = &tj_softc[tjunit];
718 	sc->sc_blkno = bdbtofsb(uio->uio_offset>>9);
719 	sc->sc_nxrec = sc->sc_blkno+1;
720 	return (0);
721 }
722 
723 /*ARGSUSED*/
724 utioctl(dev, cmd, data, flag)
725 	dev_t dev;
726 	caddr_t data;
727 {
728 	register struct tj_softc *sc = &tj_softc[TJUNIT(dev)];
729 	register struct buf *bp = &cutbuf[UTUNIT(dev)];
730 	register callcount;
731 	int fcount;
732 	struct mtop *mtop;
733 	struct mtget *mtget;
734 	/* we depend of the values and order of the MT codes here */
735 	static utops[] =
736       {UT_WEOF,UT_SFORWF,UT_SREVF,UT_SFORW,UT_SREV,UT_REW,UT_REWOFFL,UT_SENSE};
737 
738 	switch (cmd) {
739 
740 	case MTIOCTOP:
741 		mtop = (struct mtop *)data;
742 		switch(mtop->mt_op) {
743 
744 		case MTWEOF:
745 			callcount = mtop->mt_count;
746 			fcount = 1;
747 			break;
748 
749 		case MTFSF: case MTBSF:
750 		case MTFSR: case MTBSR:
751 			callcount = 1;
752 			fcount = mtop->mt_count;
753 			break;
754 
755 		case MTREW: case MTOFFL: case MTNOP:
756 			callcount = 1;
757 			fcount = 1;
758 			break;
759 
760 		default:
761 			return (ENXIO);
762 		}
763 		if (callcount <= 0 || fcount <= 0)
764 			return (EINVAL);
765 		while (--callcount >= 0) {
766 			utcommand(dev, utops[mtop->mt_op], fcount);
767 			/* note this depends on the mtop values */
768 			if ((mtop->mt_op >= MTFSF && mtop->mt_op <= MTBSR) &&
769 			    bp->b_resid)
770 				return (EIO);
771 			if ((bp->b_flags&B_ERROR) || (sc->sc_dsreg&UTDS_BOT))
772 				break;
773 		}
774 		return (geterror(bp));
775 
776 	case MTIOCGET:
777 		mtget = (struct mtget *)data;
778 		mtget->mt_dsreg = sc->sc_dsreg;
779 		mtget->mt_erreg = sc->sc_erreg;
780 		mtget->mt_resid = sc->sc_resid;
781 		mtget->mt_type = MT_ISUT;
782 		break;
783 
784 	default:
785 		return (ENXIO);
786 	}
787 	return (0);
788 }
789 
790 utreset(uban)
791 	int uban;
792 {
793 	register struct uba_ctlr *um;
794 	register ut11, tjunit;
795 	register struct uba_device *ui;
796 	register struct buf *dp;
797 
798 	for (ut11 = 0; ut11 < NUT; ut11++) {
799 		if ((um = utminfo[ut11]) == 0 || um->um_alive == 0 ||
800 		   um->um_ubanum != uban)
801 			continue;
802 		printf(" ut%d", ut11);
803 		um->um_tab.b_state = 0;
804 		um->um_tab.b_actf = um->um_tab.b_actl = 0;
805 		if (um->um_ubinfo) {
806 			printf("<%d>", (um->um_ubinfo>>28)&0xf);
807 			um->um_ubinfo = 0;
808 		}
809 		((struct utdevice *)(um->um_addr))->utcs1 = UT_CLEAR|UT_GO;
810 		((struct utdevice *)(um->um_addr))->utcs2 |= UTCS2_CLR;
811 		for (tjunit = 0; tjunit < NTJ; tjunit++) {
812 			if ((ui = tjdinfo[tjunit]) == 0 || ui->ui_mi != um ||
813 			    ui->ui_alive == 0)
814 				continue;
815 			dp = &tjutab[tjunit];
816 			dp->b_state = 0;
817 			dp->b_forw = 0;
818 			if (um->um_tab.b_actf == NULL)
819 				um->um_tab.b_actf = dp;
820 			else
821 				um->um_tab.b_actl->b_forw = dp;
822 			um->um_tab.b_actl = dp;
823 			if (tj_softc[tjunit].sc_openf > 0)
824 				tj_softc[tjunit].sc_openf = -1;
825 		}
826 		utstart(um);
827 	}
828 }
829 
830 /*
831  * Do a stand-alone core dump to tape --
832  * from here down, routines are used only in dump context
833  */
834 #define	DBSIZE	20
835 
836 utdump()
837 {
838 	register struct uba_device *ui;
839 	register struct uba_regs *up;
840 	register struct utdevice *addr;
841 	int blk, num = maxfree;
842 	int start = 0;
843 
844 #define	phys(a,b)		((b)((int)(a)&0x7fffffff))
845 	if (tjdinfo[0] == 0)
846 		return (ENXIO);
847 	ui = phys(tjdinfo[0], struct uba_device *);
848 	up = phys(ui->ui_hd, struct uba_hd *)->uh_physuba;
849 	ubainit(up);
850 	DELAY(1000000);
851 	addr = (struct utdevice *)ui->ui_physaddr;
852 	utwait(addr);
853 	/*
854 	 * Be sure to set the appropriate density here.  We use
855 	 * 6250, but maybe it should be done at 1600 to insure the
856 	 * tape can be read by most any other tape drive available.
857 	 */
858 	addr->uttc = UT_GCR|PDP11FMT;	/* implicit slave 0 or-ed in */
859 	addr->utcs1 = UT_CLEAR|UT_GO;
860 	while (num > 0) {
861 		blk = num > DBSIZE ? DBSIZE : num;
862 		utdwrite(start, blk, addr, up);
863 		if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE))
864 			return(EIO);
865 		start += blk;
866 		num -= blk;
867 	}
868 	uteof(addr);
869 	uteof(addr);
870 	utwait(addr);
871 	if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE))
872 		return(EIO);
873 	addr->utcs1 = UT_REW|UT_GO;
874 	return (0);
875 }
876 
877 utdwrite(dbuf, num, addr, up)
878 	register dbuf, num;
879 	register struct utdevice *addr;
880 	struct uba_regs *up;
881 {
882 	register struct pte *io;
883 	register int npf;
884 
885 	utwait(addr);
886 	io = up->uba_map;
887 	npf = num + 1;
888 	while (--npf != 0)
889 		*(int *)io++ = (dbuf++ | (1<<UBAMR_DPSHIFT) | UBAMR_MRV);
890 	*(int *)io = 0;
891 	addr->utwc = -((num*NBPG)>>1);
892 	addr->utfc = -(num*NBPG);
893 	addr->utba = 0;
894 	addr->utcs1 = UT_WCOM|UT_GO;
895 }
896 
897 utwait(addr)
898 	struct utdevice *addr;
899 {
900 	register s;
901 
902 	do
903 		s = addr->utds;
904 	while ((s&UTDS_DRY) == 0);
905 }
906 
907 uteof(addr)
908 	struct utdevice *addr;
909 {
910 
911 	utwait(addr);
912 	addr->utcs1 = UT_WEOF|UT_GO;
913 }
914 #endif
915