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

  1. #define    KERNEL    1
  2. #include "../h/pk.p"
  3.  
  4. /*
  5.  * input framing and block checking.
  6.  * frame layout for most devices is:
  7.  *    
  8.  *    S|K|X|Y|C|Z|  ... data ... |
  9.  *
  10.  *    where     S    == initial synch byte
  11.  *        K    == encoded frame size (indexes pksizes[])
  12.  *        X, Y    == block check bytes
  13.  *        C    == control byte
  14.  *        Z    == XOR of header (K^X^Y^C)
  15.  *        data    == 0 or more data bytes
  16.  *
  17.  * device driver interfaces on input are:
  18.  *    pkrint  - byte level
  19.  *    pkrend  - dma or pseudo-dma transfer level
  20.  *    pkdata - packet level
  21.  */
  22.  
  23. int pksizes[] ={
  24.     1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1
  25. };
  26.  
  27. /*
  28.  * Pseudo-dma byte collection.
  29.  * This code can be put in the device driver
  30.  * interrupt routine to eliminate the per byte
  31.  * subroutine call.
  32.  */
  33. pkrint(c, tp)
  34. register c;
  35. register struct tty *tp;
  36. {
  37.  
  38.     if (q1.c_cc<0) {
  39.         if (q1.c_cf != NULL) {
  40.             tp->t_erase = 0;
  41.             *q1.c_cf++ = c;
  42.         }
  43.         if (++q1.c_cc)
  44.             return;
  45.         pkrend(tp);
  46.         return;
  47.     }
  48. }
  49.  
  50.  
  51.  
  52. /*
  53.  * End of input transfer.
  54.  */
  55. pkrend(tp)
  56. register struct tty *tp;
  57. {
  58. register char *p;
  59. struct pack *pk;
  60. struct header *h;
  61. register x;
  62. char    cntl, hdcheck;
  63. unsigned short sum;
  64. int i,j,k;
  65. char **bp;
  66.  
  67.     p = q1.c_cl;
  68.     x = (int)q1.c_cf - (int)p;
  69.     pk = (struct pack *)tp->t_linep;
  70.     h = (struct header * )&pk->p_ihbuf;
  71.     if (x == HDRSIZ) {
  72.         if (*p++ == SYN ) {
  73.             hdcheck = k = *p++;
  74.             sum = (unsigned)*p;
  75.             hdcheck ^= *p++;
  76.             sum |= (unsigned)*p << 8;
  77.             hdcheck ^= *p++;
  78.             hdcheck ^= cntl = *p++;
  79.             if (hdcheck != *p) {
  80.                 goto bad;
  81.             }
  82.             if (k == 9) {
  83.                 pkcntl(cntl, pk);
  84.                 q1.c_cf = q1.c_cl;
  85.                 q1.c_cc = -HDRSIZ;
  86.                 goto istart1;
  87.             }
  88.             if (k && pksizes[k]==pk->p_rsize) {
  89.                 pk->p_rpr = cntl&MOD8;
  90.                 pksack(pk);
  91.                 bp = pk->p_ipool;
  92.                 if (bp) {
  93.                     pk->p_ipool = (char **)*bp;
  94.                     pk->p_io = bp;
  95.                 } else {
  96.                 }
  97.                 q1.c_cf = (char *)bp;
  98.                 q1.c_cc = -pk->p_rsize;
  99.                 h->sum = sum;
  100.                 h->cntl = cntl;
  101.                 goto istart1;
  102.             }
  103. bad:
  104.             pkbadframe(pk);
  105.         }
  106. scan:
  107.         x = HDRSIZ;
  108.         j = 0;
  109.         p = (caddr_t)h;
  110.         for (i = 1; i < HDRSIZ; i++)
  111.             if (p[i] == SYN)
  112.                 for(x=i; i<HDRSIZ; i++,j++)
  113.                     p[j] = p[i];
  114.  
  115.         q1.c_cc = -x;
  116.         q1.c_cf = (caddr_t)((int)p + j);
  117.         goto istart2;
  118.     }
  119.     if (x == pk->p_rsize) {
  120.         pkdata(h->cntl, h->sum, pk, q1.c_cl);
  121.         pk->p_io = NULL;
  122.         q1.c_cf = (char *)h;
  123.         q1.c_cc = -HDRSIZ;
  124.         goto istart1;
  125.     }
  126.     if (x == 0) {
  127.         q1.c_cf = (char *)h;
  128.         q1.c_cc = -HDRSIZ;
  129.         pkbadframe(pk);
  130.     } else {
  131.         pkbadframe(pk);
  132.         goto scan;
  133.     }
  134. istart1:
  135.     q1.c_cl = q1.c_cf;
  136. istart2:
  137.     if (tp->t_iproc != NULL)
  138.         (*tp->t_iproc)(tp);
  139. }
  140.  
  141.  
  142.  
  143. /*
  144.  * Put packet located at address bp
  145.  * in an input slot for further processing.
  146.  */
  147. pkdata(c, sum, pk, cp)
  148. char c;
  149. unsigned short sum;
  150. register struct pack *pk;
  151. char *cp;
  152. {
  153. register struct tty *tp;
  154. register x;
  155. char **bp;
  156. int t;
  157.  
  158.     pk->p_state &= ~BADFRAME;
  159.     bp = (char **)cp;
  160.     tp = pk->p_ttyp;
  161.     if (pk->p_state&DRAINO || !(pk->p_state&LIVE)) {
  162.         pk->p_msg |= pk->p_rmsg;
  163.         pkoutput(pk);
  164.         goto drop;
  165.     }
  166.     t = next[pk->p_pr];
  167.     for(x=pk->p_pr; x!=t; x = (x-1)&7) {
  168.         if (pk->p_is[x] == 0)
  169.             goto slot;
  170.     }
  171.     /*
  172.      * this can't happen
  173.      */
  174.     printf("no slot\n");
  175. drop:
  176.     *bp = (char *)pk->p_ipool;
  177.     pk->p_ipool = bp;
  178.     return;
  179.  
  180. slot:
  181.     pk->p_imap |= mask[x];
  182.     pk->p_is[x] = c;
  183.     pk->p_isum[x] = sum;
  184.     pk->p_ib[x] = cp;
  185.     if (tp->t_chan)
  186.         sdata(tp->t_chan); else
  187.         wakeup(&pk->p_pr);
  188. }
  189.  
  190.  
  191. /*
  192.  * Start transmission on output device associated with pk.
  193.  * For asynch devices (t_line==1) framing is
  194.  * imposed.  For devices with framing and crc
  195.  * in the driver (t_line==2) the transfer is
  196.  * passed on to the driver.
  197.  */
  198. pkxstart(pk, cntl, x)
  199. struct pack *pk;
  200. char cntl;
  201. register x;
  202. {
  203. struct tty *tp;
  204. register char *p;
  205. short checkword;
  206. char hdcheck;
  207.  
  208.     p = (caddr_t)&pk->p_ohbuf;
  209.     tp = pk->p_ttyp;
  210.  
  211.     if (tp->t_line==1) {
  212.         *p++ = SYN;
  213.         if (x < 0) {
  214.             *p = 9;
  215.             checkword = cntl;
  216.             q3.c_cl = NULL;
  217.         } else {
  218.             *p = pk->p_lpsize;
  219.             checkword = pk->p_osum[x] ^ (unsigned)cntl;
  220.             q3.c_cl = pk->p_ob[x];
  221.         }
  222.         checkword = CHECK - checkword;
  223.         hdcheck = *p++;
  224.         hdcheck ^= *p++ = checkword;
  225.         hdcheck ^= *p++ = checkword>>8;
  226.         q3.c_cc = -HDRSIZ;
  227.     } else {
  228.         q3.c_cc = -1;
  229.     }
  230.  
  231.     hdcheck ^= *p++ = cntl;
  232.     *p = hdcheck;
  233.     q3.c_cf = (caddr_t)&pk->p_ohbuf;
  234. /*
  235.     pk->p_srxmit++;
  236. */
  237.     (*tp->t_oproc)(tp);
  238. }
  239.  
  240. /*
  241.  * transmitter interrupt.
  242.  */
  243. int    pkdelay    = 2;
  244.  
  245. pkxint(tp)
  246. register struct tty *tp;
  247. {
  248. register struct pack *pk;
  249. register s;
  250. extern int pkoutput();
  251.  
  252.     pk = (struct pack *)tp->t_linep;
  253.     s = spl6();
  254.     tp->t_state &= ~BUSY;
  255.     if (q3.c_cl == NULL) {
  256.             pkoutput(pk);
  257.     } else {
  258.         q3.c_cf = q3.c_cl;
  259.         q3.c_cl = NULL;
  260.         q3.c_cc = -pk->p_xsize;
  261.         (*tp->t_oproc)(tp);
  262.     }
  263.     splx(s);
  264. }
  265.  
  266.