|
|
1.1 root 1: /* flp.c 4.5 81/03/08 */
2:
3: #if VAX780
4: #include "../h/flp.h"
5: #include "../h/param.h"
6: #include "../h/systm.h"
7: #include "../h/conf.h"
8: #include "../h/dir.h"
9: #include "../h/user.h"
10: #include "../h/mtpr.h"
11: #include "../h/buf.h"
12: #include "../h/cons.h"
13: #include "../h/cpu.h"
14:
15: struct {
16: short fl_state; /* open and busy flags */
17: short fl_active; /* driver state flag */
18: struct buf *fl_buf; /* buffer we're using */
19: unsigned char *fl_xaddr; /* transfer address */
20: short fl_errcnt;
21: } fltab;
22:
23: /*ARGSUSED*/
24: flopen(dev, flag)
25: dev_t dev;
26: int flag;
27: {
28: struct buf *geteblk();
29:
30: #if VAX750
31: if (cpu != VAX_780) {
32: u.u_error = ENXIO;
33: return;
34: }
35: #endif
36: if (fltab.fl_state != 0) {
37: u.u_error = ENXIO;
38: return;
39: }
40: fltab.fl_state = FL_OPEN;
41: fltab.fl_buf = geteblk();
42: fltab.fl_active = FL_IDLE;
43: }
44:
45: /*ARGSUSED*/
46: flclose(dev, flag)
47: dev_t dev;
48: int flag;
49: {
50:
51: brelse(fltab.fl_buf);
52: fltab.fl_state = 0;
53: }
54:
55: flstrategy(rw)
56: int rw;
57: {
58: register struct buf *bp;
59: register unsigned i;
60:
61: /*
62: * Assume one block read/written for each call -
63: * and enforce this by checking for block size of 128.
64: * Use the b_blkno field to address
65: * physical, 128-byte blocks (u.u_offset/128).
66: * This is checked for validity, and is further interpreted as:
67: *
68: * track# * (sectors/track) + sector #
69: */
70: if (u.u_count == 0)
71: return;
72: (void) spl4();
73: while (fltab.fl_state & FL_BUSY)
74: sleep((caddr_t)&fltab, PRIBIO);
75: fltab.fl_state |= FL_BUSY;
76: (void) spl0();
77:
78: bp = fltab.fl_buf;
79: while ((i = min(RXBYSEC, u.u_count)) != 0) {
80: bp->b_blkno = u.u_offset>>7;
81: if (bp->b_blkno >= MAXSEC || (u.u_offset & 0177) != 0) {
82: /* block number out of range */
83: /* or offset in middle of block */
84: u.u_error = ENXIO;
85: break;
86: }
87: if (rw == B_WRITE) {
88: iomove(bp->b_un.b_addr, i, B_WRITE);
89: if (u.u_error != 0)
90: break;
91: }
92: bp->b_flags = rw;
93: (void) spl4();
94: flstart();
95: while ((bp->b_flags & B_DONE) == 0)
96: sleep((caddr_t)bp, PRIBIO);
97: (void) spl0();
98: if (bp->b_flags & B_ERROR) {
99: u.u_error = EIO;
100: break;
101: }
102: if (rw == B_READ) {
103: iomove(bp->b_un.b_addr, i, B_READ);
104: if (u.u_error != 0)
105: break;
106: }
107: }
108: u.u_count = bp->b_resid;
109: fltab.fl_state &= ~FL_BUSY;
110: wakeup((caddr_t)&fltab);
111: }
112:
113: /*ARGSUSED*/
114: flread(dev)
115: dev_t dev;
116: {
117:
118: flstrategy(B_READ);
119: }
120:
121: /*ARGSUSED*/
122: flwrite(dev)
123: dev_t dev;
124: {
125:
126: flstrategy(B_WRITE);
127: }
128:
129: flstart()
130: {
131: register struct buf *bp;
132:
133: bp = fltab.fl_buf;
134: fltab.fl_active = FL_MAND;
135: fltab.fl_errcnt = 0;
136: fltab.fl_xaddr = (unsigned char *) bp->b_un.b_addr;
137: bp->b_resid = 0;
138: bp->b_bcount = RXBYSEC; /* always transfer a full sector */
139:
140: if ((mfpr(TXCS) & TXCS_RDY) == 0)
141: /* not ready to receive order */
142: return;
143: /*
144: * Wake up floppy LSI software with command
145: */
146: fltab.fl_active = FL_SEC;
147: if ((bp->b_flags&B_READ) == B_READ)
148: mtpr(TXDB, FL_RS);
149: else
150: mtpr(TXDB, FL_WS);
151: }
152:
153: /*
154: * See if we want to transmit something
155: * to the floppy - and do it
156: */
157: conxfl()
158: {
159: register int databyte;
160: register struct buf *bp;
161:
162: bp = fltab.fl_buf;
163: switch (fltab.fl_active) {
164:
165: case FL_MAND: /* send command */
166: if ((bp->b_flags&B_READ) == B_READ)
167: mtpr(TXDB,FL_RS);
168: else
169: mtpr(TXDB, FL_WS);
170: fltab.fl_active = FL_SEC;
171: break;
172:
173: case FL_SEC: /* send sector address */
174: databyte = (int)bp->b_blkno % RXSTRK + 1;
175: mtpr(TXDB, FL_DATA | databyte);
176: fltab.fl_active = FL_TRACK;
177: break;
178:
179: case FL_TRACK: /* send track address */
180: databyte = (int)bp->b_blkno / RXSTRK;
181: mtpr(TXDB , FL_DATA | databyte);
182: if ((bp->b_flags&B_READ) == B_READ)
183: /* prepare to receive complete */
184: fltab.fl_active = FL_COM;
185: else
186: /* prepare to send data */
187: fltab.fl_active = FL_DAX;
188: break;
189:
190: case FL_DAX:
191: databyte = *(fltab.fl_xaddr++);
192: mtpr(TXDB, FL_DATA | databyte);
193: if (--bp->b_bcount == 0)
194: fltab.fl_active = FL_COM;
195: break;
196:
197: case FL_CAN: /* give cancel order */
198: mtpr(TXDB, FL_CANCEL);
199: if (++fltab.fl_errcnt <= FLERRS) {
200: /* If error count permits, retry order */
201: fltab.fl_active = FL_MAND;
202: bp->b_bcount = RXBYSEC;
203: fltab.fl_xaddr = (unsigned char *) bp->b_un.b_addr;
204: } else {
205: /*
206: * We're really stupid today - call it an
207: * error and give up
208: */
209: bp->b_flags |= B_ERROR | B_DONE;
210: bp->b_resid = -RXBYSEC;
211: fltab.fl_active = FL_IDLE;
212: wakeup((caddr_t)bp);
213: }
214: }
215: }
216:
217: cnrfl(c)
218: int c;
219: {
220: register int datum;
221: register struct buf *bp;
222:
223: datum = c;
224: bp = fltab.fl_buf;
225: if (datum == FL_PERR) {
226: /*
227: * Got a protocol error - cancel the
228: * current function and try again if error count isn't
229: * too great. First, though, make sure that an actual
230: * transaction is in progress (so a spurious error from
231: * the LSI won't screw us up too much!
232: */
233: if (fltab.fl_active != FL_IDLE)
234: fltab.fl_active = FL_CAN;
235: } else switch(fltab.fl_active ) {
236:
237: case FL_DAR: /* expecting a datum */
238: if ((c&RXDB_ID) != FL_DATA)
239: goto error;
240: *(fltab.fl_xaddr++) = (c & RXDB_DATA);
241: if (--bp->b_bcount==0) {
242: fltab.fl_active = FL_IDLE;
243: bp->b_flags |= B_DONE;
244: wakeup((caddr_t)bp);
245: }
246: break;
247:
248: case FL_COM: /* expecting a "function complete" */
249: if ((c&RXDB_ID)!= FL_FFC || (c&FL_ERR) == FL_ERR){
250: error:
251: bp->b_flags |= B_ERROR | B_DONE;
252: bp->b_resid = -bp->b_bcount;
253: fltab.fl_active = FL_IDLE;
254: wakeup((caddr_t)bp);
255: } else if ((bp->b_flags&B_READ) == B_READ)
256: /* got function complete, now get data */
257: fltab.fl_active = FL_DAR;
258: else {
259: /* got function complete on write - finish up */
260: fltab.fl_active = FL_IDLE;
261: bp->b_flags |= B_DONE;
262: wakeup((caddr_t)bp);
263: }
264: break;
265: }
266: }
267: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.