]> rtime.felk.cvut.cz Git - linux-lin.git/blobdiff - sllin/sllin.c
sllin: Very basic LIN bus monitoring feature.
[linux-lin.git] / sllin / sllin.c
index 2e3a1c33bdf73462949755e76aed9ecd12af57cd..baa8203fbdd1fadfdcd47b4f3e57b08557eae9e7 100644 (file)
@@ -80,6 +80,14 @@ MODULE_AUTHOR("Pavel Pisa <pisa@cmp.felk.cvut.cz>");
 #define SLLIN_MAGIC            0x53CA
 /* #define BREAK_BY_BAUD */
 
+static int master = true;
+static int baudrate = 0; /* Use LIN_DEFAULT_BAUDRATE when not set */
+
+module_param(master, bool, 0);
+MODULE_PARM_DESC(master, "LIN interface is Master device");
+module_param(baudrate, int, 0);
+MODULE_PARM_DESC(baudrate, "Baudrate of LIN interface");
+
 static int maxdev = 10;                /* MAX number of SLLIN channels;
                                   This can be overridden with
                                   insmod sllin.ko maxdev=nnn   */
@@ -417,7 +425,7 @@ static void sllin_receive_buf(struct tty_struct *tty,
 {
        struct sllin *sl = (struct sllin *) tty->disc_data;
 
-       pr_debug("sllin: sllin_receive_buf invoked\n");
+       pr_debug("sllin: sllin_receive_buf invoked, count = %u\n", count);
 
        if (!sl || sl->magic != SLLIN_MAGIC || !netif_running(sl->dev))
                return;
@@ -435,6 +443,10 @@ static void sllin_receive_buf(struct tty_struct *tty,
                                if (sl->lin_master == true) {
                                        wake_up(&sl->kwt_wq);
                                        return;
+                               } else {
+                                       sl->rx_cnt = 0;
+                                       sl->rx_expect = SLLIN_BUFF_ID + 1;
+                                       return;
                                }
 
                                cp++;
@@ -444,7 +456,7 @@ static void sllin_receive_buf(struct tty_struct *tty,
 
                if (sl->rx_cnt < SLLIN_BUFF_LEN) {
 #ifndef BREAK_BY_BAUD
-                       /* We didn't receive Break character */
+                       /* We didn't receive Break character -- fake it! */
                        if ((sl->rx_cnt == SLLIN_BUFF_BREAK) && (*cp == 0x55)) {
                                sl->rx_buff[sl->rx_cnt++] = 0x00;
                        }
@@ -454,12 +466,40 @@ 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);
-               pr_debug("sllin: sllin_receive_buf count %d, wakeup\n", sl->rx_cnt);
-       } else {
-               pr_debug("sllin: sllin_receive_buf count %d, waiting\n", sl->rx_cnt);
+       if (sl->lin_master == true) {
+               if (sl->rx_cnt >= sl->rx_expect) {
+                       set_bit(SLF_RXEVENT, &sl->flags);
+                       wake_up(&sl->kwt_wq);
+                       pr_debug("sllin: sllin_receive_buf count %d, wakeup\n", sl->rx_cnt);
+               } else {
+                       pr_debug("sllin: sllin_receive_buf count %d, waiting\n", sl->rx_cnt);
+               }
+       } else { /* LIN slave */
+               int lin_id;
+               struct sllin_conf_entry *sce;
+
+       //      sl->rx_buff[sl->rx_cnt] = *cp++;
+       //      if (sl->rx_cnt == (SLLIN_BUFF_ID + 1)) { /* Received whole header */
+       //              lin_id = sl->rx_buff[sl->rx_cnt] & LIN_ID_MASK;
+       //              sce = &sl->linfr_cache[lin_id];
+
+       //              if (sce->frame_fl & LIN_LOC_SLAVE_CACHE)
+       //                      sl->rx_expect += sce->dlc;
+       //              else
+       //                      sl->rx_expect += 2;//SLLIN_DATA_MAX;
+
+       //              /* Send RTR frame here */
+       //      }
+
+               if (sl->rx_cnt >= sl->rx_expect && sl->rx_cnt > SLLIN_BUFF_DATA) {
+                       sll_bump(sl);
+                       pr_debug("sllin: Received LIN header & LIN response. "
+                               "rx_cnt = %u, rx_expect = %u\n", sl->rx_cnt,
+                               sl->rx_expect);
+                       sl->rx_cnt = 0;
+               }
+
+               sl->rx_cnt++;
        }
 }
 
@@ -1121,11 +1161,12 @@ static int sllin_open(struct tty_struct *tty)
 
        if (!test_bit(SLF_INUSE, &sl->flags)) {
                /* Perform the low-level SLLIN initialization. */
-               sl->lin_master = true;
+               sl->lin_master = master;
 
                sllin_reset_buffs(sl);
 
-               sl->lin_baud  = 19200;
+               sl->lin_baud = (baudrate == 0) ? LIN_DEFAULT_BAUDRATE : baudrate;
+               pr_debug("sllin: Baudrate set to %u\n", sl->lin_baud);
 
                sl->lin_state = SLSTATE_IDLE;