#include <linux/can.h>
#include <linux/kthread.h>
#include <linux/hrtimer.h>
+#include <linux/version.h>
#include "linux/lin_bus.h"
/* Should be in include/linux/tty.h */
*/
static int sltty_change_speed(struct tty_struct *tty, unsigned speed)
{
- struct ktermios old_termios;
+ struct ktermios old_termios, termios;
int cflag;
mutex_lock(&tty->termios_mutex);
- old_termios = *(tty->termios);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)
+ old_termios = termios = *(tty->termios);
+#else
+ old_termios = termios = tty->termios;
+#endif
cflag = CS8 | CREAD | CLOCAL | HUPCL;
cflag &= ~(CBAUD | CIBAUD);
cflag |= BOTHER;
- tty->termios->c_cflag = cflag;
- tty->termios->c_oflag = 0;
- tty->termios->c_lflag = 0;
+ termios.c_cflag = cflag;
+ termios.c_oflag = 0;
+ termios.c_lflag = 0;
/* Enable interrupt when UART-Break or Framing error received */
- tty->termios->c_iflag = BRKINT | INPCK;
+ termios.c_iflag = BRKINT | INPCK;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)
+ *(tty->termios) = termios;
+#else
+ tty->termios = termios;
+#endif
tty_encode_baud_rate(tty, speed, speed);
sl->lin_state = SLSTATE_ID_RECEIVED;
/* Is the length of data set in frame cache? */
- if (sce->frame_fl & LIN_CACHE_RESPONSE) {
+ if (sce->dlc > 0) {
sl->rx_expect += sce->dlc + 1; /* + checksum */
sl->rx_len_unknown = false;
- set_bit(SLF_MSGEVENT, &sl->flags);
wake_up(&sl->kwt_wq);
} else {
sl->rx_expect += SLLIN_DATA_MAX + 1; /* + checksum */
{
struct sllin *sl = container_of(hrtimer, struct sllin, rx_timer);
- if (sl->lin_master) {
+ /*
+ * Signal timeout when:
+ * master: We did not receive as much characters as expected
+ * slave: * we did not receive any data bytes at all
+ * * we know the length and didn't receive enough
+ */
+ if ((sl->lin_master) ||
+ (sl->rx_cnt <= SLLIN_BUFF_DATA) ||
+ ((!sl->rx_len_unknown) &&
+ (sl->rx_cnt < sl->rx_expect))) {
sllin_report_error(sl, LIN_ERR_RX_TIMEOUT);
set_bit(SLF_TMOUTEVENT, &sl->flags);
} else {
test_bit(SLF_TXEVENT, &sl->flags) ||
test_bit(SLF_TMOUTEVENT, &sl->flags) ||
test_bit(SLF_ERROR, &sl->flags) ||
+ (sl->lin_state == SLSTATE_ID_RECEIVED) ||
(((sl->lin_state == SLSTATE_IDLE) ||
- (sl->lin_state == SLSTATE_RESPONSE_WAIT) ||
- (sl->lin_state == SLSTATE_ID_RECEIVED))
+ (sl->lin_state == SLSTATE_RESPONSE_WAIT))
&& test_bit(SLF_MSGEVENT, &sl->flags)));
if (test_and_clear_bit(SLF_RXEVENT, &sl->flags)) {
spin_lock_irqsave(&sl->linfr_lock, flags);
if ((sce->frame_fl & LIN_CACHE_RESPONSE)
- && (sce->dlc > 0)
- && (test_bit(SLF_MSGEVENT, &sl->flags))) {
+ && (sce->dlc > 0)) {
int mode;
netdev_dbg(sl->dev, "Sending LIN response from linfr_cache\n");
tx_bytes = lin_dlc;
mode = SLLIN_STPMSG_RESPONLY;
- if (sl->rx_buff[SLLIN_BUFF_ID] & LIN_CHECKSUM_EXTENDED)
+ if (sce->frame_fl & LIN_CHECKSUM_EXTENDED)
mode |= SLLIN_STPMSG_CHCKSUM_ENH;
if (sllin_setup_msg(sl, mode, lin_id & LIN_ID_MASK,
sllin_send_tx_buff(sl);
}
- clear_bit(SLF_MSGEVENT, &sl->flags);
- kfree_skb(sl->tx_req_skb);
- netif_wake_queue(sl->dev);
hrtimer_start(&sl->rx_timer,
ktime_add(ktime_get(), sl->rx_timer_timeout),
HRTIMER_MODE_ABS);