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

  1. /*
  2.  * DU-11 Synchronous interface driver
  3.  */
  4.  
  5. #include "../h/param.h"
  6. #include "../h/systm.h"
  7. #include "../h/dir.h"
  8. #include "../h/user.h"
  9. #include "../h/buf.h"
  10.  
  11. /* device registers */
  12. struct dureg {
  13.     int    rxcsr, rxdbuf;
  14. #define    parcsr    rxdbuf
  15.     int    txcsr, txdbuf;
  16. };
  17.  
  18. struct du {
  19.     struct dureg    *du_addr;
  20.     int        du_state;
  21.     struct proc    *du_proc;
  22.     struct buf    *du_buf;
  23.     caddr_t        du_bufb;
  24.     caddr_t        du_bufp;
  25.     int        du_nxmit;
  26.     int        du_timer;
  27. } du[] = {
  28.     { (struct dureg *) 0160110 },
  29. };
  30.  
  31. #define    NDU    (sizeof(du)/sizeof(du[0]))
  32.  
  33. #define    DONE    0200
  34. #define    IE    0100
  35. #define    SIE    040
  36. #define CTS    020000
  37. #define    CARRIER    010000
  38. #define    RCVACT    04000
  39. #define    DSR    01000
  40. #define STRIP    0400
  41. #define SCH    020
  42. #define RTS    04
  43. #define    DTR    02
  44. #define MR    0400
  45. #define SEND    020
  46. #define    HALF    010
  47.  
  48. #define    READ    0
  49. #define    WRITE    1
  50. #define PWRIT    2
  51.  
  52. #define    DUPRI    (PZERO+1)
  53.  
  54. duopen(dev)
  55. register dev;
  56. {
  57.     int dutimeout();
  58.     register struct du *dp;
  59.     register struct dureg *lp;
  60.  
  61.     dev = minor(dev);
  62.     if (dev >= NDU ||
  63.        ((dp = &du[dev])->du_proc!=NULL && dp->du_proc!=u.u_procp)) {
  64.         u.u_error = ENXIO;
  65.         return;
  66.     }
  67.     dp->du_proc = u.u_procp;
  68.     lp = dp->du_addr;
  69.     if (dp->du_buf==NULL) {
  70.         dp->du_buf = geteblk();
  71.         dp->du_bufb = dp->du_buf->b_un.b_addr;
  72.         dp->du_state = WRITE;
  73.         lp->txcsr = MR;
  74.         lp->parcsr = 035026;        /* Sync Int, 7 bits, even parity, sync=026 */
  75.         timeout(dutimeout, (caddr_t)dp, HZ);
  76.         duturn(dp);
  77.     }
  78. }
  79.  
  80. duclose(dev)
  81. {
  82.     register struct du *dp;
  83.     register struct dureg *lp;
  84.  
  85.     dp = &du[minor(dev)];
  86.     lp = dp->du_addr;
  87.     lp->rxcsr = 0;
  88.     lp->txcsr = 0;
  89.     dp->du_timer = 0;
  90.     dp->du_proc = 0;
  91.     if (dp->du_buf != NULL) {
  92.         brelse(dp->du_buf);
  93.         dp->du_buf = NULL;
  94.     }
  95. }
  96.  
  97. duread(dev)
  98. {
  99.     register char *bp;
  100.     register struct du *dp;
  101.  
  102.     dp = &du[minor(dev)];
  103.     bp = dp->du_bufb;
  104.     for(;;) {
  105.         if(duwait(dev))
  106.             return;
  107.         if (dp->du_bufp > bp)
  108.             break;
  109.         spl6();
  110.         if (dp->du_timer <= 1) {
  111.             spl0();
  112.             return;
  113.         }
  114.         sleep((caddr_t)dp, DUPRI);
  115.         spl0();
  116.     }
  117.     u.u_offset = 0;
  118.     iomove(dp->du_bufb, (int)min(u.u_count, (unsigned)(dp->du_bufp-bp)), B_READ);
  119. }
  120.  
  121. duwrite(dev)
  122. {
  123.     register struct du *dp;
  124.     register struct dureg *lp;
  125.  
  126.     dev = minor(dev);
  127.     dp = &du[dev];
  128.     if (u.u_count==0 || duwait(dev))
  129.         return;
  130.     dp->du_bufp = dp->du_bufb;
  131.     dp->du_state = PWRIT;
  132.     dp->du_addr->rxcsr &= ~SCH;
  133.     dp->du_addr->rxcsr = SIE|RTS|DTR;
  134.     if (u.u_count > BSIZE)
  135.         u.u_count = BSIZE;
  136.     dp->du_nxmit = u.u_count;
  137.     u.u_offset = 0;
  138.     iomove(dp->du_bufb, (int)u.u_count, B_WRITE);
  139.     lp = dp->du_addr;
  140.     dp->du_timer = 10;
  141.     spl6();
  142.     while((lp->rxcsr&CTS)==0)
  143.         sleep((caddr_t)dp, DUPRI);
  144.     if (dp->du_state != WRITE) {
  145.         dp->du_state = WRITE;
  146.         lp->txcsr = IE|SIE|SEND|HALF;
  147.         dustart(dev);
  148.     }
  149.     spl0();
  150. }
  151.  
  152. duwait(dev)
  153. {
  154.     register struct du *dp;
  155.     register struct dureg *lp;
  156.  
  157.     dp = &du[minor(dev)];
  158.     lp = dp->du_addr;
  159.     for(;;) {
  160.         if ((lp->rxcsr&DSR)==0 || dp->du_buf==0) {
  161.             u.u_error = EIO;
  162.             return(1);
  163.         }
  164.         spl6();
  165.         if (dp->du_state==READ &&
  166.             ((lp->rxcsr&RCVACT)==0)) {
  167.             spl0();
  168.             return(0);
  169.         }
  170.         sleep((caddr_t)dp, DUPRI);
  171.         spl0();
  172.     }
  173. }
  174.  
  175. dustart(dev)
  176. {
  177.     register struct du *dp;
  178.     register struct dureg *lp;
  179.  
  180.     dp = &du[minor(dev)];
  181.     lp = dp->du_addr;
  182.     dp->du_timer = 10;
  183.     if (dp->du_nxmit > 0) {
  184.         dp->du_nxmit--;
  185.         lp->txdbuf = *dp->du_bufp++;
  186.     } else {
  187.         duturn(dp);
  188.     }
  189. }
  190.  
  191. durint(dev)
  192. {
  193.     register struct du *dp;
  194.     register c, s;
  195.     int dustat;
  196.  
  197.     dp = &du[minor(dev)];
  198.     dustat = dp->du_addr->rxcsr;
  199.     if(dustat<0) {
  200.         if((dustat&CARRIER)==0 && dp->du_state==READ)
  201.             duturn(dp);
  202.         else
  203.             wakeup((caddr_t)dp);
  204.     } else
  205.     if(dustat&DONE) {
  206.         dp->du_addr->rxcsr = IE|SIE|SCH|DTR;
  207.         c = s = dp->du_addr->rxdbuf;
  208.         c &= 0177;
  209.         if(s<0)
  210.             c |= 0200;
  211.         if (dp->du_bufp < dp->du_bufb+BSIZE)
  212.             *dp->du_bufp++ = c;
  213.     }
  214. }
  215.  
  216. duxint(dev)
  217. {
  218.     register struct du *dp;
  219.     register struct dureg *lp;
  220.     register int dustat;
  221.  
  222.     dp = &du[minor(dev)];
  223.     lp = dp->du_addr;
  224.     dustat = lp->txcsr;
  225.     if(dustat<0)
  226.         duturn(dp);
  227.     else if(dustat&DONE)
  228.         dustart(dev);
  229. }
  230.  
  231. duturn(dp)
  232. register struct du *dp;
  233. {
  234.     register struct dureg *lp;
  235.  
  236.     lp = dp->du_addr;
  237.     if (dp->du_state!=READ) {
  238.         dp->du_state = READ;
  239.         dp->du_timer = 10;
  240.         dp->du_bufp = dp->du_bufb;
  241.     }
  242.     lp->txcsr = HALF;
  243.     lp->rxcsr &= ~SCH;
  244.     lp->rxcsr = STRIP|IE|SIE|SCH|DTR;
  245.     wakeup((caddr_t)dp);
  246. }
  247.  
  248. dutimeout(dp)
  249. register struct du *dp;
  250. {
  251.     if (dp->du_timer == 0)
  252.         return;
  253.     if (--dp->du_timer == 0) {
  254.         duturn(dp);
  255.         dp->du_timer = 1;
  256.     }
  257.     timeout(dutimeout, (caddr_t)dp, HZ);
  258. }
  259.