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