|
|
1.1 root 1: /*
2: * Star console floppy
3: * -- traces of multiple drives; this was derived from Nautilus.
4: * It is probably easier to leave the traces in for future need.
5: */
6:
7: #include "sys/param.h"
8: #include "sys/user.h"
9: #include "sys/buf.h"
10: #include "sys/conf.h"
11:
12: /*
13: * interface to console driver
14: * this should really be in a header somewhere
15: */
16:
17: extern int *cniwrite(), *cniread();
18: extern int cniwait();
19:
20: int cbsopen(), cbsread(), cbswrite();
21:
22: struct cdevsw cbscdev = cdinit(cbsopen, nulldev, cbsread, cbswrite, nodev);
23:
24: #define NDEVS 1
25:
26: static char cbsid[NDEVS] = {
27: 1, /* (0) floppy */
28: };
29:
30: #define BSCMD 0x9 /* ID to write commands */
31: #define BSSTS 0x2 /* ID to read answers */
32: #define SECTOR 128
33: #define SECTRK 26
34: #define MAXBLK (77*SECTRK)
35: #define RCOM 0
36: #define WCOM 1
37: #define USHIFT 4
38: #define STSTS(s) ((s)&0200) /* status in status */
39: #define STOK 0
40:
41: #define UNIT(d) ((d)&077) /* in case of silly 0100 bit */
42:
43: static char cbsbusy, cbswant;
44:
45: #define MAXRAW (4*SECTOR)
46: static struct buf cbsbuf;
47: static char cbsdat[MAXRAW];
48: struct buf *cbsmkbuf();
49:
50: cbsopen(dev)
51: dev_t dev;
52: {
53: if (UNIT(minor(dev)) >= NDEVS)
54: u.u_error = ENXIO;
55: }
56:
57: cbsread(dev)
58: dev_t dev;
59: {
60: register struct buf *bp;
61:
62: if ((bp = cbsmkbuf(dev, B_READ)) == NULL)
63: return;
64: cbsdoio(bp, (daddr_t)(Ltol(u.u_offset)/SECTOR));
65: iowait(bp);
66: if (u.u_error == 0)
67: iomove(bp->b_un.b_addr, bp->b_bcount-bp->b_resid, B_READ);
68: cbsrelse(bp);
69: }
70:
71: cbswrite(dev)
72: dev_t dev;
73: {
74: register struct buf *bp;
75: daddr_t sno;
76:
77: if ((bp = cbsmkbuf(dev, B_WRITE)) == NULL)
78: return;
79: sno = Ltol(u.u_offset)/SECTOR;
80: iomove(bp->b_un.b_addr, bp->b_bcount, B_WRITE);
81: if (u.u_error) {
82: cbsrelse(bp);
83: return;
84: }
85: cbsdoio(bp, sno);
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: splx(s);
110: bp->b_bcount = min(u.u_count, MAXRAW);
111: bp->b_un.b_addr = cbsdat;
112: bp->b_dev = dev;
113: /* b_blkno unused by any code we'll call */
114: return (bp);
115: }
116:
117: cbsrelse(bp)
118: register struct buf *bp;
119: {
120:
121: if (bp->b_flags & B_WANTED)
122: wakeup((caddr_t)bp);
123: bp->b_flags &=~ (B_WANTED|B_BUSY);
124: }
125:
126: cbsdoio(bp, sno)
127: struct buf *bp;
128: daddr_t sno;
129: {
130: int s;
131:
132: if (sno >= 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, sno);
146: else
147: cbswr(bp, sno);
148: if (cbswant) {
149: cbswant = 0;
150: wakeup(&cbsbusy);
151: }
152: cbsbusy = 0;
153: }
154:
155: cbsrd(bp, sno)
156: register struct buf *bp;
157: daddr_t sno;
158: {
159: static char cmd[2];
160: static unsigned char sts;
161: register int unit;
162: register char *buf;
163: register int *pst, *pdt;
164:
165: unit = UNIT(minor(bp->b_dev));
166: bp->b_resid = bp->b_bcount;
167: buf = bp->b_un.b_addr;
168: while (bp->b_resid >= SECTOR) {
169: cmd[0] = RCOM|(unit<<USHIFT);
170: pst = cniwrite(BSCMD, cmd, 1);
171: if (cniwait(pst, 5)) {
172: bp->b_flags |= B_ERROR;
173: break;
174: }
175: cmd[0] = (sno%SECTRK) + 1;
176: cmd[1] = sno / SECTRK;
177: pst = cniread(BSSTS, &sts, 1);
178: pdt = cniread(cbsid[unit], buf, SECTOR);
179: cniwrite(cbsid[unit], cmd, 2);
180: if (cniwait(pst, 5) || STSTS(sts) != STOK) {
181: *pdt = 0;
182: if (bp->b_resid != bp->b_bcount)
183: bp->b_flags |= B_ERROR;
184: break;
185: }
186: if (cniwait(pdt, 5)) {
187: if (bp->b_resid != bp->b_bcount)
188: bp->b_flags |= B_ERROR;
189: break;
190: }
191: sno++;
192: buf += SECTOR;
193: bp->b_resid -= SECTOR;
194: }
195: iodone(bp);
196: }
197:
198: cbswr(bp, sno)
199: register struct buf *bp;
200: daddr_t sno;
201: {
202: static char cmd[2];
203: static unsigned char sts;
204: register int unit;
205: register char *buf;
206: register int *pst, *pdt;
207:
208: unit = UNIT(minor(bp->b_dev));
209: bp->b_resid = bp->b_bcount;
210: buf = bp->b_un.b_addr;
211: while (bp->b_resid >= SECTOR) {
212: cmd[0] = WCOM|(unit<<USHIFT);
213: pst = cniwrite(BSCMD, cmd, 1);
214: if (cniwait(pst, 5)) {
215: bp->b_flags |= B_ERROR;
216: break;
217: }
218: cmd[0] = (sno%SECTRK) + 1;
219: cmd[1] = sno / SECTRK;
220: pst = cniread(BSSTS, &sts, 1);
221: pdt = cniwrite(cbsid[unit], cmd, 2);
222: if (cniwait(pdt, 5)) {
223: *pst = 0;
224: bp->b_flags |= B_ERROR;
225: break;
226: }
227: pdt = cniwrite(cbsid[unit], buf, SECTOR);
228: if (cniwait(pst, 5) || STSTS(sts) != STOK) {
229: *pdt = 0;
230: if (bp->b_resid != bp->b_bcount)
231: bp->b_flags |= B_ERROR;
232: break;
233: }
234: if (cniwait(pdt, 1)) {
235: if (bp->b_resid != bp->b_bcount)
236: bp->b_flags |= B_ERROR;
237: break;
238: }
239: sno++;
240: buf += SECTOR;
241: bp->b_resid -= SECTOR;
242: }
243: iodone(bp);
244: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.