home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / sys / dev / tc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-03  |  2.9 KB  |  174 lines

  1. #
  2.  
  3. /*
  4.  * TC-11 DECtape driver
  5.  */
  6.  
  7. #include "../h/param.h"
  8. #include "../h/conf.h"
  9. #include "../h/buf.h"
  10. #include "../h/dir.h"
  11. #include "../h/user.h"
  12.  
  13. struct device {
  14.     int    tccsr;
  15.     union wb {
  16.         int    w;
  17.         char    b[2];
  18.     } tccm;
  19.     int    tcwc;
  20.     int    tcba;
  21.     int    tcdt;
  22. };
  23.  
  24. struct    buf    tctab;
  25. char    tcper[8];
  26.  
  27. #define    TCADDR    ((struct device *) 0177340)
  28. #define    NTCBLK    578
  29.  
  30. #define    TAPERR    0100000
  31. #define    TREV    04000
  32. #define    READY    0200
  33. #define    IENABLE    0100
  34. #define    UPS    0200
  35. #define    ENDZ    0100000
  36. #define    BLKM    02000
  37. #define    ILGOP    010000
  38. #define    SELERR    04000
  39.  
  40. #define    SAT    0
  41. #define    RNUM    02
  42. #define    RDATA    04
  43. #define    SST    010
  44. #define    WDATA    014
  45. #define    GO    01
  46.  
  47. #define    SFORW    1
  48. #define    SREV    2
  49. #define    SIO    3
  50.  
  51. tcclose(dev)
  52. {
  53.     bflush(dev);
  54.     tcper[dev&07] = 0;
  55. }
  56.  
  57. tcstrategy(bp)
  58. register struct buf *bp;
  59. {
  60.  
  61.     if(bp->b_flags&B_PHYS)
  62.         mapalloc(bp);
  63.     bp->b_resid = 0;
  64.     if(bp->b_blkno >= NTCBLK || tcper[minor(bp->b_dev)&07]) {
  65.         bp->b_flags |= B_ERROR;
  66.         iodone(bp);
  67.         return;
  68.     }
  69.     bp->av_forw = 0;
  70.     spl6();
  71.     if (tctab.b_actf==0)
  72.         tctab.b_actf = bp;
  73.     else
  74.         tctab.b_actl->av_forw = bp;
  75.     tctab.b_actl = bp;
  76.     if (tctab.b_active==0)
  77.         tcstart();
  78.     spl0();
  79. }
  80.  
  81. tcstart()
  82. {
  83.     register struct buf *bp;
  84.     register int com;
  85.     register union wb *tccmp;
  86.  
  87. loop:
  88.     tccmp = &TCADDR->tccm;
  89.     if ((bp = tctab.b_actf) == 0)
  90.         return;
  91.     if(tcper[minor(bp->b_dev)&07]) {
  92.         if((tctab.b_actf = bp->av_forw) == 0)
  93.             tccmp->b[0] = SAT|GO;
  94.         bp->b_flags |= B_ERROR;
  95.         iodone(bp);
  96.         goto loop;
  97.     }
  98.     if ((tccmp->b[1]&07) != minor(bp->b_dev))
  99.         tccmp->b[0] = SAT|GO;
  100.     tctab.b_errcnt = 20;
  101.     tctab.b_active = SFORW;
  102.     com = (minor(bp->b_dev)<<8) | IENABLE|RNUM|GO;
  103.     if ((TCADDR->tccsr & UPS) == 0) {
  104.         com |= TREV;
  105.         tctab.b_active = SREV;
  106.     }
  107.     tccmp->w = com;
  108. }
  109.  
  110. tcintr()
  111. {
  112.     register struct buf *bp;
  113.     register union wb *tccmp;
  114.     register int *tcdtp;
  115.  
  116.     tccmp = &TCADDR->tccm;
  117.     tcdtp = &TCADDR->tccsr;
  118.     bp = tctab.b_actf;
  119.     if (tccmp->w&TAPERR) {
  120.         if((*tcdtp&(ENDZ|BLKM)) == 0)
  121.             deverror(bp, *tcdtp, 0);
  122.         if(*tcdtp & (ILGOP|SELERR)) {
  123.             tcper[bp->b_dev&07]++;
  124.             tctab.b_errcnt = 0;
  125.         }
  126.         tccmp->w &= ~TAPERR;
  127.         if (--tctab.b_errcnt == 0) {
  128.             bp->b_flags |= B_ERROR;
  129.             goto done;
  130.         }
  131.         if (tccmp->w&TREV) {
  132.         setforw:
  133.             tctab.b_active = SFORW;
  134.             tccmp->w &= ~TREV;
  135.         } else {
  136.         setback:
  137.             tctab.b_active = SREV;
  138.             tccmp->w |= TREV;
  139.         }
  140.         tccmp->b[0] = IENABLE|RNUM|GO;
  141.         return;
  142.     }
  143.     tcdtp = &TCADDR->tcdt;
  144.     switch (tctab.b_active) {
  145.  
  146.     case SIO:
  147.     done:
  148.         tctab.b_active = 0;
  149.         if (tctab.b_actf = bp->av_forw)
  150.             tcstart();
  151.         else
  152.             TCADDR->tccm.b[0] = SAT|GO;
  153.         iodone(bp);
  154.         return;
  155.  
  156.     case SFORW:
  157.         if (*tcdtp > bp->b_blkno)
  158.             goto setback;
  159.         if (*tcdtp < bp->b_blkno)
  160.             goto setforw;
  161.         *--tcdtp = (int)bp->b_un.b_addr;    /* core address */
  162.         *--tcdtp = -(bp->b_bcount>>1);
  163.         tccmp->b[0] = ((bp->b_xmem & 03) << 4) | IENABLE|GO
  164.             | (bp->b_flags&B_READ?RDATA:WDATA);
  165.         tctab.b_active = SIO;
  166.         return;
  167.  
  168.     case SREV:
  169.         if (*tcdtp+3 > bp->b_blkno)
  170.             goto setback;
  171.         goto setforw;
  172.     }
  173. }
  174.