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