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