These fixes have been verified with the IFX6160 modem.
Signed-off-by: kmills <[email protected]>
---
drivers/char/n_gsm.c | 136 ++++++++++++++++++++++++++++++++++----------------
1 files changed, 93 insertions(+), 43 deletions(-)
diff --git a/drivers/char/n_gsm.c b/drivers/char/n_gsm.c
index 79d8464..c377b32 100644
--- a/drivers/char/n_gsm.c
+++ b/drivers/char/n_gsm.c
@@ -78,6 +78,8 @@ module_param(debug, int, 0600);
limits so this is plenty */
#define MAX_MRU 512
#define MAX_MTU 512
+#define GSM_DEFAULT_MTU 512
+#define GSM_DEFAULT_MRU GSM_DEFAULT_MTU
/*
* Each block of data we have queued to go out is in the form of
@@ -185,6 +187,9 @@ struct gsm_mux {
#define GSM_DATA 5
#define GSM_FCS 6
#define GSM_OVERRUN 7
+#define GSM_LEN0 8
+#define GSM_LEN1 9
+#define GSM_SSOF 10
unsigned int len;
unsigned int address;
unsigned int count;
@@ -192,6 +197,7 @@ struct gsm_mux {
int encoding;
u8 control;
u8 fcs;
+ u8 good_fcs;
u8 *txframe; /* TX framing buffer */
/* Methods for the receiver side */
@@ -294,6 +300,7 @@ static spinlock_t gsm_mux_lock;
#define XOFF 0x13
static const struct tty_port_operations gsm_port_ops;
+static void gsm_dlci_data_kick(struct gsm_dlci *dlci);
/*
* CRC table for GSM 0710
@@ -430,7 +437,7 @@ static void gsm_print_packet(const char *hdr, int addr, int
cr,
if (!(debug & 1))
return;
- printk(KERN_INFO "%s %d) %c: ", hdr, addr, "RC"[cr]);
+ printk(KERN_CONT "%s %d) %c: ", hdr, addr, "RC"[cr]);
switch (control & ~PF) {
case SABM:
@@ -458,13 +465,13 @@ static void gsm_print_packet(const char *hdr, int addr,
int cr,
} else
switch (control & 0x0F) {
case RR:
- printk("RR(%d)", (control & 0xE0) >> 5);
+ printk(KERN_CONT "RR(%d)", (control & 0xE0) >> 5);
break;
case RNR:
- printk("RNR(%d)", (control & 0xE0) >> 5);
+ printk(KERN_CONT "RNR(%d)", (control & 0xE0) >> 5);
break;
case REJ:
- printk("REJ(%d)", (control & 0xE0) >> 5);
+ printk(KERN_CONT "REJ(%d)", (control & 0xE0) >> 5);
break;
default:
printk(KERN_CONT "[%02X]", control);
@@ -481,7 +488,8 @@ static void gsm_print_packet(const char *hdr, int addr, int
cr,
while (dlen--) {
if (ct % 8 == 0)
printk(KERN_CONT "\n ");
- printk(KERN_CONT "%02X ", *data++);
+ printk(KERN_CONT "%02X %c ", *data, *data);
+ data++;
ct++;
}
}
@@ -525,8 +533,9 @@ static void hex_packet(const unsigned char *p, int len)
int i;
for (i = 0; i < len; i++) {
if (i && (i % 16) == 0)
- printk(KERN_INFO "\n");
- printk(KERN_INFO "%02X ", *p++);
+ printk(KERN_CONT "\n");
+ printk(KERN_CONT "%02X %c ", *p, *p);
+ p++;
}
printk("\n");
}
@@ -718,8 +727,8 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct
gsm_msg *msg)
if (msg->len < 128)
*--dp = (msg->len << 1) | EA;
else {
- *--dp = (msg->len >> 6) | EA;
- *--dp = (msg->len & 127) << 1;
+ *--dp = ((msg->len & 127) << 1) | EA;
+ *--dp = (msg->len >> 6) & 0xfe;
}
}
@@ -986,13 +995,23 @@ static void gsm_control_reply(struct gsm_mux *gsm, int
cmd, u8 *data,
* layer 2 is processed. Sort out the local modem state and throttles
*/
+#define TWO_OCTETS 0x4000
static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
- u32 modem)
+ u32 _modem)
{
int mlines = 0;
- u8 brk = modem >> 6;
+ u8 modem;
+ u8 brk = 0;
+
+ /* only two octets are defined at this time (control and break) */
+ if (_modem & TWO_OCTETS) {
+ modem = (_modem >> 7) & 0x7f;
+ brk = _modem & 0x7f;
+ } else
+ modem = _modem & 0x7f;
/* Flow control/ready to communicate */
+
if (modem & MDM_FC) {
/* Need to throttle our output on this device */
dlci->constipated = 1;
@@ -1019,6 +1038,10 @@ static void gsm_process_modem(struct tty_struct *tty,
struct gsm_dlci *dlci,
tty_insert_flip_char(tty, 0, TTY_BREAK);
}
dlci->modem_rx = mlines;
+ if (tty && (mlines & TIOCM_RTS)) {
+ pr_debug("wake up port\n");
+ wake_up_interruptible(&dlci->port.open_wait);
+ }
}
/**
@@ -1036,7 +1059,7 @@ static void gsm_process_modem(struct tty_struct *tty,
struct gsm_dlci *dlci,
static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen)
{
unsigned int addr = 0;
- unsigned int modem = 0;
+ unsigned int modem = 1;
struct gsm_dlci *dlci;
int len = clen;
u8 *dp = data;
@@ -1057,7 +1080,6 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8
*data, int clen)
if (addr == 0 || addr >= NUM_DLCI || gsm->dlci[addr] == NULL)
return;
dlci = gsm->dlci[addr];
-
while (gsm_read_ea(&modem, *dp++) == 0) {
len--;
if (len == 0)
@@ -1340,7 +1362,6 @@ static int gsm_control_wait(struct gsm_mux *gsm, struct
gsm_control *control)
return err;
}
-
/*
* DLCI level handling: Needs krefs
*/
@@ -1392,7 +1413,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
/* This will let a tty open continue */
dlci->state = DLCI_OPEN;
if (debug & 8)
- printk(KERN_DEBUG "DLCI %d goes open.\n", dlci->addr);
+ printk(KERN_INFO "DLCI %d goes open.\n", dlci->addr);
wake_up(&dlci->gsm->event);
}
@@ -1491,10 +1512,11 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, u8
*data, int len)
/* krefs .. */
struct tty_port *port = &dlci->port;
struct tty_struct *tty = tty_port_tty_get(port);
- unsigned int modem = 0;
+ unsigned int modem = 1;
if (debug & 16)
- printk(KERN_DEBUG "%d bytes for tty %p\n", len, tty);
+ pr_debug("gsm_dlci_data: %d bytes for tty %p\n", len, tty);
+
if (tty) {
switch (dlci->adaption) {
/* Unsupported types */
@@ -1625,7 +1647,6 @@ static void gsm_dlci_free(struct gsm_dlci *dlci)
kfree(dlci);
}
-
/*
* LAPBish link layer logic
*/
@@ -1644,16 +1665,20 @@ static void gsm_queue(struct gsm_mux *gsm)
{
struct gsm_dlci *dlci;
u8 cr;
+ u8 fcs;
int address;
/* We have to sneak a look at the packet body to do the FCS.
A somewhat layering violation in the spec */
+ pr_debug("gsm_queue: ctl:%x dlci:%d\n", gsm->control,
+ gsm->address >> 1);
if ((gsm->control & ~PF) == UI)
gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len);
- if (gsm->fcs != GOOD_FCS) {
+ fcs = ~gsm->fcs;
+ if (fcs != gsm->good_fcs) {
gsm->bad_fcs++;
if (debug & 4)
- printk(KERN_INFO "BAD FCS %02x\n", gsm->fcs);
+ pr_debug("BAD FCS %02x (!%02x)\n", fcs, gsm->good_fcs);
return;
}
address = gsm->address >> 1;
@@ -1737,7 +1762,6 @@ invalid:
return;
}
-
/**
* gsm0_receive - perform processing for non-transparency
* @gsm: gsm data for this ldisc instance
@@ -1748,6 +1772,8 @@ invalid:
static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
{
+ unsigned int len;
+
switch (gsm->state) {
case GSM_SEARCH: /* SOF marker */
if (c == GSM0_SOF) {
@@ -1755,9 +1781,10 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned
char c)
gsm->address = 0;
gsm->len = 0;
gsm->fcs = INIT_FCS;
+ gsm->good_fcs = 0;
}
- break; /* Address EA */
- case GSM_ADDRESS:
+ break;
+ case GSM_ADDRESS: /* Address EA */
gsm->fcs = gsm_fcs_add(gsm->fcs, c);
if (gsm_read_ea(&gsm->address, c))
gsm->state = GSM_CONTROL;
@@ -1765,9 +1792,9 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned
char c)
case GSM_CONTROL: /* Control Byte */
gsm->fcs = gsm_fcs_add(gsm->fcs, c);
gsm->control = c;
- gsm->state = GSM_LEN;
+ gsm->state = GSM_LEN0;
break;
- case GSM_LEN: /* Length EA */
+ case GSM_LEN0: /* Length EA */
gsm->fcs = gsm_fcs_add(gsm->fcs, c);
if (gsm_read_ea(&gsm->len, c)) {
if (gsm->len > gsm->mru) {
@@ -1776,8 +1803,28 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned
char c)
break;
}
gsm->count = 0;
- gsm->state = GSM_DATA;
+ if (!gsm->len)
+ gsm->state = GSM_FCS;
+ else
+ gsm->state = GSM_DATA;
+ break;
+ }
+ gsm->state = GSM_LEN1;
+ break;
+ case GSM_LEN1:
+ gsm->fcs = gsm_fcs_add(gsm->fcs, c);
+ len = c;
+ gsm->len |= len << 7;
+ if (gsm->len > gsm->mru) {
+ gsm->bad_size++;
+ gsm->state = GSM_SEARCH;
+ break;
}
+ gsm->count = 0;
+ if (!gsm->len)
+ gsm->state = GSM_FCS;
+ else
+ gsm->state = GSM_DATA;
break;
case GSM_DATA: /* Data */
gsm->buf[gsm->count++] = c;
@@ -1785,16 +1832,25 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned
char c)
gsm->state = GSM_FCS;
break;
case GSM_FCS: /* FCS follows the packet */
- gsm->fcs = c;
+ if (c == GSM0_SOF) {
+ gsm->state = GSM_SEARCH;
+ break;
+ }
+ gsm->good_fcs = c;
gsm_queue(gsm);
- /* And then back for the next frame */
- gsm->state = GSM_SEARCH;
+ gsm->state = GSM_SSOF;
+ break;
+ case GSM_SSOF:
+ if (c == GSM0_SOF) {
+ gsm->state = GSM_SEARCH;
+ break;
+ }
break;
}
}
/**
- * gsm0_receive - perform processing for non-transparency
+ * gsm1_receive - perform processing for non-transparency
* @gsm: gsm data for this ldisc instance
* @c: character
*
@@ -2025,18 +2081,15 @@ struct gsm_mux *gsm_alloc_mux(void)
gsm->ftype = UIH;
gsm->initiator = 0;
gsm->adaption = 1;
- gsm->encoding = 1;
- gsm->mru = 64; /* Default to encoding 1 so these should be 64 */
- gsm->mtu = 64;
+ gsm->encoding = 0;
+ gsm->mru = GSM_DEFAULT_MTU;
+ gsm->mtu = GSM_DEFAULT_MTU;
gsm->dead = 1; /* Avoid early tty opens */
return gsm;
}
EXPORT_SYMBOL_GPL(gsm_alloc_mux);
-
-
-
/**
* gsmld_output - write to link
* @gsm: our mux
@@ -2053,10 +2106,8 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data,
int len)
set_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags);
return -ENOSPC;
}
- if (debug & 4) {
- printk(KERN_INFO "-->%d bytes out\n", len);
+ if (debug & 4)
hex_packet(data, len);
- }
gsm->tty->ops->write(gsm->tty, data, len);
return len;
}
@@ -2110,10 +2161,8 @@ static void gsmld_receive_buf(struct tty_struct *tty,
const unsigned char *cp,
char buf[64];
char flags;
- if (debug & 4) {
- printk(KERN_INFO "Inbytes %dd\n", count);
+ if (debug & 4)
hex_packet(cp, count);
- }
for (i = count, dp = cp, f = fp; i; i--, dp++) {
flags = *f++;
@@ -2212,7 +2261,7 @@ static int gsmld_open(struct tty_struct *tty)
tty->receive_room = 65536;
/* Attach the initial passive connection */
- gsm->encoding = 1;
+ /*gsm->encoding = 1; */
return gsmld_attach_gsm(tty, gsm);
}
@@ -2377,6 +2426,7 @@ static int gsmld_config(struct tty_struct *tty, struct
gsm_mux *gsm,
gsm->mru = c->mru;
gsm->encoding = c->encapsulation;
gsm->adaption = c->adaption;
+ gsm->n2 = c->n2;
if (c->i == 1)
gsm->ftype = UIH;
--
1.7.0.4
From 1a3e3da2180cbe39a5259297885861ef1ffa1b7b Mon Sep 17 00:00:00 2001
From: kmills <[email protected]>
Date: Wed, 27 Oct 2010 18:18:23 -0700
Subject: [PATCH 2/2] Mux bug fixes.
These fixes have been verified with the IFX6160 modem.
Signed-off-by: kmills <[email protected]>
---
drivers/char/n_gsm.c | 136 ++++++++++++++++++++++++++++++++++----------------
1 files changed, 93 insertions(+), 43 deletions(-)
diff --git a/drivers/char/n_gsm.c b/drivers/char/n_gsm.c
index 79d8464..c377b32 100644
--- a/drivers/char/n_gsm.c
+++ b/drivers/char/n_gsm.c
@@ -78,6 +78,8 @@ module_param(debug, int, 0600);
limits so this is plenty */
#define MAX_MRU 512
#define MAX_MTU 512
+#define GSM_DEFAULT_MTU 512
+#define GSM_DEFAULT_MRU GSM_DEFAULT_MTU
/*
* Each block of data we have queued to go out is in the form of
@@ -185,6 +187,9 @@ struct gsm_mux {
#define GSM_DATA 5
#define GSM_FCS 6
#define GSM_OVERRUN 7
+#define GSM_LEN0 8
+#define GSM_LEN1 9
+#define GSM_SSOF 10
unsigned int len;
unsigned int address;
unsigned int count;
@@ -192,6 +197,7 @@ struct gsm_mux {
int encoding;
u8 control;
u8 fcs;
+ u8 good_fcs;
u8 *txframe; /* TX framing buffer */
/* Methods for the receiver side */
@@ -294,6 +300,7 @@ static spinlock_t gsm_mux_lock;
#define XOFF 0x13
static const struct tty_port_operations gsm_port_ops;
+static void gsm_dlci_data_kick(struct gsm_dlci *dlci);
/*
* CRC table for GSM 0710
@@ -430,7 +437,7 @@ static void gsm_print_packet(const char *hdr, int addr, int cr,
if (!(debug & 1))
return;
- printk(KERN_INFO "%s %d) %c: ", hdr, addr, "RC"[cr]);
+ printk(KERN_CONT "%s %d) %c: ", hdr, addr, "RC"[cr]);
switch (control & ~PF) {
case SABM:
@@ -458,13 +465,13 @@ static void gsm_print_packet(const char *hdr, int addr, int cr,
} else
switch (control & 0x0F) {
case RR:
- printk("RR(%d)", (control & 0xE0) >> 5);
+ printk(KERN_CONT "RR(%d)", (control & 0xE0) >> 5);
break;
case RNR:
- printk("RNR(%d)", (control & 0xE0) >> 5);
+ printk(KERN_CONT "RNR(%d)", (control & 0xE0) >> 5);
break;
case REJ:
- printk("REJ(%d)", (control & 0xE0) >> 5);
+ printk(KERN_CONT "REJ(%d)", (control & 0xE0) >> 5);
break;
default:
printk(KERN_CONT "[%02X]", control);
@@ -481,7 +488,8 @@ static void gsm_print_packet(const char *hdr, int addr, int cr,
while (dlen--) {
if (ct % 8 == 0)
printk(KERN_CONT "\n ");
- printk(KERN_CONT "%02X ", *data++);
+ printk(KERN_CONT "%02X %c ", *data, *data);
+ data++;
ct++;
}
}
@@ -525,8 +533,9 @@ static void hex_packet(const unsigned char *p, int len)
int i;
for (i = 0; i < len; i++) {
if (i && (i % 16) == 0)
- printk(KERN_INFO "\n");
- printk(KERN_INFO "%02X ", *p++);
+ printk(KERN_CONT "\n");
+ printk(KERN_CONT "%02X %c ", *p, *p);
+ p++;
}
printk("\n");
}
@@ -718,8 +727,8 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
if (msg->len < 128)
*--dp = (msg->len << 1) | EA;
else {
- *--dp = (msg->len >> 6) | EA;
- *--dp = (msg->len & 127) << 1;
+ *--dp = ((msg->len & 127) << 1) | EA;
+ *--dp = (msg->len >> 6) & 0xfe;
}
}
@@ -986,13 +995,23 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, u8 *data,
* layer 2 is processed. Sort out the local modem state and throttles
*/
+#define TWO_OCTETS 0x4000
static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
- u32 modem)
+ u32 _modem)
{
int mlines = 0;
- u8 brk = modem >> 6;
+ u8 modem;
+ u8 brk = 0;
+
+ /* only two octets are defined at this time (control and break) */
+ if (_modem & TWO_OCTETS) {
+ modem = (_modem >> 7) & 0x7f;
+ brk = _modem & 0x7f;
+ } else
+ modem = _modem & 0x7f;
/* Flow control/ready to communicate */
+
if (modem & MDM_FC) {
/* Need to throttle our output on this device */
dlci->constipated = 1;
@@ -1019,6 +1038,10 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
tty_insert_flip_char(tty, 0, TTY_BREAK);
}
dlci->modem_rx = mlines;
+ if (tty && (mlines & TIOCM_RTS)) {
+ pr_debug("wake up port\n");
+ wake_up_interruptible(&dlci->port.open_wait);
+ }
}
/**
@@ -1036,7 +1059,7 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen)
{
unsigned int addr = 0;
- unsigned int modem = 0;
+ unsigned int modem = 1;
struct gsm_dlci *dlci;
int len = clen;
u8 *dp = data;
@@ -1057,7 +1080,6 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen)
if (addr == 0 || addr >= NUM_DLCI || gsm->dlci[addr] == NULL)
return;
dlci = gsm->dlci[addr];
-
while (gsm_read_ea(&modem, *dp++) == 0) {
len--;
if (len == 0)
@@ -1340,7 +1362,6 @@ static int gsm_control_wait(struct gsm_mux *gsm, struct gsm_control *control)
return err;
}
-
/*
* DLCI level handling: Needs krefs
*/
@@ -1392,7 +1413,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
/* This will let a tty open continue */
dlci->state = DLCI_OPEN;
if (debug & 8)
- printk(KERN_DEBUG "DLCI %d goes open.\n", dlci->addr);
+ printk(KERN_INFO "DLCI %d goes open.\n", dlci->addr);
wake_up(&dlci->gsm->event);
}
@@ -1491,10 +1512,11 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len)
/* krefs .. */
struct tty_port *port = &dlci->port;
struct tty_struct *tty = tty_port_tty_get(port);
- unsigned int modem = 0;
+ unsigned int modem = 1;
if (debug & 16)
- printk(KERN_DEBUG "%d bytes for tty %p\n", len, tty);
+ pr_debug("gsm_dlci_data: %d bytes for tty %p\n", len, tty);
+
if (tty) {
switch (dlci->adaption) {
/* Unsupported types */
@@ -1625,7 +1647,6 @@ static void gsm_dlci_free(struct gsm_dlci *dlci)
kfree(dlci);
}
-
/*
* LAPBish link layer logic
*/
@@ -1644,16 +1665,20 @@ static void gsm_queue(struct gsm_mux *gsm)
{
struct gsm_dlci *dlci;
u8 cr;
+ u8 fcs;
int address;
/* We have to sneak a look at the packet body to do the FCS.
A somewhat layering violation in the spec */
+ pr_debug("gsm_queue: ctl:%x dlci:%d\n", gsm->control,
+ gsm->address >> 1);
if ((gsm->control & ~PF) == UI)
gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len);
- if (gsm->fcs != GOOD_FCS) {
+ fcs = ~gsm->fcs;
+ if (fcs != gsm->good_fcs) {
gsm->bad_fcs++;
if (debug & 4)
- printk(KERN_INFO "BAD FCS %02x\n", gsm->fcs);
+ pr_debug("BAD FCS %02x (!%02x)\n", fcs, gsm->good_fcs);
return;
}
address = gsm->address >> 1;
@@ -1737,7 +1762,6 @@ invalid:
return;
}
-
/**
* gsm0_receive - perform processing for non-transparency
* @gsm: gsm data for this ldisc instance
@@ -1748,6 +1772,8 @@ invalid:
static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
{
+ unsigned int len;
+
switch (gsm->state) {
case GSM_SEARCH: /* SOF marker */
if (c == GSM0_SOF) {
@@ -1755,9 +1781,10 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
gsm->address = 0;
gsm->len = 0;
gsm->fcs = INIT_FCS;
+ gsm->good_fcs = 0;
}
- break; /* Address EA */
- case GSM_ADDRESS:
+ break;
+ case GSM_ADDRESS: /* Address EA */
gsm->fcs = gsm_fcs_add(gsm->fcs, c);
if (gsm_read_ea(&gsm->address, c))
gsm->state = GSM_CONTROL;
@@ -1765,9 +1792,9 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
case GSM_CONTROL: /* Control Byte */
gsm->fcs = gsm_fcs_add(gsm->fcs, c);
gsm->control = c;
- gsm->state = GSM_LEN;
+ gsm->state = GSM_LEN0;
break;
- case GSM_LEN: /* Length EA */
+ case GSM_LEN0: /* Length EA */
gsm->fcs = gsm_fcs_add(gsm->fcs, c);
if (gsm_read_ea(&gsm->len, c)) {
if (gsm->len > gsm->mru) {
@@ -1776,8 +1803,28 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
break;
}
gsm->count = 0;
- gsm->state = GSM_DATA;
+ if (!gsm->len)
+ gsm->state = GSM_FCS;
+ else
+ gsm->state = GSM_DATA;
+ break;
+ }
+ gsm->state = GSM_LEN1;
+ break;
+ case GSM_LEN1:
+ gsm->fcs = gsm_fcs_add(gsm->fcs, c);
+ len = c;
+ gsm->len |= len << 7;
+ if (gsm->len > gsm->mru) {
+ gsm->bad_size++;
+ gsm->state = GSM_SEARCH;
+ break;
}
+ gsm->count = 0;
+ if (!gsm->len)
+ gsm->state = GSM_FCS;
+ else
+ gsm->state = GSM_DATA;
break;
case GSM_DATA: /* Data */
gsm->buf[gsm->count++] = c;
@@ -1785,16 +1832,25 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
gsm->state = GSM_FCS;
break;
case GSM_FCS: /* FCS follows the packet */
- gsm->fcs = c;
+ if (c == GSM0_SOF) {
+ gsm->state = GSM_SEARCH;
+ break;
+ }
+ gsm->good_fcs = c;
gsm_queue(gsm);
- /* And then back for the next frame */
- gsm->state = GSM_SEARCH;
+ gsm->state = GSM_SSOF;
+ break;
+ case GSM_SSOF:
+ if (c == GSM0_SOF) {
+ gsm->state = GSM_SEARCH;
+ break;
+ }
break;
}
}
/**
- * gsm0_receive - perform processing for non-transparency
+ * gsm1_receive - perform processing for non-transparency
* @gsm: gsm data for this ldisc instance
* @c: character
*
@@ -2025,18 +2081,15 @@ struct gsm_mux *gsm_alloc_mux(void)
gsm->ftype = UIH;
gsm->initiator = 0;
gsm->adaption = 1;
- gsm->encoding = 1;
- gsm->mru = 64; /* Default to encoding 1 so these should be 64 */
- gsm->mtu = 64;
+ gsm->encoding = 0;
+ gsm->mru = GSM_DEFAULT_MTU;
+ gsm->mtu = GSM_DEFAULT_MTU;
gsm->dead = 1; /* Avoid early tty opens */
return gsm;
}
EXPORT_SYMBOL_GPL(gsm_alloc_mux);
-
-
-
/**
* gsmld_output - write to link
* @gsm: our mux
@@ -2053,10 +2106,8 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len)
set_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags);
return -ENOSPC;
}
- if (debug & 4) {
- printk(KERN_INFO "-->%d bytes out\n", len);
+ if (debug & 4)
hex_packet(data, len);
- }
gsm->tty->ops->write(gsm->tty, data, len);
return len;
}
@@ -2110,10 +2161,8 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char buf[64];
char flags;
- if (debug & 4) {
- printk(KERN_INFO "Inbytes %dd\n", count);
+ if (debug & 4)
hex_packet(cp, count);
- }
for (i = count, dp = cp, f = fp; i; i--, dp++) {
flags = *f++;
@@ -2212,7 +2261,7 @@ static int gsmld_open(struct tty_struct *tty)
tty->receive_room = 65536;
/* Attach the initial passive connection */
- gsm->encoding = 1;
+ /*gsm->encoding = 1; */
return gsmld_attach_gsm(tty, gsm);
}
@@ -2377,6 +2426,7 @@ static int gsmld_config(struct tty_struct *tty, struct gsm_mux *gsm,
gsm->mru = c->mru;
gsm->encoding = c->encapsulation;
gsm->adaption = c->adaption;
+ gsm->n2 = c->n2;
if (c->i == 1)
gsm->ftype = UIH;
--
1.7.0.4
_______________________________________________
Meego-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel