check adaptor numbers against actual number
[unix-history] / usr / src / sys / vax / stand / ut.c
CommitLineData
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 */
28u_short utstd[MAXCTLR] = { 0172440 }; /* non-standard */
f247815c
SL
29
30utopen(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
47utclose(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
59utstrategy(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;
71retry:
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
116done:
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 126static
f247815c
SL
127utquiet(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}