xref: /original-bsd/sys/vax/stand/tm.c (revision e0c0d005)
1 /*
2  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)tm.c	7.7 (Berkeley) 12/16/90
7  */
8 
9 /*
10  * TM11/TE??
11  */
12 
13 #include "sys/param.h"
14 
15 #include "../include/pte.h"
16 
17 #include "../uba/ubareg.h"
18 #include "../uba/tmreg.h"
19 
20 #include "stand/saio.h"
21 #include "savax.h"
22 
23 #define	MAXCTLR		1		/* all addresses must be specified */
24 u_short	tmstd[MAXCTLR] = { 0172520 };
25 
26 tmopen(io)
27 	register struct iob *io;
28 {
29 	register int skip;
30 
31 	if ((u_int)io->i_adapt >= nuba)
32 		return (EADAPT);
33 	if ((u_int)io->i_ctlr >= MAXCTLR)
34 		return (ECTLR);
35 	if (badaddr((char *)ubamem(io->i_adapt, tmstd[io->i_ctlr]), sizeof(short)))
36 		return (ENXIO);
37 	tmstrategy(io, TM_REW);
38 	for (skip = io->i_part; skip--;) {
39 		io->i_cc = 0;
40 		tmstrategy(io, TM_SFORW);
41 	}
42 	return (0);
43 }
44 
45 tmclose(io)
46 	register struct iob *io;
47 {
48 	tmstrategy(io, TM_REW);
49 }
50 
51 tmstrategy(io, func)
52 	register struct iob *io;
53 {
54 	register int com, errcnt;
55 	register struct tmdevice *tmaddr;
56 	int word, info;
57 
58 	tmaddr = (struct tmdevice *)ubamem(io->i_adapt, tmstd[io->i_ctlr]);
59 	errcnt = 0;
60 retry:
61 	tmquiet(tmaddr);
62 	info = ubasetup(io, 1);
63 	tmaddr->tmbc = -io->i_cc;
64 	tmaddr->tmba = info;
65 	com = (io->i_unit<<8) | TM_GO;
66 	if (func == READ)
67 		tmaddr->tmcs = com | TM_RCOM;
68 	else if (func == WRITE)
69 		tmaddr->tmcs = com | TM_WCOM;
70 	else if (func == TM_SREV) {
71 		tmaddr->tmbc = -1;
72 		tmaddr->tmcs = com | TM_SREV;
73 		return (0);
74 	} else
75 		tmaddr->tmcs = com | func;
76 	for (;;) {
77 		word = tmaddr->tmcs;
78 		DELAY(100);
79 		if (word & TM_CUR)
80 			break;
81 	}
82 	ubafree(io, info);
83 	word = tmaddr->tmer;
84 	if (word & TMER_EOT)
85 		return (0);
86 	if (word & TM_ERR) {
87 		if (word & TMER_EOF)
88 			return (0);
89 		printf("tm tape error: er=%b\n", word, TMER_BITS);
90 		if (errcnt++ == 10) {
91 			printf("tm: unrecovered error\n");
92 			return (-1);
93 		}
94 		tmstrategy(io, TM_SREV);
95 		goto retry;
96 	}
97 	if (errcnt)
98 		printf("tm: recovered by retry\n");
99 	if (word & TMER_EOF)
100 		return (0);
101 	return (io->i_cc + tmaddr->tmbc);
102 }
103 
104 tmquiet(tmaddr)
105 	register struct tmdevice *tmaddr;
106 {
107 	register word;
108 	for (;;) {
109 		word = tmaddr->tmcs;
110 		DELAY(100);
111 		if (word&TM_CUR)
112 			break;
113 	}
114 	for (;;) {
115 		word = tmaddr->tmer;
116 		DELAY(100);
117 		if ((word&TMER_TUR) && (word&TMER_SDWN)==0)
118 			break;
119 	}
120 }
121