|
|
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.