aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/isdn/i4l/isdnhdlc.c366
-rw-r--r--include/linux/isdn/hdlc.h68
2 files changed, 231 insertions, 203 deletions
diff --git a/drivers/isdn/i4l/isdnhdlc.c b/drivers/isdn/i4l/isdnhdlc.c
index 44ec7418496b..b80e55ab8914 100644
--- a/drivers/isdn/i4l/isdnhdlc.c
+++ b/drivers/isdn/i4l/isdnhdlc.c
@@ -1,23 +1,24 @@
1/* 1/*
2 * isdnhdlc.c -- General purpose ISDN HDLC decoder. 2 * isdnhdlc.c -- General purpose ISDN HDLC decoder.
3 * 3 *
4 *Copyright (C) 2002 Wolfgang Mües <wolfgang@iksw-muees.de> 4 * Copyright (C)
5 * 2001 Frode Isaksen <fisaksen@bewan.com> 5 * 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
6 * 2001 Kai Germaschewski <kai.germaschewski@gmx.de> 6 * 2001 Frode Isaksen <fisaksen@bewan.com>
7 * 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 11 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 12 * (at your option) any later version.
12 * 13 *
13 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 17 * GNU General Public License for more details.
17 * 18 *
18 * You should have received a copy of the GNU General Public License 19 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */ 22 */
22 23
23#include <linux/module.h> 24#include <linux/module.h>
@@ -36,20 +37,20 @@ MODULE_LICENSE("GPL");
36/*-------------------------------------------------------------------*/ 37/*-------------------------------------------------------------------*/
37 38
38enum { 39enum {
39 HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7, 40 HDLC_FAST_IDLE, HDLC_GET_FLAG_B0, HDLC_GETFLAG_B1A6, HDLC_GETFLAG_B7,
40 HDLC_GET_DATA,HDLC_FAST_FLAG 41 HDLC_GET_DATA, HDLC_FAST_FLAG
41}; 42};
42 43
43enum { 44enum {
44 HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG, 45 HDLC_SEND_DATA, HDLC_SEND_CRC1, HDLC_SEND_FAST_FLAG,
45 HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG, 46 HDLC_SEND_FIRST_FLAG, HDLC_SEND_CRC2, HDLC_SEND_CLOSING_FLAG,
46 HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0, 47 HDLC_SEND_IDLE1, HDLC_SEND_FAST_IDLE, HDLC_SENDFLAG_B0,
47 HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED 48 HDLC_SENDFLAG_B1A6, HDLC_SENDFLAG_B7, STOPPED
48}; 49};
49 50
50void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56) 51void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, int do_adapt56)
51{ 52{
52 hdlc->bit_shift = 0; 53 hdlc->bit_shift = 0;
53 hdlc->hdlc_bits1 = 0; 54 hdlc->hdlc_bits1 = 0;
54 hdlc->data_bits = 0; 55 hdlc->data_bits = 0;
55 hdlc->ffbit_shift = 0; 56 hdlc->ffbit_shift = 0;
@@ -63,10 +64,12 @@ void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56)
63 hdlc->ffvalue = 0; 64 hdlc->ffvalue = 0;
64 hdlc->dstpos = 0; 65 hdlc->dstpos = 0;
65} 66}
67EXPORT_SYMBOL(isdnhdlc_out_init);
66 68
67void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_adapt56) 69void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, int is_d_channel,
70 int do_adapt56)
68{ 71{
69 hdlc->bit_shift = 0; 72 hdlc->bit_shift = 0;
70 hdlc->hdlc_bits1 = 0; 73 hdlc->hdlc_bits1 = 0;
71 hdlc->data_bits = 0; 74 hdlc->data_bits = 0;
72 hdlc->ffbit_shift = 0; 75 hdlc->ffbit_shift = 0;
@@ -83,7 +86,7 @@ void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_ada
83 } 86 }
84 hdlc->cbin = 0x7e; 87 hdlc->cbin = 0x7e;
85 hdlc->bit_shift = 0; 88 hdlc->bit_shift = 0;
86 if(do_adapt56){ 89 if (do_adapt56) {
87 hdlc->do_adapt56 = 1; 90 hdlc->do_adapt56 = 1;
88 hdlc->data_bits = 0; 91 hdlc->data_bits = 0;
89 hdlc->state = HDLC_SENDFLAG_B0; 92 hdlc->state = HDLC_SENDFLAG_B0;
@@ -93,6 +96,25 @@ void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_ada
93 } 96 }
94 hdlc->shift_reg = 0; 97 hdlc->shift_reg = 0;
95} 98}
99EXPORT_SYMBOL(isdnhdlc_rcv_init);
100
101static int
102check_frame(struct isdnhdlc_vars *hdlc)
103{
104 int status;
105
106 if (hdlc->dstpos < 2) /* too small - framing error */
107 status = -HDLC_FRAMING_ERROR;
108 else if (hdlc->crc != 0xf0b8) /* crc error */
109 status = -HDLC_CRC_ERROR;
110 else {
111 /* remove CRC */
112 hdlc->dstpos -= 2;
113 /* good frame */
114 status = hdlc->dstpos;
115 }
116 return status;
117}
96 118
97/* 119/*
98 isdnhdlc_decode - decodes HDLC frames from a transparent bit stream. 120 isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
@@ -121,40 +143,63 @@ void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_ada
121 returns - number of decoded bytes in the destination buffer and status 143 returns - number of decoded bytes in the destination buffer and status
122 flag. 144 flag.
123 */ 145 */
124int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src, 146int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
125 int slen, int *count, unsigned char *dst, int dsize) 147 int *count, u8 *dst, int dsize)
126{ 148{
127 int status=0; 149 int status = 0;
128 150
129 static const unsigned char fast_flag[]={ 151 static const unsigned char fast_flag[] = {
130 0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f 152 0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x3f
131 }; 153 };
132 154
133 static const unsigned char fast_flag_value[]={ 155 static const unsigned char fast_flag_value[] = {
134 0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f 156 0x00, 0x7e, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f
135 }; 157 };
136 158
137 static const unsigned char fast_abort[]={ 159 static const unsigned char fast_abort[] = {
138 0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff 160 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
139 }; 161 };
140 162
163#define handle_fast_flag(h) \
164 do {\
165 if (h->cbin == fast_flag[h->bit_shift]) {\
166 h->ffvalue = fast_flag_value[h->bit_shift];\
167 h->state = HDLC_FAST_FLAG;\
168 h->ffbit_shift = h->bit_shift;\
169 h->bit_shift = 1;\
170 } else {\
171 h->state = HDLC_GET_DATA;\
172 h->data_received = 0;\
173 } \
174 } while (0)
175
176#define handle_abort(h) \
177 do {\
178 h->shift_reg = fast_abort[h->ffbit_shift - 1];\
179 h->hdlc_bits1 = h->ffbit_shift - 2;\
180 if (h->hdlc_bits1 < 0)\
181 h->hdlc_bits1 = 0;\
182 h->data_bits = h->ffbit_shift - 1;\
183 h->state = HDLC_GET_DATA;\
184 h->data_received = 0;\
185 } while (0)
186
141 *count = slen; 187 *count = slen;
142 188
143 while(slen > 0){ 189 while (slen > 0) {
144 if(hdlc->bit_shift==0){ 190 if (hdlc->bit_shift == 0) {
145 hdlc->cbin = *src++; 191 hdlc->cbin = *src++;
146 slen--; 192 slen--;
147 hdlc->bit_shift = 8; 193 hdlc->bit_shift = 8;
148 if(hdlc->do_adapt56){ 194 if (hdlc->do_adapt56)
149 hdlc->bit_shift --; 195 hdlc->bit_shift--;
150 }
151 } 196 }
152 197
153 switch(hdlc->state){ 198 switch (hdlc->state) {
154 case STOPPED: 199 case STOPPED:
155 return 0; 200 return 0;
156 case HDLC_FAST_IDLE: 201 case HDLC_FAST_IDLE:
157 if(hdlc->cbin == 0xff){ 202 if (hdlc->cbin == 0xff) {
158 hdlc->bit_shift = 0; 203 hdlc->bit_shift = 0;
159 break; 204 break;
160 } 205 }
@@ -163,32 +208,30 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
163 hdlc->bit_shift = 8; 208 hdlc->bit_shift = 8;
164 break; 209 break;
165 case HDLC_GET_FLAG_B0: 210 case HDLC_GET_FLAG_B0:
166 if(!(hdlc->cbin & 0x80)) { 211 if (!(hdlc->cbin & 0x80)) {
167 hdlc->state = HDLC_GETFLAG_B1A6; 212 hdlc->state = HDLC_GETFLAG_B1A6;
168 hdlc->hdlc_bits1 = 0; 213 hdlc->hdlc_bits1 = 0;
169 } else { 214 } else {
170 if(!hdlc->do_adapt56){ 215 if ((!hdlc->do_adapt56) &&
171 if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1) 216 (++hdlc->hdlc_bits1 >= 8) &&
217 (hdlc->bit_shift == 1))
172 hdlc->state = HDLC_FAST_IDLE; 218 hdlc->state = HDLC_FAST_IDLE;
173 }
174 } 219 }
175 hdlc->cbin<<=1; 220 hdlc->cbin <<= 1;
176 hdlc->bit_shift --; 221 hdlc->bit_shift--;
177 break; 222 break;
178 case HDLC_GETFLAG_B1A6: 223 case HDLC_GETFLAG_B1A6:
179 if(hdlc->cbin & 0x80){ 224 if (hdlc->cbin & 0x80) {
180 hdlc->hdlc_bits1++; 225 hdlc->hdlc_bits1++;
181 if(hdlc->hdlc_bits1==6){ 226 if (hdlc->hdlc_bits1 == 6)
182 hdlc->state = HDLC_GETFLAG_B7; 227 hdlc->state = HDLC_GETFLAG_B7;
183 } 228 } else
184 } else {
185 hdlc->hdlc_bits1 = 0; 229 hdlc->hdlc_bits1 = 0;
186 } 230 hdlc->cbin <<= 1;
187 hdlc->cbin<<=1; 231 hdlc->bit_shift--;
188 hdlc->bit_shift --;
189 break; 232 break;
190 case HDLC_GETFLAG_B7: 233 case HDLC_GETFLAG_B7:
191 if(hdlc->cbin & 0x80) { 234 if (hdlc->cbin & 0x80) {
192 hdlc->state = HDLC_GET_FLAG_B0; 235 hdlc->state = HDLC_GET_FLAG_B0;
193 } else { 236 } else {
194 hdlc->state = HDLC_GET_DATA; 237 hdlc->state = HDLC_GET_DATA;
@@ -198,74 +241,55 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
198 hdlc->data_bits = 0; 241 hdlc->data_bits = 0;
199 hdlc->data_received = 0; 242 hdlc->data_received = 0;
200 } 243 }
201 hdlc->cbin<<=1; 244 hdlc->cbin <<= 1;
202 hdlc->bit_shift --; 245 hdlc->bit_shift--;
203 break; 246 break;
204 case HDLC_GET_DATA: 247 case HDLC_GET_DATA:
205 if(hdlc->cbin & 0x80){ 248 if (hdlc->cbin & 0x80) {
206 hdlc->hdlc_bits1++; 249 hdlc->hdlc_bits1++;
207 switch(hdlc->hdlc_bits1){ 250 switch (hdlc->hdlc_bits1) {
208 case 6: 251 case 6:
209 break; 252 break;
210 case 7: 253 case 7:
211 if(hdlc->data_received) { 254 if (hdlc->data_received)
212 // bad frame 255 /* bad frame */
213 status = -HDLC_FRAMING_ERROR; 256 status = -HDLC_FRAMING_ERROR;
214 } 257 if (!hdlc->do_adapt56) {
215 if(!hdlc->do_adapt56){ 258 if (hdlc->cbin == fast_abort
216 if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){ 259 [hdlc->bit_shift + 1]) {
217 hdlc->state = HDLC_FAST_IDLE; 260 hdlc->state =
218 hdlc->bit_shift=1; 261 HDLC_FAST_IDLE;
262 hdlc->bit_shift = 1;
219 break; 263 break;
220 } 264 }
221 } else { 265 } else
222 hdlc->state = HDLC_GET_FLAG_B0; 266 hdlc->state = HDLC_GET_FLAG_B0;
223 }
224 break; 267 break;
225 default: 268 default:
226 hdlc->shift_reg>>=1; 269 hdlc->shift_reg >>= 1;
227 hdlc->shift_reg |= 0x80; 270 hdlc->shift_reg |= 0x80;
228 hdlc->data_bits++; 271 hdlc->data_bits++;
229 break; 272 break;
230 } 273 }
231 } else { 274 } else {
232 switch(hdlc->hdlc_bits1){ 275 switch (hdlc->hdlc_bits1) {
233 case 5: 276 case 5:
234 break; 277 break;
235 case 6: 278 case 6:
236 if(hdlc->data_received){ 279 if (hdlc->data_received)
237 if (hdlc->dstpos < 2) { 280 status = check_frame(hdlc);
238 status = -HDLC_FRAMING_ERROR;
239 } else if (hdlc->crc != 0xf0b8){
240 // crc error
241 status = -HDLC_CRC_ERROR;
242 } else {
243 // remove CRC
244 hdlc->dstpos -= 2;
245 // good frame
246 status = hdlc->dstpos;
247 }
248 }
249 hdlc->crc = 0xffff; 281 hdlc->crc = 0xffff;
250 hdlc->shift_reg = 0; 282 hdlc->shift_reg = 0;
251 hdlc->data_bits = 0; 283 hdlc->data_bits = 0;
252 if(!hdlc->do_adapt56){ 284 if (!hdlc->do_adapt56)
253 if(hdlc->cbin==fast_flag[hdlc->bit_shift]){ 285 handle_fast_flag(hdlc);
254 hdlc->ffvalue = fast_flag_value[hdlc->bit_shift]; 286 else {
255 hdlc->state = HDLC_FAST_FLAG;
256 hdlc->ffbit_shift = hdlc->bit_shift;
257 hdlc->bit_shift = 1;
258 } else {
259 hdlc->state = HDLC_GET_DATA;
260 hdlc->data_received = 0;
261 }
262 } else {
263 hdlc->state = HDLC_GET_DATA; 287 hdlc->state = HDLC_GET_DATA;
264 hdlc->data_received = 0; 288 hdlc->data_received = 0;
265 } 289 }
266 break; 290 break;
267 default: 291 default:
268 hdlc->shift_reg>>=1; 292 hdlc->shift_reg >>= 1;
269 hdlc->data_bits++; 293 hdlc->data_bits++;
270 break; 294 break;
271 } 295 }
@@ -278,16 +302,17 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
278 hdlc->bit_shift--; 302 hdlc->bit_shift--;
279 return status; 303 return status;
280 } 304 }
281 if(hdlc->data_bits==8){ 305 if (hdlc->data_bits == 8) {
282 hdlc->data_bits = 0; 306 hdlc->data_bits = 0;
283 hdlc->data_received = 1; 307 hdlc->data_received = 1;
284 hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg); 308 hdlc->crc = crc_ccitt_byte(hdlc->crc,
309 hdlc->shift_reg);
285 310
286 // good byte received 311 /* good byte received */
287 if (hdlc->dstpos < dsize) { 312 if (hdlc->dstpos < dsize)
288 dst[hdlc->dstpos++] = hdlc->shift_reg; 313 dst[hdlc->dstpos++] = hdlc->shift_reg;
289 } else { 314 else {
290 // frame too long 315 /* frame too long */
291 status = -HDLC_LENGTH_ERROR; 316 status = -HDLC_LENGTH_ERROR;
292 hdlc->dstpos = 0; 317 hdlc->dstpos = 0;
293 } 318 }
@@ -296,24 +321,18 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
296 hdlc->bit_shift--; 321 hdlc->bit_shift--;
297 break; 322 break;
298 case HDLC_FAST_FLAG: 323 case HDLC_FAST_FLAG:
299 if(hdlc->cbin==hdlc->ffvalue){ 324 if (hdlc->cbin == hdlc->ffvalue) {
300 hdlc->bit_shift = 0; 325 hdlc->bit_shift = 0;
301 break; 326 break;
302 } else { 327 } else {
303 if(hdlc->cbin == 0xff){ 328 if (hdlc->cbin == 0xff) {
304 hdlc->state = HDLC_FAST_IDLE; 329 hdlc->state = HDLC_FAST_IDLE;
305 hdlc->bit_shift=0; 330 hdlc->bit_shift = 0;
306 } else if(hdlc->ffbit_shift==8){ 331 } else if (hdlc->ffbit_shift == 8) {
307 hdlc->state = HDLC_GETFLAG_B7; 332 hdlc->state = HDLC_GETFLAG_B7;
308 break; 333 break;
309 } else { 334 } else
310 hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1]; 335 handle_abort(hdlc);
311 hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
312 if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
313 hdlc->data_bits = hdlc->ffbit_shift-1;
314 hdlc->state = HDLC_GET_DATA;
315 hdlc->data_received = 0;
316 }
317 } 336 }
318 break; 337 break;
319 default: 338 default:
@@ -323,7 +342,7 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
323 *count -= slen; 342 *count -= slen;
324 return 0; 343 return 0;
325} 344}
326 345EXPORT_SYMBOL(isdnhdlc_decode);
327/* 346/*
328 isdnhdlc_encode - encodes HDLC frames to a transparent bit stream. 347 isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
329 348
@@ -343,12 +362,11 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
343 dsize - destination buffer size 362 dsize - destination buffer size
344 returns - number of encoded bytes in the destination buffer 363 returns - number of encoded bytes in the destination buffer
345*/ 364*/
346int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src, 365int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
347 unsigned short slen, int *count, 366 int *count, u8 *dst, int dsize)
348 unsigned char *dst, int dsize)
349{ 367{
350 static const unsigned char xfast_flag_value[] = { 368 static const unsigned char xfast_flag_value[] = {
351 0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e 369 0x7e, 0x3f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xfc, 0x7e
352 }; 370 };
353 371
354 int len = 0; 372 int len = 0;
@@ -356,31 +374,34 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
356 *count = slen; 374 *count = slen;
357 375
358 while (dsize > 0) { 376 while (dsize > 0) {
359 if(hdlc->bit_shift==0){ 377 if (hdlc->bit_shift == 0) {
360 if(slen && !hdlc->do_closing){ 378 if (slen && !hdlc->do_closing) {
361 hdlc->shift_reg = *src++; 379 hdlc->shift_reg = *src++;
362 slen--; 380 slen--;
363 if (slen == 0) 381 if (slen == 0)
364 hdlc->do_closing = 1; /* closing sequence, CRC + flag(s) */ 382 /* closing sequence, CRC + flag(s) */
383 hdlc->do_closing = 1;
365 hdlc->bit_shift = 8; 384 hdlc->bit_shift = 8;
366 } else { 385 } else {
367 if(hdlc->state == HDLC_SEND_DATA){ 386 if (hdlc->state == HDLC_SEND_DATA) {
368 if(hdlc->data_received){ 387 if (hdlc->data_received) {
369 hdlc->state = HDLC_SEND_CRC1; 388 hdlc->state = HDLC_SEND_CRC1;
370 hdlc->crc ^= 0xffff; 389 hdlc->crc ^= 0xffff;
371 hdlc->bit_shift = 8; 390 hdlc->bit_shift = 8;
372 hdlc->shift_reg = hdlc->crc & 0xff; 391 hdlc->shift_reg =
373 } else if(!hdlc->do_adapt56){ 392 hdlc->crc & 0xff;
374 hdlc->state = HDLC_SEND_FAST_FLAG; 393 } else if (!hdlc->do_adapt56)
375 } else { 394 hdlc->state =
376 hdlc->state = HDLC_SENDFLAG_B0; 395 HDLC_SEND_FAST_FLAG;
377 } 396 else
397 hdlc->state =
398 HDLC_SENDFLAG_B0;
378 } 399 }
379 400
380 } 401 }
381 } 402 }
382 403
383 switch(hdlc->state){ 404 switch (hdlc->state) {
384 case STOPPED: 405 case STOPPED:
385 while (dsize--) 406 while (dsize--)
386 *dst++ = 0xff; 407 *dst++ = 0xff;
@@ -388,14 +409,15 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
388 return dsize; 409 return dsize;
389 case HDLC_SEND_FAST_FLAG: 410 case HDLC_SEND_FAST_FLAG:
390 hdlc->do_closing = 0; 411 hdlc->do_closing = 0;
391 if(slen == 0){ 412 if (slen == 0) {
392 *dst++ = hdlc->ffvalue; 413 *dst++ = hdlc->ffvalue;
393 len++; 414 len++;
394 dsize--; 415 dsize--;
395 break; 416 break;
396 } 417 }
397 if(hdlc->bit_shift==8){ 418 if (hdlc->bit_shift == 8) {
398 hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits); 419 hdlc->cbin = hdlc->ffvalue >>
420 (8 - hdlc->data_bits);
399 hdlc->state = HDLC_SEND_DATA; 421 hdlc->state = HDLC_SEND_DATA;
400 hdlc->crc = 0xffff; 422 hdlc->crc = 0xffff;
401 hdlc->hdlc_bits1 = 0; 423 hdlc->hdlc_bits1 = 0;
@@ -413,17 +435,17 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
413 hdlc->cbin <<= 1; 435 hdlc->cbin <<= 1;
414 hdlc->data_bits++; 436 hdlc->data_bits++;
415 hdlc->cbin++; 437 hdlc->cbin++;
416 if(++hdlc->hdlc_bits1 == 6) 438 if (++hdlc->hdlc_bits1 == 6)
417 hdlc->state = HDLC_SENDFLAG_B7; 439 hdlc->state = HDLC_SENDFLAG_B7;
418 break; 440 break;
419 case HDLC_SENDFLAG_B7: 441 case HDLC_SENDFLAG_B7:
420 hdlc->cbin <<= 1; 442 hdlc->cbin <<= 1;
421 hdlc->data_bits++; 443 hdlc->data_bits++;
422 if(slen == 0){ 444 if (slen == 0) {
423 hdlc->state = HDLC_SENDFLAG_B0; 445 hdlc->state = HDLC_SENDFLAG_B0;
424 break; 446 break;
425 } 447 }
426 if(hdlc->bit_shift==8){ 448 if (hdlc->bit_shift == 8) {
427 hdlc->state = HDLC_SEND_DATA; 449 hdlc->state = HDLC_SEND_DATA;
428 hdlc->crc = 0xffff; 450 hdlc->crc = 0xffff;
429 hdlc->hdlc_bits1 = 0; 451 hdlc->hdlc_bits1 = 0;
@@ -432,7 +454,7 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
432 break; 454 break;
433 case HDLC_SEND_FIRST_FLAG: 455 case HDLC_SEND_FIRST_FLAG:
434 hdlc->data_received = 1; 456 hdlc->data_received = 1;
435 if(hdlc->data_bits==8){ 457 if (hdlc->data_bits == 8) {
436 hdlc->state = HDLC_SEND_DATA; 458 hdlc->state = HDLC_SEND_DATA;
437 hdlc->crc = 0xffff; 459 hdlc->crc = 0xffff;
438 hdlc->hdlc_bits1 = 0; 460 hdlc->hdlc_bits1 = 0;
@@ -440,11 +462,11 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
440 } 462 }
441 hdlc->cbin <<= 1; 463 hdlc->cbin <<= 1;
442 hdlc->data_bits++; 464 hdlc->data_bits++;
443 if(hdlc->shift_reg & 0x01) 465 if (hdlc->shift_reg & 0x01)
444 hdlc->cbin++; 466 hdlc->cbin++;
445 hdlc->shift_reg >>= 1; 467 hdlc->shift_reg >>= 1;
446 hdlc->bit_shift--; 468 hdlc->bit_shift--;
447 if(hdlc->bit_shift==0){ 469 if (hdlc->bit_shift == 0) {
448 hdlc->state = HDLC_SEND_DATA; 470 hdlc->state = HDLC_SEND_DATA;
449 hdlc->crc = 0xffff; 471 hdlc->crc = 0xffff;
450 hdlc->hdlc_bits1 = 0; 472 hdlc->hdlc_bits1 = 0;
@@ -453,14 +475,14 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
453 case HDLC_SEND_DATA: 475 case HDLC_SEND_DATA:
454 hdlc->cbin <<= 1; 476 hdlc->cbin <<= 1;
455 hdlc->data_bits++; 477 hdlc->data_bits++;
456 if(hdlc->hdlc_bits1 == 5){ 478 if (hdlc->hdlc_bits1 == 5) {
457 hdlc->hdlc_bits1 = 0; 479 hdlc->hdlc_bits1 = 0;
458 break; 480 break;
459 } 481 }
460 if(hdlc->bit_shift==8){ 482 if (hdlc->bit_shift == 8)
461 hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg); 483 hdlc->crc = crc_ccitt_byte(hdlc->crc,
462 } 484 hdlc->shift_reg);
463 if(hdlc->shift_reg & 0x01){ 485 if (hdlc->shift_reg & 0x01) {
464 hdlc->hdlc_bits1++; 486 hdlc->hdlc_bits1++;
465 hdlc->cbin++; 487 hdlc->cbin++;
466 hdlc->shift_reg >>= 1; 488 hdlc->shift_reg >>= 1;
@@ -474,11 +496,11 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
474 case HDLC_SEND_CRC1: 496 case HDLC_SEND_CRC1:
475 hdlc->cbin <<= 1; 497 hdlc->cbin <<= 1;
476 hdlc->data_bits++; 498 hdlc->data_bits++;
477 if(hdlc->hdlc_bits1 == 5){ 499 if (hdlc->hdlc_bits1 == 5) {
478 hdlc->hdlc_bits1 = 0; 500 hdlc->hdlc_bits1 = 0;
479 break; 501 break;
480 } 502 }
481 if(hdlc->shift_reg & 0x01){ 503 if (hdlc->shift_reg & 0x01) {
482 hdlc->hdlc_bits1++; 504 hdlc->hdlc_bits1++;
483 hdlc->cbin++; 505 hdlc->cbin++;
484 hdlc->shift_reg >>= 1; 506 hdlc->shift_reg >>= 1;
@@ -488,7 +510,7 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
488 hdlc->shift_reg >>= 1; 510 hdlc->shift_reg >>= 1;
489 hdlc->bit_shift--; 511 hdlc->bit_shift--;
490 } 512 }
491 if(hdlc->bit_shift==0){ 513 if (hdlc->bit_shift == 0) {
492 hdlc->shift_reg = (hdlc->crc >> 8); 514 hdlc->shift_reg = (hdlc->crc >> 8);
493 hdlc->state = HDLC_SEND_CRC2; 515 hdlc->state = HDLC_SEND_CRC2;
494 hdlc->bit_shift = 8; 516 hdlc->bit_shift = 8;
@@ -497,11 +519,11 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
497 case HDLC_SEND_CRC2: 519 case HDLC_SEND_CRC2:
498 hdlc->cbin <<= 1; 520 hdlc->cbin <<= 1;
499 hdlc->data_bits++; 521 hdlc->data_bits++;
500 if(hdlc->hdlc_bits1 == 5){ 522 if (hdlc->hdlc_bits1 == 5) {
501 hdlc->hdlc_bits1 = 0; 523 hdlc->hdlc_bits1 = 0;
502 break; 524 break;
503 } 525 }
504 if(hdlc->shift_reg & 0x01){ 526 if (hdlc->shift_reg & 0x01) {
505 hdlc->hdlc_bits1++; 527 hdlc->hdlc_bits1++;
506 hdlc->cbin++; 528 hdlc->cbin++;
507 hdlc->shift_reg >>= 1; 529 hdlc->shift_reg >>= 1;
@@ -511,7 +533,7 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
511 hdlc->shift_reg >>= 1; 533 hdlc->shift_reg >>= 1;
512 hdlc->bit_shift--; 534 hdlc->bit_shift--;
513 } 535 }
514 if(hdlc->bit_shift==0){ 536 if (hdlc->bit_shift == 0) {
515 hdlc->shift_reg = 0x7e; 537 hdlc->shift_reg = 0x7e;
516 hdlc->state = HDLC_SEND_CLOSING_FLAG; 538 hdlc->state = HDLC_SEND_CLOSING_FLAG;
517 hdlc->bit_shift = 8; 539 hdlc->bit_shift = 8;
@@ -520,33 +542,36 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
520 case HDLC_SEND_CLOSING_FLAG: 542 case HDLC_SEND_CLOSING_FLAG:
521 hdlc->cbin <<= 1; 543 hdlc->cbin <<= 1;
522 hdlc->data_bits++; 544 hdlc->data_bits++;
523 if(hdlc->hdlc_bits1 == 5){ 545 if (hdlc->hdlc_bits1 == 5) {
524 hdlc->hdlc_bits1 = 0; 546 hdlc->hdlc_bits1 = 0;
525 break; 547 break;
526 } 548 }
527 if(hdlc->shift_reg & 0x01){ 549 if (hdlc->shift_reg & 0x01)
528 hdlc->cbin++; 550 hdlc->cbin++;
529 }
530 hdlc->shift_reg >>= 1; 551 hdlc->shift_reg >>= 1;
531 hdlc->bit_shift--; 552 hdlc->bit_shift--;
532 if(hdlc->bit_shift==0){ 553 if (hdlc->bit_shift == 0) {
533 hdlc->ffvalue = xfast_flag_value[hdlc->data_bits]; 554 hdlc->ffvalue =
534 if(hdlc->dchannel){ 555 xfast_flag_value[hdlc->data_bits];
556 if (hdlc->dchannel) {
535 hdlc->ffvalue = 0x7e; 557 hdlc->ffvalue = 0x7e;
536 hdlc->state = HDLC_SEND_IDLE1; 558 hdlc->state = HDLC_SEND_IDLE1;
537 hdlc->bit_shift = 8-hdlc->data_bits; 559 hdlc->bit_shift = 8-hdlc->data_bits;
538 if(hdlc->bit_shift==0) 560 if (hdlc->bit_shift == 0)
539 hdlc->state = HDLC_SEND_FAST_IDLE; 561 hdlc->state =
562 HDLC_SEND_FAST_IDLE;
540 } else { 563 } else {
541 if(!hdlc->do_adapt56){ 564 if (!hdlc->do_adapt56) {
542 hdlc->state = HDLC_SEND_FAST_FLAG; 565 hdlc->state =
566 HDLC_SEND_FAST_FLAG;
543 hdlc->data_received = 0; 567 hdlc->data_received = 0;
544 } else { 568 } else {
545 hdlc->state = HDLC_SENDFLAG_B0; 569 hdlc->state = HDLC_SENDFLAG_B0;
546 hdlc->data_received = 0; 570 hdlc->data_received = 0;
547 } 571 }
548 // Finished with this frame, send flags 572 /* Finished this frame, send flags */
549 if (dsize > 1) dsize = 1; 573 if (dsize > 1)
574 dsize = 1;
550 } 575 }
551 } 576 }
552 break; 577 break;
@@ -556,7 +581,7 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
556 hdlc->cbin++; 581 hdlc->cbin++;
557 hdlc->data_bits++; 582 hdlc->data_bits++;
558 hdlc->bit_shift--; 583 hdlc->bit_shift--;
559 if(hdlc->bit_shift==0){ 584 if (hdlc->bit_shift == 0) {
560 hdlc->state = HDLC_SEND_FAST_IDLE; 585 hdlc->state = HDLC_SEND_FAST_IDLE;
561 hdlc->bit_shift = 0; 586 hdlc->bit_shift = 0;
562 } 587 }
@@ -565,12 +590,13 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
565 hdlc->do_closing = 0; 590 hdlc->do_closing = 0;
566 hdlc->cbin = 0xff; 591 hdlc->cbin = 0xff;
567 hdlc->data_bits = 8; 592 hdlc->data_bits = 8;
568 if(hdlc->bit_shift == 8){ 593 if (hdlc->bit_shift == 8) {
569 hdlc->cbin = 0x7e; 594 hdlc->cbin = 0x7e;
570 hdlc->state = HDLC_SEND_FIRST_FLAG; 595 hdlc->state = HDLC_SEND_FIRST_FLAG;
571 } else { 596 } else {
572 *dst++ = hdlc->cbin; 597 *dst++ = hdlc->cbin;
573 hdlc->bit_shift = hdlc->data_bits = 0; 598 hdlc->bit_shift = 0;
599 hdlc->data_bits = 0;
574 len++; 600 len++;
575 dsize = 0; 601 dsize = 0;
576 } 602 }
@@ -578,14 +604,14 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
578 default: 604 default:
579 break; 605 break;
580 } 606 }
581 if(hdlc->do_adapt56){ 607 if (hdlc->do_adapt56) {
582 if(hdlc->data_bits==7){ 608 if (hdlc->data_bits == 7) {
583 hdlc->cbin <<= 1; 609 hdlc->cbin <<= 1;
584 hdlc->cbin++; 610 hdlc->cbin++;
585 hdlc->data_bits++; 611 hdlc->data_bits++;
586 } 612 }
587 } 613 }
588 if(hdlc->data_bits==8){ 614 if (hdlc->data_bits == 8) {
589 *dst++ = hdlc->cbin; 615 *dst++ = hdlc->cbin;
590 hdlc->data_bits = 0; 616 hdlc->data_bits = 0;
591 len++; 617 len++;
@@ -596,8 +622,4 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
596 622
597 return len; 623 return len;
598} 624}
599
600EXPORT_SYMBOL(isdnhdlc_rcv_init);
601EXPORT_SYMBOL(isdnhdlc_decode);
602EXPORT_SYMBOL(isdnhdlc_out_init);
603EXPORT_SYMBOL(isdnhdlc_encode); 625EXPORT_SYMBOL(isdnhdlc_encode);
diff --git a/include/linux/isdn/hdlc.h b/include/linux/isdn/hdlc.h
index cf0a95a24015..8f3540c7f692 100644
--- a/include/linux/isdn/hdlc.h
+++ b/include/linux/isdn/hdlc.h
@@ -1,27 +1,28 @@
1/* 1/*
2 * isdnhdlc.h -- General purpose ISDN HDLC decoder. 2 * hdlc.h -- General purpose ISDN HDLC decoder.
3 * 3 *
4 * Implementation of a HDLC decoder/encoder in software. 4 * Implementation of a HDLC decoder/encoder in software.
5 * Neccessary because some ISDN devices don't have HDLC 5 * Neccessary because some ISDN devices don't have HDLC
6 * controllers. Also included: a bit reversal table. 6 * controllers.
7 * 7 *
8 *Copyright (C) 2002 Wolfgang Mües <wolfgang@iksw-muees.de> 8 * Copyright (C)
9 * 2001 Frode Isaksen <fisaksen@bewan.com> 9 * 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
10 * 2001 Kai Germaschewski <kai.germaschewski@gmx.de> 10 * 2001 Frode Isaksen <fisaksen@bewan.com>
11 * 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 14 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or 15 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version. 16 * (at your option) any later version.
16 * 17 *
17 * This program is distributed in the hope that it will be useful, 18 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details. 21 * GNU General Public License for more details.
21 * 22 *
22 * You should have received a copy of the GNU General Public License 23 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software 24 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */ 26 */
26 27
27#ifndef __ISDNHDLC_H__ 28#ifndef __ISDNHDLC_H__
@@ -31,20 +32,24 @@ struct isdnhdlc_vars {
31 int bit_shift; 32 int bit_shift;
32 int hdlc_bits1; 33 int hdlc_bits1;
33 int data_bits; 34 int data_bits;
34 int ffbit_shift; // encoding only 35 int ffbit_shift; /* encoding only */
35 int state; 36 int state;
36 int dstpos; 37 int dstpos;
37 38
38 unsigned short crc; 39 u16 crc;
39 40
40 unsigned char cbin; 41 u8 cbin;
41 unsigned char shift_reg; 42 u8 shift_reg;
42 unsigned char ffvalue; 43 u8 ffvalue;
43 44
44 unsigned int data_received:1; // set if transferring data 45 /* set if transferring data */
45 unsigned int dchannel:1; // set if D channel (send idle instead of flags) 46 u32 data_received:1;
46 unsigned int do_adapt56:1; // set if 56K adaptation 47 /* set if D channel (send idle instead of flags) */
47 unsigned int do_closing:1; // set if in closing phase (need to send CRC + flag 48 u32 dchannel:1;
49 /* set if 56K adaptation */
50 u32 do_adapt56:1;
51 /* set if in closing phase (need to send CRC + flag) */
52 u32 do_closing:1;
48}; 53};
49 54
50 55
@@ -57,14 +62,15 @@ struct isdnhdlc_vars {
57#define HDLC_CRC_ERROR 2 62#define HDLC_CRC_ERROR 2
58#define HDLC_LENGTH_ERROR 3 63#define HDLC_LENGTH_ERROR 3
59 64
60extern void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56); 65extern void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, int do_adapt56);
61 66
62extern int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src, int slen,int *count, 67extern int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src,
63 unsigned char *dst, int dsize); 68 int slen, int *count, u8 *dst, int dsize);
64 69
65extern void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc,int is_d_channel,int do_adapt56); 70extern void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, int is_d_channel,
71 int do_adapt56);
66 72
67extern int isdnhdlc_encode (struct isdnhdlc_vars *hdlc,const unsigned char *src,unsigned short slen,int *count, 73extern int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src,
68 unsigned char *dst,int dsize); 74 u16 slen, int *count, u8 *dst, int dsize);
69 75
70#endif /* __ISDNHDLC_H__ */ 76#endif /* __ISDNHDLC_H__ */