xref: /csrg-svn/sys/vax/stand/ht.c (revision 49100)
123227Smckusick /*
229300Smckusick  * Copyright (c) 1982, 1986 Regents of the University of California.
323227Smckusick  * All rights reserved.  The Berkeley software License Agreement
423227Smckusick  * specifies the terms and conditions for redistribution.
523227Smckusick  *
6*49100Sbostic  *	@(#)ht.c	7.7 (Berkeley) 05/04/91
723227Smckusick  */
8319Sbill 
9319Sbill /*
103262Swnj  * TM03/TU?? tape driver
11319Sbill  */
1245803Sbostic #include "../include/pte.h"
13319Sbill 
1445803Sbostic #include "sys/param.h"
159186Ssam 
1645803Sbostic #include "../mba/htreg.h"
1745803Sbostic #include "../mba/mbareg.h"
189186Ssam 
1945803Sbostic #include "stand/saio.h"
203262Swnj #include "savax.h"
21319Sbill 
223349Swnj short	httypes[] =
233349Swnj 	{ MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 };
243349Swnj 
253349Swnj #define	MASKREG(reg)	((reg)&0xffff)
263349Swnj 
htopen(io)27319Sbill htopen(io)
283262Swnj 	register struct iob *io;
29319Sbill {
3033526Sbostic 	register struct htdevice *htaddr;
3133526Sbostic 	register int i, skip;
32319Sbill 
3333526Sbostic 	htaddr = (struct htdevice *)mbadrv(io->i_adapt, io->i_ctlr);
3433526Sbostic 	if (mbainit(io->i_adapt) == 0)
3533526Sbostic 		return (EADAPT);
3633526Sbostic 	for (i = 0;; i++) {
3733526Sbostic 		if (!httypes[i]) {
3833526Sbostic 			printf("ht: not a tape\n");
3933526Sbostic 			return (ENXIO);
4033526Sbostic 		}
413349Swnj 		if (httypes[i] == (htaddr->htdt&MBDT_TYPE))
4233526Sbostic 			break;
4333526Sbostic 	}
443262Swnj 	htaddr->htcs1 = HT_DCLR|HT_GO;
453262Swnj 	htstrategy(io, HT_REW);
4633526Sbostic 	for (skip = io->i_part; skip--;) {
47319Sbill 		io->i_cc = -1;
4833526Sbostic 		while (htstrategy(io, HT_SFORW));
493262Swnj 		DELAY(65536);
503262Swnj 		htstrategy(io, HT_SENSE);
51319Sbill 	}
5233408Skarels 	return (0);
53319Sbill }
54319Sbill 
htclose(io)55319Sbill htclose(io)
563262Swnj 	register struct iob *io;
57319Sbill {
583262Swnj 	htstrategy(io, HT_REW);
59319Sbill }
60319Sbill 
htstrategy(io,func)61319Sbill htstrategy(io, func)
623262Swnj 	register struct iob *io;
633262Swnj 	int func;
64319Sbill {
6533526Sbostic 	register struct htdevice *htaddr;
663262Swnj 	register int den, errcnt, ds;
675159Sroot 	int er;
68319Sbill 	short fc;
69319Sbill 
70319Sbill 	errcnt = 0;
7133526Sbostic 	htaddr = (struct htdevice *)mbadrv(io->i_adapt, io->i_ctlr);
72319Sbill retry:
7333526Sbostic 	den = HTTC_1600BPI | HTTC_PDP11 | io->i_unit;
743262Swnj 	htquiet(htaddr);
753349Swnj 	htaddr->htcs1 = HT_DCLR|HT_GO;
763262Swnj 	htaddr->httc = den;
773262Swnj 	htaddr->htfc = -io->i_cc;
783262Swnj 	if (func == HT_SREV) {
793262Swnj 		htaddr->htfc = -1;
803262Swnj 		htaddr->htcs1 = HT_SREV|HT_GO;
813262Swnj 		return (0);
82319Sbill 	}
83*49100Sbostic 	if (func == F_READ || func == F_WRITE)
8433526Sbostic 		mbastart(io, io->i_ctlr, func);
85319Sbill 	else
863262Swnj 		htaddr->htcs1 = func|HT_GO;
873262Swnj 	htquiet(htaddr);
883262Swnj 	ds = htaddr->htds;
895159Sroot 	er = htaddr->hter;
903262Swnj 	if (ds & HTDS_TM) {
913262Swnj 		htaddr->htcs1 = HT_DCLR|HT_GO;
923262Swnj 		return (0);
93319Sbill 	}
943262Swnj 	if (ds & HTDS_ERR) {
953262Swnj 		htaddr->htcs1 = HT_DCLR|HT_GO;
965159Sroot 		if ((er & HTER_CORCRC) == 0) {
975159Sroot 			printf("ht error: ds=%b, er=%b\n",
985159Sroot 			    MASKREG(ds), HTDS_BITS,
995159Sroot 			    MASKREG(er), HTER_BITS);
10033526Sbostic 			if (errcnt++ == 10) {
1015159Sroot 				printf("ht: unrecovered error\n");
1025159Sroot 				return (-1);
1035159Sroot 			}
1045159Sroot 			htstrategy(io, HT_SREV);
1055159Sroot 			goto retry;
106319Sbill 		}
107319Sbill 	}
108319Sbill 	if (errcnt)
1093349Swnj 		printf("ht: recovered by retry\n");
1103262Swnj 	fc = htaddr->htfc;
1113262Swnj 	return (io->i_cc+fc);
112319Sbill }
113319Sbill 
11433526Sbostic static
htquiet(htaddr)1153262Swnj htquiet(htaddr)
1163262Swnj 	register struct htdevice *htaddr;
117319Sbill {
118319Sbill 	register int s;
119319Sbill 
120319Sbill 	do
1213262Swnj 		s = htaddr->htds;
1223262Swnj 	while ((s & HTDS_DRY) == 0);
123319Sbill }
124