Undo buffer rework for TTY RX
[elmcan.git] / module / elmcan.c
index 07899f7e982dadb94a0d42e58b5597537d741a7a..2fd861d54d1f5c248b0404e490abe4922102ac66 100644 (file)
@@ -60,6 +60,9 @@ MODULE_PARM_DESC(accept_flaky_uart, "Don't bail at the first invalid character.
 #define N_ELMCAN 29
 #endif
 
+#define ELM327_SIZE_RXBUF 256
+#define ELM327_SIZE_TXBUF 32
+
 #define ELM327_CAN_CONFIG_SEND_SFF           0x8000
 #define ELM327_CAN_CONFIG_VARIABLE_DLC       0x4000
 #define ELM327_CAN_CONFIG_RECV_BOTH_SFF_EFF  0x2000
@@ -111,12 +114,12 @@ struct elmcan {
 
        /* TTY TX helpers */
        struct work_struct      tx_work;        /* Flushes TTY TX buffer   */
-       unsigned char           txbuf[32];
+       unsigned char           *txbuf;
        unsigned char           *txhead;        /* Pointer to next TX byte */
        int                     txleft;         /* Bytes left to TX */
 
        /* TTY RX helpers */
-       unsigned char rxbuf[256];
+       unsigned char rxbuf[ELM327_SIZE_RXBUF];
        int rxfill;
 
        /* State machine */
@@ -156,11 +159,11 @@ static inline void elm327_hw_failure(struct elmcan *elm);
 
 
 
- /************************************************************************
-  *            ELM327: Transmission                            *
-  *                                                            *
-  * (all functions assume elm->lock taken)                     *
-  ************************************************************************/
+ /***********************************************************************
+  *            ELM327: Transmission                                    *
+  *                                                                    *
+  * (all functions assume elm->lock taken)                             *
+  ***********************************************************************/
 
 static void elm327_send(struct elmcan *elm, const void *buf, size_t len)
 {
@@ -247,11 +250,11 @@ static void elm327_send_frame(struct elmcan *elm, struct can_frame *frame)
 
 
 
- /************************************************************************
-  *            ELM327: Initialization sequence                 *
-  *                                                            *
-  * (assumes elm->lock taken)                                  *
-  ************************************************************************/
+ /***********************************************************************
+  *            ELM327: Initialization sequence                         *
+  *                                                                    *
+  * (assumes elm->lock taken)                                          *
+  ***********************************************************************/
 
 static char *elm327_init_script[] = {
        "AT WS\r",        /* v1.0: Warm Start */
@@ -305,11 +308,11 @@ static void elm327_init(struct elmcan *elm)
 
 
 
- /************************************************************************
-  *            ELM327: Reception -> netdev glue                *
-  *                                                            *
-  * (assumes elm->lock taken)                                  *
-  ************************************************************************/
+ /***********************************************************************
+  *            ELM327: Reception -> netdev glue                        *
+  *                                                                    *
+  * (assumes elm->lock taken)                                          *
+  ***********************************************************************/
 
 static void elm327_feed_frame_to_netdev(struct elmcan *elm,
                                        const struct can_frame *frame)
@@ -336,11 +339,11 @@ static void elm327_feed_frame_to_netdev(struct elmcan *elm,
 
 
 
- /************************************************************************
-  *            ELM327: "Panic" handler                         *
-  *                                                            *
-  * (assumes elm->lock taken)                                  *
-  ************************************************************************/
+ /***********************************************************************
+  *            ELM327: "Panic" handler                                 *
+  *                                                                    *
+  * (assumes elm->lock taken)                                          *
+  ***********************************************************************/
 
 /* Called when we're out of ideas and just want it all to end. */
 static inline void elm327_hw_failure(struct elmcan *elm)
@@ -363,11 +366,11 @@ static inline void elm327_hw_failure(struct elmcan *elm)
 
 
 
- /************************************************************************
-  *            ELM327: Reception parser                        *
-  *                                                            *
-  * (assumes elm->lock taken)                                  *
-  ************************************************************************/
+ /***********************************************************************
+  *            ELM327: Reception parser                                *
+  *                                                                    *
+  * (assumes elm->lock taken)                                          *
+  ***********************************************************************/
 
 static void elm327_parse_error(struct elmcan *elm, int len)
 {
@@ -687,7 +690,7 @@ static bool elm327_is_ready_char(char c)
 
 static void elm327_drop_bytes(struct elmcan *elm, int i)
 {
-       memmove(&elm->rxbuf[0], &elm->rxbuf[i], sizeof(elm->rxbuf) - i);
+       memmove(&elm->rxbuf[0], &elm->rxbuf[i], ELM327_SIZE_RXBUF - i);
        elm->rxfill -= i;
 }
 
@@ -739,7 +742,7 @@ static void elm327_parse_rxbuf(struct elmcan *elm)
                        /* empty loop */
                }
 
-               if (len == sizeof(elm->rxbuf)) {
+               if (len == ELM327_SIZE_RXBUF) {
                        /* Line exceeds buffer. It's probably all garbage.
                         * Did we even connect at the right baud rate?
                         */
@@ -781,11 +784,11 @@ static void elm327_parse_rxbuf(struct elmcan *elm)
 
 
 
- /************************************************************************
-  *            netdev                                          *
-  *                                                            *
-  * (takes elm->lock)                                          *
-  ************************************************************************/
+ /***********************************************************************
+  *            netdev                                                  *
+  *                                                                    *
+  * (takes elm->lock)                                                  *
+  ***********************************************************************/
 
 static int elmcan_netdev_open(struct net_device *dev)
 {
@@ -909,11 +912,11 @@ static const struct net_device_ops elmcan_netdev_ops = {
 
 
 
- /************************************************************************
-  *            Line discipline                                 *
-  *                                                            *
-  * (takes elm->lock)                                          *
-  ************************************************************************/
+ /***********************************************************************
+  *            Line discipline                                         *
+  *                                                                    *
+  * (takes elm->lock)                                                  *
+  ***********************************************************************/
 
 /* Get a reference to our struct, taking into account locks/refcounts.
  * This is to ensure ordering in case we are shutting down, and to ensure
@@ -984,7 +987,7 @@ static void elmcan_ldisc_rx(struct tty_struct *tty,
                goto out;
        }
 
-       while (count-- && elm->rxfill < sizeof(elm->rxbuf)) {
+       while (count-- && elm->rxfill < ELM327_SIZE_RXBUF) {
                if (fp && *fp++) {
                        netdev_err(elm->dev, "Error in received character stream. Check your wiring.");
 
@@ -1137,6 +1140,12 @@ static int elmcan_ldisc_open(struct tty_struct *tty)
                return -ENFILE;
        elm = netdev_priv(dev);
 
+       elm->txbuf = kmalloc(ELM327_SIZE_TXBUF, GFP_KERNEL);
+       if (!elm->txbuf) {
+               err = -ENOMEM;
+               goto out_err;
+       }
+
        /* Configure TTY interface */
        tty->receive_room = 65536; /* We don't flow control */
        elm->txleft = 0; /* Clear TTY TX buffer */
@@ -1163,14 +1172,18 @@ static int elmcan_ldisc_open(struct tty_struct *tty)
 
        /* Let 'er rip */
        err = register_candev(elm->dev);
-       if (err) {
-               free_candev(elm->dev);
-               return err;
-       }
+       if (err)
+               goto out_err;
 
        netdev_info(elm->dev, "elmcan on %s.\n", tty->name);
 
        return 0;
+
+out_err:
+       if (elm->txbuf)
+               kfree(elm->txbuf);
+       free_candev(elm->dev);
+       return err;
 }
 
 /* Close down an elmcan channel.
@@ -1212,6 +1225,7 @@ static void elmcan_ldisc_close(struct tty_struct *tty)
 
        netdev_info(elm->dev, "elmcan off %s.\n", tty->name);
 
+       kfree(elm->txbuf);
        free_candev(elm->dev);
 }