#include <linux/delay.h>
#include <linux/init.h>
#include <linux/can.h>
+#include <linux/kthread.h>
/* Should be in include/linux/tty.h */
#define N_SLLIN 25
unsigned char leased;
dev_t line;
- pid_t pid;
+ struct task_struct *kwthread;
+ wait_queue_head_t kwt_wq;
};
static struct net_device **sllin_devs;
/* Send only header */
if (cf->can_id & CAN_RTR_FLAG) {
- pr_debug("sllin: RTR CAN frame\n", __FUNCTION__);
+ pr_debug("sllin: %s() RTR CAN frame\n", __FUNCTION__);
lframe[2] = (u8)cf->can_id; /* Get one byte LIN ID */
sltty_change_speed(tty, 1200);
tty->ops->write(tty, &lframe[1], 1);
tty->ops->write(tty, &lframe[2], 1);
} else {
- pr_debug("sllin: non-RTR CAN frame\n", __FUNCTION__);
+ pr_debug("sllin: %s() non-RTR CAN frame\n", __FUNCTION__);
/* idx = strlen(sl->xbuff);
for (i = 0; i < cf->can_dlc; i++)
}
}
+/*****************************************
+ * sllin_kwthread - kernel worker thread
+ *****************************************/
+
+int sllin_kwthread(void *ptr)
+{
+ struct sllin *sl = (struct sllin *)ptr;
+
+ printk(KERN_INFO "sllin: sllin_kwthread started.\n");
+
+ while (!kthread_should_stop()) {
+
+ wait_event_killable(sl->kwt_wq, kthread_should_stop());
+
+ }
+
+ printk(KERN_INFO "sllin: sllin_kwthread stopped.\n");
+
+ return 0;
+}
+
+
/************************************
* sllin_open helper routines.
************************************/
sl->tty = tty;
tty->disc_data = sl;
sl->line = tty_devnum(tty);
- sl->pid = current->pid;
if (!test_bit(SLF_INUSE, &sl->flags)) {
/* Perform the low-level SLLIN initialization. */
set_bit(SLF_INUSE, &sl->flags);
+ init_waitqueue_head(&sl->kwt_wq);
+ sl->kwthread = kthread_run(sllin_kwthread, sl, "sllin");
+ if (sl->kwthread == NULL)
+ goto err_free_chan;
+
err = register_netdevice(sl->dev);
if (err)
- goto err_free_chan;
+ goto err_free_chan_and_thread;
}
/* Done. We have linked the TTY line to a channel. */
/* TTY layer expects 0 on success */
return 0;
+err_free_chan_and_thread:
+ kthread_stop(sl->kwthread);
+ sl->kwthread = NULL;
+
err_free_chan:
sl->tty = NULL;
tty->disc_data = NULL;
if (!sl || sl->magic != SLLIN_MAGIC || sl->tty != tty)
return;
+ kthread_stop(sl->kwthread);
+ sl->kwthread = NULL;
+
tty->disc_data = NULL;
sl->tty = NULL;
if (!sl->leased)