|
|
1.1 root 1: /* flp.c 6.1 83/07/29 */
2:
3: #if VAX780
4: #include "../h/param.h"
5: #include "../h/systm.h"
6: #include "../h/conf.h"
7: #include "../h/dir.h"
8: #include "../h/user.h"
9: #include "../h/buf.h"
10: #include "../h/uio.h"
11:
12: #include "../vax/cons.h"
13: #include "../vax/cpu.h"
14: #include "../vax/flp.h"
15: #include "../vax/mtpr.h"
16:
17: struct {
18: short fl_state; /* open and busy flags */
19: short fl_active; /* driver state flag */
20: struct buf *fl_buf; /* buffer we're using */
21: unsigned char *fl_xaddr; /* transfer address */
22: short fl_errcnt;
23: } fltab;
24:
25: /*ARGSUSED*/
26: flopen(dev, flag)
27: dev_t dev;
28: int flag;
29: {
30: struct buf *geteblk();
31:
32: #if VAX750
33: if (cpu != VAX_780)
34: return (ENXIO);
35: #endif
36: if (fltab.fl_state != 0)
37: return (ENXIO);
38: fltab.fl_state = FL_OPEN;
39: fltab.fl_buf = geteblk(512);
40: fltab.fl_active = FL_IDLE;
41: return (0);
42: }
43:
44: /*ARGSUSED*/
45: flclose(dev, flag)
46: dev_t dev;
47: int flag;
48: {
49:
50: brelse(fltab.fl_buf);
51: fltab.fl_state = 0;
52: }
53:
54: floperation(rw, uio)
55: enum uio_rw rw;
56: struct uio *uio;
57: {
58: register struct buf *bp;
59: register int i;
60: int error;
61:
62: /*
63: * Assume one block read/written for each call -
64: * and enforce this by checking for block size of 128.
65: * Use the b_blkno field to address
66: * physical, 128-byte blocks (u.u_offset/128).
67: * This is checked for validity, and is further interpreted as:
68: *
69: * track# * (sectors/track) + sector #
70: */
71: if (uio->uio_resid == 0)
72: return (0);
73: (void) spl4();
74: while (fltab.fl_state & FL_BUSY)
75: sleep((caddr_t)&fltab, PRIBIO);
76: fltab.fl_state |= FL_BUSY;
77: (void) spl0();
78:
79: bp = fltab.fl_buf;
80: error = 0;
81: while ((i = imin(RXBYSEC, uio->uio_resid)) > 0) {
82: bp->b_blkno = uio->uio_offset>>7;
83: if (bp->b_blkno >= MAXSEC || (uio->uio_offset & 0177) != 0)
84: return (ENXIO);
85: if (rw == UIO_WRITE) {
86: error = uiomove(bp->b_un.b_addr, i, UIO_WRITE, uio);
87: if (error)
88: break;
89: }
90: bp->b_flags = rw == UIO_WRITE ? B_WRITE : B_READ;
91: (void) spl4();
92: flstart();
93: while ((bp->b_flags & B_DONE) == 0)
94: sleep((caddr_t)bp, PRIBIO);
95: (void) spl0();
96: if (bp->b_flags & B_ERROR) {
97: error = EIO;
98: break;
99: }
100: if (rw == UIO_READ) {
101: error = uiomove(bp->b_un.b_addr, i, UIO_READ, uio);
102: if (error)
103: break;
104: }
105: }
106: fltab.fl_state &= ~FL_BUSY;
107: wakeup((caddr_t)&fltab);
108: return (error);
109: }
110:
111: /*ARGSUSED*/
112: flread(dev, uio)
113: dev_t dev;
114: struct uio *uio;
115: {
116:
117: return (floperation(UIO_READ, uio));
118: }
119:
120: /*ARGSUSED*/
121: flwrite(dev, uio)
122: dev_t dev;
123: struct uio *uio;
124: {
125:
126: return (floperation(UIO_WRITE, uio));
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.