]> rtime.felk.cvut.cz Git - linux-lin.git/blobdiff - sllin/sllin.c
Update for changes in recent linux kernels
[linux-lin.git] / sllin / sllin.c
index ffbdf0133b65330f2876af45c418ad19d0b32283..2db896fd8e812da8bd1f535862e3ae98e76d4f1a 100644 (file)
@@ -210,7 +210,11 @@ static int sltty_change_speed(struct tty_struct *tty, unsigned speed)
        struct ktermios old_termios, termios;
        int cflag;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
        mutex_lock(&tty->termios_mutex);
+#else
+       down_write(&tty->termios_rwsem);
+#endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)
        old_termios = termios = *(tty->termios);
@@ -238,7 +242,11 @@ static int sltty_change_speed(struct tty_struct *tty, unsigned speed)
        if (tty->ops->set_termios)
                tty->ops->set_termios(tty, &old_termios);
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
        mutex_unlock(&tty->termios_mutex);
+#else
+       up_write(&tty->termios_rwsem);
+#endif
 
        return 0;
 }
@@ -311,7 +319,12 @@ static void sllin_write_wakeup(struct tty_struct *tty)
                        return; /* ongoing concurrent processing */
 
                clear_bit(SLF_TXBUFF_RQ, &sl->flags);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
                smp_mb__after_clear_bit();
+#else
+               smp_mb__after_atomic();
+#endif
 
                if (sl->lin_state != SLSTATE_BREAK_SENT)
                        remains = sl->tx_lim - sl->tx_cnt;
@@ -325,7 +338,11 @@ static void sllin_write_wakeup(struct tty_struct *tty)
                        remains -= actual;
                }
                clear_bit(SLF_TXBUFF_INPR, &sl->flags);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
                smp_mb__after_clear_bit();
+#else
+               smp_mb__after_atomic();
+#endif
 
        } while (unlikely(test_bit(SLF_TXBUFF_RQ, &sl->flags)));
 
@@ -517,6 +534,9 @@ static void sllin_master_receive_buf(struct tty_struct *tty,
  */
 static void sllin_report_error(struct sllin *sl, int err)
 {
+       unsigned char *lin_buff;
+       int lin_id;
+
        switch (err) {
        case LIN_ERR_CHECKSUM:
                sl->dev->stats.rx_crc_errors++;
@@ -531,7 +551,9 @@ static void sllin_report_error(struct sllin *sl, int err)
                break;
        }
 
-       sllin_send_canfr(sl, 0 | CAN_EFF_FLAG |
+       lin_buff = (sl->lin_master) ? sl->tx_buff : sl->rx_buff;
+       lin_id = lin_buff[SLLIN_BUFF_ID] & LIN_ID_MASK;
+       sllin_send_canfr(sl, lin_id | CAN_EFF_FLAG |
                (err & ~LIN_ID_MASK), NULL, 0);
 }
 
@@ -711,10 +733,12 @@ static void sllin_slave_receive_buf(struct tty_struct *tty,
                if (fp && *fp++) {
                        /*
                         * If we don't know the length of the current message
-                        * we received the break of the next message.
-                        * Evaluate the previous one before continuing
+                        * and received at least the LIN ID, we received here
+                        * the break of the next message.
+                        * Evaluate the previous one before continuing.
                         */
-                       if (sl->rx_len_unknown == true)
+                       if ((sl->rx_len_unknown == true) &&
+                               (sl->rx_cnt >= SLLIN_BUFF_ID))
                        {
                                hrtimer_cancel(&sl->rx_timer);
                                sllin_slave_finish_rx_msg(sl);
@@ -831,7 +855,11 @@ static int sllin_send_tx_buff(struct sllin *sl)
                        return 0;       /* ongoing concurrent processing */
 
                clear_bit(SLF_TXBUFF_RQ, &sl->flags);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
                smp_mb__after_clear_bit();
+#else
+               smp_mb__after_atomic();
+#endif
 
 #ifdef BREAK_BY_BAUD
                if (sl->lin_state != SLSTATE_BREAK_SENT)
@@ -865,7 +893,11 @@ static int sllin_send_tx_buff(struct sllin *sl)
                                sl->tx_cnt, remains);
 
                clear_bit(SLF_TXBUFF_INPR, &sl->flags);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
                smp_mb__after_clear_bit();
+#else
+               smp_mb__after_atomic();
+#endif
 
        } while (unlikely(test_bit(SLF_TXBUFF_RQ, &sl->flags)));
 
@@ -1241,8 +1273,6 @@ slstate_response_wait:
                                        sllin_send_tx_buff(sl);
                                }
 
-                               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);
@@ -1332,7 +1362,12 @@ static struct sllin *sll_alloc(dev_t line)
                char name[IFNAMSIZ];
                sprintf(name, "sllin%d", i);
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0))
                dev = alloc_netdev(sizeof(*sl), name, sll_setup);
+#else
+               dev = alloc_netdev(sizeof(*sl), name, NET_NAME_UNKNOWN, sll_setup);
+#endif
+
                if (!dev)
                        return NULL;
                dev->base_addr  = i;