xref: /original-bsd/sys/vax/stand/ht.c (revision d3ba9304)
1c73d3aa6Smckusick /*
21508bc20Smckusick  * Copyright (c) 1982, 1986 Regents of the University of California.
3c73d3aa6Smckusick  * All rights reserved.  The Berkeley software License Agreement
4c73d3aa6Smckusick  * specifies the terms and conditions for redistribution.
5c73d3aa6Smckusick  *
6*d3ba9304Sbostic  *	@(#)ht.c	7.7 (Berkeley) 05/04/91
7c73d3aa6Smckusick  */
8ef666d76Sbill 
9ef666d76Sbill /*
1007ee211aSwnj  * TM03/TU?? tape driver
11ef666d76Sbill  */
12805e418eSbostic #include "../include/pte.h"
13ef666d76Sbill 
14805e418eSbostic #include "sys/param.h"
151330c7b2Ssam 
16805e418eSbostic #include "../mba/htreg.h"
17805e418eSbostic #include "../mba/mbareg.h"
181330c7b2Ssam 
19805e418eSbostic #include "stand/saio.h"
2007ee211aSwnj #include "savax.h"
21ef666d76Sbill 
22d79ba013Swnj short	httypes[] =
23d79ba013Swnj 	{ MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 };
24d79ba013Swnj 
25d79ba013Swnj #define	MASKREG(reg)	((reg)&0xffff)
26d79ba013Swnj 
htopen(io)27ef666d76Sbill htopen(io)
28ef666d76Sbill 	register struct iob *io;
29ef666d76Sbill {
30269e4fdeSbostic 	register struct htdevice *htaddr;
31269e4fdeSbostic 	register int i, skip;
32ef666d76Sbill 
33269e4fdeSbostic 	htaddr = (struct htdevice *)mbadrv(io->i_adapt, io->i_ctlr);
34269e4fdeSbostic 	if (mbainit(io->i_adapt) == 0)
35269e4fdeSbostic 		return (EADAPT);
36269e4fdeSbostic 	for (i = 0;; i++) {
37269e4fdeSbostic 		if (!httypes[i]) {
38269e4fdeSbostic 			printf("ht: not a tape\n");
39eea9e99bSkarels 			return (ENXIO);
40269e4fdeSbostic 		}
41d79ba013Swnj 		if (httypes[i] == (htaddr->htdt&MBDT_TYPE))
42269e4fdeSbostic 			break;
43269e4fdeSbostic 	}
4407ee211aSwnj 	htaddr->htcs1 = HT_DCLR|HT_GO;
4507ee211aSwnj 	htstrategy(io, HT_REW);
46269e4fdeSbostic 	for (skip = io->i_part; skip--;) {
47ef666d76Sbill 		io->i_cc = -1;
48269e4fdeSbostic 		while (htstrategy(io, HT_SFORW));
4907ee211aSwnj 		DELAY(65536);
5007ee211aSwnj 		htstrategy(io, HT_SENSE);
51ef666d76Sbill 	}
52eea9e99bSkarels 	return (0);
53ef666d76Sbill }
54ef666d76Sbill 
htclose(io)55ef666d76Sbill htclose(io)
56ef666d76Sbill 	register struct iob *io;
57ef666d76Sbill {
5807ee211aSwnj 	htstrategy(io, HT_REW);
59ef666d76Sbill }
60ef666d76Sbill 
htstrategy(io,func)61ef666d76Sbill htstrategy(io, func)
62ef666d76Sbill 	register struct iob *io;
6307ee211aSwnj 	int func;
64ef666d76Sbill {
65269e4fdeSbostic 	register struct htdevice *htaddr;
6607ee211aSwnj 	register int den, errcnt, ds;
6751bf2014Sroot 	int er;
68ef666d76Sbill 	short fc;
69ef666d76Sbill 
70ef666d76Sbill 	errcnt = 0;
71269e4fdeSbostic 	htaddr = (struct htdevice *)mbadrv(io->i_adapt, io->i_ctlr);
72ef666d76Sbill retry:
73269e4fdeSbostic 	den = HTTC_1600BPI | HTTC_PDP11 | io->i_unit;
7407ee211aSwnj 	htquiet(htaddr);
75d79ba013Swnj 	htaddr->htcs1 = HT_DCLR|HT_GO;
7607ee211aSwnj 	htaddr->httc = den;
7707ee211aSwnj 	htaddr->htfc = -io->i_cc;
7807ee211aSwnj 	if (func == HT_SREV) {
7907ee211aSwnj 		htaddr->htfc = -1;
8007ee211aSwnj 		htaddr->htcs1 = HT_SREV|HT_GO;
81ef666d76Sbill 		return (0);
82ef666d76Sbill 	}
83*d3ba9304Sbostic 	if (func == F_READ || func == F_WRITE)
84269e4fdeSbostic 		mbastart(io, io->i_ctlr, func);
85ef666d76Sbill 	else
8607ee211aSwnj 		htaddr->htcs1 = func|HT_GO;
8707ee211aSwnj 	htquiet(htaddr);
8807ee211aSwnj 	ds = htaddr->htds;
8951bf2014Sroot 	er = htaddr->hter;
9007ee211aSwnj 	if (ds & HTDS_TM) {
9107ee211aSwnj 		htaddr->htcs1 = HT_DCLR|HT_GO;
92ef666d76Sbill 		return (0);
93ef666d76Sbill 	}
9407ee211aSwnj 	if (ds & HTDS_ERR) {
9507ee211aSwnj 		htaddr->htcs1 = HT_DCLR|HT_GO;
9651bf2014Sroot 		if ((er & HTER_CORCRC) == 0) {
9751bf2014Sroot 			printf("ht error: ds=%b, er=%b\n",
9851bf2014Sroot 			    MASKREG(ds), HTDS_BITS,
9951bf2014Sroot 			    MASKREG(er), HTER_BITS);
100269e4fdeSbostic 			if (errcnt++ == 10) {
101d79ba013Swnj 				printf("ht: unrecovered error\n");
102ef666d76Sbill 				return (-1);
103ef666d76Sbill 			}
10407ee211aSwnj 			htstrategy(io, HT_SREV);
105ef666d76Sbill 			goto retry;
106ef666d76Sbill 		}
10751bf2014Sroot 	}
108ef666d76Sbill 	if (errcnt)
109d79ba013Swnj 		printf("ht: recovered by retry\n");
11007ee211aSwnj 	fc = htaddr->htfc;
111ef666d76Sbill 	return (io->i_cc+fc);
112ef666d76Sbill }
113ef666d76Sbill 
114269e4fdeSbostic static
htquiet(htaddr)11507ee211aSwnj htquiet(htaddr)
11607ee211aSwnj 	register struct htdevice *htaddr;
117ef666d76Sbill {
118ef666d76Sbill 	register int s;
119ef666d76Sbill 
120ef666d76Sbill 	do
12107ee211aSwnj 		s = htaddr->htds;
12207ee211aSwnj 	while ((s & HTDS_DRY) == 0);
123ef666d76Sbill }
124