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