home *** CD-ROM | disk | FTP | other *** search
- #define KERNEL 1
- #include "../h/pk.p"
-
-
- /*
- * kernel support routines.
- */
-
- struct pack *pklines[NPLINES];
- int maxwindow =2;
-
- /*
- * start initial synchronization.
- * allocate space.
- */
- pkopen(dev, tp, addr)
- register struct tty *tp;
- caddr_t addr;
- {
- register struct pack *pk;
- register i;
- int pktimeout();
- char **bp;
- static timer_on;
- int s;
- struct piocb piocb;
-
-
- if (tp->t_line)
- return;
- /*
- * copy user parameters
- */
- if (copyin(addr, (caddr_t)&piocb, sizeof (piocb))) {
- u.u_error = EFAULT;
- return;
- }
- npbits = dtom(sizeof(struct pack));
- pk = (struct pack *)getepack(npbits);
- if (pk==NULL)
- goto notsobad;
- pkzero((caddr_t)pk,sizeof (struct pack));
- pk->p_rwindow = piocb.window;
- if (pk->p_rwindow > maxwindow)
- pk->p_rwindow = maxwindow;
- pk->p_rsize = piocb.psize;
- if (pk->p_rsize > 512 || pk->p_rsize & 037)
- goto notsobad;
- pk->p_mode = piocb.mode;
- if (pk->p_mode & 01)
- pkdebug++;
- /*
- * try to allocate input window
- */
- pk->p_bits = dtom(pk->p_rsize);
- for(i=0; i<pk->p_rwindow; i++) {
- bp = (char **)getepack(pk->p_bits);
- if (bp==NULL)
- break;
- *bp = (char *)pk->p_ipool;
- pk->p_ipool = bp;
- }
-
- if (i==0 && bp==NULL)
- goto notsobad;
- pk->p_rwindow = i;
-
-
- /*
- * start timer process,
- * wait for synchronization.
- */
- flushtty(tp);
- s = spl6();
- pkdisc = tp->t_line = piocb.t;
- pk->p_ttyp = tp;
- tp->t_linep = (caddr_t)pk;
- q2.c_cf = q2.c_cl = NULL;
- q1.c_cf = q1.c_cl = (caddr_t)&pk->p_ihbuf;
- q1.c_cc = -HDRSIZ;
- if (tp->t_iproc != NULL)
- (*tp->t_iproc)(tp);
-
- pk->p_rmsg = M_INITA;
- for(i=0; i<NPLINES; i++) {
- if (pklines[i]==NULL) {
- pklines[i] = pk;
- goto found;
- }
- }
- goto notsobad;
- found:
- pk->p_timer++;
- if (timer_on==0) {
- timer_on++;
- pktimeout();
- }
- splx(s);
- SLEEP(&pk->p_state, PKOPRI);
- pkreset(pk);
-
- if ((pk->p_state&LIVE)==0) {
- pk->p_state = DOWN;
- pk->p_rmsg = 0;
- notsobad:
- u.u_error = ENXIO;
- return;
- }
-
- pksetgrp(tp);
- pkioctl(DIOCGETP, tp, addr);
-
- }
-
-
-
-
- /*
- * unix ioctl interface
- */
- pkioctl(com,tp,addr)
- register struct tty *tp;
- caddr_t addr;
- {
- struct piocb piocb;
- register struct pack *pk;
-
- pk = (struct pack *)tp->t_linep;
- if (com == DIOCGETP) {
- piocb.window = pk->p_swindow;
- piocb.psize = pk->p_xsize;
- piocb.state = pk->p_state;
- if (copyout((caddr_t)&piocb, addr, sizeof(piocb))) {
- u.u_error = EFAULT;
- }
- if (u.u_error==0)
- u.u_r.r_val1 = piocb.psize;
- }
- }
-
-
- /*
- * Arrange for the device (i.e. tp)
- * to be able to generate signals if need be.
- */
- pksetgrp(tp)
- register struct tty *tp;
- {
- register struct proc *pp;
-
- pp = u.u_procp;
- if (pp->p_pgrp == 0)
- pp->p_pgrp = pp->p_pid;
- if (tp->t_pgrp == 0)
- tp->t_pgrp = pp->p_pgrp;
- }
-
-
-
- /*
- * Shut down io.
- * The problem is mainly input since the
- * device driver may have a buffer.
- */
- pkturnoff(tp)
- register struct tty *tp;
- {
- register char **bp;
- register struct pack *pk;
- register s;
-
- pk = PADDR;
- LOCK;
- bp = pk->p_io;
- tp->t_line = 0;
- q1.c_cf = NULL;
- flushtty(tp);
- if (bp!=NULL) {
- *bp = (char *)pk->p_ipool;
- pk->p_ipool = bp;
- }
- UNLOCK;
- }
-
-
-
- /*
- * link dead?
- */
- pklive(pk)
- register struct pack *pk;
- {
- register struct tty *tp;
-
- tp = pk->p_ttyp;
- if (tp->t_line!=pkdisc || tp->t_linep!=(caddr_t)pk) {
- return(0);
- }
- return(tp->t_state&CARR_ON);
- }
-
-
-
- /*
- * timeout process:
- * wakes up periodically to check status
- * of active lines.
- */
- pktimeout()
- {
- register struct pack *pk;
- extern time_t time;
- register i;
-
- for(i=0;i<NPLINES;i++) {
- if ((pk=pklines[i])==NULL)
- continue;
- if (pk->p_nout == pk->p_tout) {
- if (pk->p_xcount && pk->p_timer==0) {
- pk->p_timer = 3;
- pk->p_state |= WAITO;
- }
- } else
- pk->p_tout = pk->p_nout;
- if (pk->p_timer==0) {
- if (pk->p_state & BADFRAME) {
- pk->p_msg |= M_RJ;
- pk->p_state &= ~BADFRAME;
- goto startup;
- }
- if (pk->p_rmsg)
- goto startup;
- WAKEUP(&pk->p_ps);
- continue;
- }
- if (--pk->p_timer == 0) {
- if ((pk->p_state&LIVE)==0) {
- startup:
- pk->p_timer = 1;
- } else
- if (pk->p_state & WAITO) {
- if (pk->p_state&DRAINO) {
- pk->p_state |= DOWN;
- } else {
- pk->p_state |= RXMIT;
- }
- pkoutput(pk);
- pk->p_timer = 5+2*pkzot;
- }
- WAKEUP(&pk->p_ps);
- pk->p_msg |= pk->p_rmsg;
- if (pk->p_msg)
- pkoutput(pk);
- }
- }
- timeout(pktimeout, (caddr_t)pk, 60);
-
-
- /*
- * randomize timeouts.
- */
- pkzot = 2 + time&07;
- }
-
-
-