Restore WAKEUP set_bit vs. write() order in elm327_send()
[elmcan.git] / module / elmcan.c
index 7707c4d4c04fdae1cfc8173e84b77cc2df46c84a..e2d616f2b5c631666fb44363d4bbde528a339fd9 100644 (file)
@@ -92,18 +92,18 @@ struct elmcan {
        u8 rxbuf[ELM327_SIZE_RXBUF];
        u8 txbuf[ELM327_SIZE_TXBUF] ____cacheline_aligned;
 
-       /* TTY buffer accounting */
-       struct work_struct tx_work;     /* Flushes TTY TX buffer */
-       u8 *txhead;                     /* Next TX byte */
-       unsigned txleft;                /* Bytes left to TX */
-       int rxfill;                     /* Bytes already RX'd in buffer */
+       /* Per-channel lock */
+       spinlock_t lock;
 
        /* TTY and netdev devices that we're bridging */
        struct tty_struct *tty;
        struct net_device *dev;
 
-       /* Per-channel lock */
-       spinlock_t lock;
+       /* TTY buffer accounting */
+       struct work_struct tx_work;     /* Flushes TTY TX buffer */
+       u8 *txhead;                     /* Next TX byte */
+       size_t txleft;                  /* Bytes left to TX */
+       int rxfill;                     /* Bytes already RX'd in buffer */
 
        /* State machine */
        enum {
@@ -148,6 +148,15 @@ static void elm327_send(struct elmcan *elm, const void *buf, size_t len)
 
        memcpy(elm->txbuf, buf, len);
 
+       /* 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, &elm->tty->flags);
        written = elm->tty->ops->write(elm->tty, elm->txbuf, len);
        if (written < 0) {
                netdev_err(elm->dev,
@@ -159,9 +168,6 @@ static void elm327_send(struct elmcan *elm, const void *buf, size_t len)
 
        elm->txleft = len - written;
        elm->txhead = elm->txbuf + written;
-
-       if (elm->txleft)
-               set_bit(TTY_DO_WRITE_WAKEUP, &elm->tty->flags);
 }
 
 /* Take the ELM327 out of almost any state and back into command mode.
@@ -303,6 +309,8 @@ static inline void elm327_uart_side_failure(struct elmcan *elm)
 
        elm->uart_side_failure = true;
 
+       clear_bit(TTY_DO_WRITE_WAKEUP, &elm->tty->flags);
+
        elm->can.can_stats.bus_off++;
        netif_stop_queue(elm->dev);
        elm->can.state = CAN_STATE_BUS_OFF;
@@ -571,7 +579,7 @@ static void elm327_handle_prompt(struct elmcan *elm)
                elm->state = ELM327_STATE_RECEIVING;
 
                /* We will be in the default state once this command is
-                * send, so enable the TX packet queue.
+                * sent, so enable the TX packet queue.
                 */
                netif_wake_queue(elm->dev);
 
@@ -650,7 +658,7 @@ static void elm327_handle_prompt(struct elmcan *elm)
                elm->state = ELM327_STATE_RECEIVING;
 
                /* We will be in the default state once this command is
-                * send, so enable the TX packet queue.
+                * sent, so enable the TX packet queue.
                 */
                netif_wake_queue(elm->dev);
        }