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