xref: /openbmc/linux/arch/um/drivers/slip_common.h (revision d7a3d85e)
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
106