X-Git-Url: http://rtime.felk.cvut.cz/gitweb/linux-lin.git/blobdiff_plain/e2414b4fbb15520fe38c8319e5fb7c3fe5e1b679..12611a51fc163174a95c5d1df02edf7a85a17f04:/sllin/sllin.c diff --git a/sllin/sllin.c b/sllin/sllin.c index 3e020b1..ffbdf01 100644 --- a/sllin/sllin.c +++ b/sllin/sllin.c @@ -62,6 +62,7 @@ #include #include #include +#include #include "linux/lin_bus.h" /* Should be in include/linux/tty.h */ @@ -206,22 +207,31 @@ const unsigned char sllin_id_parity_table[] = { */ 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); @@ -758,10 +768,9 @@ static void sllin_slave_receive_buf(struct tty_struct *tty, 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 */ @@ -940,7 +949,16 @@ static enum hrtimer_restart sllin_rx_timeout_handler(struct hrtimer *hrtimer) { 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 { @@ -991,9 +1009,9 @@ static int sllin_kwthread(void *ptr) 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)) { @@ -1191,8 +1209,7 @@ slstate_response_wait: 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"); @@ -1206,7 +1223,7 @@ slstate_response_wait: 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, @@ -1224,7 +1241,6 @@ slstate_response_wait: 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,