xref: /csrg-svn/sys/vax/stand/tm.c (revision 14279)
1 /*	tm.c	6.1	83/07/29	*/
2 
3 /*
4  * TM11/TE??
5  */
6 #include "../machine/pte.h"
7 
8 #include "../h/param.h"
9 #include "../h/inode.h"
10 #include "../h/fs.h"
11 
12 #include "../vaxuba/ubareg.h"
13 #include "../vaxuba/tmreg.h"
14 
15 #include "saio.h"
16 #include "savax.h"
17 
18 
19 u_short	tmstd[] = { 0172520 };
20 
21 tmopen(io)
22 	register struct iob *io;
23 {
24 	register skip;
25 
26 	tmstrategy(io, TM_REW);
27 	skip = io->i_boff;
28 	while (skip--) {
29 		io->i_cc = 0;
30 		tmstrategy(io, TM_SFORW);
31 	}
32 }
33 
34 tmclose(io)
35 	register struct iob *io;
36 {
37 
38 	tmstrategy(io, TM_REW);
39 }
40 
41 tmstrategy(io, func)
42 	register struct iob *io;
43 {
44 	register int com, unit, errcnt;
45 	register struct tmdevice *tmaddr =
46 	    (struct tmdevice *)ubamem(io->i_unit, tmstd[0]);
47 	int word, info;
48 
49 	unit = io->i_unit;
50 	errcnt = 0;
51 retry:
52 	tmquiet(tmaddr);
53 	com = (unit<<8);
54 	info = ubasetup(io, 1);
55 	tmaddr->tmbc = -io->i_cc;
56 	tmaddr->tmba = info;
57 	if (func == READ)
58 		tmaddr->tmcs = com | TM_RCOM | TM_GO;
59 	else if (func == WRITE)
60 		tmaddr->tmcs = com | TM_WCOM | TM_GO;
61 	else if (func == TM_SREV) {
62 		tmaddr->tmbc = -1;
63 		tmaddr->tmcs = com | TM_SREV | TM_GO;
64 		return (0);
65 	} else
66 		tmaddr->tmcs = com | func | TM_GO;
67 	for (;;) {
68 		word = tmaddr->tmcs;
69 		DELAY(100);
70 		if (word & TM_CUR)
71 			break;
72 	}
73 	ubafree(io, info);
74 	word = tmaddr->tmer;
75 	if (word & TMER_EOT)
76 		return (0);
77 	if (word & TM_ERR) {
78 		if (word & TMER_EOF)
79 			return (0);
80 		if (errcnt == 0)
81 			printf("te error: er=%b", word, TMER_BITS);
82 		if (errcnt == 10) {
83 			printf("\n");
84 			return (-1);
85 		}
86 		errcnt++;
87 		tmstrategy(io, TM_SREV);
88 		goto retry;
89 	}
90 	if (errcnt)
91 		printf(" recovered by retry\n");
92 	if (word & TMER_EOF)
93 		return (0);
94 	return (io->i_cc + tmaddr->tmbc);
95 }
96 
97 tmquiet(tmaddr)
98 	register struct tmdevice *tmaddr;
99 {
100 	register word;
101 	for (;;) {
102 		word = tmaddr->tmcs;
103 		DELAY(100);
104 		if (word&TM_CUR)
105 			break;
106 	}
107 	for (;;) {
108 		word = tmaddr->tmer;
109 		DELAY(100);
110 		if ((word&TMER_TUR) && (word&TMER_SDWN)==0)
111 			break;
112 	}
113 }
114