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