xref: /csrg-svn/sys/vax/stand/tm.c (revision 35052)
123244Smckusick /*
2*35052Skarels  * 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*35052Skarels  *	@(#)tm.c	7.5 (Berkeley) 07/09/88
723244Smckusick  */
83263Swnj 
91811Sbill /*
103263Swnj  * TM11/TE??
111811Sbill  */
121811Sbill 
1333408Skarels #include "param.h"
1433408Skarels #include "inode.h"
1533408Skarels #include "fs.h"
169186Ssam 
17*35052Skarels #include "../vax/pte.h"
18*35052Skarels 
199186Ssam #include "../vaxuba/ubareg.h"
209186Ssam #include "../vaxuba/tmreg.h"
219186Ssam 
221811Sbill #include "saio.h"
233263Swnj #include "savax.h"
241811Sbill 
2533531Sbostic #define	MAXCTLR		1		/* all addresses must be specified */
2633531Sbostic u_short	tmstd[MAXCTLR] = { 0172520 };
271811Sbill 
281811Sbill tmopen(io)
291924Swnj 	register struct iob *io;
301811Sbill {
3133531Sbostic 	register int skip;
321811Sbill 
33*35052Skarels 	if ((u_int)io->i_adapt >= nuba)
34*35052Skarels 		return (EADAPT);
3533531Sbostic 	if ((u_int)io->i_ctlr >= MAXCTLR)
3633531Sbostic 		return (ECTLR);
3733550Sbostic 	if (badaddr((char *)ubamem(io->i_adapt, tmstd[io->i_ctlr]), sizeof(short)))
3833408Skarels 		return (ENXIO);
393263Swnj 	tmstrategy(io, TM_REW);
4033531Sbostic 	for (skip = io->i_part; skip--;) {
411811Sbill 		io->i_cc = 0;
423477Sroot 		tmstrategy(io, TM_SFORW);
431811Sbill 	}
4433408Skarels 	return (0);
451811Sbill }
461811Sbill 
471811Sbill tmclose(io)
481924Swnj 	register struct iob *io;
491811Sbill {
503263Swnj 	tmstrategy(io, TM_REW);
511811Sbill }
521811Sbill 
531811Sbill tmstrategy(io, func)
541924Swnj 	register struct iob *io;
551811Sbill {
5633531Sbostic 	register int com, errcnt;
5733531Sbostic 	register struct tmdevice *tmaddr;
583263Swnj 	int word, info;
591811Sbill 
6033531Sbostic 	tmaddr = (struct tmdevice *)ubamem(io->i_adapt, tmstd[io->i_ctlr]);
611811Sbill 	errcnt = 0;
621811Sbill retry:
633263Swnj 	tmquiet(tmaddr);
641811Sbill 	info = ubasetup(io, 1);
653263Swnj 	tmaddr->tmbc = -io->i_cc;
663263Swnj 	tmaddr->tmba = info;
6733531Sbostic 	com = (io->i_unit<<8) | TM_GO;
681811Sbill 	if (func == READ)
6933531Sbostic 		tmaddr->tmcs = com | TM_RCOM;
701811Sbill 	else if (func == WRITE)
7133531Sbostic 		tmaddr->tmcs = com | TM_WCOM;
723263Swnj 	else if (func == TM_SREV) {
733263Swnj 		tmaddr->tmbc = -1;
7433531Sbostic 		tmaddr->tmcs = com | TM_SREV;
751924Swnj 		return (0);
761811Sbill 	} else
7733531Sbostic 		tmaddr->tmcs = com | func;
781924Swnj 	for (;;) {
793263Swnj 		word = tmaddr->tmcs;
8013568Ssam 		DELAY(100);
8111383Ssam 		if (word & TM_CUR)
821924Swnj 			break;
831924Swnj 	}
843263Swnj 	ubafree(io, info);
853263Swnj 	word = tmaddr->tmer;
8611383Ssam 	if (word & TMER_EOT)
8711383Ssam 		return (0);
8811383Ssam 	if (word & TM_ERR) {
8911383Ssam 		if (word & TMER_EOF)
9011383Ssam 			return (0);
9133531Sbostic 		printf("tm tape error: er=%b\n", word, TMER_BITS);
9233531Sbostic 		if (errcnt++ == 10) {
9333531Sbostic 			printf("tm: unrecovered error\n");
9411383Ssam 			return (-1);
951811Sbill 		}
963263Swnj 		tmstrategy(io, TM_SREV);
971811Sbill 		goto retry;
981811Sbill 	}
991811Sbill 	if (errcnt)
10033531Sbostic 		printf("tm: recovered by retry\n");
10111383Ssam 	if (word & TMER_EOF)
10211383Ssam 		return (0);
10311383Ssam 	return (io->i_cc + tmaddr->tmbc);
1041811Sbill }
1051811Sbill 
1063263Swnj tmquiet(tmaddr)
1075157Sroot 	register struct tmdevice *tmaddr;
1081811Sbill {
1091924Swnj 	register word;
1101924Swnj 	for (;;) {
1113263Swnj 		word = tmaddr->tmcs;
11213568Ssam 		DELAY(100);
1133263Swnj 		if (word&TM_CUR)
1141924Swnj 			break;
1151924Swnj 	}
1161924Swnj 	for (;;) {
1173263Swnj 		word = tmaddr->tmer;
11813568Ssam 		DELAY(100);
1193263Swnj 		if ((word&TMER_TUR) && (word&TMER_SDWN)==0)
1201924Swnj 			break;
1211924Swnj 	}
1221811Sbill }
123