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