]> rtime.felk.cvut.cz Git - linux-lin.git/blobdiff - sllin/sllin.c
Merge branch 'master' of ssh://rtime.felk.cvut.cz/lisovros/pcan_lin
[linux-lin.git] / sllin / sllin.c
index cf387e7534e486c53d512f1d22666d9e938f408e..bfa5dc515336d2ea9b1df1f18c576a27c5172fe4 100644 (file)
@@ -114,7 +114,7 @@ struct sllin {
        char                    lin_master;     /* node is a master node */
        int                     lin_baud;       /* LIN baudrate */
        int                     lin_state;      /* state */
-       int                     id_to_sent;     /* there is ID to be sent */
+       int                     id_to_send;     /* there is ID to be sent */
 
        unsigned long           flags;          /* Flag values/ mode etc     */
 #define SLF_INUSE              0               /* Channel in use            */
@@ -123,7 +123,6 @@ struct sllin {
 #define SLF_TXEVENT            3               /* Tx wake event             */
 #define SLF_MSGEVENT           4               /* CAN message to sent       */
 
-       unsigned char           leased;
        dev_t                   line;
        struct task_struct      *kwthread;
        wait_queue_head_t       kwt_wq;
@@ -148,9 +147,15 @@ static int sltty_change_speed(struct tty_struct *tty, unsigned speed)
        int cflag;
 
        mutex_lock(&tty->termios_mutex);
+
        old_termios = *(tty->termios);
        cflag = tty->termios->c_cflag;
+       cflag &= ~(CBAUD | CIBAUD);
+       cflag |= BOTHER;
+       tty->termios->c_cflag = cflag;
+
        tty_encode_baud_rate(tty, speed, speed);
+
        if (tty->ops->set_termios)
                tty->ops->set_termios(tty, &old_termios);
        //priv->io.speed = speed;
@@ -249,7 +254,7 @@ static void sll_encaps(struct sllin *sl, struct can_frame *cf)
                pr_debug("sllin: %s() RTR CAN frame\n", __FUNCTION__);
                lframe[2] = (u8)cf->can_id; /* Get one byte LIN ID */
 
-               sltty_change_speed(tty, sl->lin_baud / 2);
+               sltty_change_speed(tty, sl->lin_baud * 2 / 3);
                tty->ops->write(tty, &lframe[0], 1);
                sltty_change_speed(tty, sl->lin_baud);
                tty->ops->write(tty, &lframe[1], 1);
@@ -302,14 +307,18 @@ static void sllin_write_wakeup(struct tty_struct *tty)
                actual = tty->ops->write(tty, sl->tx_buff + sl->tx_cnt, sl->tx_cnt - sl->tx_lim);
                sl->tx_cnt += actual;
 
-               if(sl->tx_cnt < sl->tx_lim)
+               if (sl->tx_cnt < sl->tx_lim) {
+                       printk(KERN_INFO "sllin_write_wakeup sent %d, remains %d, waiting\n",
+                               sl->tx_cnt, sl->tx_lim - sl->tx_cnt);
                        return;
+               }
        }
 
        clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
        set_bit(SLF_TXEVENT, &sl->flags);
        wake_up(&sl->kwt_wq);
 
+       printk(KERN_INFO "sllin_write_wakeup sent %d, wakeup\n", sl->tx_cnt);
 }
 
 /* Send a can_frame to a TTY queue. */
@@ -427,6 +436,8 @@ static void sllin_receive_buf(struct tty_struct *tty,
 {
        struct sllin *sl = (struct sllin *) tty->disc_data;
 
+       printk(KERN_INFO "sllin_receive_buf invoked\n");
+
        if (!sl || sl->magic != SLLIN_MAGIC || !netif_running(sl->dev))
                return;
 
@@ -435,6 +446,8 @@ static void sllin_receive_buf(struct tty_struct *tty,
                if (fp && *fp++) {
                        if (!test_and_set_bit(SLF_ERROR, &sl->flags))
                                sl->dev->stats.rx_errors++;
+                       printk(KERN_INFO "sllin_receive_buf char 0x%02x ignored due marker 0x%02x, flags 0x%lx\n",
+                               *cp, *(fp-1), sl->flags);
                        cp++;
                        continue;
                }
@@ -447,6 +460,9 @@ static void sllin_receive_buf(struct tty_struct *tty,
        if(sl->rx_cnt >= sl->rx_expect) {
                set_bit(SLF_RXEVENT, &sl->flags);
                wake_up(&sl->kwt_wq);
+               printk(KERN_INFO "sllin_receive_buf count %d, wakeup\n", sl->rx_cnt);
+       } else {
+               printk(KERN_INFO "sllin_receive_buf count %d, waiting\n", sl->rx_cnt);
        }
 }
 
@@ -470,10 +486,22 @@ int sllin_setup_msg(struct sllin *sl, int mode, int id,
        sl->tx_lim = SLLIN_BUFF_DATA;
 
        if ((data != NULL) && len) {
+               int i;
+               unsigned csum  = 0;
+
                sl->tx_lim += len;
                memcpy(sl->tx_buff + SLLIN_BUFF_DATA, data, len);
+               /* compute data parity there */
+               for (i = SLLIN_BUFF_DATA; i < sl->tx_lim; i++) {
+                       csum += sl->tx_buff[i];
+                       if (csum > 255)
+                               csum -= 255;
+               }
+
+               sl->tx_buff[sl->tx_lim++] = csum;
        }
-       sl->rx_lim += len;
+       if (len != 0)
+               sl->rx_lim += len + 1;
 
        return 0;
 }
@@ -505,8 +533,13 @@ int sllin_send_tx_buff(struct sllin *sl)
                        clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
                        return -1;
                }
+               
+               remains -= res;
+               sl->tx_cnt += res;
        }
-       sl->tx_cnt += res;
+
+       printk(KERN_INFO "sllin_send_tx_buff sent %d, remains %d\n",
+                       sl->tx_cnt, remains);
 
        return 0;
 }
@@ -517,7 +550,8 @@ int sllin_send_break(struct sllin *sl)
        unsigned long break_baud = sl->lin_baud;
        int res;
 
-       break_baud = (break_baud * 8) / 14;
+       //break_baud = (break_baud * 8) / 14;
+       break_baud /= 2;
 
        sltty_change_speed(tty, break_baud);
 
@@ -551,11 +585,12 @@ int sllin_kwthread(void *ptr)
        sltty_change_speed(tty, sl->lin_baud);
 
        sllin_setup_msg(sl, 0, 0x33, NULL, 0);
+       sl->id_to_send = 1;
 
        while (!kthread_should_stop()) {
 
                if ((sl->lin_state == SLSTATE_IDLE) && sl->lin_master &&
-                       sl->id_to_sent) {
+                       sl->id_to_send) {
                        if(sllin_send_break(sl)<0) {
                                /* error processing */
                        }
@@ -567,11 +602,11 @@ int sllin_kwthread(void *ptr)
                        test_bit(SLF_TXEVENT, &sl->flags));
 
                if (test_and_clear_bit(SLF_RXEVENT, &sl->flags)) {
-
+                       printk(KERN_INFO "sllin_kthread RXEVENT \n");
                }
 
                if (test_and_clear_bit(SLF_TXEVENT, &sl->flags)) {
-
+                       printk(KERN_INFO "sllin_kthread TXEVENT \n");
                }
 
                switch (sl->lin_state) {
@@ -585,6 +620,10 @@ int sllin_kwthread(void *ptr)
 
                                sl->lin_state = SLSTATE_ID_SENT;
 
+                               break;
+                       case SLSTATE_ID_SENT:
+                               sl->id_to_send = 0;
+                               sl->lin_state = SLSTATE_IDLE;
                                break;
                }
 
@@ -620,7 +659,7 @@ static void sll_sync(void)
                        break;
 
                sl = netdev_priv(dev);
-               if (sl->tty || sl->leased)
+               if (sl->tty)
                        continue;
                if (dev->flags & IFF_UP)
                        dev_close(dev);
@@ -794,8 +833,6 @@ static void sllin_close(struct tty_struct *tty)
 
        tty->disc_data = NULL;
        sl->tty = NULL;
-       if (!sl->leased)
-               sl->line = 0;
 
        /* Flush network side */
        unregister_netdev(sl->dev);