Commit | Line | Data |
---|---|---|
32ce6f5e BJ |
1 | /* tm.c 4.1 %G% */ |
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 WEOF 06 | |
27 | #define SFORW 010 | |
28 | #define SREV 012 | |
29 | #define WIRG 014 | |
30 | #define REW 016 | |
31 | #define DENS 060000 /* 9-channel */ | |
32 | #define IENABLE 0100 | |
33 | #define CRDY 0200 | |
34 | #define GAPSD 010000 | |
35 | #define TUR 1 | |
36 | #define SDWN 010 | |
37 | #define HARD 0102200 /* ILC, EOT, NXM */ | |
38 | #define EOF 0040000 | |
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 | tmstrategy(io, REW); | |
61 | } | |
62 | ||
63 | tmstrategy(io, func) | |
64 | register struct iob *io; | |
65 | { | |
66 | register int com, unit, errcnt; | |
67 | int info; | |
68 | ||
69 | unit = io->i_unit; | |
70 | errcnt = 0; | |
71 | retry: | |
72 | tmquiet(); | |
73 | com = (unit<<8)|DENS; | |
74 | info = ubasetup(io, 1); | |
75 | TMADDR->tmbc = -io->i_cc; | |
76 | TMADDR->tmba = info; | |
77 | if (func == READ) | |
78 | TMADDR->tmcs = com | RCOM | GO; | |
79 | else if (func == WRITE) | |
80 | TMADDR->tmcs = com | WCOM | GO; | |
81 | else if (func == SREV) { | |
82 | TMADDR->tmbc = -1; | |
83 | TMADDR->tmcs = com | SREV | GO; | |
84 | return(0); | |
85 | } else | |
86 | TMADDR->tmcs = com | func | GO; | |
87 | while ((TMADDR->tmcs&CRDY) == 0) | |
88 | ; | |
89 | ubafree(info); | |
90 | if (TMADDR->tmer&EOF) | |
91 | return(0); | |
92 | if (TMADDR->tmer < 0) { | |
93 | if (errcnt == 0) | |
94 | printf("tape error: er=%o", TMADDR->tmer); | |
95 | if (errcnt==10) { | |
96 | printf("\n"); | |
97 | return(-1); | |
98 | } | |
99 | errcnt++; | |
100 | tmstrategy(io, SREV); | |
101 | goto retry; | |
102 | } | |
103 | if (errcnt) | |
104 | printf(" recovered by retry\n"); | |
105 | return( io->i_cc+TMADDR->tmbc ); | |
106 | } | |
107 | ||
108 | tmquiet() | |
109 | { | |
110 | while ((TMADDR->tmcs&CRDY) == 0) | |
111 | ; | |
112 | while ((TMADDR->tmer&TUR) == 0) | |
113 | ; | |
114 | while ((TMADDR->tmer&SDWN) != 0) | |
115 | ; | |
116 | } |