Merge branch 'fb' into devel
[linux-2.6] / arch / um / drivers / slip_common.h
1 #ifndef __UM_SLIP_COMMON_H
2 #define __UM_SLIP_COMMON_H
3
4 #define BUF_SIZE 1500
5  /* two bytes each for a (pathological) max packet of escaped chars +  *
6   * terminating END char + initial END char                            */
7 #define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8
9 /* SLIP protocol characters. */
10 #define SLIP_END             0300       /* indicates end of frame       */
11 #define SLIP_ESC             0333       /* indicates byte stuffing      */
12 #define SLIP_ESC_END         0334       /* ESC ESC_END means END 'data' */
13 #define SLIP_ESC_ESC         0335       /* ESC ESC_ESC means ESC 'data' */
14
15 static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos,
16                              int *esc)
17 {
18         int ret;
19
20         switch(c){
21         case SLIP_END:
22                 *esc = 0;
23                 ret=*pos;
24                 *pos=0;
25                 return(ret);
26         case SLIP_ESC:
27                 *esc = 1;
28                 return(0);
29         case SLIP_ESC_ESC:
30                 if(*esc){
31                         *esc = 0;
32                         c = SLIP_ESC;
33                 }
34                 break;
35         case SLIP_ESC_END:
36                 if(*esc){
37                         *esc = 0;
38                         c = SLIP_END;
39                 }
40                 break;
41         }
42         buf[(*pos)++] = c;
43         return(0);
44 }
45
46 static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
47 {
48         unsigned char *ptr = d;
49         unsigned char c;
50
51         /*
52          * Send an initial END character to flush out any
53          * data that may have accumulated in the receiver
54          * due to line noise.
55          */
56
57         *ptr++ = SLIP_END;
58
59         /*
60          * For each byte in the packet, send the appropriate
61          * character sequence, according to the SLIP protocol.
62          */
63
64         while (len-- > 0) {
65                 switch(c = *s++) {
66                 case SLIP_END:
67                         *ptr++ = SLIP_ESC;
68                         *ptr++ = SLIP_ESC_END;
69                         break;
70                 case SLIP_ESC:
71                         *ptr++ = SLIP_ESC;
72                         *ptr++ = SLIP_ESC_ESC;
73                         break;
74                 default:
75                         *ptr++ = c;
76                         break;
77                 }
78         }
79         *ptr++ = SLIP_END;
80         return (ptr - d);
81 }
82
83 struct slip_proto {
84         unsigned char ibuf[ENC_BUF_SIZE];
85         unsigned char obuf[ENC_BUF_SIZE];
86         int more; /* more data: do not read fd until ibuf has been drained */
87         int pos;
88         int esc;
89 };
90
91 static inline void slip_proto_init(struct slip_proto * slip)
92 {
93         memset(slip->ibuf, 0, sizeof(slip->ibuf));
94         memset(slip->obuf, 0, sizeof(slip->obuf));
95         slip->more = 0;
96         slip->pos = 0;
97         slip->esc = 0;
98 }
99
100 extern int slip_proto_read(int fd, void *buf, int len,
101                            struct slip_proto *slip);
102 extern int slip_proto_write(int fd, void *buf, int len,
103                             struct slip_proto *slip);
104
105 #endif