|
|
1.1 root 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: * @(#)ut.c 7.6 (Berkeley) 4/4/90
7: */
8:
9: /*
10: * SI Model 9700 -- emulates TU45 on the UNIBUS
11: */
12:
13: #include "param.h"
14:
15: #include "../vax/pte.h"
16:
17: #include "../vaxuba/ubareg.h"
18: #include "../vaxuba/utreg.h"
19:
20: #include "saio.h"
21: #include "savax.h"
22:
23: #define MASKREG(reg) ((reg)&0xffff)
24:
25: #define MAXCTLR 1 /* all addresses must be specified */
26: u_short utstd[MAXCTLR] = { 0172440 }; /* non-standard */
27:
28: utopen(io)
29: register struct iob *io;
30: {
31: register int skip;
32:
33: if ((u_int)io->i_adapt >= nuba)
34: return (EADAPT);
35: if ((u_int)io->i_ctlr >= MAXCTLR)
36: return (ECTLR);
37: if (badaddr((char *)ubamem(io->i_unit, utstd[io->i_ctlr]), sizeof(short)))
38: return (ENXIO);
39: utstrategy(io, UT_REW);
40: for (skip = io->i_part; skip--;)
41: utstrategy(io, UT_SFORWF);
42: return (0);
43: }
44:
45: utclose(io)
46: register struct iob *io;
47: {
48: utstrategy(io, UT_REW);
49: }
50:
51: #define UTWAIT(addr) { \
52: do \
53: word = addr->utcs1; \
54: while((word&UT_RDY) == 0); \
55: }
56:
57: utstrategy(io, func)
58: register struct iob *io;
59: {
60: register struct utdevice *addr;
61: register u_short word;
62: register int errcnt;
63: int info, resid;
64: u_short dens;
65:
66: addr = (struct utdevice *)ubamem(io->i_unit, utstd[io->i_ctlr]);
67: dens = io->i_unit | PDP11FMT | UT_PE;
68: errcnt = 0;
69: retry:
70: utquiet(addr);
71: addr->uttc = dens;
72: info = ubasetup(io, 1);
73: addr->utwc = -((io->i_cc+1) >> 1);
74: addr->utfc = -io->i_cc;
75: if (func == READ) {
76: addr->utba = info;
77: addr->utcs1 = UT_RCOM | ((info>>8) & 0x30) | UT_GO;
78: } else if (func == WRITE) {
79: addr->utba = info;
80: addr->utcs1 = UT_WCOM | ((info>>8) & 0x30) | UT_GO;
81: } else if (func == UT_SREV) {
82: addr->utcs1 = UT_SREV | UT_GO;
83: return (0);
84: } else
85: addr->utcs1 = func | UT_GO;
86: UTWAIT(addr);
87: ubafree(io, info);
88: word = addr->utds;
89: if (word&(UTDS_EOT|UTDS_TM)) {
90: addr->utcs1 = UT_CLEAR | UT_GO;
91: goto done;
92: }
93: if ((word&UTDS_ERR) || (addr->utcs1&UT_TRE)) {
94: printf("ut error: cs1=%b er=%b cs2=%b ds=%b",
95: addr->utcs1, UT_BITS, addr->uter, UTER_BITS,
96: addr->utcs2, UTCS2_BITS, word, UTDS_BITS);
97: if (errcnt++ == 10) {
98: printf("ut: unrecovered error\n");
99: return (-1);
100: }
101: if (addr->utcs1&UT_TRE)
102: addr->utcs2 |= UTCS2_CLR;
103: addr->utcs1 = UT_CLEAR | UT_GO;
104: utstrategy(io, UT_SREV);
105: utquiet(addr);
106: if (func == WRITE) {
107: addr->utcs1 = UT_ERASE | UT_GO;
108: UTWAIT(addr);
109: }
110: goto retry;
111: }
112: if (errcnt)
113: printf("ut: recovered by retry\n");
114: done:
115: if (func == READ) {
116: resid = 0;
117: if (io->i_cc > MASKREG(addr->utfc))
118: resid = io->i_cc - MASKREG(addr->utfc);
119: } else
120: resid = MASKREG(-addr->utfc);
121: return (io->i_cc - resid);
122: }
123:
124: static
125: utquiet(addr)
126: register struct utdevice *addr;
127: {
128: register u_short word;
129:
130: UTWAIT(addr);
131: do
132: word = addr->utds;
133: while ((word&UTDS_DRY) == 0 && (word&UTDS_PIP));
134: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.