X-Git-Url: http://rtime.felk.cvut.cz/gitweb/linux-lin.git/blobdiff_plain/7be6ba578d92f4b9251293aee99b74adfbdef069..27f5e61b1ab9d29f1e5bc6d2676c747c488a94d8:/sllin/sllin.c diff --git a/sllin/sllin.c b/sllin/sllin.c index 011743e..bb30cf3 100644 --- a/sllin/sllin.c +++ b/sllin/sllin.c @@ -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; @@ -234,49 +239,49 @@ static void sll_bump(struct sllin *sl) /* Convert particular CAN frame into LIN frame and send it to TTY queue. */ static void sll_encaps(struct sllin *sl, struct can_frame *cf) { - int actual, idx, i; - char lframe[16] = {0x00, 0x55}; /* Fake break, Sync byte */ - struct tty_struct *tty = sl->tty; - - pr_debug("sllin: %s() invoked\n", __FUNCTION__); - - /* We do care only about SFF frames */ - if (cf->can_id & CAN_EFF_FLAG) - return; - - /* Send only header */ - if (cf->can_id & CAN_RTR_FLAG) { - 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); - tty->ops->write(tty, &lframe[0], 1); - sltty_change_speed(tty, sl->lin_baud); - tty->ops->write(tty, &lframe[1], 1); - tty->ops->write(tty, &lframe[2], 1); - } else { - pr_debug("sllin: %s() non-RTR CAN frame\n", __FUNCTION__); - /* idx = strlen(sl->xbuff); - - for (i = 0; i < cf->can_dlc; i++) - sprintf(&sl->xbuff[idx + 2*i], "%02X", cf->data[i]); - - * Order of next two lines is *very* important. - * When we are sending a little amount of data, - * the transfer may be completed inside the ops->write() - * routine, because it's running with interrupts enabled. - * In this case we *never* got WRITE_WAKEUP event, - * if we did not request it before write operation. - * 14 Oct 1994 Dmitry Gorodchanin. - - set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags); - actual = sl->tty->ops->write(sl->tty, sl->xbuff, strlen(sl->xbuff)); - sl->xleft = strlen(sl->xbuff) - actual; - sl->xhead = sl->xbuff + actual; - sl->dev->stats.tx_bytes += cf->can_dlc; - */ - } - +// int actual, idx, i; +// char lframe[16] = {0x00, 0x55}; /* Fake break, Sync byte */ +// struct tty_struct *tty = sl->tty; +// +// pr_debug("sllin: %s() invoked\n", __FUNCTION__); +// +// /* We do care only about SFF frames */ +// if (cf->can_id & CAN_EFF_FLAG) +// return; +// +// /* Send only header */ +// if (cf->can_id & CAN_RTR_FLAG) { +// 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 / 3); +// tty->ops->write(tty, &lframe[0], 1); +// sltty_change_speed(tty, sl->lin_baud); +// tty->ops->write(tty, &lframe[1], 1); +// tty->ops->write(tty, &lframe[2], 1); +// } else { +// pr_debug("sllin: %s() non-RTR CAN frame\n", __FUNCTION__); +// /* idx = strlen(sl->xbuff); +// +// for (i = 0; i < cf->can_dlc; i++) +// sprintf(&sl->xbuff[idx + 2*i], "%02X", cf->data[i]); +// +// * Order of next two lines is *very* important. +// * When we are sending a little amount of data, +// * the transfer may be completed inside the ops->write() +// * routine, because it's running with interrupts enabled. +// * In this case we *never* got WRITE_WAKEUP event, +// * if we did not request it before write operation. +// * 14 Oct 1994 Dmitry Gorodchanin. +// +// set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags); +// actual = sl->tty->ops->write(sl->tty, sl->xbuff, strlen(sl->xbuff)); +// sl->xleft = strlen(sl->xbuff) - actual; +// sl->xhead = sl->xbuff + actual; +// sl->dev->stats.tx_bytes += cf->can_dlc; +// */ +// } +// } /* @@ -290,8 +295,8 @@ static void sllin_write_wakeup(struct tty_struct *tty) struct sllin *sl = (struct sllin *) tty->disc_data; /* First make sure we're connected. */ - if (!sl || sl->magic != SLLIN_MAGIC || !netif_running(sl->dev)) - return; + //if (!sl || sl->magic != SLLIN_MAGIC || !netif_running(sl->dev)) + // return; if (sl->lin_state != SLSTATE_BREAK_SENT) remains = sl->tx_lim - sl->tx_cnt; @@ -433,14 +438,16 @@ static void sllin_receive_buf(struct tty_struct *tty, printk(KERN_INFO "sllin_receive_buf invoked\n"); - if (!sl || sl->magic != SLLIN_MAGIC || !netif_running(sl->dev)) - return; + //if (!sl || sl->magic != SLLIN_MAGIC || !netif_running(sl->dev)) + // return; /* Read the characters out of the buffer */ while (count--) { 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; } @@ -541,23 +548,41 @@ int sllin_send_break(struct sllin *sl) { struct tty_struct *tty = sl->tty; unsigned long break_baud = sl->lin_baud; - int res; - - //break_baud = (break_baud * 8) / 14; - break_baud /= 2; + spinlock_t mr_lock = SPIN_LOCK_UNLOCKED; + unsigned long flags; + int retval; +#if 0 + break_baud = ((break_baud * 2) / 3); sltty_change_speed(tty, break_baud); sl->rx_expect = SLLIN_BUFF_BREAK + 1; - sl->lin_state = SLSTATE_BREAK_SENT; - res = sllin_send_tx_buff(sl); - if (res < 0) { + retval = sllin_send_tx_buff(sl); + if (retval < 0) { sl->lin_state = SLSTATE_IDLE; return res; } +#else + /* Do the break ourselves; Inspired by + http://lxr.linux.no/#linux+v3.1.2/drivers/tty/tty_io.c#L2452 */ + + spin_lock_irqsave(&mr_lock, flags); + retval = tty->ops->break_ctl(tty, -1); + if (retval) + goto out; + udelay(712); + //usleep_range(650, 750); + + retval = tty->ops->break_ctl(tty, 0); +out: + spin_unlock_irqrestore(&mr_lock, flags); + + sl->lin_state = SLSTATE_BREAK_SENT; +#endif + //return retval; return 0; } @@ -607,7 +632,7 @@ int sllin_kwthread(void *ptr) if (sl->rx_cnt <= SLLIN_BUFF_BREAK) continue; - res = sltty_change_speed(tty, sl->lin_baud); + //res = sltty_change_speed(tty, sl->lin_baud); sllin_send_tx_buff(sl); @@ -652,7 +677,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); @@ -765,7 +790,7 @@ static int sllin_open(struct tty_struct *tty) sl->tx_cnt = 0; sl->tx_lim = 0; - sl->lin_baud = 2400; + sl->lin_baud = 19200; sl->lin_master = 1; sl->lin_state = SLSTATE_IDLE; @@ -826,8 +851,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);