X-Git-Url: http://rtime.felk.cvut.cz/gitweb/linux-lin.git/blobdiff_plain/869fb1f62714fcde79938ef8e5030aec986431bc..1e920bfd0d3f0f9f5a4998ee8f8551e721354271:/sllin/sllin.c diff --git a/sllin/sllin.c b/sllin/sllin.c index cf387e7..d177f54 100644 --- a/sllin/sllin.c +++ b/sllin/sllin.c @@ -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 */ @@ -148,9 +148,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 +255,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 +308,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 +437,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 +447,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 +461,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 +487,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 +534,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 +551,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 +586,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 +603,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 +621,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; }