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