|
|
1.1 root 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: *
8: * Redistribution is only permitted until one year after the first shipment
9: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
10: * binary forms are permitted provided that: (1) source distributions retain
11: * this entire copyright notice and comment, and (2) distributions including
12: * binaries display the following acknowledgement: This product includes
13: * software developed by the University of California, Berkeley and its
14: * contributors'' in the documentation or other materials provided with the
15: * distribution and in all advertising materials mentioning features or use
16: * of this software. Neither the name of the University nor the names of
17: * its contributors may be used to endorse or promote products derived from
18: * this software without specific prior written permission.
19: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22: *
23: * @(#)rx50.c 7.4 (Berkeley) 6/28/90
24: */
25:
26: #if VAX8200
27:
28: /*
29: * Routines to handle the console RX50.
30: */
31:
32: #include "param.h"
33: #include "time.h"
34: #include "kernel.h"
35: #include "vmmac.h"
36: #include "buf.h"
37: #include "errno.h"
38: #include "uio.h"
39:
40: #include "cpu.h"
41: #include "rx50reg.h"
42:
43: struct rx50device rx50device;
44:
45: #define rx50unit(dev) minor(dev)
46:
47: struct rx50state {
48: short rs_flags; /* see below */
49: short rs_drive; /* current drive number */
50: u_int rs_blkno; /* current block number */
51: } rx50state;
52:
53: /* flags */
54: #define RS_0OPEN 0x01 /* drive 0 open -- must be first */
55: #define RS_1OPEN 0x02 /* drive 1 open -- must be second */
56: #define RS_BUSY 0x04 /* operation in progress */
57: #define RS_WANT 0x08 /* wakeup when done */
58: #define RS_DONE 0x20 /* I/O operation done */
59: #define RS_ERROR 0x40 /* error bit set at interrupt */
60:
61: /*
62: * Open a console RX50.
63: */
64: /*ARGSUSED*/
65: rx50open(dev, flags)
66: dev_t dev;
67: int flags;
68: {
69: int unit;
70:
71: /* only on 8200 (yet) */
72: if (cpu != VAX_8200 || (unit = rx50unit(dev)) >= 2)
73: return (ENXIO);
74:
75: /* enforce exclusive access */
76: if (rx50state.rs_flags & (1 << unit))
77: return (EBUSY);
78: rx50state.rs_flags |= 1 << unit;
79: return (0);
80: }
81:
82: /*
83: * Close a console RX50.
84: */
85: /*ARGSUSED*/
86: rx50close(dev, flags)
87: dev_t dev;
88: int flags;
89: {
90:
91: rx50state.rs_flags &= ~(1 << dev); /* atomic */
92: }
93:
94: /*
95: * Perform a read (uio->uio_rw==UIO_READ) or write (uio->uio_rw==UIO_WRITE).
96: */
97: rx50rw(dev, uio, flags)
98: dev_t dev;
99: register struct uio *uio;
100: int flags;
101: {
102: register struct rx50device *rxaddr;
103: register struct rx50state *rs;
104: register char *cp;
105: register int error, i, t;
106: char secbuf[512];
107: static char driveselect[2] = { RXCMD_DRIVE0, RXCMD_DRIVE1 };
108:
109: /* enforce whole-sector I/O */
110: if ((uio->uio_offset & 511) || (uio->uio_resid & 511))
111: return (EINVAL);
112:
113: rs = &rx50state;
114:
115: /* lock out others */
116: i = spl4();
117: while (rs->rs_flags & RS_BUSY) {
118: rs->rs_flags |= RS_WANT;
119: sleep((caddr_t) &rx50state, PZERO - 1);
120: }
121: rs->rs_flags |= RS_BUSY;
122: rs->rs_drive = rx50unit(dev);
123: splx(i);
124:
125: rxaddr = &rx50device;
126: error = 0;
127:
128: while (uio->uio_resid) {
129: rs->rs_blkno = uio->uio_offset >> 9;
130: if (rs->rs_blkno >= RX50MAXSEC) {
131: if (rs->rs_blkno > RX50MAXSEC)
132: error = EINVAL;
133: else if (uio->uio_rw == UIO_WRITE)
134: error = ENOSPC;
135: /* else ``eof'' */
136: break;
137: }
138: rs->rs_flags &= ~(RS_ERROR | RS_DONE);
139: if (uio->uio_rw == UIO_WRITE) {
140: /* copy the data to the RX50 silo */
141: error = uiomove(secbuf, 512, uio);
142: if (error)
143: break;
144: i = rxaddr->rxrda;
145: for (cp = secbuf, i = 512; --i >= 0;)
146: rxaddr->rxfdb = *cp++;
147: i = RXCMD_WRITE;
148: } else
149: i = RXCMD_READ;
150: rxaddr->rxcmd = i | driveselect[rs->rs_drive];
151: i = rs->rs_blkno - ((t = rs->rs_blkno / RX50SEC) * RX50SEC);
152: rxaddr->rxtrk = t == 79 ? 0 : t + 1;
153: #ifdef notdef
154: rxaddr->rxsec = "\1\3\5\7\11\1\3\5\7"[(2*t + i) % 5] + (i > 4);
155: #else
156: rxaddr->rxsec = RX50SKEW(i, t);
157: #endif
158: i = rxaddr->rxgo; /* start it up */
159: i = spl4();
160: while ((rs->rs_flags & RS_DONE) == 0)
161: sleep((caddr_t) &rs->rs_blkno, PRIBIO);
162: splx(i);
163: if (rs->rs_flags & RS_ERROR) {
164: error = EIO;
165: break;
166: }
167: if (uio->uio_rw == UIO_READ) {
168: /* copy the data out of the silo */
169: i = rxaddr->rxrda;
170: for (cp = secbuf, i = 512; --i >= 0;)
171: *cp++ = rxaddr->rxedb;
172: error = uiomove(secbuf, 512, uio);
173: if (error)
174: break;
175: }
176: }
177:
178: /* let others in */
179: rs->rs_flags &= ~RS_BUSY;
180: if (rs->rs_flags & RS_WANT)
181: wakeup((caddr_t) rs);
182:
183: return (error);
184: }
185:
186: rx50intr()
187: {
188: register struct rx50device *rxaddr = &rx50device;
189: register struct rx50state *rs = &rx50state;
190: int i;
191:
192: #ifdef lint
193: i = 0; i = i;
194: #endif
195:
196: /* ignore spurious interrupts */
197: if ((rxaddr->rxcmd & RXCMD_DONE) == 0)
198: return;
199: if ((rs->rs_flags & RS_BUSY) == 0) {
200: printf("stray rx50 interrupt ignored\n");
201: return;
202: }
203: if (rxaddr->rxcmd & RXCMD_ERROR) {
204: printf(
205: "csa%d: hard error sn%d: cmd=%x trk=%x sec=%x csc=%x ict=%x ext=%x\n",
206: rs->rs_drive + 1, rs->rs_blkno,
207: rxaddr->rxcmd, rxaddr->rxtrk, rxaddr->rxsec,
208: rxaddr->rxcsc, rxaddr->rxict, rxaddr->rxext);
209: rxaddr->rxcmd = RXCMD_RESET;
210: i = rxaddr->rxgo;
211: rs->rs_flags |= RS_ERROR;
212: }
213: rs->rs_flags |= RS_DONE;
214: wakeup((caddr_t) &rs->rs_blkno);
215: }
216: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.