Skip to content

Commit

Permalink
ISDN: Add support for none reverse bitstreams to isdnhdc
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Karsten Keil committed Jul 25, 2009
1 parent 6bd4bcd commit c38fc3b
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 44 deletions.
5 changes: 4 additions & 1 deletion drivers/isdn/hisax/st5481_b.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,10 @@ static void st5481B_mode(struct st5481_bcs *bcs, int mode)
if (bcs->mode != L1_MODE_NULL) {
// Open the B channel
if (bcs->mode != L1_MODE_TRANS) {
isdnhdlc_out_init(&b_out->hdlc_state, 0, bcs->mode == L1_MODE_HDLC_56K);
u32 features = HDLC_BITREVERSE;
if (bcs->mode == L1_MODE_HDLC_56K)
features |= HDLC_56KBIT;
isdnhdlc_out_init(&b_out->hdlc_state, features);
}
st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2, NULL, NULL);

Expand Down
2 changes: 1 addition & 1 deletion drivers/isdn/hisax/st5481_d.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg)

DBG(2,"len=%d",skb->len);

isdnhdlc_out_init(&d_out->hdlc_state, 1, 0);
isdnhdlc_out_init(&d_out->hdlc_state, HDLC_DCHANNEL | HDLC_BITREVERSE);

if (test_and_set_bit(buf_nr, &d_out->busy)) {
WARNING("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy);
Expand Down
11 changes: 7 additions & 4 deletions drivers/isdn/hisax/st5481_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,10 +637,13 @@ void st5481_in_mode(struct st5481_in *in, int mode)
usb_unlink_urb(in->urb[1]);

if (in->mode != L1_MODE_NULL) {
if (in->mode != L1_MODE_TRANS)
isdnhdlc_rcv_init(&in->hdlc_state,
in->mode == L1_MODE_HDLC_56K);

if (in->mode != L1_MODE_TRANS) {
u32 features = HDLC_BITREVERSE;

if (in->mode == L1_MODE_HDLC_56K)
features |= HDLC_56KBIT;
isdnhdlc_rcv_init(&in->hdlc_state, features);
}
st5481_usb_pipe_reset(in->adapter, in->ep, NULL, NULL);
st5481_usb_device_ctrl_msg(in->adapter, in->counter,
in->packet_size,
Expand Down
70 changes: 35 additions & 35 deletions drivers/isdn/i4l/isdnhdlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* isdnhdlc.c -- General purpose ISDN HDLC decoder.
*
* Copyright (C)
* 2009 Karsten Keil <keil@b1-systems.de>
* 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
* 2001 Frode Isaksen <fisaksen@bewan.com>
* 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
Expand All @@ -25,6 +26,7 @@
#include <linux/init.h>
#include <linux/crc-ccitt.h>
#include <linux/isdn/hdlc.h>
#include <linux/bitrev.h>

/*-------------------------------------------------------------------*/

Expand All @@ -48,35 +50,21 @@ enum {
HDLC_SENDFLAG_B1A6, HDLC_SENDFLAG_B7, STOPPED
};

void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, int do_adapt56)
void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features)
{
hdlc->bit_shift = 0;
hdlc->hdlc_bits1 = 0;
hdlc->data_bits = 0;
hdlc->ffbit_shift = 0;
hdlc->data_received = 0;
memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
hdlc->state = HDLC_GET_DATA;
hdlc->do_adapt56 = do_adapt56;
hdlc->dchannel = 0;
hdlc->crc = 0;
hdlc->cbin = 0;
hdlc->shift_reg = 0;
hdlc->ffvalue = 0;
hdlc->dstpos = 0;
if (features & HDLC_56KBIT)
hdlc->do_adapt56 = 1;
if (features & HDLC_BITREVERSE)
hdlc->do_bitreverse = 1;
}
EXPORT_SYMBOL(isdnhdlc_out_init);

void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, int is_d_channel,
int do_adapt56)
void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features)
{
hdlc->bit_shift = 0;
hdlc->hdlc_bits1 = 0;
hdlc->data_bits = 0;
hdlc->ffbit_shift = 0;
hdlc->data_received = 0;
hdlc->do_closing = 0;
hdlc->ffvalue = 0;
if (is_d_channel) {
memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
if (features & HDLC_DCHANNEL) {
hdlc->dchannel = 1;
hdlc->state = HDLC_SEND_FIRST_FLAG;
} else {
Expand All @@ -85,16 +73,13 @@ void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, int is_d_channel,
hdlc->ffvalue = 0x7e;
}
hdlc->cbin = 0x7e;
hdlc->bit_shift = 0;
if (do_adapt56) {
if (features & HDLC_56KBIT) {
hdlc->do_adapt56 = 1;
hdlc->data_bits = 0;
hdlc->state = HDLC_SENDFLAG_B0;
} else {
hdlc->do_adapt56 = 0;
} else
hdlc->data_bits = 8;
}
hdlc->shift_reg = 0;
if (features & HDLC_BITREVERSE)
hdlc->do_bitreverse = 1;
}
EXPORT_SYMBOL(isdnhdlc_rcv_init);

Expand Down Expand Up @@ -188,7 +173,11 @@ int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,

while (slen > 0) {
if (hdlc->bit_shift == 0) {
hdlc->cbin = *src++;
/* the code is for bitreverse streams */
if (hdlc->do_bitreverse == 0)
hdlc->cbin = bitrev8(*src++);
else
hdlc->cbin = *src++;
slen--;
hdlc->bit_shift = 8;
if (hdlc->do_adapt56)
Expand Down Expand Up @@ -405,12 +394,15 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
case STOPPED:
while (dsize--)
*dst++ = 0xff;

return dsize;
case HDLC_SEND_FAST_FLAG:
hdlc->do_closing = 0;
if (slen == 0) {
*dst++ = hdlc->ffvalue;
/* the code is for bitreverse streams */
if (hdlc->do_bitreverse == 0)
*dst++ = bitrev8(hdlc->ffvalue);
else
*dst++ = hdlc->ffvalue;
len++;
dsize--;
break;
Expand Down Expand Up @@ -594,7 +586,11 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
hdlc->cbin = 0x7e;
hdlc->state = HDLC_SEND_FIRST_FLAG;
} else {
*dst++ = hdlc->cbin;
/* the code is for bitreverse streams */
if (hdlc->do_bitreverse == 0)
*dst++ = bitrev8(hdlc->cbin);
else
*dst++ = hdlc->cbin;
hdlc->bit_shift = 0;
hdlc->data_bits = 0;
len++;
Expand All @@ -612,7 +608,11 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
}
}
if (hdlc->data_bits == 8) {
*dst++ = hdlc->cbin;
/* the code is for bitreverse streams */
if (hdlc->do_bitreverse == 0)
*dst++ = bitrev8(hdlc->cbin);
else
*dst++ = hdlc->cbin;
hdlc->data_bits = 0;
len++;
dsize--;
Expand Down
12 changes: 9 additions & 3 deletions include/linux/isdn/hdlc.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* controllers.
*
* Copyright (C)
* 2009 Karsten Keil <keil@b1-systems.de>
* 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
* 2001 Frode Isaksen <fisaksen@bewan.com>
* 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
Expand Down Expand Up @@ -50,8 +51,14 @@ struct isdnhdlc_vars {
u32 do_adapt56:1;
/* set if in closing phase (need to send CRC + flag) */
u32 do_closing:1;
/* set if data is bitreverse */
u32 do_bitreverse:1;
};

/* Feature Flags */
#define HDLC_56KBIT 0x01
#define HDLC_DCHANNEL 0x02
#define HDLC_BITREVERSE 0x04

/*
The return value from isdnhdlc_decode is
Expand All @@ -62,13 +69,12 @@ struct isdnhdlc_vars {
#define HDLC_CRC_ERROR 2
#define HDLC_LENGTH_ERROR 3

extern void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, int do_adapt56);
extern void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features);

extern int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src,
int slen, int *count, u8 *dst, int dsize);

extern void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, int is_d_channel,
int do_adapt56);
extern void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features);

extern int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src,
u16 slen, int *count, u8 *dst, int dsize);
Expand Down

0 comments on commit c38fc3b

Please sign in to comment.