xref: /csrg-svn/sys/vax/stand/ts.c (revision 9186)
1*9186Ssam /*	ts.c	4.6	82/11/13	*/
23268Swnj 
33268Swnj /*
43268Swnj  * TS11 tape driver
53268Swnj  */
63268Swnj 
73268Swnj #include "../h/param.h"
83268Swnj #include "../h/inode.h"
93268Swnj #include "../h/pte.h"
107447Sroot #include "../h/fs.h"
11*9186Ssam 
12*9186Ssam #include "../vaxuba/tsreg.h"
13*9186Ssam #include "../vaxuba/ubareg.h"
14*9186Ssam 
153268Swnj #include "saio.h"
163268Swnj #include "savax.h"
173268Swnj 
183268Swnj 
193268Swnj u_short	tsstd[] = { 0772520 };
203268Swnj 
213268Swnj struct	iob	ctsbuf;
223268Swnj 
233268Swnj u_short	ts_uba;			/* Unibus address of ts structure */
243268Swnj 
255158Sroot struct tsdevice *tsaddr = 0;
263268Swnj 
273268Swnj struct ts {
283268Swnj 	struct ts_cmd ts_cmd;
293268Swnj 	struct ts_char ts_char;
303268Swnj 	struct ts_sts ts_sts;
313268Swnj } ts;
323268Swnj 
333268Swnj tsopen(io)
343268Swnj 	register struct iob *io;
353268Swnj {
363268Swnj 	static struct ts *ts_ubaddr;
373344Swnj 	long i = 0;
383268Swnj 
393268Swnj 	if (tsaddr == 0)
407447Sroot 		tsaddr = (struct tsdevice *)ubamem(io->i_unit, tsstd[0]);
413344Swnj 	tsaddr->tssr = 0;
423344Swnj 	while ((tsaddr->tssr & TS_SSR)==0) {
437447Sroot 		DELAY(10);
443344Swnj 		if (++i > 1000000) {
453344Swnj 			printf("ts: not ready\n");
463344Swnj 			return;
473268Swnj 		}
483268Swnj 	}
493268Swnj 	if (tsaddr->tssr&TS_OFL) {
503268Swnj 		printf("ts: offline\n");
513268Swnj 		return;
523268Swnj 	}
533268Swnj 	if (tsaddr->tssr&TS_NBA) {
543344Swnj 		int i;
553344Swnj 
563268Swnj 		ctsbuf.i_ma = (caddr_t) &ts;
573268Swnj 		ctsbuf.i_cc = sizeof(ts);
583268Swnj 		if (ts_ubaddr == 0)
593344Swnj 			ts_ubaddr = (struct ts *)ubasetup(&ctsbuf, 2);
603344Swnj 		ts_uba = (u_short)((long)ts_ubaddr + (((long)ts_ubaddr>>16)&03));
613268Swnj 		ts.ts_char.char_addr = (int)&ts_ubaddr->ts_sts;
623268Swnj 		ts.ts_char.char_size = sizeof(ts.ts_sts);
633344Swnj 		ts.ts_char.char_mode = TS_ESS;
643344Swnj 		ts.ts_cmd.c_cmd = TS_ACK|TS_SETCHR;
653344Swnj 		i = (int)&ts_ubaddr->ts_char;
663344Swnj 		ts.ts_cmd.c_loba = i;
673344Swnj 		ts.ts_cmd.c_hiba = (i>>16)&3;
683268Swnj 		ts.ts_cmd.c_size = sizeof(ts.ts_char);
693268Swnj 		tsaddr->tsdb = ts_uba;
703268Swnj 	}
713268Swnj 	tsstrategy(io, TS_REW);
723268Swnj 	if (io->i_cc = io->i_boff)
733268Swnj 		tsstrategy(io, TS_SFORWF);
743268Swnj }
753268Swnj 
763268Swnj tsclose(io)
773268Swnj 	register struct iob *io;
783268Swnj {
793344Swnj 
803268Swnj 	tsstrategy(io, TS_REW);
813268Swnj }
823268Swnj 
833268Swnj tsstrategy(io, func)
843268Swnj 	register struct iob *io;
853268Swnj {
863344Swnj 	register int errcnt, info = 0;
873268Swnj 
883268Swnj 	errcnt = 0;
893268Swnj retry:
903268Swnj 	while ((tsaddr->tssr & TS_SSR) == 0)
913344Swnj 		DELAY(100);
923344Swnj 	if (func == TS_REW || func == TS_SFORWF)
933344Swnj 		ts.ts_cmd.c_repcnt = io->i_cc;
943344Swnj 	else {
953344Swnj 		info = ubasetup(io, 1);
963344Swnj 		ts.ts_cmd.c_size = io->i_cc;
973344Swnj 		ts.ts_cmd.c_loba = info;
983344Swnj 		ts.ts_cmd.c_hiba = (info>>16)&3;
993344Swnj 	}
1003268Swnj 	if (func == READ)
1013268Swnj 		func = TS_RCOM;
1023268Swnj 	else if (func == WRITE)
1033268Swnj 		func = TS_WCOM;
1043268Swnj 	ts.ts_cmd.c_cmd = TS_ACK|TS_CVC|func;
1053268Swnj 	tsaddr->tsdb = ts_uba;
1063344Swnj 	do
1073344Swnj 		DELAY(100)
1083344Swnj 	while ((tsaddr->tssr & TS_SSR) == 0);
1093344Swnj 	if (info)
1103344Swnj 		ubafree(io, info);
1113344Swnj 	if (ts.ts_sts.s_xs0 & TS_TMK)
1123268Swnj 		return (0);
1133268Swnj 	if (tsaddr->tssr & TS_SC) {
1147447Sroot 		printf("ts tape error: er=%b, xs0=%b\n",
1153349Swnj 		    tsaddr->tssr, TSSR_BITS,
1163349Swnj 		    ts.ts_sts.s_xs0, TSXS0_BITS);
1173268Swnj 		if (errcnt==10) {
1183349Swnj 			printf("ts: unrecovered error\n");
1193268Swnj 			return (-1);
1203268Swnj 		}
1213268Swnj 		errcnt++;
1223268Swnj 		if (func == TS_RCOM || func == TS_WCOM)
1233268Swnj 			func |= TS_RETRY;
1243268Swnj 		goto retry;
1253268Swnj 	}
1263268Swnj 	if (errcnt)
1273349Swnj 		printf("ts: recovered by retry\n");
1283268Swnj 	return (io->i_cc - ts.ts_sts.s_rbpcr);
1293268Swnj }
130