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