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