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