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

Defined functions

cnrfl defined in line 223; used 1 times
conxfl defined in line 163; used 1 times
flclose defined in line 49; never used
flopen defined in line 32; never used
floperation defined in line 58; used 2 times
flread defined in line 118; never used
flstart defined in line 135; used 1 times
  • in line 98
flwrite defined in line 127; never used
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1152
Valid CSS Valid XHTML 1.0 Strict