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