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