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