1: /*
   2:  * RX11 floppy disk driver
   3:  * Modified 2/1/78, Brad Blasing, to emulate DMA operations
   4:  *
   5:  * Modified 15 DEC 77 by SSB,DWD,BEB, University of Minnesota
   6:  * for RX11 floppy drive.
   7:  * Modified 6/16/78, Brad Blasing, to provide better error recovery
   8:  *  (we don't loop at spl5 waiting for INIT to finish any more).
   9:  * Modified 10/19/79, Scott Bertilson, to run with slow floppy interfaces.
  10:  * Modified 4/5/80, Scott Bertilson, added CP/M interleaving to table.
  11:  * Modified 2/1/81, Scott Bertilson, to run on Version 7.
  12:  * Modified at Tek to "sort of" run under 2.9bsd; 5/83; dgc
  13:  */
  14: 
  15: #include "rx.h"
  16: #if NRX > 0
  17: #include "param.h"
  18: #include <sys/buf.h>
  19: #include <sys/conf.h>
  20: #include <sys/dir.h>
  21: #include <sys/user.h>
  22: #include <sys/rxreg.h>
  23: extern  struct rxdevice *RXADDR;
  24: 
  25: /* #define DEBUG	1 */
  26: #define DMA 1
  27: /* #define RXADDR	((struct rxdevice *)0177170)	/* MAE - 3/29/83 */
  28: #define NRXTYP  4
  29: #define MAXRETRY  5
  30: #define TTIME   60  /* Timeout time in HZ */
  31: #define RRATE   6   /* Recall rate for rxreset */
  32: #define RESETMAX 10 /* Max. num. of reset recalls before timeout */
  33:             /* RESETMAX*RRATE/60 = time in second */
  34: 
  35: #define RXWAIT  while((rxaddr->rxcs & (TR | DONE)) == 0) ;
  36: #define KISA    0172340
  37: #define KISD    0172300
  38: 
  39: struct  rxtype {
  40:     int secsize;        /* size (bytes) one sector */
  41:     int secpertrk;      /* sectors/track */
  42:     int secperblk;      /* sectors/unix block */
  43:     int numsec;         /* total sectors on device */
  44:     int numblks;        /* number of blocks on device */
  45:     int secincr;        /* increment to get next sector of block */
  46:     int intrlv;         /* interleaving factor */
  47:     int skew;           /* sector skew across tracks */
  48:     int trkoffset;      /* offset num of 1st sec */
  49: } rxtypes[NRXTYP] {
  50:         128, 26, 4, 77*26, 500, 2, 13, 6, 0,    /* our "standard" format */
  51:         128, 26, 4, 77*26, 500, 1, 26, 0, 0,    /* IBM format */
  52:         128, 26, 4, 76*26, 494, 2, 13, 6, 1,    /* Terak or RT11 format */
  53:         128, 26, 4, 76*26, 494, 6, 13, 0, 2 /* CP/M format */
  54: };
  55: 
  56: struct  rxstat {
  57:     int fminor;         /* present request device number */
  58:     struct  rxtype *ftype;      /* present request floppy type */
  59:     int bytect;         /* remaining bytes (neg) */
  60:     int sector;         /* absolute sector (0..numsec-1) */
  61:     int toutact;        /* timeout active */
  62:     int reqnum;         /* floppy request number for timeout */
  63:     caddr_t coreaddr;       /* current core address for transfer */
  64: #ifdef DMA
  65:     char    *coreblk;       /* block no. to put in seg. register */
  66: #endif
  67: } rxstat;
  68: 
  69: struct  buf rxtab;
  70: 
  71: rxstrategy(abp)
  72: struct buf *abp;
  73: {
  74:     register struct buf *bp;
  75:     extern int rxtimeout();
  76: 
  77: #ifdef DEBUG
  78:     if(minor(abp->b_dev) == 127) {
  79:         rxdebug();
  80:         iodone(abp);
  81:         spl0();
  82:         return;
  83:     }
  84: #endif
  85:     bp = abp;
  86:     /*
  87: 	 * test for valid request
  88: 	 */
  89:     if(rxok(bp) == 0) {
  90:         bp->b_flags =| B_ERROR;
  91:         iodone(bp);
  92:         return;
  93:     }
  94:     /*
  95: 	 * link buffer into device queue
  96: 	 */
  97:     bp->av_forw = NULL;
  98:     spl5();
  99:     if(rxtab.b_actf == NULL)
 100:         rxtab.b_actf = bp;
 101:     else
 102:         rxtab.b_actl->av_forw = bp;
 103:     rxtab.b_actl = bp;
 104:     /*
 105: 	 * start rxtimeout if inactive
 106: 	 */
 107:     if(rxstat.toutact == 0) {
 108:         rxstat.toutact++;
 109:         timeout(rxtimeout, (caddr_t)0, TTIME);
 110:     }
 111:     /*
 112: 	 * start device if there is no current request
 113: 	 */
 114:     if(rxtab.b_active == NULL)
 115:         rxstart();
 116:     spl0();
 117: }
 118: 
 119: rxstart()
 120: {
 121:     register struct buf *bp;
 122:     register struct rxdevice *rxaddr;
 123:     register int dminor;
 124: 
 125:     rxaddr = RXADDR;
 126:     /*
 127: 	 * if there is no request in queue...return
 128: 	 */
 129: loop:   if((bp = rxtab.b_actf) == NULL)
 130:         return;
 131:     /*
 132: 	 * check if drive ready
 133: 	 */
 134:     dminor = (minor(bp->b_dev) & 1) << 4;
 135:     rxaddr->rxcs = dminor | RDSTAT | GO;
 136:     RXWAIT
 137:     if((rxaddr->rxdb & DR) == 0) {
 138:         printf("rx%d: Floppy not ready\n", minor(bp->b_dev));
 139:         rxabtbuf();
 140:         goto loop;
 141:     }
 142:     /*
 143: 	 * set active request flag
 144: 	 */
 145:     rxtab.b_active++;
 146:     rxsetup(bp);
 147:     rxregs(bp);
 148: }
 149: 
 150: rxintr()
 151: {
 152:     register struct buf *bp;
 153:     register struct rxtype *rxt;
 154:     register struct rxdevice *rxaddr;
 155: 
 156:     rxaddr = RXADDR;
 157:     /*
 158: 	 * if there is no active request, false alarm.
 159: 	 */
 160:     if(rxtab.b_active == NULL)
 161:         return;
 162:     rxtab.b_active = NULL;
 163:     /*
 164: 	 * pointer to the buffer
 165: 	 */
 166:     bp = rxtab.b_actf;
 167:     /*
 168: 	 * pointer to a data structure describing
 169: 	 *  the type of device (i.e. interleaving)
 170: 	 */
 171:     rxt = rxstat.ftype;
 172:     /*
 173: 	 * check error bit
 174: 	 */
 175:     if(rxaddr->rxcs & ERROR) {
 176:         /*
 177: 		 * send read error register command
 178: 		 */
 179:         rxaddr->rxcs = RDERR | GO;
 180:         RXWAIT
 181: #ifndef UCB_DEVERR
 182:         deverror(bp, rxaddr->rxcs, rxaddr->rxdb);
 183: #else
 184:         harderr(bp, "rx");
 185:         printf("cs=%b, es=%b\n", rxaddr->rxcs, RXCS_BITS,
 186:             rxaddr->rxdb, RXES_BITS);
 187: #endif
 188:         /*
 189: 		 * make MAXRETRY retries on an error
 190: 		 */
 191:         if(++rxtab.b_errcnt <= MAXRETRY) {
 192:             rxreset(0);
 193:             return;
 194:         }
 195:         /*
 196: 		 * return an i/o error
 197: 		 */
 198:         bp->b_flags =| B_ERROR;
 199:     } else {
 200:         /*
 201: 		 * if we just read a sector, we need to
 202: 		 *  empty the device buffer
 203: 		 */
 204:         if(bp->b_flags & B_READ)
 205:             rxempty(bp);
 206:         /*
 207: 		 * see if there is more data to read for
 208: 		 * this request.
 209: 		 */
 210:         rxstat.bytect =+ rxt->secsize;
 211:         rxstat.sector++;
 212:         if(rxstat.bytect < 0 && rxstat.sector < rxt->numsec) {
 213:             rxtab.b_active++;
 214:             rxregs(bp);
 215:             return;
 216:         }
 217:     }
 218:     rxtab.b_errcnt = 0;
 219:     /*
 220: 	 * unlink block from queue
 221: 	 */
 222:     rxtab.b_actf = bp->av_forw;
 223:     iodone(bp);
 224:     /*
 225: 	 * start i/o on next buffer in queue
 226: 	 */
 227:     rxstart();
 228: }
 229: 
 230: rxreset(flag)
 231: {
 232:     register struct rxdevice *rxaddr;
 233: 
 234:     rxaddr = RXADDR;
 235:     /*
 236: 	 * Check to see if this is a call from rxintr or
 237: 	 * a recall from timeout.
 238: 	 */
 239:     if(flag) {
 240:         if(rxaddr->rxcs & DONE) {
 241:             rxtab.b_active = 0;
 242:             rxstart();
 243:         } else
 244:             if(flag > RESETMAX) {
 245:                 printf("rx%d: Reset timeout\n", minor(rxtab.b_actf->b_dev));
 246:                 rxabtbuf();
 247:                 rxstart();
 248:             } else {
 249:                 timeout(rxreset, (caddr_t)flag+1, RRATE);
 250:                 /*
 251: 				 * Keep rxtimeout from timing out.
 252: 				 */
 253:                 rxstat.reqnum++;
 254:             }
 255:     } else {
 256:         rxaddr->rxcs = INIT;
 257:         rxtab.b_active++;
 258:         rxstat.reqnum++;
 259:         timeout(rxreset, (caddr_t)1, 1);
 260:     }
 261: }
 262: 
 263: rxregs(abp)
 264: struct buf *abp;
 265: {
 266:     register struct buf *bp;
 267:     register struct rxtype *rxt;
 268:     register struct rxdevice *rxaddr;
 269:     int dminor, cursec, curtrk;
 270: 
 271:     rxaddr = RXADDR;
 272:     /*
 273: 	 * set device bit into proper position for command
 274: 	 */
 275:     dminor = rxstat.fminor << 4;
 276:     bp = abp;
 277:     rxt = rxstat.ftype;
 278:     /*
 279: 	 * increment interrupt request number
 280: 	 */
 281:     rxstat.reqnum++;
 282:     /*
 283: 	 * if command is read, initiate the command
 284: 	 */
 285:     if(bp->b_flags & B_READ){
 286:         RXWAIT
 287:         rxaddr->rxcs = dminor | IENABLE | GO | READ;
 288:     } else {
 289:         /*
 290: 		 * if command is write, fill the device buffer,
 291: 		 *   then initiate the write
 292: 		 */
 293:         rxfill(bp);
 294:         RXWAIT
 295:         rxaddr->rxcs = dminor | IENABLE | GO | WRITE;
 296:     }
 297:     /*
 298: 	 * set track number
 299: 	 */
 300:     curtrk = rxstat.sector / rxt->secpertrk;
 301:     /*
 302: 	 * set sector number
 303: 	 */
 304:     dminor = rxstat.sector % rxt->secpertrk;
 305:     cursec = (dminor % rxt->intrlv) * rxt->secincr +
 306:         (dminor / rxt->intrlv);
 307:     /*
 308: 	 * add skew to sector
 309: 	 */
 310:     cursec = (cursec + curtrk * rxt->skew)
 311:         % rxt->secpertrk;
 312:     /*
 313: 	 * massage registers
 314: 	 */
 315:     RXWAIT
 316:     rxaddr->rxdb = cursec + 1;
 317:     RXWAIT
 318:     rxaddr->rxdb = curtrk + rxt->trkoffset;
 319: }
 320: 
 321: rxok(abp)
 322: struct buf *abp;
 323: {
 324:     register struct buf *bp;
 325:     register int type;
 326:     register int dminor;
 327: 
 328:     /*
 329: 	 * get sub-device number and type from dminor device number
 330: 	 */
 331:     dminor = minor((bp = abp)->b_dev);
 332:     type = dminor >> 3;
 333:     /*
 334: 	 * check for valid type
 335: 	 *
 336: 	 * check for block number within range of device
 337: 	 */
 338:     if(type >= NRXTYP ||
 339:         bp->b_blkno >= (daddr_t)rxtypes[type].numblks)
 340:         return(0);
 341: #ifndef DMA
 342:     if(bp->b_xmem != 0) {       /* No buffers outside kernel space */
 343:         prdev("Buffer outside kernel space", bp->b_dev);
 344:         return(0);
 345:     }
 346: #endif
 347:     return(1);
 348: }
 349: 
 350: rxsetup(abp)
 351: struct buf *abp;
 352: {
 353:     register struct buf *bp;
 354:     register int dminor;
 355:     register struct rxtype *rxt;
 356: 
 357:     /*
 358: 	 * get dminor device number from buffer
 359: 	 */
 360:     dminor = minor((bp = abp)->b_dev);
 361:     /*
 362: 	 * get sub-device number from dminor device number
 363: 	 */
 364:     rxt = rxstat.ftype = &rxtypes[dminor >> 3];
 365:     /*
 366: 	 * make sure device number is only 0 or 1
 367: 	 */
 368:     rxstat.fminor = dminor & 1;
 369:     /*
 370: 	 * get byte count to read from buffer (negative number)
 371: 	 */
 372:     rxstat.bytect = -bp->b_bcount;
 373:     /*
 374: 	 * transform block number into the first
 375: 	 * sector to read on the floppy
 376: 	 */
 377:     rxstat.sector = (int)bp->b_blkno * rxt->secperblk;
 378:     /*
 379: 	 * set the core address to get or put bytes.
 380: 	 */
 381: #ifndef DMA
 382:     rxstat.coreaddr = bp->b_un.b_addr;
 383: #endif
 384: #ifdef DMA
 385:     rxstat.coreaddr = (bp->b_un.b_addr & 077) + 0120000;
 386:     rxstat.coreblk = ((bp->b_un.b_addr >> 6) & 01777) |
 387:         ((bp->b_xmem & 03) << 10);
 388: #endif
 389: }
 390: 
 391: #ifndef DMA
 392: rxempty(abp)
 393: struct buf *abp;
 394: {
 395:     register struct rxdevice *rxaddr;
 396:     register int i;
 397:     register char *cp;
 398:     int wc;
 399: 
 400:     rxaddr = RXADDR;
 401:     /*
 402: 	 * start empty buffer command
 403: 	 */
 404:     RXWAIT
 405:     rxaddr->rxcs = EMPTY | GO;
 406:     spl1();
 407:     /*
 408: 	 * get core address and byte count
 409: 	 */
 410:     cp = rxstat.coreaddr;
 411:     rxstat.coreaddr =+ 128;
 412:     wc = ((rxstat.bytect <= -128)? 128 : -rxstat.bytect);
 413:     /*
 414: 	 * move wc bytes from the device buffer
 415: 	 *   into the in core buffer
 416: 	 */
 417:     for(i=wc; i>0; --i) {
 418:         RXWAIT
 419:         *cp++ = rxaddr->rxdb;
 420:     }
 421:     /*
 422: 	 * sluff excess bytes
 423: 	 */
 424:     for(i=128-wc; i>0; --i) {
 425:         RXWAIT
 426:         cp = rxaddr->rxdb;
 427:     }
 428:     spl5();
 429: }
 430: 
 431: rxfill(abp)
 432: struct buf *abp;
 433: {
 434:     register struct rxdevice *rxaddr;
 435:     register int i;
 436:     register char *cp;
 437:     int wc;
 438: 
 439:     rxaddr = RXADDR;
 440:     /*
 441: 	 * initiate the fill buffer command
 442: 	 */
 443:     RXWAIT
 444:     rxaddr->rxcs = FILL | GO;
 445:     spl1();
 446:     /*
 447: 	 * get core address and byte count
 448: 	 */
 449:     cp = rxstat.coreaddr;
 450:     rxstat.coreaddr =+ 128;
 451:     wc = ((rxstat.bytect <= -128)? 128 : -rxstat.bytect);
 452:     /*
 453: 	 * move wc bytes from the in-core buffer to
 454: 	 *   the device buffer
 455: 	 */
 456:     for(i=wc;  i>0; --i) {
 457:         RXWAIT
 458:         rxaddr->rxdb = *cp++;
 459:     }
 460:     /*
 461: 	 * sluff excess bytes
 462: 	 */
 463:     for(i=128-wc; i>0; --i) {
 464:         RXWAIT
 465:         rxaddr->rxdb = 0;
 466:     }
 467:     spl5();
 468: }
 469: #endif
 470: 
 471: #ifdef DMA
 472:     /*
 473: 	 * This copy of the fill and empty routines emulate a dma
 474: 	 * floppy controller.  It adds the feature of being able
 475: 	 * to write anywhere in physical memory, just like an rk
 476: 	 * disk.  To do this, we borrow a segmentation register
 477: 	 * to do the transfer.  While the segmentation register
 478: 	 * is pointing to the proper place, we need to run at spl7.
 479: 	 * This is harder on the system, so the non-dma driver should
 480: 	 * be used if you only intend to do buffer requests (i.e.
 481: 	 * no swapping or raw i/o).
 482: 	 */
 483: 
 484: struct { int r[]; };
 485: 
 486: rxempty(abp)
 487: struct buf *abp;
 488: {
 489:     register int i;
 490:     register char *cp;
 491:     register int wc;
 492:     int a,d;
 493:     struct rxdevice *rxaddr;
 494: 
 495:     rxaddr = RXADDR;
 496:     /*
 497: 	 * start empty buffer command
 498: 	 */
 499:     rxaddr->rxcs = EMPTY | GO;
 500:     /*
 501: 	 * get core address and byte count
 502: 	 */
 503:     cp = rxstat.coreaddr;
 504:     wc = ((rxstat.bytect <= -128)? 128 : -rxstat.bytect);
 505:     /*
 506: 	 * save and set segmentation register.
 507: 	 */
 508:     a = KISA->r[5];
 509:     d = KISD->r[5];
 510:     spl7();
 511:     KISA->r[5] = rxstat.coreblk;
 512:     KISD->r[5] = 01006;
 513:     /*
 514: 	 * move wc bytes from the device buffer
 515: 	 *   into the in core buffer
 516: 	 */
 517:     for(i=wc; i>0; --i) {
 518:         RXWAIT
 519:         *cp++ = rxaddr->rxdb;
 520:     }
 521:     /*
 522: 	 * sluff excess bytes
 523: 	 */
 524:     for(i=128-wc; i>0; --i) {
 525:         RXWAIT
 526:         cp = rxaddr->rxdb;
 527:     }
 528:     KISA->r[5] = a;
 529:     KISD->r[5] = d;
 530:     spl5();
 531:     rxstat.coreblk =+ 2;
 532: }
 533: 
 534: rxfill(abp)
 535: struct buf *abp;
 536: {
 537:     register int i;
 538:     register char *cp;
 539:     register int wc;
 540:     int a,d;
 541:     struct rxdevice *rxaddr;
 542: 
 543:     rxaddr = RXADDR;
 544:     /*
 545: 	 * initiate the fill buffer command
 546: 	 */
 547:     rxaddr->rxcs = FILL | GO;
 548:     /*
 549: 	 * get core address and byte count
 550: 	 */
 551:     cp = rxstat.coreaddr;
 552:     wc = ((rxstat.bytect <= -128)? 128 : -rxstat.bytect);
 553:     /*
 554: 	 * save and set segmentation register.
 555: 	 */
 556:     a = KISA->r[5];
 557:     d = KISD->r[5];
 558:     spl7();
 559:     KISA->r[5] = rxstat.coreblk;
 560:     KISD->r[5] = 01006;
 561:     /*
 562: 	 * move wc bytes from the in-core buffer to
 563: 	 *   the device buffer
 564: 	 */
 565:     for(i=wc;  i>0; --i) {
 566:         RXWAIT
 567:         rxaddr->rxdb = *cp++;
 568:     }
 569:     /*
 570: 	 * sluff excess bytes
 571: 	 */
 572:     for(i=128-wc; i>0; --i) {
 573:         RXWAIT
 574:         rxaddr->rxdb = 0;
 575:     }
 576:     KISA->r[5] = a;
 577:     KISD->r[5] = d;
 578:     spl5();
 579:     rxstat.coreblk =+ 2;
 580: }
 581: #endif
 582: 
 583: rxtimeout(dummy)
 584: {
 585:     static int prevreq;
 586:     register struct buf *bp;
 587: 
 588:     bp = rxtab.b_actf;
 589:     /*
 590: 	 * if the queue isn't empty and the current request number is the
 591: 	 * same as last time, abort the buffer and restart i/o.
 592: 	 */
 593:     if(bp) {
 594:         if(prevreq == rxstat.reqnum) {
 595:             printf("rx%d: Floppy timeout\n", minor(bp->b_dev));
 596:             rxabtbuf();
 597:             rxstart();
 598:         }
 599:         prevreq = rxstat.reqnum;
 600:         timeout(rxtimeout, (caddr_t)0, TTIME);
 601:     } else {
 602:         /*
 603: 		 * if queue is empty, just quit and rxstrategy will
 604: 		 * restart us.
 605: 		 */
 606:         rxstat.toutact = 0;
 607:     }
 608: }
 609: 
 610: rxabtbuf()
 611: {
 612:     register struct buf *bp;
 613: 
 614:     /*
 615: 	 * abort the current buffer with an error and unlink it.
 616: 	 */
 617:     bp = rxtab.b_actf;
 618:     bp->b_flags =| B_ERROR;
 619:     rxtab.b_actf = bp->av_forw;
 620:     rxtab.b_errcnt = 0;
 621:     rxtab.b_active = NULL;
 622:     iodone(bp);
 623: }
 624: 
 625: #ifdef DEBUG
 626: rxdebug() {
 627:     register struct buf *bp;
 628: 
 629:     spl5();
 630:     printf("Debug:  &rxtab=%o, &rxstat=%o\n", &rxtab, &rxstat);
 631:     printf(" rxstat:  fminor=%l, bytect=%l, sec=%l\n",
 632:         rxstat.fminor, -rxstat.bytect, rxstat.sector);
 633:     printf("   reqnum=%l\n", rxstat.reqnum);
 634:     printf(" rxtab:  d_active=%l, buffers:\n", rxtab.b_active);
 635:     for(bp=rxtab.b_actf; bp; bp=bp->av_forw)
 636:         printf(" dev=%l/%l, blkno=%l, bcnt=%l, flags=%o.\n", major(bp->b_dev),
 637:             minor(bp->b_dev), bp->b_blkno, -bp->b_bcount, bp->b_flags);
 638:     putchar('\n');
 639: }
 640: #endif

Defined functions

rxabtbuf defined in line 610; used 3 times
rxdebug defined in line 626; used 1 times
  • in line 79
rxempty defined in line 486; used 1 times
rxfill defined in line 534; used 1 times
rxintr defined in line 150; never used
rxok defined in line 321; used 1 times
  • in line 89
rxregs defined in line 263; used 2 times
rxreset defined in line 230; used 3 times
rxsetup defined in line 350; used 1 times
rxstart defined in line 119; used 5 times
rxstrategy defined in line 71; never used
rxtimeout defined in line 583; used 3 times

Defined variables

rxstat defined in line 67; used 47 times
rxtab defined in line 69; used 25 times
rxtypes defined in line 49; used 2 times

Defined struct's

rxstat defined in line 56; never used
rxtype defined in line 39; used 8 times

Defined macros

DMA defined in line 26; used 6 times
KISA defined in line 36; used 6 times
KISD defined in line 37; used 6 times
MAXRETRY defined in line 29; used 1 times
NRXTYP defined in line 28; used 2 times
RESETMAX defined in line 32; used 1 times
RRATE defined in line 31; used 1 times
RXWAIT defined in line 35; used 16 times
TTIME defined in line 30; used 2 times
Last modified: 1983-06-02
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1393
Valid CSS Valid XHTML 1.0 Strict