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