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