]> rtime.felk.cvut.cz Git - linux-lin.git/blobdiff - sllin/sllin.c
sllin: Select enhanced checksum mode according to the cache and SFF frame even for...
[linux-lin.git] / sllin / sllin.c
index 8d7ad6975ab08873245b423bd826552db438cae4..3437631c465b83a7569ad9cb1dddd6ab164d8c94 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)));
 
@@ -838,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)
@@ -872,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)));
 
@@ -988,6 +1013,7 @@ static int sllin_kwthread(void *ptr)
        struct sched_param schparam = { .sched_priority = 40 };
        int tx_bytes = 0; /* Used for Network statistics */
        unsigned long flags;
+       int mode;
        int lin_id;
        struct sllin_conf_entry *sce;
 
@@ -1058,8 +1084,12 @@ static int sllin_kwthread(void *ptr)
                        if (!test_bit(SLF_MSGEVENT, &sl->flags))
                                break;
 
+                       mode = 0;
                        cf = (struct can_frame *)sl->tx_req_skb->data;
 
+                       if (cf->can_id & LIN_CHECKSUM_EXTENDED)
+                               mode |= SLLIN_STPMSG_CHCKSUM_ENH;
+
                        /* SFF RTR CAN frame -> LIN header */
                        if (cf->can_id & CAN_RTR_FLAG) {
                                struct sllin_conf_entry *sce;
@@ -1069,6 +1099,8 @@ static int sllin_kwthread(void *ptr)
 
                                sce = &sl->linfr_cache[cf->can_id & LIN_ID_MASK];
                                spin_lock_irqsave(&sl->linfr_lock, flags);
+                               if (sce->frame_fl & LIN_CHECKSUM_EXTENDED)
+                                       mode |= SLLIN_STPMSG_CHCKSUM_ENH;
 
                                /* Is there Slave response in linfr_cache to be sent? */
                                if ((sce->frame_fl & LIN_CACHE_RESPONSE)
@@ -1089,9 +1121,15 @@ static int sllin_kwthread(void *ptr)
                                spin_unlock_irqrestore(&sl->linfr_lock, flags);
 
                        } else { /* SFF NON-RTR CAN frame -> LIN header + LIN response */
+                               struct sllin_conf_entry *sce;
+
                                netdev_dbg(sl->dev, "%s: NON-RTR SFF CAN frame, ID = %x\n",
                                        __func__, (int)cf->can_id & LIN_ID_MASK);
 
+                               sce = &sl->linfr_cache[cf->can_id & LIN_ID_MASK];
+                               if (sce->frame_fl & LIN_CHECKSUM_EXTENDED)
+                                       mode |= SLLIN_STPMSG_CHCKSUM_ENH;
+
                                lin_data = cf->data;
                                lin_dlc = cf->can_dlc;
                                if (lin_dlc > SLLIN_DATA_MAX)
@@ -1099,7 +1137,7 @@ static int sllin_kwthread(void *ptr)
                                tx_bytes = lin_dlc;
                        }
 
-                       if (sllin_setup_msg(sl, 0, cf->can_id & LIN_ID_MASK,
+                       if (sllin_setup_msg(sl, mode, cf->can_id & LIN_ID_MASK,
                                lin_data, lin_dlc) != -1) {
 
                                sl->id_to_send = true;
@@ -1217,7 +1255,6 @@ slstate_response_wait:
 
                        if ((sce->frame_fl & LIN_CACHE_RESPONSE)
                                        && (sce->dlc > 0)) {
-                               int mode;
 
                                netdev_dbg(sl->dev, "Sending LIN response from linfr_cache\n");
 
@@ -1337,7 +1374,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;