home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / sys / dmr / hp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-07-18  |  4.3 KB  |  219 lines

  1. #
  2. /*
  3.  */
  4.  
  5. /*
  6.  * RP04 disk driver
  7.  *
  8.  * This driver has been tested on a working RP04 for a few hours.
  9.  * It does not attempt ECC error correction and is probably
  10.  * deficient in general in the case of errors and when packs
  11.  * are dismounted.
  12.  */
  13.  
  14. #include "../param.h"
  15. #include "../buf.h"
  16. #include "../conf.h"
  17. #include "../user.h"
  18.  
  19. struct {
  20.     int    hpcs1;    /* Control and Status register 1 */
  21.     int    hpwc;    /* Word count register */
  22.     int    hpba;    /* UNIBUS address register */
  23.     int    hpda;    /* Desired address register */
  24.     int    hpcs2;    /* Control and Status register 2*/
  25.     int    hpds;    /* Drive Status */
  26.     int    hper1;    /* Error register 1 */
  27.     int    hpas;    /* Attention Summary */
  28.     int    hpla;    /* Look ahead */
  29.     int    hpdb;    /* Data buffer */
  30.     int    hpmr;    /* Maintenance register */
  31.     int    hpdt;    /* Drive type */
  32.     int    hpsn;    /* Serial number */
  33.     int    hpof;    /* Offset register */
  34.     int    hpca;    /* Desired Cylinder address register*/
  35.     int    hpcc;    /* Current Cylinder */
  36.     int    hper2;    /* Error register 2 */
  37.     int    hper3;    /* Error register 3 */
  38.     int    hppos;    /* Burst error bit position */
  39.     int    hppat;    /* Burst error bit pattern */
  40.     int    hpbae;    /* 11/70 bus extension */
  41. };
  42.  
  43. #define    HPADDR    0176700
  44. #define    NHP    8
  45.  
  46. struct {
  47.     char    *nblocks;
  48.     int    cyloff;
  49. } hp_sizes[] {
  50.     9614,    0,        /* cyl 0 thru 23 */
  51.                 /* cyl 24 thru 43 available */
  52.     -1,    44,        /* cyl 44 thru 200 */
  53.     -1,    201,        /* cyl 201 thru 357 */
  54.     20900,    358,        /* cyl 358 thru 407 */
  55.                 /* cyl 408 thru 410 blank */
  56.     40600,    0,
  57.     40600,    100,
  58.     40600,    200,
  59.     40600,    300,
  60. };
  61.  
  62.  
  63. struct    devtab    hptab;
  64. struct    buf    hpbuf;
  65.  
  66. char    hp_openf;
  67.  
  68.             /* Drive Commands */
  69. #define    GO    01
  70. #define    PRESET    020
  71. #define    RECAL    06
  72. #define RCLR    010
  73. #define OFFSET    014
  74.  
  75. #define    READY    0200    /* hpds - drive ready */
  76. #define    PIP    020000    /* hpds - Positioning Operation in Progress */
  77. #define    ERR    040000    /* hpcs1 - composite error */
  78.  
  79. #define    DU    040000    /* hper1 - Drive Unsafe    */
  80. #define    DTE    010000  /* hper1 - Drive Timing Error    */
  81. #define    OPI    020000  /* hper1 - Operation Incomplete    */
  82.         /* Error Correction Code errors */
  83. #define DCK    0100000    /* hper1 - Data Check error */
  84. #define ECH    0100    /* hper1 - ECC hard error */
  85.  
  86. #define CLR    040    /* hpcs2 - Controller Clear */
  87.  
  88. #define FMT22    010000    /* hpof - 16 bit /word format */
  89. /*
  90.  * Use av_back to save track+sector,
  91.  * b_resid for cylinder.
  92.  */
  93.  
  94. #define    trksec    av_back
  95. #define    cylin    b_resid
  96.  
  97. hpopen()
  98. {
  99.  
  100.     if(!hp_openf){
  101.         hp_openf++;
  102.         HPADDR->hpcs2 = CLR;
  103.         HPADDR->hpcs1 = RCLR|GO;
  104.         HPADDR->hpcs1 = PRESET|GO;
  105.         HPADDR->hpof = FMT22;
  106.     }
  107. }
  108.  
  109. hpstrategy(abp)
  110. struct buf *abp;
  111. {
  112.     register struct buf *bp;
  113.     register char *p1, *p2;
  114.  
  115.     bp = abp;
  116.     p1 = &hp_sizes[bp->b_dev.d_minor&07];
  117.     if (bp->b_dev.d_minor >= (NHP<<3) ||
  118.         bp->b_blkno >= p1->nblocks) {
  119.         bp->b_flags =| B_ERROR;
  120.         iodone(bp);
  121.         return;
  122.     }
  123.     bp->av_forw = 0;
  124.     bp->cylin = p1->cyloff;
  125.     p1 = bp->b_blkno;
  126.     p2 = lrem(p1, 22);
  127.     p1 = ldiv(p1, 22);
  128.     bp->trksec = (p1%19)<<8 | p2;
  129.     bp->cylin =+ p1/19;
  130.     spl5();
  131.     if ((p1 = hptab.d_actf)==0)
  132.         hptab.d_actf = bp;
  133.     else {
  134.         for (; p2 = p1->av_forw; p1 = p2) {
  135.             if (p1->cylin <= bp->cylin
  136.              && bp->cylin <  p2->cylin
  137.              || p1->cylin >= bp->cylin
  138.              && bp->cylin >  p2->cylin) 
  139.                 break;
  140.         }
  141.         bp->av_forw = p2;
  142.         p1->av_forw = bp;
  143.     }
  144.     if (hptab.d_active==0)
  145.         hpstart();
  146.     spl0();
  147. }
  148.  
  149. hpstart()
  150. {
  151.     register struct buf *bp;
  152.  
  153.     if ((bp = hptab.d_actf) == 0)
  154.         return;
  155.     hptab.d_active++;
  156.     HPADDR->hpcs2 = bp->b_dev.d_minor >> 3;
  157.     HPADDR->hpca = bp->cylin;
  158.     rhstart(bp, &HPADDR->hpda, bp->trksec, &HPADDR->hpbae);
  159. }
  160.  
  161. hpintr()
  162. {
  163.     register struct buf *bp;
  164.     register int ctr;
  165.  
  166.     if (hptab.d_active == 0)
  167.         return;
  168.     bp = hptab.d_actf;
  169.     hptab.d_active = 0;
  170.     if (HPADDR->hpcs1 & ERR) {        /* error bit */
  171.         deverror(bp, HPADDR->hpcs2, 0);
  172.         if(HPADDR->hper1 & (DU|DTE|OPI)) {
  173.             HPADDR->hpcs2 = CLR;
  174.             HPADDR->hpcs1 = RECAL|GO;
  175.             ctr = 0;
  176.             while ((HPADDR->hpds&PIP) && --ctr);
  177.         }
  178.         HPADDR->hpcs1 = RCLR|GO;
  179.         if (++hptab.d_errcnt <= 10) {
  180.             hpstart();
  181.             return;
  182.         }
  183.         bp->b_flags =| B_ERROR;
  184.     }
  185.     hptab.d_errcnt = 0;
  186.     hptab.d_actf = bp->av_forw;
  187.     bp->b_resid = HPADDR->hpwc;
  188.     iodone(bp);
  189.     hpstart();
  190. }
  191.  
  192. hpread(dev)
  193. {
  194.  
  195.     if(hpphys(dev))
  196.     physio(hpstrategy, &hpbuf, dev, B_READ);
  197. }
  198.  
  199. hpwrite(dev)
  200. {
  201.  
  202.     if(hpphys(dev))
  203.     physio(hpstrategy, &hpbuf, dev, B_WRITE);
  204. }
  205.  
  206. hpphys(dev)
  207. {
  208.     register c;
  209.  
  210.     c = lshift(u.u_offset, -9);
  211.     c =+ ldiv(u.u_count+511, 512);
  212.     if(c > hp_sizes[dev.d_minor & 07].nblocks) {
  213.         u.u_error = ENXIO;
  214.         return(0);
  215.     }
  216.     return(1);
  217. }
  218.  
  219.