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