Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
99152021 | 2 | * Copyright (c) 1982, 1986, 1988 Regents of the University of California. |
da7c5cc6 KM |
3 | * All rights reserved. The Berkeley software License Agreement |
4 | * specifies the terms and conditions for redistribution. | |
5 | * | |
99152021 | 6 | * @(#)ut.c 7.5 (Berkeley) %G% |
da7c5cc6 | 7 | */ |
f247815c SL |
8 | |
9 | /* | |
10 | * SI Model 9700 -- emulates TU45 on the UNIBUS | |
11 | */ | |
12 | ||
39c71180 MK |
13 | #include "param.h" |
14 | #include "inode.h" | |
15 | #include "fs.h" | |
a031a31b | 16 | |
99152021 MK |
17 | #include "../vax/pte.h" |
18 | ||
a031a31b SL |
19 | #include "../vaxuba/ubareg.h" |
20 | #include "../vaxuba/utreg.h" | |
21 | ||
f247815c SL |
22 | #include "saio.h" |
23 | #include "savax.h" | |
24 | ||
cfcb4a04 | 25 | #define MASKREG(reg) ((reg)&0xffff) |
f247815c | 26 | |
c48789a9 KB |
27 | #define MAXCTLR 1 /* all addresses must be specified */ |
28 | u_short utstd[MAXCTLR] = { 0172440 }; /* non-standard */ | |
f247815c SL |
29 | |
30 | utopen(io) | |
31 | register struct iob *io; | |
32 | { | |
c48789a9 | 33 | register int skip; |
f247815c | 34 | |
99152021 MK |
35 | if ((u_int)io->i_adapt >= nuba) |
36 | return (EADAPT); | |
c48789a9 KB |
37 | if ((u_int)io->i_ctlr >= MAXCTLR) |
38 | return (ECTLR); | |
9ab9be08 | 39 | if (badaddr((char *)ubamem(io->i_unit, utstd[io->i_ctlr]), sizeof(short))) |
39c71180 | 40 | return (ENXIO); |
f247815c | 41 | utstrategy(io, UT_REW); |
c48789a9 | 42 | for (skip = io->i_part; skip--;) |
69fe5ef5 | 43 | utstrategy(io, UT_SFORWF); |
39c71180 | 44 | return (0); |
f247815c SL |
45 | } |
46 | ||
47 | utclose(io) | |
48 | register struct iob *io; | |
49 | { | |
50 | utstrategy(io, UT_REW); | |
51 | } | |
52 | ||
c48789a9 KB |
53 | #define UTWAIT(addr) { \ |
54 | do \ | |
55 | word = addr->utcs1; \ | |
56 | while((word&UT_RDY) == 0); \ | |
57 | } | |
f247815c SL |
58 | |
59 | utstrategy(io, func) | |
60 | register struct iob *io; | |
61 | { | |
c48789a9 | 62 | register struct utdevice *addr; |
f247815c SL |
63 | register u_short word; |
64 | register int errcnt; | |
cfcb4a04 | 65 | int info, resid; |
f247815c SL |
66 | u_short dens; |
67 | ||
c48789a9 KB |
68 | addr = (struct utdevice *)ubamem(io->i_unit, utstd[io->i_ctlr]); |
69 | dens = io->i_unit | PDP11FMT | UT_PE; | |
f247815c SL |
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; | |
c48789a9 | 88 | UTWAIT(addr); |
f247815c SL |
89 | ubafree(io, info); |
90 | word = addr->utds; | |
91 | if (word&(UTDS_EOT|UTDS_TM)) { | |
92 | addr->utcs1 = UT_CLEAR | UT_GO; | |
cfcb4a04 | 93 | goto done; |
f247815c SL |
94 | } |
95 | if ((word&UTDS_ERR) || (addr->utcs1&UT_TRE)) { | |
c48789a9 KB |
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"); | |
cfcb4a04 | 101 | return (-1); |
f247815c | 102 | } |
f247815c SL |
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; | |
c48789a9 | 110 | UTWAIT(addr); |
f247815c SL |
111 | } |
112 | goto retry; | |
113 | } | |
114 | if (errcnt) | |
c48789a9 | 115 | printf("ut: recovered by retry\n"); |
cfcb4a04 SL |
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); | |
f247815c SL |
124 | } |
125 | ||
c48789a9 | 126 | static |
f247815c SL |
127 | utquiet(addr) |
128 | register struct utdevice *addr; | |
129 | { | |
130 | register u_short word; | |
131 | ||
c48789a9 | 132 | UTWAIT(addr); |
f247815c SL |
133 | do |
134 | word = addr->utds; | |
135 | while ((word&UTDS_DRY) == 0 && (word&UTDS_PIP)); | |
136 | } |