Removed definition "LIB= rpc". We want libc.a to contain librpc.a, not
[unix-history] / .ref-BSD-4_3_Net_2 / usr / src / sys / vax / vax / rx50.c
CommitLineData
d6489fd6
MK
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
af359dea
C
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
d6489fd6 23 *
af359dea
C
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)rx50.c 7.5 (Berkeley) 12/16/90
d6489fd6
MK
37 */
38
39#if VAX8200
40
41/*
42 * Routines to handle the console RX50.
43 */
44
b28b3a13
KB
45#include "sys/param.h"
46#include "sys/time.h"
47#include "sys/kernel.h"
48#include "sys/vmmac.h"
49#include "sys/buf.h"
50#include "sys/errno.h"
51#include "sys/uio.h"
d6489fd6 52
b28b3a13 53#include "../include/cpu.h"
d6489fd6
MK
54#include "rx50reg.h"
55
56struct rx50device rx50device;
57
58#define rx50unit(dev) minor(dev)
59
60struct rx50state {
61 short rs_flags; /* see below */
62 short rs_drive; /* current drive number */
63 u_int rs_blkno; /* current block number */
64} rx50state;
65
66/* flags */
67#define RS_0OPEN 0x01 /* drive 0 open -- must be first */
68#define RS_1OPEN 0x02 /* drive 1 open -- must be second */
69#define RS_BUSY 0x04 /* operation in progress */
70#define RS_WANT 0x08 /* wakeup when done */
71#define RS_DONE 0x20 /* I/O operation done */
72#define RS_ERROR 0x40 /* error bit set at interrupt */
73
74/*
75 * Open a console RX50.
76 */
77/*ARGSUSED*/
78rx50open(dev, flags)
79 dev_t dev;
80 int flags;
81{
82 int unit;
83
84 /* only on 8200 (yet) */
85 if (cpu != VAX_8200 || (unit = rx50unit(dev)) >= 2)
86 return (ENXIO);
87
88 /* enforce exclusive access */
89 if (rx50state.rs_flags & (1 << unit))
90 return (EBUSY);
91 rx50state.rs_flags |= 1 << unit;
92 return (0);
93}
94
95/*
96 * Close a console RX50.
97 */
98/*ARGSUSED*/
99rx50close(dev, flags)
100 dev_t dev;
101 int flags;
102{
103
104 rx50state.rs_flags &= ~(1 << dev); /* atomic */
105}
106
107/*
3299817a 108 * Perform a read (uio->uio_rw==UIO_READ) or write (uio->uio_rw==UIO_WRITE).
d6489fd6 109 */
c8c58db5 110rx50rw(dev, uio, flags)
d6489fd6 111 dev_t dev;
d6489fd6 112 register struct uio *uio;
3299817a 113 int flags;
d6489fd6
MK
114{
115 register struct rx50device *rxaddr;
116 register struct rx50state *rs;
117 register char *cp;
118 register int error, i, t;
119 char secbuf[512];
120 static char driveselect[2] = { RXCMD_DRIVE0, RXCMD_DRIVE1 };
121
122 /* enforce whole-sector I/O */
123 if ((uio->uio_offset & 511) || (uio->uio_resid & 511))
124 return (EINVAL);
125
126 rs = &rx50state;
127
128 /* lock out others */
129 i = spl4();
130 while (rs->rs_flags & RS_BUSY) {
131 rs->rs_flags |= RS_WANT;
132 sleep((caddr_t) &rx50state, PZERO - 1);
133 }
134 rs->rs_flags |= RS_BUSY;
135 rs->rs_drive = rx50unit(dev);
136 splx(i);
137
138 rxaddr = &rx50device;
139 error = 0;
140
141 while (uio->uio_resid) {
142 rs->rs_blkno = uio->uio_offset >> 9;
143 if (rs->rs_blkno >= RX50MAXSEC) {
144 if (rs->rs_blkno > RX50MAXSEC)
145 error = EINVAL;
3299817a 146 else if (uio->uio_rw == UIO_WRITE)
d6489fd6
MK
147 error = ENOSPC;
148 /* else ``eof'' */
149 break;
150 }
151 rs->rs_flags &= ~(RS_ERROR | RS_DONE);
3299817a 152 if (uio->uio_rw == UIO_WRITE) {
d6489fd6 153 /* copy the data to the RX50 silo */
3299817a 154 error = uiomove(secbuf, 512, uio);
d6489fd6
MK
155 if (error)
156 break;
157 i = rxaddr->rxrda;
158 for (cp = secbuf, i = 512; --i >= 0;)
159 rxaddr->rxfdb = *cp++;
160 i = RXCMD_WRITE;
161 } else
162 i = RXCMD_READ;
163 rxaddr->rxcmd = i | driveselect[rs->rs_drive];
164 i = rs->rs_blkno - ((t = rs->rs_blkno / RX50SEC) * RX50SEC);
165 rxaddr->rxtrk = t == 79 ? 0 : t + 1;
166#ifdef notdef
167 rxaddr->rxsec = "\1\3\5\7\11\1\3\5\7"[(2*t + i) % 5] + (i > 4);
168#else
169 rxaddr->rxsec = RX50SKEW(i, t);
170#endif
171 i = rxaddr->rxgo; /* start it up */
172 i = spl4();
173 while ((rs->rs_flags & RS_DONE) == 0)
174 sleep((caddr_t) &rs->rs_blkno, PRIBIO);
175 splx(i);
176 if (rs->rs_flags & RS_ERROR) {
177 error = EIO;
178 break;
179 }
3299817a 180 if (uio->uio_rw == UIO_READ) {
d6489fd6
MK
181 /* copy the data out of the silo */
182 i = rxaddr->rxrda;
183 for (cp = secbuf, i = 512; --i >= 0;)
184 *cp++ = rxaddr->rxedb;
3299817a 185 error = uiomove(secbuf, 512, uio);
d6489fd6
MK
186 if (error)
187 break;
188 }
189 }
190
191 /* let others in */
192 rs->rs_flags &= ~RS_BUSY;
193 if (rs->rs_flags & RS_WANT)
194 wakeup((caddr_t) rs);
195
196 return (error);
197}
198
d6489fd6
MK
199rx50intr()
200{
201 register struct rx50device *rxaddr = &rx50device;
202 register struct rx50state *rs = &rx50state;
203 int i;
204
205#ifdef lint
206 i = 0; i = i;
207#endif
208
209 /* ignore spurious interrupts */
210 if ((rxaddr->rxcmd & RXCMD_DONE) == 0)
211 return;
212 if ((rs->rs_flags & RS_BUSY) == 0) {
213 printf("stray rx50 interrupt ignored\n");
214 return;
215 }
216 if (rxaddr->rxcmd & RXCMD_ERROR) {
217 printf(
218 "csa%d: hard error sn%d: cmd=%x trk=%x sec=%x csc=%x ict=%x ext=%x\n",
219 rs->rs_drive + 1, rs->rs_blkno,
220 rxaddr->rxcmd, rxaddr->rxtrk, rxaddr->rxsec,
221 rxaddr->rxcsc, rxaddr->rxict, rxaddr->rxext);
222 rxaddr->rxcmd = RXCMD_RESET;
223 i = rxaddr->rxgo;
224 rs->rs_flags |= RS_ERROR;
225 }
226 rs->rs_flags |= RS_DONE;
227 wakeup((caddr_t) &rs->rs_blkno);
228}
229#endif