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

  1. #define    KERNEL    1
  2. #include "../h/pk.p"
  3.  
  4.  
  5. /*
  6.  * kernel support routines.
  7.  */
  8.  
  9. struct pack *pklines[NPLINES];
  10. int    maxwindow =2;
  11.  
  12. /*
  13.  * start initial synchronization.
  14.  * allocate space.
  15.  */
  16. pkopen(dev, tp, addr)
  17. register struct tty *tp;
  18. caddr_t addr;
  19. {
  20. register struct pack *pk;
  21. register i;
  22. int pktimeout();
  23. char **bp;
  24. static    timer_on;
  25. int s;
  26. struct    piocb    piocb;
  27.  
  28.  
  29.     if (tp->t_line)
  30.         return;
  31.     /*
  32.      * copy user parameters
  33.      */
  34.     if (copyin(addr, (caddr_t)&piocb, sizeof (piocb))) {
  35.         u.u_error = EFAULT;
  36.         return;
  37.     }
  38.     npbits = dtom(sizeof(struct pack));
  39.     pk = (struct pack *)getepack(npbits);
  40.     if (pk==NULL)
  41.         goto notsobad;
  42.     pkzero((caddr_t)pk,sizeof (struct pack));
  43.     pk->p_rwindow = piocb.window;
  44.     if (pk->p_rwindow > maxwindow)
  45.         pk->p_rwindow = maxwindow;
  46.     pk->p_rsize = piocb.psize;
  47.     if (pk->p_rsize > 512 || pk->p_rsize & 037)
  48.         goto notsobad;
  49.     pk->p_mode = piocb.mode;
  50.     if (pk->p_mode & 01)
  51.         pkdebug++;
  52.     /*
  53.      * try to allocate input window
  54.      */
  55.     pk->p_bits = dtom(pk->p_rsize);
  56.     for(i=0; i<pk->p_rwindow; i++) {
  57.         bp = (char **)getepack(pk->p_bits);
  58.         if (bp==NULL)
  59.             break;
  60.         *bp = (char *)pk->p_ipool;
  61.         pk->p_ipool = bp;
  62.     }
  63.  
  64.     if (i==0 && bp==NULL)
  65.         goto notsobad;
  66.     pk->p_rwindow = i;
  67.  
  68.  
  69.     /*
  70.      * start timer process,
  71.      * wait for synchronization.
  72.      */
  73.     flushtty(tp);
  74.     s = spl6();
  75.     pkdisc = tp->t_line = piocb.t;
  76.     pk->p_ttyp = tp;
  77.     tp->t_linep = (caddr_t)pk;
  78.     q2.c_cf = q2.c_cl = NULL;
  79.     q1.c_cf = q1.c_cl = (caddr_t)&pk->p_ihbuf;
  80.     q1.c_cc = -HDRSIZ;
  81.     if (tp->t_iproc != NULL)
  82.         (*tp->t_iproc)(tp);
  83.  
  84.     pk->p_rmsg = M_INITA;
  85.     for(i=0; i<NPLINES; i++) {
  86.         if (pklines[i]==NULL) {
  87.             pklines[i] = pk;
  88.             goto found;
  89.         }
  90.     }
  91.     goto notsobad;
  92. found:
  93.     pk->p_timer++;
  94.     if (timer_on==0) {
  95.         timer_on++;
  96.         pktimeout();
  97.     }
  98.     splx(s);
  99.     SLEEP(&pk->p_state, PKOPRI);
  100.     pkreset(pk);
  101.  
  102.     if ((pk->p_state&LIVE)==0) {
  103.         pk->p_state = DOWN;
  104.         pk->p_rmsg = 0;
  105. notsobad:
  106.         u.u_error = ENXIO;
  107.         return;
  108.     }
  109.  
  110.     pksetgrp(tp);
  111.     pkioctl(DIOCGETP, tp, addr);
  112.  
  113. }
  114.  
  115.  
  116.  
  117.  
  118. /*
  119.  * unix ioctl interface
  120.  */
  121. pkioctl(com,tp,addr)
  122. register struct tty *tp;
  123. caddr_t addr;
  124. {
  125. struct piocb piocb;
  126. register struct pack *pk;
  127.  
  128.     pk = (struct pack *)tp->t_linep;
  129.     if (com == DIOCGETP) {
  130.         piocb.window = pk->p_swindow;
  131.         piocb.psize  = pk->p_xsize;
  132.         piocb.state  = pk->p_state;
  133.         if (copyout((caddr_t)&piocb, addr, sizeof(piocb))) {
  134.             u.u_error = EFAULT;
  135.         }
  136.         if (u.u_error==0)
  137.             u.u_r.r_val1 = piocb.psize;
  138.     }
  139. }
  140.  
  141.  
  142. /*
  143.  * Arrange for the device (i.e. tp)
  144.  * to be able to generate signals if need be.
  145.  */
  146. pksetgrp(tp)
  147. register struct tty *tp;
  148. {
  149. register struct proc *pp;
  150.  
  151.     pp = u.u_procp;
  152.     if (pp->p_pgrp == 0)
  153.         pp->p_pgrp = pp->p_pid;
  154.     if (tp->t_pgrp == 0)
  155.         tp->t_pgrp = pp->p_pgrp;
  156. }
  157.  
  158.  
  159.  
  160. /*
  161.  * Shut down io.
  162.  * The problem is mainly input since the
  163.  * device driver may have a buffer.
  164.  */
  165. pkturnoff(tp)
  166. register struct tty *tp;
  167. {
  168. register char **bp;
  169. register struct pack *pk;
  170. register s;
  171.  
  172.     pk = PADDR;
  173.     LOCK;
  174.     bp = pk->p_io;
  175.     tp->t_line = 0;
  176.     q1.c_cf = NULL;
  177.     flushtty(tp);
  178.     if (bp!=NULL) {
  179.         *bp = (char *)pk->p_ipool;
  180.         pk->p_ipool = bp;
  181.     }
  182.     UNLOCK;
  183. }
  184.  
  185.  
  186.  
  187. /*
  188.  * link dead?
  189.  */
  190. pklive(pk)
  191. register struct pack *pk;
  192. {
  193. register struct tty  *tp;
  194.  
  195.     tp = pk->p_ttyp;
  196.     if (tp->t_line!=pkdisc || tp->t_linep!=(caddr_t)pk) {
  197.         return(0);
  198.     }
  199.     return(tp->t_state&CARR_ON);
  200. }
  201.  
  202.  
  203.  
  204. /*
  205.  * timeout process:
  206.  * wakes up periodically to check status
  207.  * of active lines.
  208.  */
  209. pktimeout()
  210. {
  211. register struct pack *pk;
  212. extern time_t time;
  213. register i;
  214.  
  215.     for(i=0;i<NPLINES;i++) {
  216.         if ((pk=pklines[i])==NULL)
  217.             continue;
  218.         if (pk->p_nout == pk->p_tout) {
  219.             if (pk->p_xcount && pk->p_timer==0) {
  220.                 pk->p_timer = 3;
  221.                 pk->p_state |= WAITO;
  222.             }
  223.         } else
  224.             pk->p_tout = pk->p_nout;
  225.         if (pk->p_timer==0) {
  226.             if (pk->p_state & BADFRAME) {
  227.                 pk->p_msg |= M_RJ;
  228.                 pk->p_state &= ~BADFRAME;
  229.                 goto startup;
  230.             }
  231.             if (pk->p_rmsg)
  232.                 goto startup;
  233.             WAKEUP(&pk->p_ps);
  234.             continue;
  235.         }
  236.         if (--pk->p_timer == 0) {
  237.             if ((pk->p_state&LIVE)==0) {
  238.             startup:
  239.                 pk->p_timer = 1;
  240.             } else
  241.             if (pk->p_state & WAITO) {
  242.                 if (pk->p_state&DRAINO)  {
  243.                     pk->p_state |= DOWN; 
  244.                 } else {
  245.                     pk->p_state |= RXMIT;
  246.                 }
  247.                 pkoutput(pk);
  248.                 pk->p_timer = 5+2*pkzot;
  249.             }
  250.             WAKEUP(&pk->p_ps);
  251.             pk->p_msg |= pk->p_rmsg;
  252.             if (pk->p_msg)
  253.                 pkoutput(pk);
  254.         }
  255.     }
  256.     timeout(pktimeout, (caddr_t)pk, 60);
  257.  
  258.  
  259.     /*
  260.      * randomize timeouts.
  261.      */
  262.     pkzot = 2 + time&07;
  263. }
  264.  
  265.  
  266.