|
|
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.1 (Berkeley) 6/5/86 ! 7: */ ! 8: ! 9: #if VAX780 ! 10: #include "param.h" ! 11: #include "systm.h" ! 12: #include "conf.h" ! 13: #include "dir.h" ! 14: #include "user.h" ! 15: #include "buf.h" ! 16: #include "uio.h" ! 17: ! 18: #include "cons.h" ! 19: #include "cpu.h" ! 20: #include "flp.h" ! 21: #include "mtpr.h" ! 22: ! 23: struct { ! 24: short fl_state; /* open and busy flags */ ! 25: short fl_active; /* driver state flag */ ! 26: struct buf *fl_buf; /* buffer we're using */ ! 27: unsigned char *fl_xaddr; /* transfer address */ ! 28: short fl_errcnt; ! 29: } fltab; ! 30: ! 31: /*ARGSUSED*/ ! 32: flopen(dev, flag) ! 33: dev_t dev; ! 34: int flag; ! 35: { ! 36: struct buf *geteblk(); ! 37: ! 38: if (cpu != VAX_780) ! 39: return (ENXIO); ! 40: if (fltab.fl_state != 0) ! 41: return (ENXIO); ! 42: fltab.fl_state = FL_OPEN; ! 43: fltab.fl_buf = geteblk(512); ! 44: fltab.fl_active = FL_IDLE; ! 45: return (0); ! 46: } ! 47: ! 48: /*ARGSUSED*/ ! 49: flclose(dev, flag) ! 50: dev_t dev; ! 51: int flag; ! 52: { ! 53: ! 54: brelse(fltab.fl_buf); ! 55: fltab.fl_state = 0; ! 56: } ! 57: ! 58: floperation(rw, uio) ! 59: enum uio_rw rw; ! 60: struct uio *uio; ! 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 (rw == UIO_WRITE) { ! 92: error = uiomove(bp->b_un.b_addr, i, UIO_WRITE, uio); ! 93: if (error) ! 94: break; ! 95: } ! 96: bp->b_flags = 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 (rw == UIO_READ) { ! 107: error = uiomove(bp->b_un.b_addr, i, UIO_READ, 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: /*ARGSUSED*/ ! 118: flread(dev, uio) ! 119: dev_t dev; ! 120: struct uio *uio; ! 121: { ! 122: ! 123: return (floperation(UIO_READ, uio)); ! 124: } ! 125: ! 126: /*ARGSUSED*/ ! 127: flwrite(dev, uio) ! 128: dev_t dev; ! 129: struct uio *uio; ! 130: { ! 131: ! 132: return (floperation(UIO_WRITE, uio)); ! 133: } ! 134: ! 135: flstart() ! 136: { ! 137: register struct buf *bp; ! 138: ! 139: bp = fltab.fl_buf; ! 140: fltab.fl_active = FL_MAND; ! 141: fltab.fl_errcnt = 0; ! 142: fltab.fl_xaddr = (unsigned char *) bp->b_un.b_addr; ! 143: bp->b_resid = 0; ! 144: bp->b_bcount = RXBYSEC; /* always transfer a full sector */ ! 145: ! 146: if ((mfpr(TXCS) & TXCS_RDY) == 0) ! 147: /* not ready to receive order */ ! 148: return; ! 149: /* ! 150: * Wake up floppy LSI software with command ! 151: */ ! 152: fltab.fl_active = FL_SEC; ! 153: if ((bp->b_flags&B_READ) == B_READ) ! 154: mtpr(TXDB, FL_RS); ! 155: else ! 156: mtpr(TXDB, FL_WS); ! 157: } ! 158: ! 159: /* ! 160: * See if we want to transmit something ! 161: * to the floppy - and do it ! 162: */ ! 163: conxfl() ! 164: { ! 165: register int databyte; ! 166: register struct buf *bp; ! 167: ! 168: bp = fltab.fl_buf; ! 169: switch (fltab.fl_active) { ! 170: ! 171: case FL_MAND: /* send command */ ! 172: if ((bp->b_flags&B_READ) == B_READ) ! 173: mtpr(TXDB,FL_RS); ! 174: else ! 175: mtpr(TXDB, FL_WS); ! 176: fltab.fl_active = FL_SEC; ! 177: break; ! 178: ! 179: case FL_SEC: /* send sector address */ ! 180: databyte = (int)bp->b_blkno % RXSTRK + 1; ! 181: mtpr(TXDB, FL_DATA | databyte); ! 182: fltab.fl_active = FL_TRACK; ! 183: break; ! 184: ! 185: case FL_TRACK: /* send track address */ ! 186: databyte = (int)bp->b_blkno / RXSTRK; ! 187: mtpr(TXDB , FL_DATA | databyte); ! 188: if ((bp->b_flags&B_READ) == B_READ) ! 189: /* prepare to receive complete */ ! 190: fltab.fl_active = FL_COM; ! 191: else ! 192: /* prepare to send data */ ! 193: fltab.fl_active = FL_DAX; ! 194: break; ! 195: ! 196: case FL_DAX: ! 197: databyte = *(fltab.fl_xaddr++); ! 198: mtpr(TXDB, FL_DATA | databyte); ! 199: if (--bp->b_bcount == 0) ! 200: fltab.fl_active = FL_COM; ! 201: break; ! 202: ! 203: case FL_CAN: /* give cancel order */ ! 204: mtpr(TXDB, FL_CANCEL); ! 205: if (++fltab.fl_errcnt <= FLERRS) { ! 206: /* If error count permits, retry order */ ! 207: fltab.fl_active = FL_MAND; ! 208: bp->b_bcount = RXBYSEC; ! 209: fltab.fl_xaddr = (unsigned char *) bp->b_un.b_addr; ! 210: } else { ! 211: /* ! 212: * We're really stupid today - call it an ! 213: * error and give up ! 214: */ ! 215: bp->b_flags |= B_ERROR | B_DONE; ! 216: bp->b_resid = -RXBYSEC; ! 217: fltab.fl_active = FL_IDLE; ! 218: wakeup((caddr_t)bp); ! 219: } ! 220: } ! 221: } ! 222: ! 223: cnrfl(c) ! 224: int c; ! 225: { ! 226: register int datum; ! 227: register struct buf *bp; ! 228: ! 229: datum = c; ! 230: bp = fltab.fl_buf; ! 231: if (datum == FL_PERR) { ! 232: /* ! 233: * Got a protocol error - cancel the ! 234: * current function and try again if error count isn't ! 235: * too great. First, though, make sure that an actual ! 236: * transaction is in progress (so a spurious error from ! 237: * the LSI won't screw us up too much! ! 238: */ ! 239: if (fltab.fl_active != FL_IDLE) ! 240: fltab.fl_active = FL_CAN; ! 241: } else switch(fltab.fl_active ) { ! 242: ! 243: case FL_DAR: /* expecting a datum */ ! 244: if ((c&RXDB_ID) != FL_DATA) ! 245: goto error; ! 246: *(fltab.fl_xaddr++) = (c & RXDB_DATA); ! 247: if (--bp->b_bcount==0) { ! 248: fltab.fl_active = FL_IDLE; ! 249: bp->b_flags |= B_DONE; ! 250: wakeup((caddr_t)bp); ! 251: } ! 252: break; ! 253: ! 254: case FL_COM: /* expecting a "function complete" */ ! 255: if ((c&RXDB_ID)!= FL_FFC || (c&FL_ERR) == FL_ERR){ ! 256: error: ! 257: bp->b_flags |= B_ERROR | B_DONE; ! 258: bp->b_resid = -bp->b_bcount; ! 259: fltab.fl_active = FL_IDLE; ! 260: wakeup((caddr_t)bp); ! 261: } else if ((bp->b_flags&B_READ) == B_READ) ! 262: /* got function complete, now get data */ ! 263: fltab.fl_active = FL_DAR; ! 264: else { ! 265: /* got function complete on write - finish up */ ! 266: fltab.fl_active = FL_IDLE; ! 267: bp->b_flags |= B_DONE; ! 268: wakeup((caddr_t)bp); ! 269: } ! 270: break; ! 271: } ! 272: } ! 273: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.