X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=module%2Fcan327.c;h=82dbc668271e21f4696f1c9de7eb812d3cc4347b;hb=bff8a2dbb84c74b59099bd4b39d6ea43a9aebea3;hp=0ff377ab319710dd3b967ed8f4a951af7be869f0;hpb=850314679973283af02d1dc802c4670ca3350cdd;p=elmcan.git diff --git a/module/can327.c b/module/can327.c index 0ff377a..82dbc66 100644 --- a/module/can327.c +++ b/module/can327.c @@ -14,14 +14,10 @@ #include #include -#include -#include #include #include -#include #include -#include #include #include #include @@ -39,7 +35,6 @@ #include #include #include -#include #include /* Line discipline ID number. @@ -57,8 +52,8 @@ #define ELM327_NAPI_WEIGHT 4 -#define ELM327_SIZE_RXBUF 224 #define ELM327_SIZE_TXBUF 32 +#define ELM327_SIZE_RXBUF 1024 #define ELM327_CAN_CONFIG_SEND_SFF 0x8000 #define ELM327_CAN_CONFIG_VARIABLE_DLC 0x4000 @@ -89,8 +84,8 @@ struct can327 { struct can_rx_offload offload; /* TTY buffers */ - u8 rxbuf[ELM327_SIZE_RXBUF]; u8 txbuf[ELM327_SIZE_TXBUF]; + u8 rxbuf[ELM327_SIZE_RXBUF]; /* Per-channel lock */ spinlock_t lock; @@ -260,7 +255,7 @@ static void elm327_init(struct can327 *elm) elm->drop_next_line = 0; /* We can only set the bitrate as a fraction of 500000. - * The bit timing constants in can327_bittiming_const will + * The bitrates listed in can327_bitrate_const will * limit the user to the right values. */ elm->can_bitrate_divisor = 500000 / elm->can.bittiming.bitrate; @@ -444,6 +439,7 @@ static int elm327_parse_frame(struct can327 *elm, size_t len) /* The line is likely garbled anyway, so bail. * The main code will restart listening. */ + kfree_skb(skb); return -ENODATA; } @@ -462,6 +458,7 @@ static int elm327_parse_frame(struct can327 *elm, size_t len) /* This is not a well-formatted data line. * Assume it's an error message. */ + kfree_skb(skb); return -ENODATA; } @@ -469,6 +466,7 @@ static int elm327_parse_frame(struct can327 *elm, size_t len) /* The line is too short to be a valid frame hex dump. * Something interrupted the hex dump or it is invalid. */ + kfree_skb(skb); return -ENODATA; } @@ -520,6 +518,7 @@ static int elm327_parse_frame(struct can327 *elm, size_t len) * However, this will correctly drop the state machine back into * command mode. */ + kfree_skb(skb); return -ENODATA; } @@ -682,10 +681,9 @@ static void elm327_drop_bytes(struct can327 *elm, size_t i) elm->rxfill -= i; } -static void elm327_parse_rxbuf(struct can327 *elm) +static void elm327_parse_rxbuf(struct can327 *elm, size_t first_new_char_idx) { - size_t len; - int i; + size_t len, pos; lockdep_assert_held(&elm->lock); @@ -696,20 +694,20 @@ static void elm327_parse_rxbuf(struct can327 *elm) case ELM327_STATE_GETDUMMYCHAR: /* Wait for 'y' or '>' */ - for (i = 0; i < elm->rxfill; i++) { - if (elm->rxbuf[i] == ELM327_DUMMY_CHAR) { + for (pos = 0; pos < elm->rxfill; pos++) { + if (elm->rxbuf[pos] == ELM327_DUMMY_CHAR) { elm327_send(elm, "\r", 1); elm->state = ELM327_STATE_GETPROMPT; - i++; + pos++; break; - } else if (elm327_is_ready_char(elm->rxbuf[i])) { + } else if (elm327_is_ready_char(elm->rxbuf[pos])) { elm327_send(elm, ELM327_DUMMY_STRING, 1); - i++; + pos++; break; } } - elm327_drop_bytes(elm, i); + elm327_drop_bytes(elm, pos); break; case ELM327_STATE_GETPROMPT: @@ -722,7 +720,7 @@ static void elm327_parse_rxbuf(struct can327 *elm) case ELM327_STATE_RECEIVING: /* Find delimiting feedback lines. */ - len = 0; + len = first_new_char_idx; while (len < elm->rxfill && elm->rxbuf[len] != '\r') len++; @@ -756,13 +754,23 @@ static void elm327_parse_rxbuf(struct can327 *elm) /* More data to parse? */ if (elm->rxfill) - elm327_parse_rxbuf(elm); + elm327_parse_rxbuf(elm, 0); } } } #if LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0) /* Dummy needed to use can_rx_offload */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,5,0) +static unsigned int *can327_mailbox_read(struct can_rx_offload *offload, + struct can_frame *cf, + u32 *timestamp, unsigned int n) +{ + WARN_ON_ONCE(1); /* This function is a dummy, so don't call it! */ + + return -ENOBUFS; +} +#else /* Since 4e9c9484b085 (included in v5.5) */ static struct sk_buff *can327_mailbox_read(struct can_rx_offload *offload, unsigned int n, u32 *timestamp, bool drop) @@ -772,6 +780,7 @@ static struct sk_buff *can327_mailbox_read(struct can_rx_offload *offload, return ERR_PTR(-ENOBUFS); } #endif +#endif static int can327_netdev_open(struct net_device *dev) { @@ -815,7 +824,6 @@ static int can327_netdev_open(struct net_device *dev) can_rx_offload_enable(&elm->offload); - can_led_event(dev, CAN_LED_EVENT_OPEN); elm->can.state = CAN_STATE_ERROR_ACTIVE; netif_start_queue(dev); @@ -841,7 +849,6 @@ static int can327_netdev_close(struct net_device *dev) elm->can.state = CAN_STATE_STOPPED; can_rx_offload_del(&elm->offload); close_candev(dev); - can_led_event(dev, CAN_LED_EVENT_STOP); return 0; } @@ -880,9 +887,7 @@ static netdev_tx_t can327_netdev_start_xmit(struct sk_buff *skb, spin_unlock(&elm->lock); dev->stats.tx_packets++; - dev->stats.tx_bytes += frame->len; - - can_led_event(dev, CAN_LED_EVENT_TX); + dev->stats.tx_bytes += frame->can_id & CAN_RTR_FLAG ? 0 : frame->len; out: kfree_skb(skb); @@ -896,20 +901,30 @@ static const struct net_device_ops can327_netdev_ops = { .ndo_change_mtu = can_change_mtu, }; -static bool can327_is_valid_rx_char(char c) +static bool can327_is_valid_rx_char(u8 c) { - return (isdigit(c) || - isupper(c) || - c == ELM327_DUMMY_CHAR || - c == ELM327_READY_CHAR || - c == '<' || - c == 'a' || - c == 'b' || - c == 'v' || - c == '.' || - c == '?' || - c == '\r' || - c == ' '); + static const bool lut_char_is_valid['z'] = { + ['\r'] = true, + [' '] = true, + ['.'] = true, + ['0'] = true, true, true, true, true, + ['5'] = true, true, true, true, true, + ['<'] = true, + [ELM327_READY_CHAR] = true, + ['?'] = true, + ['A'] = true, true, true, true, true, true, true, + ['H'] = true, true, true, true, true, true, true, + ['O'] = true, true, true, true, true, true, true, + ['V'] = true, true, true, true, true, + ['a'] = true, + ['b'] = true, + ['v'] = true, + [ELM327_DUMMY_CHAR] = true, + }; + BUILD_BUG_ON(ELM327_DUMMY_CHAR >= 'z'); + + return (c < ARRAY_SIZE(lut_char_is_valid) && + lut_char_is_valid[c]); } /* Handle incoming ELM327 ASCII data. @@ -925,12 +940,18 @@ static void can327_ldisc_rx(struct tty_struct *tty, #endif { struct can327 *elm = (struct can327 *)tty->disc_data; + size_t first_new_char_idx; if (elm->uart_side_failure) return; spin_lock_bh(&elm->lock); + /* Store old rxfill, so elm327_parse_rxbuf() will have + * the option of skipping already checked characters. + */ + first_new_char_idx = elm->rxfill; + while (count-- && elm->rxfill < ELM327_SIZE_RXBUF) { if (fp && *fp++) { netdev_err(elm->dev, "Error in received character stream. Check your wiring."); @@ -967,7 +988,7 @@ static void can327_ldisc_rx(struct tty_struct *tty, } if (count >= 0) { - netdev_err(elm->dev, "Receive buffer overflowed. Bad chip or wiring?"); + netdev_err(elm->dev, "Receive buffer overflowed. Bad chip or wiring? count = %i", count); elm327_uart_side_failure(elm); @@ -975,7 +996,7 @@ static void can327_ldisc_rx(struct tty_struct *tty, return; } - elm327_parse_rxbuf(elm); + elm327_parse_rxbuf(elm, first_new_char_idx); spin_unlock_bh(&elm->lock); } @@ -1026,7 +1047,7 @@ static void can327_ldisc_tx_wakeup(struct tty_struct *tty) * or 7/8 of that. Divisors are 1 to 64. * Currently we don't implement support for 7/8 rates. */ -static const u32 can327_bitrate_const[64] = { +static const u32 can327_bitrate_const[] = { 7812, 7936, 8064, 8196, 8333, 8474, 8620, 8771, 8928, 9090, 9259, 9433, 9615, 9803, 10000, 10204, 10416, 10638, 10869, 11111, 11363, 11627, 11904, 12195, @@ -1079,8 +1100,6 @@ static int can327_ldisc_open(struct tty_struct *tty) elm->tty = tty; tty->disc_data = elm; - devm_can_led_init(elm->dev); - /* Let 'er rip */ err = register_candev(elm->dev); if (err) {