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

  1. #
  2. /*
  3.  */
  4.  
  5. /*
  6.  * RP disk driver
  7.  */
  8.  
  9. #include "../param.h"
  10. #include "../buf.h"
  11. #include "../conf.h"
  12. #include "../user.h"
  13.  
  14. struct {
  15.     int    rpds;
  16.     int    rper;
  17.     int    rpcs;
  18.     int    rpwc;
  19.     int    rpba;
  20.     int    rpca;
  21.     int    rpda;
  22. };
  23.  
  24. #define    RPADDR    0176710
  25. #define    NRP    8
  26.  
  27. struct {
  28.     char    *nblocks;
  29.     int    cyloff;
  30. } rp_sizes[] {
  31.     40600,    0,        /* cyl 0 thru 202 */
  32.     40600,    203,        /* cyl 203 thru 405 */
  33.     9200,    0,        /* cyl 0 thru 45 */
  34.     9200,    360,        /* cyl 360 thru 405 */
  35.     -1,    0,        /* cyl 0 thru 327 */
  36.     -1,    78,        /* cyl 78 thru 405 */
  37.     15600,    0,        /* cyl 0 thru 77 */
  38.     15600,    328,        /* cyl 328 thru 405 */
  39. };
  40.  
  41. struct    devtab    rptab;
  42. struct    buf    rrpbuf;
  43.  
  44. #define    GO    01
  45. #define    RESET    0
  46. #define    HSEEK    014
  47.  
  48. #define    IENABLE    0100
  49. #define    READY    0200
  50.  
  51. #define    SUFU    01000
  52. #define    SUSU    02000
  53. #define    SUSI    04000
  54. #define    HNF    010000
  55.  
  56. /*
  57.  * Use av_back to save track+sector,
  58.  * b_resid for cylinder.
  59.  */
  60.  
  61. #define    trksec    av_back
  62. #define    cylin    b_resid
  63.  
  64. rpstrategy(abp)
  65. struct buf *abp;
  66. {
  67.     register struct buf *bp;
  68.     register char *p1, *p2;
  69.  
  70.     bp = abp;
  71.     if(bp->b_flags&B_PHYS)
  72.         mapalloc(bp);
  73.     p1 = &rp_sizes[bp->b_dev.d_minor&07];
  74.     if (bp->b_dev.d_minor >= (NRP<<3) ||
  75.         bp->b_blkno >= p1->nblocks) {
  76.         bp->b_flags =| B_ERROR;
  77.         iodone(bp);
  78.         return;
  79.     }
  80.     bp->av_forw = 0;
  81.     bp->cylin = p1->cyloff;
  82.     p1 = bp->b_blkno;
  83.     p2 = lrem(p1, 10);
  84.     p1 = ldiv(p1, 10);
  85.     bp->trksec = (p1%20)<<8 | p2;
  86.     bp->cylin =+ p1/20;
  87.     spl5();
  88.     if ((p1 = rptab.d_actf)==0)
  89.         rptab.d_actf = bp;
  90.     else {
  91.         for (; p2 = p1->av_forw; p1 = p2) {
  92.             if (p1->cylin <= bp->cylin
  93.              && bp->cylin <  p2->cylin
  94.              || p1->cylin >= bp->cylin
  95.              && bp->cylin >  p2->cylin) 
  96.                 break;
  97.         }
  98.         bp->av_forw = p2;
  99.         p1->av_forw = bp;
  100.     }
  101.     if (rptab.d_active==0)
  102.         rpstart();
  103.     spl0();
  104. }
  105.  
  106. rpstart()
  107. {
  108.     register struct buf *bp;
  109.  
  110.     if ((bp = rptab.d_actf) == 0)
  111.         return;
  112.     rptab.d_active++;
  113.     RPADDR->rpda = bp->trksec;
  114.     devstart(bp, &RPADDR->rpca, bp->cylin, bp->b_dev.d_minor>>3);
  115. }
  116.  
  117. rpintr()
  118. {
  119.     register struct buf *bp;
  120.     register int ctr;
  121.  
  122.     if (rptab.d_active == 0)
  123.         return;
  124.     bp = rptab.d_actf;
  125.     rptab.d_active = 0;
  126.     if (RPADDR->rpcs < 0) {        /* error bit */
  127.         deverror(bp, RPADDR->rper, RPADDR->rpds);
  128.         if(RPADDR->rpds & (SUFU|SUSI|HNF)) {
  129.             RPADDR->rpcs.lobyte = HSEEK|GO;
  130.             ctr = 0;
  131.             while ((RPADDR->rpds&SUSU) && --ctr);
  132.         }
  133.         RPADDR->rpcs = RESET|GO;
  134.         ctr = 0;
  135.         while ((RPADDR->rpcs&READY) == 0 && --ctr);
  136.         if (++rptab.d_errcnt <= 10) {
  137.             rpstart();
  138.             return;
  139.         }
  140.         bp->b_flags =| B_ERROR;
  141.     }
  142.     rptab.d_errcnt = 0;
  143.     rptab.d_actf = bp->av_forw;
  144.     bp->b_resid = RPADDR->rpwc;
  145.     iodone(bp);
  146.     rpstart();
  147. }
  148.  
  149. rpread(dev)
  150. {
  151.  
  152.     if(rpphys(dev))
  153.     physio(rpstrategy, &rrpbuf, dev, B_READ);
  154. }
  155.  
  156. rpwrite(dev)
  157. {
  158.  
  159.     if(rpphys(dev))
  160.     physio(rpstrategy, &rrpbuf, dev, B_WRITE);
  161. }
  162.  
  163. rpphys(dev)
  164. {
  165.     register c;
  166.  
  167.     c = lshift(u.u_offset, -9);
  168.     c =+ ldiv(u.u_count+511, 512);
  169.     if(c > rp_sizes[dev.d_minor & 07].nblocks) {
  170.         u.u_error = ENXIO;
  171.         return(0);
  172.     }
  173.     return(1);
  174. }
  175.