xref: /csrg-svn/sys/vax/stand/tm.c (revision 49100)
123244Smckusick /*
235052Skarels  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
323244Smckusick  * All rights reserved.  The Berkeley software License Agreement
423244Smckusick  * specifies the terms and conditions for redistribution.
523244Smckusick  *
6*49100Sbostic  *	@(#)tm.c	7.8 (Berkeley) 05/04/91
723244Smckusick  */
83263Swnj 
91811Sbill /*
103263Swnj  * TM11/TE??
111811Sbill  */
121811Sbill 
1345803Sbostic #include "sys/param.h"
149186Ssam 
1545803Sbostic #include "../include/pte.h"
1635052Skarels 
1745803Sbostic #include "../uba/ubareg.h"
1845803Sbostic #include "../uba/tmreg.h"
199186Ssam 
2045803Sbostic #include "stand/saio.h"
213263Swnj #include "savax.h"
221811Sbill 
2333531Sbostic #define	MAXCTLR		1		/* all addresses must be specified */
2433531Sbostic u_short	tmstd[MAXCTLR] = { 0172520 };
251811Sbill 
tmopen(io)261811Sbill tmopen(io)
271924Swnj 	register struct iob *io;
281811Sbill {
2933531Sbostic 	register int skip;
301811Sbill 
3135052Skarels 	if ((u_int)io->i_adapt >= nuba)
3235052Skarels 		return (EADAPT);
3333531Sbostic 	if ((u_int)io->i_ctlr >= MAXCTLR)
3433531Sbostic 		return (ECTLR);
3533550Sbostic 	if (badaddr((char *)ubamem(io->i_adapt, tmstd[io->i_ctlr]), sizeof(short)))
3633408Skarels 		return (ENXIO);
373263Swnj 	tmstrategy(io, TM_REW);
3833531Sbostic 	for (skip = io->i_part; skip--;) {
391811Sbill 		io->i_cc = 0;
403477Sroot 		tmstrategy(io, TM_SFORW);
411811Sbill 	}
4233408Skarels 	return (0);
431811Sbill }
441811Sbill 
tmclose(io)451811Sbill tmclose(io)
461924Swnj 	register struct iob *io;
471811Sbill {
483263Swnj 	tmstrategy(io, TM_REW);
491811Sbill }
501811Sbill 
tmstrategy(io,func)511811Sbill tmstrategy(io, func)
521924Swnj 	register struct iob *io;
531811Sbill {
5433531Sbostic 	register int com, errcnt;
5533531Sbostic 	register struct tmdevice *tmaddr;
563263Swnj 	int word, info;
571811Sbill 
5833531Sbostic 	tmaddr = (struct tmdevice *)ubamem(io->i_adapt, tmstd[io->i_ctlr]);
591811Sbill 	errcnt = 0;
601811Sbill retry:
613263Swnj 	tmquiet(tmaddr);
621811Sbill 	info = ubasetup(io, 1);
633263Swnj 	tmaddr->tmbc = -io->i_cc;
643263Swnj 	tmaddr->tmba = info;
6533531Sbostic 	com = (io->i_unit<<8) | TM_GO;
66*49100Sbostic 	if (func == F_READ)
6733531Sbostic 		tmaddr->tmcs = com | TM_RCOM;
68*49100Sbostic 	else if (func == F_WRITE)
6933531Sbostic 		tmaddr->tmcs = com | TM_WCOM;
703263Swnj 	else if (func == TM_SREV) {
713263Swnj 		tmaddr->tmbc = -1;
7233531Sbostic 		tmaddr->tmcs = com | TM_SREV;
731924Swnj 		return (0);
741811Sbill 	} else
7533531Sbostic 		tmaddr->tmcs = com | func;
761924Swnj 	for (;;) {
773263Swnj 		word = tmaddr->tmcs;
7813568Ssam 		DELAY(100);
7911383Ssam 		if (word & TM_CUR)
801924Swnj 			break;
811924Swnj 	}
823263Swnj 	ubafree(io, info);
833263Swnj 	word = tmaddr->tmer;
8411383Ssam 	if (word & TMER_EOT)
8511383Ssam 		return (0);
8611383Ssam 	if (word & TM_ERR) {
8711383Ssam 		if (word & TMER_EOF)
8811383Ssam 			return (0);
8933531Sbostic 		printf("tm tape error: er=%b\n", word, TMER_BITS);
9033531Sbostic 		if (errcnt++ == 10) {
9133531Sbostic 			printf("tm: unrecovered error\n");
9211383Ssam 			return (-1);
931811Sbill 		}
943263Swnj 		tmstrategy(io, TM_SREV);
951811Sbill 		goto retry;
961811Sbill 	}
971811Sbill 	if (errcnt)
9833531Sbostic 		printf("tm: recovered by retry\n");
9911383Ssam 	if (word & TMER_EOF)
10011383Ssam 		return (0);
10111383Ssam 	return (io->i_cc + tmaddr->tmbc);
1021811Sbill }
1031811Sbill 
tmquiet(tmaddr)1043263Swnj tmquiet(tmaddr)
1055157Sroot 	register struct tmdevice *tmaddr;
1061811Sbill {
1071924Swnj 	register word;
1081924Swnj 	for (;;) {
1093263Swnj 		word = tmaddr->tmcs;
11013568Ssam 		DELAY(100);
1113263Swnj 		if (word&TM_CUR)
1121924Swnj 			break;
1131924Swnj 	}
1141924Swnj 	for (;;) {
1153263Swnj 		word = tmaddr->tmer;
11613568Ssam 		DELAY(100);
1173263Swnj 		if ((word&TMER_TUR) && (word&TMER_SDWN)==0)
1181924Swnj 			break;
1191924Swnj 	}
1201811Sbill }
121