xref: /csrg-svn/sys/vax/stand/ht.c (revision 33526)
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*33526Sbostic  *	@(#)ht.c	7.3 (Berkeley) 02/22/88
723227Smckusick  */
8319Sbill 
9319Sbill /*
103262Swnj  * TM03/TU?? tape driver
11319Sbill  */
129804Ssam #include "../machine/pte.h"
13319Sbill 
1433408Skarels #include "param.h"
1533408Skarels #include "inode.h"
1633408Skarels #include "fs.h"
179186Ssam 
189186Ssam #include "../vaxmba/htreg.h"
199186Ssam #include "../vaxmba/mbareg.h"
209186Ssam 
21319Sbill #include "saio.h"
223262Swnj #include "savax.h"
23319Sbill 
243349Swnj short	httypes[] =
253349Swnj 	{ MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 };
263349Swnj 
273349Swnj #define	MASKREG(reg)	((reg)&0xffff)
283349Swnj 
29319Sbill htopen(io)
303262Swnj 	register struct iob *io;
31319Sbill {
32*33526Sbostic 	register struct htdevice *htaddr;
33*33526Sbostic 	register int i, skip;
34319Sbill 
35*33526Sbostic 	htaddr = (struct htdevice *)mbadrv(io->i_adapt, io->i_ctlr);
36*33526Sbostic 	if (mbainit(io->i_adapt) == 0)
37*33526Sbostic 		return (EADAPT);
38*33526Sbostic 	for (i = 0;; i++) {
39*33526Sbostic 		if (!httypes[i]) {
40*33526Sbostic 			printf("ht: not a tape\n");
41*33526Sbostic 			return (ENXIO);
42*33526Sbostic 		}
433349Swnj 		if (httypes[i] == (htaddr->htdt&MBDT_TYPE))
44*33526Sbostic 			break;
45*33526Sbostic 	}
463262Swnj 	htaddr->htcs1 = HT_DCLR|HT_GO;
473262Swnj 	htstrategy(io, HT_REW);
48*33526Sbostic 	for (skip = io->i_part; skip--;) {
49319Sbill 		io->i_cc = -1;
50*33526Sbostic 		while (htstrategy(io, HT_SFORW));
513262Swnj 		DELAY(65536);
523262Swnj 		htstrategy(io, HT_SENSE);
53319Sbill 	}
5433408Skarels 	return (0);
55319Sbill }
56319Sbill 
57319Sbill htclose(io)
583262Swnj 	register struct iob *io;
59319Sbill {
603262Swnj 	htstrategy(io, HT_REW);
61319Sbill }
62319Sbill 
63319Sbill htstrategy(io, func)
643262Swnj 	register struct iob *io;
653262Swnj 	int func;
66319Sbill {
67*33526Sbostic 	register struct htdevice *htaddr;
683262Swnj 	register int den, errcnt, ds;
695159Sroot 	int er;
70319Sbill 	short fc;
71319Sbill 
72319Sbill 	errcnt = 0;
73*33526Sbostic 	htaddr = (struct htdevice *)mbadrv(io->i_adapt, io->i_ctlr);
74319Sbill retry:
75*33526Sbostic 	den = HTTC_1600BPI | HTTC_PDP11 | io->i_unit;
763262Swnj 	htquiet(htaddr);
773349Swnj 	htaddr->htcs1 = HT_DCLR|HT_GO;
783262Swnj 	htaddr->httc = den;
793262Swnj 	htaddr->htfc = -io->i_cc;
803262Swnj 	if (func == HT_SREV) {
813262Swnj 		htaddr->htfc = -1;
823262Swnj 		htaddr->htcs1 = HT_SREV|HT_GO;
833262Swnj 		return (0);
84319Sbill 	}
853274Swnj 	if (func == READ || func == WRITE)
86*33526Sbostic 		mbastart(io, io->i_ctlr, func);
87319Sbill 	else
883262Swnj 		htaddr->htcs1 = func|HT_GO;
893262Swnj 	htquiet(htaddr);
903262Swnj 	ds = htaddr->htds;
915159Sroot 	er = htaddr->hter;
923262Swnj 	if (ds & HTDS_TM) {
933262Swnj 		htaddr->htcs1 = HT_DCLR|HT_GO;
943262Swnj 		return (0);
95319Sbill 	}
963262Swnj 	if (ds & HTDS_ERR) {
973262Swnj 		htaddr->htcs1 = HT_DCLR|HT_GO;
985159Sroot 		if ((er & HTER_CORCRC) == 0) {
995159Sroot 			printf("ht error: ds=%b, er=%b\n",
1005159Sroot 			    MASKREG(ds), HTDS_BITS,
1015159Sroot 			    MASKREG(er), HTER_BITS);
102*33526Sbostic 			if (errcnt++ == 10) {
1035159Sroot 				printf("ht: unrecovered error\n");
1045159Sroot 				return (-1);
1055159Sroot 			}
1065159Sroot 			htstrategy(io, HT_SREV);
1075159Sroot 			goto retry;
108319Sbill 		}
109319Sbill 	}
110319Sbill 	if (errcnt)
1113349Swnj 		printf("ht: recovered by retry\n");
1123262Swnj 	fc = htaddr->htfc;
1133262Swnj 	return (io->i_cc+fc);
114319Sbill }
115319Sbill 
116*33526Sbostic static
1173262Swnj htquiet(htaddr)
1183262Swnj 	register struct htdevice *htaddr;
119319Sbill {
120319Sbill 	register int s;
121319Sbill 
122319Sbill 	do
1233262Swnj 		s = htaddr->htds;
1243262Swnj 	while ((s & HTDS_DRY) == 0);
125319Sbill }
126