|
|
1.1 root 1: /*
2: * Nautilus console disks
3: */
4:
5: #include "sys/param.h"
6: #include "sys/user.h"
7: #include "sys/buf.h"
8: #include "sys/conf.h"
9:
10: /*
11: * interface to console driver
12: * (on nautilus only)
13: * this should really be in a header somewhere
14: */
15:
16: extern int *cniwrite(), *cniread();
17: extern int cniwait();
18:
19: int cbsopen(), cbsstrat();
20: int cbsread(), cbswrite();
21:
22: struct bdevsw cbsbdev = bdinit(cbsopen, nulldev, cbsstrat, 0);
23: struct cdevsw cbscdev = cdinit(cbsopen, nulldev, cbsread, cbswrite, nodev);
24:
25: #define NDEVS 3
26:
27: static char cbsid[NDEVS] = {
28: 1, /* (0) first floppy */
29: 4, /* (1) second floppy */
30: 2, /* (2) winchester -- read only */
31: };
32:
33: #define BSCMD 0x9 /* ID to write commands */
34: #define BSSTS 0x8 /* ID to read answers */
35: #define SECTOR 512
36: #define MAXBLK 65535 /* the limit is in the protocol */
37: #define RCOM 0
38: #define WCOM 1
39: #define USHIFT 4
40: #define STSTS(s) ((s)&017) /* status in status */
41: #define STOK 0
42:
43: #define UNIT(d) ((d)&077) /* in case of silly 0100 bit */
44:
45: static char cbsbusy, cbswant;
46:
47: #define MAXRAW (8*SECTOR)
48: static struct buf cbsbuf;
49: static char cbsdat[MAXRAW];
50: struct buf *cbsmkbuf();
51:
52: cbsopen(dev)
53: dev_t dev;
54: {
55: if (UNIT(minor(dev)) >= NDEVS)
56: u.u_error = ENXIO;
57: }
58:
59: cbsread(dev)
60: dev_t dev;
61: {
62: register struct buf *bp;
63:
64: if ((bp = cbsmkbuf(dev, B_READ)) == NULL)
65: return;
66: cbsstrat(bp);
67: iowait(bp);
68: if (u.u_error == 0)
69: iomove(bp->b_un.b_addr, bp->b_bcount-bp->b_resid, B_READ);
70: cbsrelse(bp);
71: }
72:
73: cbswrite(dev)
74: dev_t dev;
75: {
76: register struct buf *bp;
77:
78: if ((bp = cbsmkbuf(dev, B_WRITE)) == NULL)
79: return;
80: iomove(bp->b_un.b_addr, bp->b_bcount, B_WRITE);
81: if (u.u_error) {
82: cbsrelse(bp);
83: return;
84: }
85: cbsstrat(bp);
86: iowait(bp);
87: cbsrelse(bp);
88: }
89:
90: struct buf *
91: cbsmkbuf(dev, rw)
92: dev_t dev;
93: int rw;
94: {
95: register struct buf *bp;
96: register int s;
97:
98: if (u.u_count < SECTOR || (Ltol(u.u_offset) % SECTOR) != 0) {
99: u.u_error = ENXIO;
100: return (NULL);
101: }
102: bp = &cbsbuf;
103: s = spl6();
104: while (bp->b_flags & B_BUSY) {
105: bp->b_flags |= B_WANTED;
106: sleep((caddr_t)bp, PRIBIO);
107: }
108: bp->b_flags |= B_BUSY | rw;
109: bp->b_flags &=~ B_DONE;
110: splx(s);
111: bp->b_bcount = min(u.u_count, MAXRAW);
112: bp->b_un.b_addr = cbsdat;
113: bp->b_blkno = Ltol(u.u_offset) / SECTOR;
114: bp->b_dev = dev;
115: return (bp);
116: }
117:
118: cbsrelse(bp)
119: register struct buf *bp;
120: {
121:
122: if (bp->b_flags & B_WANTED)
123: wakeup((caddr_t)bp);
124: bp->b_flags &=~ (B_WANTED|B_BUSY);
125: }
126:
127: cbsstrat(bp)
128: struct buf *bp;
129: {
130: int s;
131:
132: if (bp->b_blkno >= MAXBLK) {
133: bp->b_flags |= B_ERROR;
134: iodone(bp);
135: return;
136: }
137: s = spl6();
138: while (cbsbusy) {
139: cbswant++;
140: sleep(&cbsbusy);
141: }
142: cbsbusy++;
143: splx(s);
144: if (bp->b_flags & B_READ)
145: cbsrd(bp);
146: else
147: cbswr(bp);
148: if (cbswant) {
149: cbswant = 0;
150: wakeup(&cbsbusy);
151: }
152: cbsbusy = 0;
153: }
154:
155: cbsrd(bp)
156: register struct buf *bp;
157: {
158: static char cmd[3];
159: static char sts;
160: register int unit;
161: daddr_t blkno;
162: register char *buf;
163: register int *pst, *pdt;
164:
165: unit = UNIT(minor(bp->b_dev));
166: blkno = bp->b_blkno;
167: bp->b_resid = bp->b_bcount;
168: buf = bp->b_un.b_addr;
169: while (bp->b_resid >= SECTOR) {
170: cmd[0] = RCOM|(unit<<USHIFT);
171: cmd[1] = blkno;
172: cmd[2] = blkno>>8;
173: pst = cniread(BSSTS, &sts, 1);
174: pdt = cniread(cbsid[unit], buf, SECTOR);
175: cniwrite(BSCMD, cmd, 3);
176: if (cniwait(pst, 5) || STSTS(sts) != STOK) {
177: *pdt = 0;
178: if (bp->b_resid != bp->b_bcount)
179: bp->b_flags |= B_ERROR;
180: break;
181: }
182: if (cniwait(pdt, 5)) {
183: if (bp->b_resid != bp->b_bcount)
184: bp->b_flags |= B_ERROR;
185: break;
186: }
187: blkno++;
188: buf += SECTOR;
189: bp->b_resid -= SECTOR;
190: }
191: iodone(bp);
192: }
193:
194: cbswr(bp)
195: register struct buf *bp;
196: {
197: static char cmd[3];
198: static char sts;
199: register int unit;
200: daddr_t blkno;
201: register char *buf;
202: register int *pst, *pdt;
203:
204: unit = UNIT(minor(bp->b_dev));
205: blkno = bp->b_blkno;
206: bp->b_resid = bp->b_bcount;
207: buf = bp->b_un.b_addr;
208: while (bp->b_resid >= SECTOR) {
209: cmd[0] = WCOM|(unit<<USHIFT);
210: cmd[1] = blkno;
211: cmd[2] = blkno>>8;
212: pst = cniread(BSSTS, &sts, 1);
213: cniwrite(BSCMD, cmd, 3);
214: pdt = cniwrite(cbsid[unit], buf, SECTOR);
215: if (cniwait(pst, 5) || STSTS(sts) != STOK) {
216: *pdt = 0;
217: if (bp->b_resid != bp->b_bcount)
218: bp->b_flags |= B_ERROR;
219: break;
220: }
221: if (cniwait(pdt, 1)) {
222: if (bp->b_resid != bp->b_bcount)
223: bp->b_flags |= B_ERROR;
224: break;
225: }
226: blkno++;
227: buf += SECTOR;
228: bp->b_resid -= SECTOR;
229: }
230: iodone(bp);
231: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.