diff options
Diffstat (limited to 'drivers/net/can/slcan/slcan-core.c')
| -rw-r--r-- | drivers/net/can/slcan/slcan-core.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c index f4db77007c13..cd789e178d34 100644 --- a/drivers/net/can/slcan/slcan-core.c +++ b/drivers/net/can/slcan/slcan-core.c @@ -71,12 +71,21 @@ MODULE_AUTHOR("Dario Binacchi <dario.binacchi@amarulasolutions.com>"); #define SLCAN_CMD_LEN 1 #define SLCAN_SFF_ID_LEN 3 #define SLCAN_EFF_ID_LEN 8 +#define SLCAN_DATA_LENGTH_LEN 1 +#define SLCAN_ERROR_LEN 1 #define SLCAN_STATE_LEN 1 #define SLCAN_STATE_BE_RXCNT_LEN 3 #define SLCAN_STATE_BE_TXCNT_LEN 3 -#define SLCAN_STATE_FRAME_LEN (1 + SLCAN_CMD_LEN + \ - SLCAN_STATE_BE_RXCNT_LEN + \ - SLCAN_STATE_BE_TXCNT_LEN) +#define SLCAN_STATE_MSG_LEN (SLCAN_CMD_LEN + \ + SLCAN_STATE_LEN + \ + SLCAN_STATE_BE_RXCNT_LEN + \ + SLCAN_STATE_BE_TXCNT_LEN) +#define SLCAN_ERROR_MSG_LEN_MIN (SLCAN_CMD_LEN + \ + SLCAN_ERROR_LEN + \ + SLCAN_DATA_LENGTH_LEN) +#define SLCAN_FRAME_MSG_LEN_MIN (SLCAN_CMD_LEN + \ + SLCAN_SFF_ID_LEN + \ + SLCAN_DATA_LENGTH_LEN) struct slcan { struct can_priv can; @@ -176,6 +185,9 @@ static void slcan_bump_frame(struct slcan *sl) u32 tmpid; char *cmd = sl->rbuff; + if (sl->rcount < SLCAN_FRAME_MSG_LEN_MIN) + return; + skb = alloc_can_skb(sl->dev, &cf); if (unlikely(!skb)) { sl->dev->stats.rx_dropped++; @@ -281,7 +293,7 @@ static void slcan_bump_state(struct slcan *sl) return; } - if (state == sl->can.state || sl->rcount < SLCAN_STATE_FRAME_LEN) + if (state == sl->can.state || sl->rcount != SLCAN_STATE_MSG_LEN) return; cmd += SLCAN_STATE_BE_RXCNT_LEN + SLCAN_CMD_LEN + 1; @@ -328,6 +340,9 @@ static void slcan_bump_err(struct slcan *sl) bool rx_errors = false, tx_errors = false, rx_over_errors = false; int i, len; + if (sl->rcount < SLCAN_ERROR_MSG_LEN_MIN) + return; + /* get len from sanitized ASCII value */ len = cmd[1]; if (len >= '0' && len < '9') @@ -456,8 +471,7 @@ static void slcan_bump(struct slcan *sl) static void slcan_unesc(struct slcan *sl, unsigned char s) { if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */ - if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && - sl->rcount > 4) + if (!test_and_clear_bit(SLF_ERROR, &sl->flags)) slcan_bump(sl); sl->rcount = 0; @@ -583,7 +597,7 @@ static void slcan_transmit(struct work_struct *work) */ static void slcan_write_wakeup(struct tty_struct *tty) { - struct slcan *sl = (struct slcan *)tty->disc_data; + struct slcan *sl = tty->disc_data; schedule_work(&sl->tx_work); } @@ -760,7 +774,6 @@ static const struct net_device_ops slcan_netdev_ops = { .ndo_open = slcan_netdev_open, .ndo_stop = slcan_netdev_close, .ndo_start_xmit = slcan_netdev_xmit, - .ndo_change_mtu = can_change_mtu, }; /****************************************** @@ -774,11 +787,10 @@ static const struct net_device_ops slcan_netdev_ops = { * be re-entered while running but other ldisc functions may be called * in parallel */ -static void slcan_receive_buf(struct tty_struct *tty, - const unsigned char *cp, const char *fp, - int count) +static void slcan_receive_buf(struct tty_struct *tty, const u8 *cp, + const u8 *fp, size_t count) { - struct slcan *sl = (struct slcan *)tty->disc_data; + struct slcan *sl = tty->disc_data; if (!netif_running(sl->dev)) return; @@ -862,7 +874,7 @@ static int slcan_open(struct tty_struct *tty) */ static void slcan_close(struct tty_struct *tty) { - struct slcan *sl = (struct slcan *)tty->disc_data; + struct slcan *sl = tty->disc_data; unregister_candev(sl->dev); @@ -886,7 +898,7 @@ static void slcan_close(struct tty_struct *tty) static int slcan_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - struct slcan *sl = (struct slcan *)tty->disc_data; + struct slcan *sl = tty->disc_data; unsigned int tmp; switch (cmd) { |
