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