xref: /csrg-svn/sys/vax/stand/tm.c (revision 33550)
123244Smckusick /*
229311Smckusick  * Copyright (c) 1982, 1986 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*33550Sbostic  *	@(#)tm.c	7.4 (Berkeley) 02/24/88
723244Smckusick  */
83263Swnj 
91811Sbill /*
103263Swnj  * TM11/TE??
111811Sbill  */
129806Ssam #include "../machine/pte.h"
131811Sbill 
1433408Skarels #include "param.h"
1533408Skarels #include "inode.h"
1633408Skarels #include "fs.h"
179186Ssam 
189186Ssam #include "../vaxuba/ubareg.h"
199186Ssam #include "../vaxuba/tmreg.h"
209186Ssam 
211811Sbill #include "saio.h"
223263Swnj #include "savax.h"
231811Sbill 
2433531Sbostic #define	MAXCTLR		1		/* all addresses must be specified */
2533531Sbostic u_short	tmstd[MAXCTLR] = { 0172520 };
261811Sbill 
271811Sbill tmopen(io)
281924Swnj 	register struct iob *io;
291811Sbill {
3033531Sbostic 	register int skip;
311811Sbill 
3233531Sbostic 	if ((u_int)io->i_ctlr >= MAXCTLR)
3333531Sbostic 		return (ECTLR);
34*33550Sbostic 	if (badaddr((char *)ubamem(io->i_adapt, tmstd[io->i_ctlr]), sizeof(short)))
3533408Skarels 		return (ENXIO);
363263Swnj 	tmstrategy(io, TM_REW);
3733531Sbostic 	for (skip = io->i_part; skip--;) {
381811Sbill 		io->i_cc = 0;
393477Sroot 		tmstrategy(io, TM_SFORW);
401811Sbill 	}
4133408Skarels 	return (0);
421811Sbill }
431811Sbill 
441811Sbill tmclose(io)
451924Swnj 	register struct iob *io;
461811Sbill {
473263Swnj 	tmstrategy(io, TM_REW);
481811Sbill }
491811Sbill 
501811Sbill tmstrategy(io, func)
511924Swnj 	register struct iob *io;
521811Sbill {
5333531Sbostic 	register int com, errcnt;
5433531Sbostic 	register struct tmdevice *tmaddr;
553263Swnj 	int word, info;
561811Sbill 
5733531Sbostic 	tmaddr = (struct tmdevice *)ubamem(io->i_adapt, tmstd[io->i_ctlr]);
581811Sbill 	errcnt = 0;
591811Sbill retry:
603263Swnj 	tmquiet(tmaddr);
611811Sbill 	info = ubasetup(io, 1);
623263Swnj 	tmaddr->tmbc = -io->i_cc;
633263Swnj 	tmaddr->tmba = info;
6433531Sbostic 	com = (io->i_unit<<8) | TM_GO;
651811Sbill 	if (func == READ)
6633531Sbostic 		tmaddr->tmcs = com | TM_RCOM;
671811Sbill 	else if (func == WRITE)
6833531Sbostic 		tmaddr->tmcs = com | TM_WCOM;
693263Swnj 	else if (func == TM_SREV) {
703263Swnj 		tmaddr->tmbc = -1;
7133531Sbostic 		tmaddr->tmcs = com | TM_SREV;
721924Swnj 		return (0);
731811Sbill 	} else
7433531Sbostic 		tmaddr->tmcs = com | func;
751924Swnj 	for (;;) {
763263Swnj 		word = tmaddr->tmcs;
7713568Ssam 		DELAY(100);
7811383Ssam 		if (word & TM_CUR)
791924Swnj 			break;
801924Swnj 	}
813263Swnj 	ubafree(io, info);
823263Swnj 	word = tmaddr->tmer;
8311383Ssam 	if (word & TMER_EOT)
8411383Ssam 		return (0);
8511383Ssam 	if (word & TM_ERR) {
8611383Ssam 		if (word & TMER_EOF)
8711383Ssam 			return (0);
8833531Sbostic 		printf("tm tape error: er=%b\n", word, TMER_BITS);
8933531Sbostic 		if (errcnt++ == 10) {
9033531Sbostic 			printf("tm: unrecovered error\n");
9111383Ssam 			return (-1);
921811Sbill 		}
933263Swnj 		tmstrategy(io, TM_SREV);
941811Sbill 		goto retry;
951811Sbill 	}
961811Sbill 	if (errcnt)
9733531Sbostic 		printf("tm: recovered by retry\n");
9811383Ssam 	if (word & TMER_EOF)
9911383Ssam 		return (0);
10011383Ssam 	return (io->i_cc + tmaddr->tmbc);
1011811Sbill }
1021811Sbill 
1033263Swnj tmquiet(tmaddr)
1045157Sroot 	register struct tmdevice *tmaddr;
1051811Sbill {
1061924Swnj 	register word;
1071924Swnj 	for (;;) {
1083263Swnj 		word = tmaddr->tmcs;
10913568Ssam 		DELAY(100);
1103263Swnj 		if (word&TM_CUR)
1111924Swnj 			break;
1121924Swnj 	}
1131924Swnj 	for (;;) {
1143263Swnj 		word = tmaddr->tmer;
11513568Ssam 		DELAY(100);
1163263Swnj 		if ((word&TMER_TUR) && (word&TMER_SDWN)==0)
1171924Swnj 			break;
1181924Swnj 	}
1191811Sbill }
120