fix for hdlc_decode

This commit is contained in:
Kai Germaschewski 2001-07-19 20:39:19 +00:00
parent e10f085bbb
commit 4c5152e3ed
3 changed files with 16 additions and 31 deletions

View File

@ -835,16 +835,14 @@ usb_b_in_complete(struct urb *urb)
len = 0;
} else {
status = hdlc_decode(hw->hdlc_state_in, ptr, len, &count,
hw->rcvbuf + hw->rcvidx, HSCX_BUFMAX - hw->rcvidx);
hw->rcvbuf, HSCX_BUFMAX);
ptr += count;
len -= count;
}
count = status & 0x0FFF;
if (status & HDLC_END_OF_FRAME) {
// Good frame received
count += hw->rcvidx;
hw->rcvidx = 0;
count = status & 0x0FFF;
DBG(4,"B%d,count=%d",bcs->channel+1,count);
DUMP_PACKET(0x10, hw->rcvbuf, count);
if (bcs->cs->debug & L1_DEB_HSCX_FIFO)
@ -858,21 +856,14 @@ usb_b_in_complete(struct urb *urb)
st5481B_sched_event(bcs, B_RCVBUFREADY);
} else if (status & HDLC_CRC_ERROR) {
WARN("CRC error");
DUMP_PACKET(4, hw->rcvbuf, count+hw->rcvidx+2);
#ifdef ERROR_STATISTIC
++bcs->err_crc;
#endif
hw->rcvidx = 0;
} else if (status & (HDLC_FRAMING_ERROR | HDLC_LENGTH_ERROR)) {
WARN("framing/length error");
DUMP_PACKET(4, hw->rcvbuf, count+hw->rcvidx+2);
#ifdef ERROR_STATISTIC
++bcs->err_inv;
#endif
hw->rcvidx = 0;
} else {
// Good frame received
hw->rcvidx += count;
}
}
@ -1035,14 +1026,12 @@ usb_d_in_complete(struct urb *urb)
ptr = urb->transfer_buffer;
while (len > 0) {
status = hdlc_decode(hw->hdlc_state_in, ptr, len, &count,
cs->rcvbuf + cs->rcvidx, MAX_DFRAME_LEN_L1 - cs->rcvidx);
cs->rcvbuf, MAX_DFRAME_LEN_L1);
ptr += count;
len -= count;
count = status & 0x0FFF;
if (status & HDLC_END_OF_FRAME) {
count += cs->rcvidx;
cs->rcvidx = 0;
count = status & 0x0FFF;
DBG(2,"count=%d",count);
DUMP_PACKET(0x10, cs->rcvbuf, count);
// Good frame received
@ -1055,25 +1044,18 @@ usb_d_in_complete(struct urb *urb)
st5481_sched_event(cs, D_RCVBUFREADY);
} else if (status & HDLC_CRC_ERROR) {
WARN("CRC error");
DUMP_PACKET(2, cs->rcvbuf, count+cs->rcvidx+2);
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "st5481 CRC error");
#ifdef ERROR_STATISTIC
cs->err_crc++;
#endif
cs->rcvidx = 0;
} else if (status & (HDLC_FRAMING_ERROR | HDLC_LENGTH_ERROR)) {
WARN("framing/length error");
DUMP_PACKET(2, cs->rcvbuf, count+cs->rcvidx+2);
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "st5481 framing/length error");
#ifdef ERROR_STATISTIC
cs->err_rx++;
#endif
cs->rcvidx = 0;
} else {
// Good frame received
cs->rcvidx += count;
}
}

View File

@ -84,6 +84,7 @@ hdlc_rcv_init(struct hdlc_vars *hdlc, int do_adapt56)
hdlc->cbin = 0;
hdlc->shift_reg = 0;
hdlc->ffvalue = 0;
hdlc->dstpos = 0;
}
void
@ -159,7 +160,7 @@ hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, int slen, int *cou
};
static const unsigned char fast_abort[]={
0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe
0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff
};
*count = slen;
@ -234,7 +235,7 @@ hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, int slen, int *cou
case 7:
if(hdlc->data_received) {
// bad frame
status = status | HDLC_FRAMING_ERROR;
status = HDLC_FRAMING_ERROR;
}
if(!hdlc->do_adapt56){
if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
@ -260,12 +261,12 @@ hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, int slen, int *cou
if(hdlc->data_received){
if(hdlc->crc != 0xf0b8){
// crc error
status |= HDLC_CRC_ERROR;
status = HDLC_CRC_ERROR;
} else {
// remove CRC
status -= 2;
hdlc->dstpos -= 2;
// good frame
status |= HDLC_END_OF_FRAME;
status = hdlc->dstpos | HDLC_END_OF_FRAME;
}
}
hdlc->crc = 0xffff;
@ -294,6 +295,7 @@ hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, int slen, int *cou
hdlc->hdlc_bits1 = 0;
}
if (status & 0xF000) {
hdlc->dstpos = 0;
*count -= slen;
hdlc->cbin <<= 1;
hdlc->bit_shift--;
@ -308,11 +310,11 @@ hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, int slen, int *cou
hdlc->crc = (hdlc->crc>>8)^crc16_tab[cval];
// good byte received
if (dsize--) {
*dst++ = hdlc->shift_reg;
status++;
dst[hdlc->dstpos++] = hdlc->shift_reg;
} else {
// frame too long
status |= HDLC_LENGTH_ERROR;
status = HDLC_LENGTH_ERROR;
hdlc->dstpos = 0;
}
}
hdlc->cbin <<= 1;
@ -344,7 +346,7 @@ hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, int slen, int *cou
}
}
*count -= slen;
return status;
return 0;
}
/*

View File

@ -7,6 +7,7 @@ struct hdlc_vars {
int data_bits;
int ffbit_shift; // encoding only
int state;
int dstpos;
int data_received:1; // set if transferring data
int dchannel:1; // set if D channel (send idle instead of flags)