xref: /csrg-svn/sys/vax/stand/tm.c (revision 33550)
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.4 (Berkeley) 02/24/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 		return (ENXIO);
36 	tmstrategy(io, TM_REW);
37 	for (skip = io->i_part; skip--;) {
38 		io->i_cc = 0;
39 		tmstrategy(io, TM_SFORW);
40 	}
41 	return (0);
42 }
43 
44 tmclose(io)
45 	register struct iob *io;
46 {
47 	tmstrategy(io, TM_REW);
48 }
49 
50 tmstrategy(io, func)
51 	register struct iob *io;
52 {
53 	register int com, errcnt;
54 	register struct tmdevice *tmaddr;
55 	int word, info;
56 
57 	tmaddr = (struct tmdevice *)ubamem(io->i_adapt, tmstd[io->i_ctlr]);
58 	errcnt = 0;
59 retry:
60 	tmquiet(tmaddr);
61 	info = ubasetup(io, 1);
62 	tmaddr->tmbc = -io->i_cc;
63 	tmaddr->tmba = info;
64 	com = (io->i_unit<<8) | TM_GO;
65 	if (func == READ)
66 		tmaddr->tmcs = com | TM_RCOM;
67 	else if (func == WRITE)
68 		tmaddr->tmcs = com | TM_WCOM;
69 	else if (func == TM_SREV) {
70 		tmaddr->tmbc = -1;
71 		tmaddr->tmcs = com | TM_SREV;
72 		return (0);
73 	} else
74 		tmaddr->tmcs = com | func;
75 	for (;;) {
76 		word = tmaddr->tmcs;
77 		DELAY(100);
78 		if (word & TM_CUR)
79 			break;
80 	}
81 	ubafree(io, info);
82 	word = tmaddr->tmer;
83 	if (word & TMER_EOT)
84 		return (0);
85 	if (word & TM_ERR) {
86 		if (word & TMER_EOF)
87 			return (0);
88 		printf("tm tape error: er=%b\n", word, TMER_BITS);
89 		if (errcnt++ == 10) {
90 			printf("tm: unrecovered error\n");
91 			return (-1);
92 		}
93 		tmstrategy(io, TM_SREV);
94 		goto retry;
95 	}
96 	if (errcnt)
97 		printf("tm: recovered by retry\n");
98 	if (word & TMER_EOF)
99 		return (0);
100 	return (io->i_cc + tmaddr->tmbc);
101 }
102 
103 tmquiet(tmaddr)
104 	register struct tmdevice *tmaddr;
105 {
106 	register word;
107 	for (;;) {
108 		word = tmaddr->tmcs;
109 		DELAY(100);
110 		if (word&TM_CUR)
111 			break;
112 	}
113 	for (;;) {
114 		word = tmaddr->tmer;
115 		DELAY(100);
116 		if ((word&TMER_TUR) && (word&TMER_SDWN)==0)
117 			break;
118 	}
119 }
120