xref: /csrg-svn/sys/vax/stand/tm.c (revision 33531)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)tm.c	7.3 (Berkeley) 02/22/88
7  */
8 
9 /*
10  * TM11/TE??
11  */
12 #include "../machine/pte.h"
13 
14 #include "param.h"
15 #include "inode.h"
16 #include "fs.h"
17 
18 #include "../vaxuba/ubareg.h"
19 #include "../vaxuba/tmreg.h"
20 
21 #include "saio.h"
22 #include "savax.h"
23 
24 #define	MAXCTLR		1		/* all addresses must be specified */
25 u_short	tmstd[MAXCTLR] = { 0172520 };
26 
27 tmopen(io)
28 	register struct iob *io;
29 {
30 	register int skip;
31 
32 	if ((u_int)io->i_ctlr >= MAXCTLR)
33 		return (ECTLR);
34 	if (badaddr((char *)ubamem(io->i_adapt, tmstd[io->i_ctlr]), sizeof(short))) {
35 		printf("tm: nonexistent device\n");
36 		return (ENXIO);
37 	}
38 	tmstrategy(io, TM_REW);
39 	for (skip = io->i_part; skip--;) {
40 		io->i_cc = 0;
41 		tmstrategy(io, TM_SFORW);
42 	}
43 	return (0);
44 }
45 
46 tmclose(io)
47 	register struct iob *io;
48 {
49 	tmstrategy(io, TM_REW);
50 }
51 
52 tmstrategy(io, func)
53 	register struct iob *io;
54 {
55 	register int com, errcnt;
56 	register struct tmdevice *tmaddr;
57 	int word, info;
58 
59 	tmaddr = (struct tmdevice *)ubamem(io->i_adapt, tmstd[io->i_ctlr]);
60 	errcnt = 0;
61 retry:
62 	tmquiet(tmaddr);
63 	info = ubasetup(io, 1);
64 	tmaddr->tmbc = -io->i_cc;
65 	tmaddr->tmba = info;
66 	com = (io->i_unit<<8) | TM_GO;
67 	if (func == READ)
68 		tmaddr->tmcs = com | TM_RCOM;
69 	else if (func == WRITE)
70 		tmaddr->tmcs = com | TM_WCOM;
71 	else if (func == TM_SREV) {
72 		tmaddr->tmbc = -1;
73 		tmaddr->tmcs = com | TM_SREV;
74 		return (0);
75 	} else
76 		tmaddr->tmcs = com | func;
77 	for (;;) {
78 		word = tmaddr->tmcs;
79 		DELAY(100);
80 		if (word & TM_CUR)
81 			break;
82 	}
83 	ubafree(io, info);
84 	word = tmaddr->tmer;
85 	if (word & TMER_EOT)
86 		return (0);
87 	if (word & TM_ERR) {
88 		if (word & TMER_EOF)
89 			return (0);
90 		printf("tm tape error: er=%b\n", word, TMER_BITS);
91 		if (errcnt++ == 10) {
92 			printf("tm: unrecovered error\n");
93 			return (-1);
94 		}
95 		tmstrategy(io, TM_SREV);
96 		goto retry;
97 	}
98 	if (errcnt)
99 		printf("tm: recovered by retry\n");
100 	if (word & TMER_EOF)
101 		return (0);
102 	return (io->i_cc + tmaddr->tmbc);
103 }
104 
105 tmquiet(tmaddr)
106 	register struct tmdevice *tmaddr;
107 {
108 	register word;
109 	for (;;) {
110 		word = tmaddr->tmcs;
111 		DELAY(100);
112 		if (word&TM_CUR)
113 			break;
114 	}
115 	for (;;) {
116 		word = tmaddr->tmer;
117 		DELAY(100);
118 		if ((word&TMER_TUR) && (word&TMER_SDWN)==0)
119 			break;
120 	}
121 }
122