xref: /csrg-svn/sys/vax/stand/ts.c (revision 5158)
1*5158Sroot /*	ts.c	4.4	81/12/01	*/
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 
22*5158Sroot struct tsdevice *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;
343344Swnj 	long i = 0;
353268Swnj 
363268Swnj 	if (tsaddr == 0)
373268Swnj 		tsaddr = ubamem(io->i_unit, tsstd[0]);
383344Swnj 	tsaddr->tssr = 0;
393344Swnj 	while ((tsaddr->tssr & TS_SSR)==0) {
403344Swnj 		if (++i > 1000000) {
413344Swnj 			printf("ts: not ready\n");
423344Swnj 			return;
433268Swnj 		}
443268Swnj 	}
453268Swnj 	if (tsaddr->tssr&TS_OFL) {
463268Swnj 		printf("ts: offline\n");
473268Swnj 		return;
483268Swnj 	}
493268Swnj 	if (tsaddr->tssr&TS_NBA) {
503344Swnj 		int i;
513344Swnj 
523268Swnj 		ctsbuf.i_ma = (caddr_t) &ts;
533268Swnj 		ctsbuf.i_cc = sizeof(ts);
543268Swnj 		if (ts_ubaddr == 0)
553344Swnj 			ts_ubaddr = (struct ts *)ubasetup(&ctsbuf, 2);
563344Swnj 		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);
593344Swnj 		ts.ts_char.char_mode = TS_ESS;
603344Swnj 		ts.ts_cmd.c_cmd = TS_ACK|TS_SETCHR;
613344Swnj 		i = (int)&ts_ubaddr->ts_char;
623344Swnj 		ts.ts_cmd.c_loba = i;
633344Swnj 		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 {
753344Swnj 
763268Swnj 	tsstrategy(io, TS_REW);
773268Swnj }
783268Swnj 
793268Swnj tsstrategy(io, func)
803268Swnj 	register struct iob *io;
813268Swnj {
823344Swnj 	register int errcnt, info = 0;
833268Swnj 
843268Swnj 	errcnt = 0;
853268Swnj retry:
863268Swnj 	while ((tsaddr->tssr & TS_SSR) == 0)
873344Swnj 		DELAY(100);
883344Swnj 	if (func == TS_REW || func == TS_SFORWF)
893344Swnj 		ts.ts_cmd.c_repcnt = io->i_cc;
903344Swnj 	else {
913344Swnj 		info = ubasetup(io, 1);
923344Swnj 		ts.ts_cmd.c_size = io->i_cc;
933344Swnj 		ts.ts_cmd.c_loba = info;
943344Swnj 		ts.ts_cmd.c_hiba = (info>>16)&3;
953344Swnj 	}
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;
1023344Swnj 	do
1033344Swnj 		DELAY(100)
1043344Swnj 	while ((tsaddr->tssr & TS_SSR) == 0);
1053344Swnj 	if (info)
1063344Swnj 		ubafree(io, info);
1073344Swnj 	if (ts.ts_sts.s_xs0 & TS_TMK)
1083268Swnj 		return (0);
1093268Swnj 	if (tsaddr->tssr & TS_SC) {
1103349Swnj 		printf("ts tape error: er=%b, xs0=%b",
1113349Swnj 		    tsaddr->tssr, TSSR_BITS,
1123349Swnj 		    ts.ts_sts.s_xs0, TSXS0_BITS);
1133268Swnj 		if (errcnt==10) {
1143349Swnj 			printf("ts: unrecovered error\n");
1153268Swnj 			return (-1);
1163268Swnj 		}
1173268Swnj 		errcnt++;
1183268Swnj 		if (func == TS_RCOM || func == TS_WCOM)
1193268Swnj 			func |= TS_RETRY;
1203268Swnj 		goto retry;
1213268Swnj 	}
1223268Swnj 	if (errcnt)
1233349Swnj 		printf("ts: recovered by retry\n");
1243268Swnj 	return (io->i_cc - ts.ts_sts.s_rbpcr);
1253268Swnj }
126