xref: /csrg-svn/sys/vax/stand/ut.c (revision 49100)
123250Smckusick /*
235052Skarels  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
323250Smckusick  * All rights reserved.  The Berkeley software License Agreement
423250Smckusick  * specifies the terms and conditions for redistribution.
523250Smckusick  *
6*49100Sbostic  *	@(#)ut.c	7.8 (Berkeley) 05/04/91
723250Smckusick  */
85152Ssam 
95152Ssam /*
105152Ssam  * SI Model 9700 -- emulates TU45 on the UNIBUS
115152Ssam  */
125152Ssam 
1345803Sbostic #include "sys/param.h"
149186Ssam 
1545803Sbostic #include "../include/pte.h"
1635052Skarels 
1745803Sbostic #include "../uba/ubareg.h"
1845803Sbostic #include "../uba/utreg.h"
199186Ssam 
2045803Sbostic #include "stand/saio.h"
215152Ssam #include "savax.h"
225152Ssam 
2311177Ssam #define	MASKREG(reg)	((reg)&0xffff)
245152Ssam 
2533534Sbostic #define	MAXCTLR		1		/* all addresses must be specified */
2633534Sbostic u_short	utstd[MAXCTLR] = { 0172440 };	/* non-standard */
275152Ssam 
utopen(io)285152Ssam utopen(io)
295152Ssam 	register struct iob *io;
305152Ssam {
3133534Sbostic 	register int skip;
325152Ssam 
3335052Skarels 	if ((u_int)io->i_adapt >= nuba)
3435052Skarels 		return (EADAPT);
3533534Sbostic 	if ((u_int)io->i_ctlr >= MAXCTLR)
3633534Sbostic 		return (ECTLR);
3733551Sbostic 	if (badaddr((char *)ubamem(io->i_unit, utstd[io->i_ctlr]), sizeof(short)))
3833408Skarels 		return (ENXIO);
395152Ssam 	utstrategy(io, UT_REW);
4033534Sbostic 	for (skip = io->i_part; skip--;)
4111412Ssam 		utstrategy(io, UT_SFORWF);
4233408Skarels 	return (0);
435152Ssam }
445152Ssam 
utclose(io)455152Ssam utclose(io)
465152Ssam 	register struct iob *io;
475152Ssam {
485152Ssam 	utstrategy(io, UT_REW);
495152Ssam }
505152Ssam 
5133534Sbostic #define	UTWAIT(addr) { \
5233534Sbostic 	do \
5333534Sbostic 		word = addr->utcs1; \
5433534Sbostic 	while((word&UT_RDY) == 0); \
5533534Sbostic }
565152Ssam 
utstrategy(io,func)575152Ssam utstrategy(io, func)
585152Ssam 	register struct iob *io;
595152Ssam {
6033534Sbostic 	register struct utdevice *addr;
615152Ssam 	register u_short word;
625152Ssam 	register int errcnt;
6311177Ssam 	int info, resid;
645152Ssam 	u_short dens;
655152Ssam 
6633534Sbostic 	addr = (struct utdevice *)ubamem(io->i_unit, utstd[io->i_ctlr]);
6733534Sbostic 	dens = io->i_unit | PDP11FMT | UT_PE;
685152Ssam 	errcnt = 0;
695152Ssam retry:
705152Ssam 	utquiet(addr);
715152Ssam 	addr->uttc = dens;
725152Ssam 	info = ubasetup(io, 1);
735152Ssam 	addr->utwc = -((io->i_cc+1) >> 1);
745152Ssam 	addr->utfc = -io->i_cc;
75*49100Sbostic 	if (func == F_READ) {
765152Ssam 		addr->utba = info;
775152Ssam 		addr->utcs1 = UT_RCOM | ((info>>8) & 0x30) | UT_GO;
78*49100Sbostic 	} else if (func == F_WRITE) {
795152Ssam 		addr->utba = info;
805152Ssam 		addr->utcs1 = UT_WCOM | ((info>>8) & 0x30) | UT_GO;
815152Ssam 	} else if (func == UT_SREV) {
825152Ssam 		addr->utcs1 = UT_SREV | UT_GO;
835152Ssam 		return (0);
845152Ssam 	} else
855152Ssam 		addr->utcs1 = func | UT_GO;
8633534Sbostic 	UTWAIT(addr);
875152Ssam 	ubafree(io, info);
885152Ssam 	word = addr->utds;
895152Ssam 	if (word&(UTDS_EOT|UTDS_TM)) {
905152Ssam 		addr->utcs1 = UT_CLEAR | UT_GO;
9111177Ssam 		goto done;
925152Ssam 	}
935152Ssam 	if ((word&UTDS_ERR) || (addr->utcs1&UT_TRE)) {
9433534Sbostic 		printf("ut error: cs1=%b er=%b cs2=%b ds=%b",
9533534Sbostic 		  addr->utcs1, UT_BITS, addr->uter, UTER_BITS,
9633534Sbostic 		  addr->utcs2, UTCS2_BITS, word, UTDS_BITS);
9733534Sbostic 		if (errcnt++ == 10) {
9833534Sbostic 			printf("ut: unrecovered error\n");
9911177Ssam 			return (-1);
1005152Ssam 		}
1015152Ssam 		if (addr->utcs1&UT_TRE)
1025152Ssam 			addr->utcs2 |= UTCS2_CLR;
1035152Ssam 		addr->utcs1 = UT_CLEAR | UT_GO;
1045152Ssam 		utstrategy(io, UT_SREV);
1055152Ssam 		utquiet(addr);
106*49100Sbostic 		if (func == F_WRITE) {
1075152Ssam 			addr->utcs1 = UT_ERASE | UT_GO;
10833534Sbostic 			UTWAIT(addr);
1095152Ssam 		}
1105152Ssam 		goto retry;
1115152Ssam 	}
1125152Ssam 	if (errcnt)
11333534Sbostic 		printf("ut: recovered by retry\n");
11411177Ssam done:
115*49100Sbostic 	if (func == F_READ) {
11611177Ssam 		resid = 0;
11711177Ssam 		if (io->i_cc > MASKREG(addr->utfc))
11811177Ssam 			resid = io->i_cc - MASKREG(addr->utfc);
11911177Ssam 	} else
12011177Ssam 		resid = MASKREG(-addr->utfc);
12111177Ssam 	return (io->i_cc - resid);
1225152Ssam }
1235152Ssam 
12433534Sbostic static
utquiet(addr)1255152Ssam utquiet(addr)
1265152Ssam 	register struct utdevice *addr;
1275152Ssam {
1285152Ssam 	register u_short word;
1295152Ssam 
13033534Sbostic 	UTWAIT(addr);
1315152Ssam 	do
1325152Ssam 		word = addr->utds;
1335152Ssam 	while ((word&UTDS_DRY) == 0 && (word&UTDS_PIP));
1345152Ssam }
135