xref: /csrg-svn/sys/vax/stand/ts.c (revision 3344)
1*3344Swnj /*	ts.c	4.2	81/03/21	*/
23268Swnj 
33268Swnj /*
43268Swnj  * TS11 tape driver
53268Swnj  */
63268Swnj 
73268Swnj #include "../h/param.h"
83268Swnj #include "../h/tsreg.h"
93268Swnj #include "../h/inode.h"
103268Swnj #include "../h/pte.h"
113268Swnj #include "../h/ubareg.h"
123268Swnj #include "saio.h"
133268Swnj #include "savax.h"
143268Swnj 
153268Swnj 
163268Swnj u_short	tsstd[] = { 0772520 };
173268Swnj 
183268Swnj struct	iob	ctsbuf;
193268Swnj 
203268Swnj u_short	ts_uba;			/* Unibus address of ts structure */
213268Swnj 
223268Swnj struct device *tsaddr = 0;
233268Swnj 
243268Swnj struct ts {
253268Swnj 	struct ts_cmd ts_cmd;
263268Swnj 	struct ts_char ts_char;
273268Swnj 	struct ts_sts ts_sts;
283268Swnj } ts;
293268Swnj 
303268Swnj tsopen(io)
313268Swnj 	register struct iob *io;
323268Swnj {
333268Swnj 	static struct ts *ts_ubaddr;
34*3344Swnj 	long i = 0;
353268Swnj 
363268Swnj 	if (tsaddr == 0)
373268Swnj 		tsaddr = ubamem(io->i_unit, tsstd[0]);
38*3344Swnj 	tsaddr->tssr = 0;
39*3344Swnj 	while ((tsaddr->tssr & TS_SSR)==0) {
40*3344Swnj 		if (++i > 1000000) {
41*3344Swnj 			printf("ts: not ready\n");
42*3344Swnj 			return;
433268Swnj 		}
443268Swnj 	}
453268Swnj 	if (tsaddr->tssr&TS_OFL) {
463268Swnj 		printf("ts: offline\n");
473268Swnj 		return;
483268Swnj 	}
493268Swnj 	if (tsaddr->tssr&TS_NBA) {
50*3344Swnj 		int i;
51*3344Swnj 
523268Swnj 		ctsbuf.i_ma = (caddr_t) &ts;
533268Swnj 		ctsbuf.i_cc = sizeof(ts);
543268Swnj 		if (ts_ubaddr == 0)
55*3344Swnj 			ts_ubaddr = (struct ts *)ubasetup(&ctsbuf, 2);
56*3344Swnj 		ts_uba = (u_short)((long)ts_ubaddr + (((long)ts_ubaddr>>16)&03));
573268Swnj 		ts.ts_char.char_addr = (int)&ts_ubaddr->ts_sts;
583268Swnj 		ts.ts_char.char_size = sizeof(ts.ts_sts);
59*3344Swnj 		ts.ts_char.char_mode = TS_ESS;
60*3344Swnj 		ts.ts_cmd.c_cmd = TS_ACK|TS_SETCHR;
61*3344Swnj 		i = (int)&ts_ubaddr->ts_char;
62*3344Swnj 		ts.ts_cmd.c_loba = i;
63*3344Swnj 		ts.ts_cmd.c_hiba = (i>>16)&3;
643268Swnj 		ts.ts_cmd.c_size = sizeof(ts.ts_char);
653268Swnj 		tsaddr->tsdb = ts_uba;
663268Swnj 	}
673268Swnj 	tsstrategy(io, TS_REW);
683268Swnj 	if (io->i_cc = io->i_boff)
693268Swnj 		tsstrategy(io, TS_SFORWF);
703268Swnj }
713268Swnj 
723268Swnj tsclose(io)
733268Swnj 	register struct iob *io;
743268Swnj {
75*3344Swnj 
763268Swnj 	tsstrategy(io, TS_REW);
773268Swnj }
783268Swnj 
793268Swnj tsstrategy(io, func)
803268Swnj 	register struct iob *io;
813268Swnj {
82*3344Swnj 	register int errcnt, info = 0;
833268Swnj 
843268Swnj 	errcnt = 0;
853268Swnj retry:
863268Swnj 	while ((tsaddr->tssr & TS_SSR) == 0)
87*3344Swnj 		DELAY(100);
88*3344Swnj 	if (func == TS_REW || func == TS_SFORWF)
89*3344Swnj 		ts.ts_cmd.c_repcnt = io->i_cc;
90*3344Swnj 	else {
91*3344Swnj 		info = ubasetup(io, 1);
92*3344Swnj 		ts.ts_cmd.c_size = io->i_cc;
93*3344Swnj 		ts.ts_cmd.c_loba = info;
94*3344Swnj 		ts.ts_cmd.c_hiba = (info>>16)&3;
95*3344Swnj 	}
963268Swnj 	if (func == READ)
973268Swnj 		func = TS_RCOM;
983268Swnj 	else if (func == WRITE)
993268Swnj 		func = TS_WCOM;
1003268Swnj 	ts.ts_cmd.c_cmd = TS_ACK|TS_CVC|func;
1013268Swnj 	tsaddr->tsdb = ts_uba;
102*3344Swnj 	do
103*3344Swnj 		DELAY(100)
104*3344Swnj 	while ((tsaddr->tssr & TS_SSR) == 0);
105*3344Swnj 	if (info)
106*3344Swnj 		ubafree(io, info);
107*3344Swnj 	if (ts.ts_sts.s_xs0 & TS_TMK)
1083268Swnj 		return (0);
1093268Swnj 	if (tsaddr->tssr & TS_SC) {
1103268Swnj 		if (errcnt == 0)
1113268Swnj 			printf("ts tape error: er=%o", tsaddr->tssr);
1123268Swnj 		if (errcnt==10) {
1133268Swnj 			printf("\n");
1143268Swnj 			return (-1);
1153268Swnj 		}
1163268Swnj 		errcnt++;
1173268Swnj 		if (func == TS_RCOM || func == TS_WCOM)
1183268Swnj 			func |= TS_RETRY;
1193268Swnj 		goto retry;
1203268Swnj 	}
1213268Swnj 	if (errcnt)
1223268Swnj 		printf(" recovered by retry\n");
1233268Swnj 	return (io->i_cc - ts.ts_sts.s_rbpcr);
1243268Swnj }
125