xref: /original-bsd/sys/vax/stand/tm.c (revision 56abee86)
1 /*	tm.c	4.2	12/18/80	*/
2 /*
3  * TM tape driver
4  */
5 
6 #include "../h/param.h"
7 #include "../h/inode.h"
8 #include "../h/pte.h"
9 #include "../h/uba.h"
10 #include "saio.h"
11 
12 struct device {
13 	short	tmer;
14 	short	tmcs;
15 	short	tmbc;
16 	u_short	tmba;
17 	short	tmdb;
18 	short	tmrd;
19 };
20 
21 #define TMADDR ((struct device *)(PHYSUMEM + 0772520 - UNIBASE))
22 
23 #define GO	01
24 #define RCOM	02
25 #define WCOM	04
26 #define WEOT	06
27 #define SFORW	010
28 #define SREV	012
29 #define WIRG	014
30 #define REW	016
31 
32 #define DENS	0		/* 1600 bpi */
33 
34 #define CRDY	0200		/* tmcs: control unit ready */
35 #define TUR	1		/* tmer: tape unit ready */
36 #define SDWN	010		/* tmer: tape settle down */
37 #define HARD	0102200		/* tmer: ILC, EOT, NXM */
38 #define EOT	0040000		/* tmer: at end of tape */
39 
40 #define SSEEK	1
41 #define SIO	2
42 
43 tmopen(io)
44 	register struct iob *io;
45 {
46 	register skip;
47 
48 	tmstrategy(io, REW);
49 	skip = io->i_boff;
50 	while (skip--) {
51 		io->i_cc = 0;
52 		while (tmstrategy(io, SFORW))
53 			;
54 	}
55 }
56 
57 tmclose(io)
58 	register struct iob *io;
59 {
60 
61 	tmstrategy(io, REW);
62 }
63 
64 tmstrategy(io, func)
65 	register struct iob *io;
66 {
67 	register int com, unit, errcnt;
68 	int word;
69 	int info;
70 
71 	unit = io->i_unit;
72 	errcnt = 0;
73 retry:
74 	tmquiet();
75 	com = (unit<<8)|DENS;
76 	info = ubasetup(io, 1);
77 	TMADDR->tmbc = -io->i_cc;
78 	TMADDR->tmba = info;
79 	if (func == READ)
80 		TMADDR->tmcs = com | RCOM | GO;
81 	else if (func == WRITE)
82 		TMADDR->tmcs = com | WCOM | GO;
83 	else if (func == SREV) {
84 		TMADDR->tmbc = -1;
85 		TMADDR->tmcs = com | SREV | GO;
86 		return (0);
87 	} else
88 		TMADDR->tmcs = com | func | GO;
89 	for (;;) {
90 		word = TMADDR->tmcs;
91 		if (word&CRDY)
92 			break;
93 	}
94 		;
95 	ubafree(info);
96 	word = TMADDR->tmer;
97 	if (word&EOT)
98 		return(0);
99 	if (word < 0) {
100 		if (errcnt == 0)
101 			printf("tape error: er=%o", TMADDR->tmer);
102 		if (errcnt==10) {
103 			printf("\n");
104 			return(-1);
105 		}
106 		errcnt++;
107 		tmstrategy(io, SREV);
108 		goto retry;
109 	}
110 	if (errcnt)
111 		printf(" recovered by retry\n");
112 	return (io->i_cc+TMADDR->tmbc);
113 }
114 
115 tmquiet()
116 {
117 	register word;
118 	for (;;) {
119 		word = TMADDR->tmcs;
120 		if (word&CRDY)
121 			break;
122 	}
123 	for (;;) {
124 		word = TMADDR->tmer;
125 		if ((word&TUR) && (word&SDWN)==0)
126 			break;
127 	}
128 }
129