#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;
/* 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 / 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;
- */
- }
-
+// 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;
+// */
+// }
+//
}
/*
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;
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--) {
{
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;
}
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);
break;
sl = netdev_priv(dev);
- if (sl->tty || sl->leased)
+ if (sl->tty)
continue;
if (dev->flags & IFF_UP)
dev_close(dev);
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;
tty->disc_data = NULL;
sl->tty = NULL;
- if (!sl->leased)
- sl->line = 0;
/* Flush network side */
unregister_netdev(sl->dev);