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