home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / 2014.11.minnie.tuhs.org.tar / minnie.tuhs.org / UnixArchive / PDP-11 / Trees / V6 / usr / sys / dmr / tm.c < prev    next >
C/C++ Source or Header  |  1975-07-17  |  4KB  |  222 lines

  1. #
  2. /*
  3.  */
  4.  
  5. /*
  6.  * TM tape driver
  7.  */
  8.  
  9. #include "../param.h"
  10. #include "../buf.h"
  11. #include "../conf.h"
  12. #include "../user.h"
  13.  
  14. struct {
  15.     int tmer;
  16.     int tmcs;
  17.     int tmbc;
  18.     int tmba;
  19.     int tmdb;
  20.     int tmrd;
  21. };
  22.  
  23. struct    devtab    tmtab;
  24. struct    buf    rtmbuf;
  25.  
  26. char    t_openf[8];
  27. char    *t_blkno[8];
  28. char    *t_nxrec[8];
  29.  
  30. #define    TMADDR    0172520
  31.  
  32. #define    GO    01
  33. #define    RCOM    02
  34. #define    WCOM    04
  35. #define    WEOF    06
  36. #define    SFORW    010
  37. #define    SREV    012
  38. #define    WIRG    014
  39. #define    REW    016
  40. #define    DENS    060000        /* 9-channel */
  41. #define    IENABLE    0100
  42. #define    CRDY    0200
  43. #define GAPSD    010000
  44. #define    TUR    1
  45. #define    HARD    0102200    /* ILC, EOT, NXM */
  46. #define    EOF    0040000
  47.  
  48. #define    SSEEK    1
  49. #define    SIO    2
  50.  
  51. tmopen(dev, flag)
  52. {
  53.     register dminor;
  54.  
  55.     dminor = dev.d_minor;
  56.     if (t_openf[dminor])
  57.         u.u_error = ENXIO;
  58.     else {
  59.         t_openf[dminor]++;
  60.         t_blkno[dminor] = 0;
  61.         t_nxrec[dminor] = 65535;
  62.     }
  63. }
  64.  
  65. tmclose(dev, flag)
  66. {
  67.     register int dminor;
  68.  
  69.     dminor = dev.d_minor;
  70.     t_openf[dminor] = 0;
  71.     if (flag)
  72.         tcommand(dminor, WEOF);
  73.     tcommand(dminor, REW);
  74. }
  75.  
  76. tcommand(unit, com)
  77. {
  78.     extern lbolt;
  79.  
  80.     while (tmtab.d_active || (TMADDR->tmcs & CRDY)==0)
  81.         sleep(&lbolt, 1);
  82.     TMADDR->tmcs = DENS|com|GO | (unit<<8);
  83. }
  84.  
  85. tmstrategy(abp)
  86. struct buf *abp;
  87. {
  88.     register struct buf *bp;
  89.     register char **p;
  90.  
  91.     bp = abp;
  92.     p = &t_nxrec[bp->b_dev.d_minor];
  93.     if (*p <= bp->b_blkno) {
  94.         if (*p < bp->b_blkno) {
  95.             bp->b_flags =| B_ERROR;
  96.             iodone(bp);
  97.             return;
  98.         }
  99.         if (bp->b_flags&B_READ) {
  100.             clrbuf(bp);
  101.             iodone(bp);
  102.             return;
  103.         }
  104.     }
  105.     if ((bp->b_flags&B_READ)==0)
  106.         *p = bp->b_blkno + 1;
  107.     bp->av_forw = 0;
  108.     spl5();
  109.     if (tmtab.d_actf==0)
  110.         tmtab.d_actf = bp;
  111.     else
  112.         tmtab.d_actl->av_forw = bp;
  113.     tmtab.d_actl = bp;
  114.     if (tmtab.d_active==0)
  115.         tmstart();
  116.     spl0();
  117. }
  118.  
  119. tmstart()
  120. {
  121.     register struct buf *bp;
  122.     register int com;
  123.     int unit;
  124.     register char *blkno;
  125.  
  126.     loop:
  127.     if ((bp = tmtab.d_actf) == 0)
  128.         return;
  129.     unit = bp->b_dev.d_minor;
  130.     blkno = t_blkno[unit];
  131.     if (t_openf[unit] < 0 || (TMADDR->tmcs & CRDY)==0) {
  132.         bp->b_flags =| B_ERROR;
  133.         tmtab.d_actf = bp->av_forw;
  134.         iodone(bp);
  135.         goto loop;
  136.     }
  137.     com = (unit<<8) | ((bp->b_xmem & 03) << 4) | IENABLE|DENS;
  138.     if (blkno != bp->b_blkno) {
  139.         tmtab.d_active = SSEEK;
  140.         if (blkno < bp->b_blkno) {
  141.             com =| SFORW|GO;
  142.             TMADDR->tmbc = blkno - bp->b_blkno;
  143.         } else {
  144.             if (bp->b_blkno == 0)
  145.                 com =| REW|GO;
  146.             else {
  147.                 com =| SREV|GO;
  148.                 TMADDR->tmbc = bp->b_blkno - blkno;
  149.             }
  150.         }
  151.         TMADDR->tmcs = com;
  152.         return;
  153.     }
  154.     tmtab.d_active = SIO;
  155.     TMADDR->tmbc = bp->b_wcount << 1;
  156.     TMADDR->tmba = bp->b_addr;        /* core address */
  157.     TMADDR->tmcs = com | ((bp->b_flags&B_READ)? RCOM|GO:
  158.         ((tmtab.d_errcnt)? WIRG|GO: WCOM|GO));
  159. }
  160.  
  161. tmintr()
  162. {
  163.     register struct buf *bp;
  164.     register int unit;
  165.  
  166.     if ((bp = tmtab.d_actf)==0)
  167.         return;
  168.     unit = bp->b_dev.d_minor;
  169.     if (TMADDR->tmcs < 0) {        /* error bit */
  170. /*
  171.         deverror(bp, TMADDR->tmer);
  172.  */
  173.         while(TMADDR->tmrd & GAPSD) ; /* wait for gap shutdown */
  174.         if ((TMADDR->tmer&(HARD|EOF))==0 && tmtab.d_active==SIO) {
  175.             if (++tmtab.d_errcnt < 10) {
  176.                 t_blkno[unit]++;
  177.                 tmtab.d_active = 0;
  178.                 tmstart();
  179.                 return;
  180.             }
  181.         } else
  182.             if(bp != &rtmbuf && (TMADDR->tmer&EOF)==0)
  183.                 t_openf[unit] = -1;
  184.         bp->b_flags =| B_ERROR;
  185.         tmtab.d_active = SIO;
  186.     }
  187.     if (tmtab.d_active == SIO) {
  188.         tmtab.d_errcnt = 0;
  189.         t_blkno[unit]++;
  190.         tmtab.d_actf = bp->av_forw;
  191.         tmtab.d_active = 0;
  192.         iodone(bp);
  193.         bp->b_resid = TMADDR->tmbc;
  194.     } else
  195.         t_blkno[unit] = bp->b_blkno;
  196.     tmstart();
  197. }
  198.  
  199. tmread(dev)
  200. {
  201.     tmphys(dev);
  202.     physio(tmstrategy, &rtmbuf, dev, B_READ);
  203.     u.u_count = -rtmbuf.b_resid;
  204. }
  205.  
  206. tmwrite(dev)
  207. {
  208.     tmphys(dev);
  209.     physio(tmstrategy, &rtmbuf, dev, B_WRITE);
  210.     u.u_count = 0;
  211. }
  212.  
  213. tmphys(dev)
  214. {
  215.     register unit, a;
  216.  
  217.     unit = dev.d_minor;
  218.     a = lshift(u.u_offset, -9);
  219.     t_blkno[unit] = a;
  220.     t_nxrec[unit] = ++a;
  221. }
  222.