|
|
1.1 root 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: * @(#)ts.c 7.5 (Berkeley) 7/9/88
7: */
8:
9: /*
10: * TS11 tape driver
11: */
12:
13: #include "param.h"
14: #include "inode.h"
15: #include "fs.h"
16:
17: #include "../vax/pte.h"
18:
19: #include "../vaxuba/tsreg.h"
20: #include "../vaxuba/ubareg.h"
21:
22: #include "saio.h"
23: #include "savax.h"
24:
25: #define MAXCTLR 1 /* all addresses must be specified */
26: u_short tsstd[MAXCTLR] = { 0772520 };
27:
28: struct iob ctsbuf;
29:
30: u_short ts_uba; /* Unibus address of ts structure */
31:
32: struct ts {
33: struct ts_cmd ts_cmd;
34: struct ts_char ts_char;
35: struct ts_sts ts_sts;
36: } ts;
37:
38: tsopen(io)
39: register struct iob *io;
40: {
41: static struct ts *ts_ubaddr;
42: register struct tsdevice *tsaddr;
43: long i = 0;
44:
45: if ((u_int)io->i_adapt >= nuba)
46: return (EADAPT);
47: if ((u_int)io->i_ctlr >= MAXCTLR)
48: return (ECTLR);
49: /* TS11 only supports one transport per formatter */
50: if (io->i_unit)
51: return(EUNIT);
52: tsaddr = (struct tsdevice *)ubamem(io->i_adapt, tsstd[io->i_ctlr]);
53: if (badaddr((char *)tsaddr, sizeof (short)))
54: return (ENXIO);
55: tsaddr->tssr = 0;
56: while ((tsaddr->tssr & TS_SSR)==0) {
57: DELAY(10);
58: if (++i > 1000000) {
59: printf("ts: not ready\n");
60: return (ENXIO);
61: }
62: }
63: if (tsaddr->tssr&TS_OFL) {
64: printf("ts: offline\n");
65: return (ENXIO);
66: }
67: if (tsaddr->tssr&TS_NBA) {
68: int i;
69:
70: ctsbuf.i_ma = (caddr_t) &ts;
71: ctsbuf.i_cc = sizeof(ts);
72: if (ts_ubaddr == 0)
73: ts_ubaddr = (struct ts *)ubasetup(&ctsbuf, 2);
74: ts_uba = (u_short)((long)ts_ubaddr + (((long)ts_ubaddr>>16)&03));
75: ts.ts_char.char_addr = (int)&ts_ubaddr->ts_sts;
76: ts.ts_char.char_size = sizeof(ts.ts_sts);
77: ts.ts_char.char_mode = TS_ESS;
78: ts.ts_cmd.c_cmd = TS_ACK|TS_SETCHR;
79: i = (int)&ts_ubaddr->ts_char;
80: ts.ts_cmd.c_loba = i;
81: ts.ts_cmd.c_hiba = (i>>16)&3;
82: ts.ts_cmd.c_size = sizeof(ts.ts_char);
83: tsaddr->tsdb = ts_uba;
84: }
85: tsstrategy(io, TS_REW);
86: if (io->i_cc = io->i_part)
87: tsstrategy(io, TS_SFORWF);
88: return (0);
89: }
90:
91: tsclose(io)
92: register struct iob *io;
93: {
94: tsstrategy(io, TS_REW);
95: }
96:
97: tsstrategy(io, func)
98: register struct iob *io;
99: {
100: register struct tsdevice *tsaddr;
101: register int errcnt, info;
102:
103: tsaddr = (struct tsdevice *)ubamem(io->i_adapt, tsstd[io->i_ctlr]);
104: errcnt = info = 0;
105: retry:
106: while ((tsaddr->tssr & TS_SSR) == 0)
107: DELAY(100);
108: if (func == TS_REW || func == TS_SFORWF)
109: ts.ts_cmd.c_repcnt = io->i_cc;
110: else {
111: info = ubasetup(io, 1);
112: ts.ts_cmd.c_size = io->i_cc;
113: ts.ts_cmd.c_loba = info;
114: ts.ts_cmd.c_hiba = (info>>16)&3;
115: if (func == READ)
116: func = TS_RCOM;
117: else if (func == WRITE)
118: func = TS_WCOM;
119: }
120: ts.ts_cmd.c_cmd = TS_ACK|TS_CVC|func;
121: tsaddr->tsdb = ts_uba;
122: do
123: DELAY(100)
124: while ((tsaddr->tssr & TS_SSR) == 0);
125: if (info)
126: ubafree(io, info);
127: if (ts.ts_sts.s_xs0 & TS_TMK)
128: return (0);
129: if (tsaddr->tssr & TS_SC) {
130: printf("ts tape error: er=%b, xs0=%b\n",
131: tsaddr->tssr, TSSR_BITS,
132: ts.ts_sts.s_xs0, TSXS0_BITS);
133: if (errcnt++ == 10) {
134: printf("ts: unrecovered error\n");
135: return (-1);
136: }
137: if (func == TS_RCOM || func == TS_WCOM)
138: func |= TS_RETRY;
139: goto retry;
140: }
141: if (errcnt)
142: printf("ts: recovered by retry\n");
143: return (io->i_cc - ts.ts_sts.s_rbpcr);
144: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.