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

  1. /*
  2.  * TJU16 tape driver
  3.  */
  4.  
  5. #include "../h/param.h"
  6. #include "../h/systm.h"
  7. #include "../h/buf.h"
  8. #include "../h/conf.h"
  9. #include "../h/dir.h"
  10. #include "../h/file.h"
  11. #include "../h/user.h"
  12.  
  13. struct    device
  14. {
  15.     int    htcs1;
  16.     int    htwc;
  17.     caddr_t    htba;
  18.     int    htfc;
  19.     int    htcs2;
  20.     int    htds;
  21.     int    hter;
  22.     int    htas;
  23.     int    htck;
  24.     int    htdb;
  25.     int    htmr;
  26.     int    htdt;
  27.     int    htsn;
  28.     int    httc;
  29.     int    htbae;    /* 11/70 bus extension */
  30.     int    htcs3;
  31. };
  32.  
  33. struct    buf    httab;
  34. struct    buf    rhtbuf;
  35. struct    buf    chtbuf;
  36.  
  37. #define    NUNIT    1
  38. #define    INF    1000000
  39.  
  40. char    h_flags[NUNIT];
  41. char    h_openf[NUNIT];
  42. daddr_t    h_blkno[NUNIT];
  43. daddr_t    h_nxrec[NUNIT];
  44.  
  45. #define    HTADDR    ((struct device *)0172440)
  46.  
  47. #define    GO    01
  48. #define    WCOM    060
  49. #define    RCOM    070
  50. #define    NOP    0
  51. #define    WEOF    026
  52. #define    SFORW    030
  53. #define    SREV    032
  54. #define    ERASE    024
  55. #define    REW    06
  56. #define    DCLR    010
  57. #define P800    01300        /* 800 + pdp11 mode */
  58. #define    P1600    02300        /* 1600 + pdp11 mode */
  59. #define    IENABLE    0100
  60. #define    RDY    0200
  61. #define    TM    04
  62. #define    DRY    0200
  63. #define EOT    02000
  64. #define CS    02000
  65. #define COR    0100000
  66. #define PES    040
  67. #define WRL    04000
  68. #define MOL    010000
  69. #define ERR    040000
  70. #define FCE    01000
  71. #define    TRE    040000
  72. #define HARD    064023    /* UNS|OPI|NEF|FMT|RMR|ILR|ILF */
  73.  
  74. #define    CLR    040    /* controller clear (in cs2) */
  75.  
  76. #define    NED    010000
  77.  
  78. #define    SIO    1
  79. #define    SSFOR    2
  80. #define    SSREV    3
  81. #define SRETRY    4
  82. #define SCOM    5
  83. #define SOK    6
  84.  
  85. #define H_WRITTEN 1
  86. htopen(dev, flag)
  87. {
  88.     register unit, ds;
  89.  
  90.     httab.b_flags |= B_TAPE;
  91.     unit = minor(dev) & 077;
  92.     if (unit >= NUNIT || h_openf[unit]) {
  93.         u.u_error = ENXIO;
  94.         return;
  95.     }
  96.     h_blkno[unit] = 0;
  97.     h_nxrec[unit] = INF;
  98.     h_flags[unit] = 0;
  99.     ds = hcommand(dev, NOP);
  100.     if ((ds&MOL)==0 || (flag && (ds&WRL)))
  101.         u.u_error = ENXIO;
  102.     if (u.u_error==0)
  103.         h_openf[unit]++;
  104. }
  105.  
  106. htclose(dev, flag)
  107. {
  108.     register int unit;
  109.  
  110.     unit = minor(dev) & 077;
  111.     if (flag == FWRITE || ((flag&FWRITE) && (h_flags[unit]&H_WRITTEN))) {
  112.         hcommand(dev, WEOF);
  113.         hcommand(dev, WEOF);
  114.         hcommand(dev, SREV);
  115.     }
  116.     if ((minor(dev)&0200) == 0)
  117.         hcommand(dev, REW);
  118.     h_openf[unit] = 0;
  119. }
  120.  
  121. hcommand(dev, com)
  122. {
  123.     register struct buf *bp;
  124.  
  125.     bp = &chtbuf;
  126.     spl5();
  127.     while(bp->b_flags&B_BUSY) {
  128.         bp->b_flags |= B_WANTED;
  129.         sleep((caddr_t)bp, PRIBIO);
  130.     }
  131.     spl0();
  132.     bp->b_dev = dev;
  133.     bp->b_resid = com;
  134.     bp->b_blkno = 0;
  135.     bp->b_flags = B_BUSY|B_READ;
  136.     htstrategy(bp);
  137.     iowait(bp);
  138.     if(bp->b_flags&B_WANTED)
  139.         wakeup((caddr_t)bp);
  140.     bp->b_flags = 0;
  141.     return(bp->b_resid);
  142. }
  143.  
  144. htstrategy(bp)
  145. register struct buf *bp;
  146. {
  147.     register daddr_t *p;
  148.  
  149.     if(bp != &chtbuf) {
  150.         p = &h_nxrec[minor(bp->b_dev)&077];
  151.         if(bp->b_blkno > *p) {
  152.             bp->b_flags |= B_ERROR;
  153.             bp->b_error = ENXIO;
  154.             iodone(bp);
  155.             return;
  156.         }
  157.         if(bp->b_blkno == *p && bp->b_flags&B_READ) {
  158.             clrbuf(bp);
  159.             bp->b_resid = bp->b_bcount;
  160.             iodone(bp);
  161.             return;
  162.         }
  163.         if ((bp->b_flags&B_READ)==0) {
  164.             *p = bp->b_blkno + 1;
  165.             h_flags[minor(bp->b_dev)&077] |= H_WRITTEN;
  166.         }
  167.     }
  168.     bp->av_forw = NULL;
  169.     spl5();
  170.     if (httab.b_actf == NULL)
  171.         httab.b_actf = bp;
  172.     else
  173.         httab.b_actl->av_forw = bp;
  174.     httab.b_actl = bp;
  175.     if (httab.b_active==0)
  176.         htstart();
  177.     spl0();
  178. }
  179.  
  180. htstart()
  181. {
  182.     register struct buf *bp;
  183.     register unit, den;
  184.     daddr_t blkno;
  185.  
  186.     loop:
  187.     if ((bp = httab.b_actf) == NULL)
  188.         return;
  189.     unit = minor(bp->b_dev) & 0177;
  190.     HTADDR->htcs2 = ((unit>>3)&07);
  191.     den = P1600 | (unit&07);
  192.     if(unit > 077)
  193.         den = P800 | (unit&07);
  194.     if((HTADDR->httc&03777) != den)
  195.         HTADDR->httc = den;
  196.     if (HTADDR->htcs2 & NED || (HTADDR->htds&MOL)==0)
  197.         goto abort;
  198.     unit &= 077;
  199.     blkno = h_blkno[unit];
  200.     if (bp == &chtbuf) {
  201.         if (bp->b_resid==NOP) {
  202.             bp->b_resid = HTADDR->htds;
  203.             goto next;
  204.         }
  205.         httab.b_active = SCOM;
  206.         HTADDR->htfc = 0;
  207.         HTADDR->htcs1 = bp->b_resid|IENABLE|GO;
  208.         return;
  209.     }
  210.     if (h_openf[unit] < 0 || bp->b_blkno > h_nxrec[unit])
  211.         goto abort;
  212.     if (blkno == bp->b_blkno) {
  213.         httab.b_active = SIO;
  214.         HTADDR->htba = bp->b_un.b_addr;
  215.         if(cputype == 70)
  216.             HTADDR->htbae = bp->b_xmem;
  217.         HTADDR->htfc = -bp->b_bcount;
  218.         HTADDR->htwc = -(bp->b_bcount>>1);
  219.         den = ((bp->b_xmem&3) << 8) | IENABLE | GO;
  220.         if(bp->b_flags & B_READ)
  221.             den |= RCOM;
  222.         else {
  223.             if(HTADDR->htds & EOT) {
  224.                 bp->b_resid = bp->b_bcount;
  225.                 goto next;
  226.             }
  227.             den |= WCOM;
  228.         }
  229.         HTADDR->htcs1 = den;
  230.     } else {
  231.         if (blkno < bp->b_blkno) {
  232.             httab.b_active = SSFOR;
  233.             HTADDR->htfc = blkno - bp->b_blkno;
  234.             HTADDR->htcs1 = SFORW|IENABLE|GO;
  235.         } else {
  236.             httab.b_active = SSREV;
  237.             HTADDR->htfc = bp->b_blkno - blkno;
  238.             HTADDR->htcs1 = SREV|IENABLE|GO;
  239.         }
  240.     }
  241.     return;
  242.  
  243.     abort:
  244.     bp->b_flags |= B_ERROR;
  245.  
  246.     next:
  247.     httab.b_actf = bp->av_forw;
  248.     iodone(bp);
  249.     goto loop;
  250. }
  251.  
  252. htintr()
  253. {
  254.     register struct buf *bp;
  255.     register int unit, state;
  256.     int    err;
  257.  
  258.     if ((bp = httab.b_actf)==NULL)
  259.         return;
  260.     unit = minor(bp->b_dev) & 077;
  261.     state = httab.b_active;
  262.     httab.b_active = 0;
  263.     if (HTADDR->htcs1&TRE) {
  264.         err = HTADDR->hter;
  265.         if (HTADDR->htcs2&077400 || (err&HARD))
  266.             state = 0;
  267.         if (bp == &rhtbuf)
  268.             err &= ~FCE;
  269.         if ((bp->b_flags&B_READ) && (HTADDR->htds&PES))
  270.             err &= ~(CS|COR);
  271.         if((HTADDR->htds&MOL) == 0) {
  272.             if(h_openf[unit])
  273.                 h_openf[unit] = -1;
  274.         }
  275.         else if(HTADDR->htds&TM) {
  276.             HTADDR->htwc = -(bp->b_bcount>>1);
  277.             h_nxrec[unit] = bp->b_blkno;
  278.             state = SOK;
  279.         }
  280.         else if(state && err == 0)
  281.             state = SOK;
  282.         if(httab.b_errcnt > 4)
  283.             deverror(bp, HTADDR->hter, HTADDR->htcs2);
  284.         htinit();
  285.         if (state==SIO && ++httab.b_errcnt < 10) {
  286.             httab.b_active = SRETRY;
  287.             h_blkno[unit]++;
  288.             HTADDR->htfc = -1;
  289.             HTADDR->htcs1 = SREV|IENABLE|GO;
  290.             return;
  291.         }
  292.         if (state!=SOK) {
  293.             bp->b_flags |= B_ERROR;
  294.             state = SIO;
  295.         }
  296.     } else if (HTADDR->htcs1 < 0) {    /* SC */
  297.         if(HTADDR->htds & ERR)
  298.             htinit();
  299.     }
  300.     switch(state) {
  301.     case SIO:
  302.     case SOK:
  303.         h_blkno[unit]++;
  304.  
  305.     case SCOM:
  306.         httab.b_errcnt = 0;
  307.         httab.b_actf = bp->av_forw;
  308.         iodone(bp);
  309.         bp->b_resid = (-HTADDR->htwc)<<1;
  310.         break;
  311.  
  312.     case SRETRY:
  313.         if((bp->b_flags&B_READ)==0) {
  314.             httab.b_active = SSFOR;
  315.             HTADDR->htcs1 = ERASE|IENABLE|GO;
  316.             return;
  317.         }
  318.  
  319.     case SSFOR:
  320.     case SSREV:
  321.         if(HTADDR->htds & TM) {
  322.             if(state == SSREV) {
  323.                 h_nxrec[unit] = bp->b_blkno - HTADDR->htfc;
  324.                 h_blkno[unit] = h_nxrec[unit];
  325.             } else {
  326.                 h_nxrec[unit] = bp->b_blkno + HTADDR->htfc - 1;
  327.                 h_blkno[unit] = h_nxrec[unit]+1;
  328.             }
  329.         } else
  330.             h_blkno[unit] = bp->b_blkno;
  331.         break;
  332.  
  333.     default:
  334.         return;
  335.     }
  336.     htstart();
  337. }
  338.  
  339. htinit()
  340. {
  341.     register ocs2;
  342.     register omttc;
  343.     
  344.     omttc = HTADDR->httc & 03777;    /* preserve old slave select, dens, format */
  345.     ocs2 = HTADDR->htcs2 & 07;    /* preserve old unit */
  346.  
  347.     HTADDR->htcs2 = CLR;
  348.     HTADDR->htcs2 = ocs2;
  349.     HTADDR->httc = omttc;
  350.     HTADDR->htcs1 = DCLR|GO;
  351. }
  352.  
  353. htread(dev)
  354. {
  355.     htphys(dev);
  356.     physio(htstrategy, &rhtbuf, dev, B_READ);
  357. }
  358.  
  359. htwrite(dev)
  360. {
  361.     htphys(dev);
  362.     physio(htstrategy, &rhtbuf, dev, B_WRITE);
  363. }
  364.  
  365. htphys(dev)
  366. {
  367.     register unit;
  368.     daddr_t a;
  369.  
  370.     unit = minor(dev) & 077;
  371.     if(unit < NUNIT) {
  372.         a = u.u_offset >> 9;
  373.         h_blkno[unit] = a;
  374.         h_nxrec[unit] = a+1;
  375.     }
  376. }
  377.