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