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