Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ISDN: Add support for none reverse bitstreams to isdnhdc

The original isdnhdlc code was developed for devices which had
reversed bitorder in the byte stream. Adding code to handle normal
bitstreams as well.

Signed-off-by: Karsten Keil <keil@b1-systems.de>

+56 -44
+4 -1
drivers/isdn/hisax/st5481_b.c
··· 218 218 if (bcs->mode != L1_MODE_NULL) { 219 219 // Open the B channel 220 220 if (bcs->mode != L1_MODE_TRANS) { 221 - isdnhdlc_out_init(&b_out->hdlc_state, 0, bcs->mode == L1_MODE_HDLC_56K); 221 + u32 features = HDLC_BITREVERSE; 222 + if (bcs->mode == L1_MODE_HDLC_56K) 223 + features |= HDLC_56KBIT; 224 + isdnhdlc_out_init(&b_out->hdlc_state, features); 222 225 } 223 226 st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2, NULL, NULL); 224 227
+1 -1
drivers/isdn/hisax/st5481_d.c
··· 417 417 418 418 DBG(2,"len=%d",skb->len); 419 419 420 - isdnhdlc_out_init(&d_out->hdlc_state, 1, 0); 420 + isdnhdlc_out_init(&d_out->hdlc_state, HDLC_DCHANNEL | HDLC_BITREVERSE); 421 421 422 422 if (test_and_set_bit(buf_nr, &d_out->busy)) { 423 423 WARNING("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy);
+7 -4
drivers/isdn/hisax/st5481_usb.c
··· 637 637 usb_unlink_urb(in->urb[1]); 638 638 639 639 if (in->mode != L1_MODE_NULL) { 640 - if (in->mode != L1_MODE_TRANS) 641 - isdnhdlc_rcv_init(&in->hdlc_state, 642 - in->mode == L1_MODE_HDLC_56K); 643 - 640 + if (in->mode != L1_MODE_TRANS) { 641 + u32 features = HDLC_BITREVERSE; 642 + 643 + if (in->mode == L1_MODE_HDLC_56K) 644 + features |= HDLC_56KBIT; 645 + isdnhdlc_rcv_init(&in->hdlc_state, features); 646 + } 644 647 st5481_usb_pipe_reset(in->adapter, in->ep, NULL, NULL); 645 648 st5481_usb_device_ctrl_msg(in->adapter, in->counter, 646 649 in->packet_size,
+35 -35
drivers/isdn/i4l/isdnhdlc.c
··· 2 2 * isdnhdlc.c -- General purpose ISDN HDLC decoder. 3 3 * 4 4 * Copyright (C) 5 + * 2009 Karsten Keil <keil@b1-systems.de> 5 6 * 2002 Wolfgang Mües <wolfgang@iksw-muees.de> 6 7 * 2001 Frode Isaksen <fisaksen@bewan.com> 7 8 * 2001 Kai Germaschewski <kai.germaschewski@gmx.de> ··· 26 25 #include <linux/init.h> 27 26 #include <linux/crc-ccitt.h> 28 27 #include <linux/isdn/hdlc.h> 28 + #include <linux/bitrev.h> 29 29 30 30 /*-------------------------------------------------------------------*/ 31 31 ··· 50 48 HDLC_SENDFLAG_B1A6, HDLC_SENDFLAG_B7, STOPPED 51 49 }; 52 50 53 - void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, int do_adapt56) 51 + void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features) 54 52 { 55 - hdlc->bit_shift = 0; 56 - hdlc->hdlc_bits1 = 0; 57 - hdlc->data_bits = 0; 58 - hdlc->ffbit_shift = 0; 59 - hdlc->data_received = 0; 53 + memset(hdlc, 0, sizeof(struct isdnhdlc_vars)); 60 54 hdlc->state = HDLC_GET_DATA; 61 - hdlc->do_adapt56 = do_adapt56; 62 - hdlc->dchannel = 0; 63 - hdlc->crc = 0; 64 - hdlc->cbin = 0; 65 - hdlc->shift_reg = 0; 66 - hdlc->ffvalue = 0; 67 - hdlc->dstpos = 0; 55 + if (features & HDLC_56KBIT) 56 + hdlc->do_adapt56 = 1; 57 + if (features & HDLC_BITREVERSE) 58 + hdlc->do_bitreverse = 1; 68 59 } 69 60 EXPORT_SYMBOL(isdnhdlc_out_init); 70 61 71 - void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, int is_d_channel, 72 - int do_adapt56) 62 + void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features) 73 63 { 74 - hdlc->bit_shift = 0; 75 - hdlc->hdlc_bits1 = 0; 76 - hdlc->data_bits = 0; 77 - hdlc->ffbit_shift = 0; 78 - hdlc->data_received = 0; 79 - hdlc->do_closing = 0; 80 - hdlc->ffvalue = 0; 81 - if (is_d_channel) { 64 + memset(hdlc, 0, sizeof(struct isdnhdlc_vars)); 65 + if (features & HDLC_DCHANNEL) { 82 66 hdlc->dchannel = 1; 83 67 hdlc->state = HDLC_SEND_FIRST_FLAG; 84 68 } else { ··· 73 85 hdlc->ffvalue = 0x7e; 74 86 } 75 87 hdlc->cbin = 0x7e; 76 - hdlc->bit_shift = 0; 77 - if (do_adapt56) { 88 + if (features & HDLC_56KBIT) { 78 89 hdlc->do_adapt56 = 1; 79 - hdlc->data_bits = 0; 80 90 hdlc->state = HDLC_SENDFLAG_B0; 81 - } else { 82 - hdlc->do_adapt56 = 0; 91 + } else 83 92 hdlc->data_bits = 8; 84 - } 85 - hdlc->shift_reg = 0; 93 + if (features & HDLC_BITREVERSE) 94 + hdlc->do_bitreverse = 1; 86 95 } 87 96 EXPORT_SYMBOL(isdnhdlc_rcv_init); 88 97 ··· 173 188 174 189 while (slen > 0) { 175 190 if (hdlc->bit_shift == 0) { 176 - hdlc->cbin = *src++; 191 + /* the code is for bitreverse streams */ 192 + if (hdlc->do_bitreverse == 0) 193 + hdlc->cbin = bitrev8(*src++); 194 + else 195 + hdlc->cbin = *src++; 177 196 slen--; 178 197 hdlc->bit_shift = 8; 179 198 if (hdlc->do_adapt56) ··· 394 405 case STOPPED: 395 406 while (dsize--) 396 407 *dst++ = 0xff; 397 - 398 408 return dsize; 399 409 case HDLC_SEND_FAST_FLAG: 400 410 hdlc->do_closing = 0; 401 411 if (slen == 0) { 402 - *dst++ = hdlc->ffvalue; 412 + /* the code is for bitreverse streams */ 413 + if (hdlc->do_bitreverse == 0) 414 + *dst++ = bitrev8(hdlc->ffvalue); 415 + else 416 + *dst++ = hdlc->ffvalue; 403 417 len++; 404 418 dsize--; 405 419 break; ··· 586 594 hdlc->cbin = 0x7e; 587 595 hdlc->state = HDLC_SEND_FIRST_FLAG; 588 596 } else { 589 - *dst++ = hdlc->cbin; 597 + /* the code is for bitreverse streams */ 598 + if (hdlc->do_bitreverse == 0) 599 + *dst++ = bitrev8(hdlc->cbin); 600 + else 601 + *dst++ = hdlc->cbin; 590 602 hdlc->bit_shift = 0; 591 603 hdlc->data_bits = 0; 592 604 len++; ··· 608 612 } 609 613 } 610 614 if (hdlc->data_bits == 8) { 611 - *dst++ = hdlc->cbin; 615 + /* the code is for bitreverse streams */ 616 + if (hdlc->do_bitreverse == 0) 617 + *dst++ = bitrev8(hdlc->cbin); 618 + else 619 + *dst++ = hdlc->cbin; 612 620 hdlc->data_bits = 0; 613 621 len++; 614 622 dsize--;
+9 -3
include/linux/isdn/hdlc.h
··· 6 6 * controllers. 7 7 * 8 8 * Copyright (C) 9 + * 2009 Karsten Keil <keil@b1-systems.de> 9 10 * 2002 Wolfgang Mües <wolfgang@iksw-muees.de> 10 11 * 2001 Frode Isaksen <fisaksen@bewan.com> 11 12 * 2001 Kai Germaschewski <kai.germaschewski@gmx.de> ··· 51 50 u32 do_adapt56:1; 52 51 /* set if in closing phase (need to send CRC + flag) */ 53 52 u32 do_closing:1; 53 + /* set if data is bitreverse */ 54 + u32 do_bitreverse:1; 54 55 }; 55 56 57 + /* Feature Flags */ 58 + #define HDLC_56KBIT 0x01 59 + #define HDLC_DCHANNEL 0x02 60 + #define HDLC_BITREVERSE 0x04 56 61 57 62 /* 58 63 The return value from isdnhdlc_decode is ··· 69 62 #define HDLC_CRC_ERROR 2 70 63 #define HDLC_LENGTH_ERROR 3 71 64 72 - extern void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, int do_adapt56); 65 + extern void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features); 73 66 74 67 extern int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, 75 68 int slen, int *count, u8 *dst, int dsize); 76 69 77 - extern void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, int is_d_channel, 78 - int do_adapt56); 70 + extern void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features); 79 71 80 72 extern int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, 81 73 u16 slen, int *count, u8 *dst, int dsize);