xref: /csrg-svn/sys/vax/stand/ut.c (revision 7448)
1 /*	ut.c	4.3	82/07/15	*/
2 
3 /*
4  * SI Model 9700 -- emulates TU45 on the UNIBUS
5  */
6 
7 #include "../h/param.h"
8 #include "../h/inode.h"
9 #include "../h/pte.h"
10 #include "../h/ubareg.h"
11 #include "../h/fs.h"
12 #include "saio.h"
13 #include "savax.h"
14 
15 #include "../h/utreg.h"
16 
17 u_short	utstd[] = { 0172440 };		/* non-standard */
18 
19 utopen(io)
20 	register struct iob *io;
21 {
22 	register skip;
23 
24 	utstrategy(io, UT_REW);
25 	skip = io->i_boff;
26 	while (skip--) {
27 		io->i_cc = 0;
28 		utstrategy(io, UT_SFORW);
29 	}
30 }
31 
32 utclose(io)
33 	register struct iob *io;
34 {
35 	utstrategy(io, UT_REW);
36 }
37 
38 #define utwait(addr)	{do word=addr->utcs1; while((word&UT_RDY)==0);}
39 
40 utstrategy(io, func)
41 	register struct iob *io;
42 {
43 	register u_short word;
44 	register int errcnt;
45 	register struct utdevice *addr =
46 	    (struct utdevice *)ubamem(io->i_unit, utstd[0]);
47 	int info;
48 	u_short dens;
49 
50 	dens = (io->i_unit&07) | PDP11FMT | UT_PE;
51 	errcnt = 0;
52 retry:
53 	utquiet(addr);
54 	addr->uttc = dens;
55 	info = ubasetup(io, 1);
56 	addr->utwc = -((io->i_cc+1) >> 1);
57 	addr->utfc = -io->i_cc;
58 	if (func == READ) {
59 		addr->utba = info;
60 		addr->utcs1 = UT_RCOM | ((info>>8) & 0x30) | UT_GO;
61 	} else if (func == WRITE) {
62 		addr->utba = info;
63 		addr->utcs1 = UT_WCOM | ((info>>8) & 0x30) | UT_GO;
64 	} else if (func == UT_SREV) {
65 		addr->utcs1 = UT_SREV | UT_GO;
66 		return (0);
67 	} else
68 		addr->utcs1 = func | UT_GO;
69 	utwait(addr);
70 	ubafree(io, info);
71 	word = addr->utds;
72 	if (word&(UTDS_EOT|UTDS_TM)) {
73 		addr->utcs1 = UT_CLEAR | UT_GO;
74 		return(0);
75 	}
76 	if ((word&UTDS_ERR) || (addr->utcs1&UT_TRE)) {
77 		if (errcnt == 0)
78 			printf("tj error: cs1=%b er=%b cs2=%b ds=%b",
79 				addr->utcs1, UT_BITS, addr->uter, UTER_BITS,
80 				addr->utcs2, UTCS2_BITS, word, UTDS_BITS);
81 		if (errcnt == 10) {
82 			printf("\n");
83 			return(-1);
84 		}
85 		errcnt++;
86 		if (addr->utcs1&UT_TRE)
87 			addr->utcs2 |= UTCS2_CLR;
88 		addr->utcs1 = UT_CLEAR | UT_GO;
89 		utstrategy(io, UT_SREV);
90 		utquiet(addr);
91 		if (func == WRITE) {
92 			addr->utcs1 = UT_ERASE | UT_GO;
93 			utwait(addr);
94 		}
95 		goto retry;
96 	}
97 	if (errcnt)
98 		printf(" recovered by retry\n");
99 	return (func == READ ?
100 		io->i_cc - ((-addr->utfc) & 0xffff) : -addr->utwc << 1);
101 }
102 
103 utquiet(addr)
104 	register struct utdevice *addr;
105 {
106 	register u_short word;
107 
108 	utwait(addr);
109 	do
110 		word = addr->utds;
111 	while ((word&UTDS_DRY) == 0 && (word&UTDS_PIP));
112 }
113