]> git.ozlabs.org Git - ppp.git/blobdiff - linux/ppp.c
update for 2.3.11
[ppp.git] / linux / ppp.c
index aa0ebc54a9fb7677e4045f80810abd357a530ca7..0fa98fd1eebffd00101716061106ed3f8a0f342a 100644 (file)
@@ -4,7 +4,7 @@
  *  Al Longyear <longyear@netcom.com>
  *  Extensively rewritten by Paul Mackerras <paulus@cs.anu.edu.au>
  *
- *  ==FILEVERSION 990331==
+ *  ==FILEVERSION 990910==
  *
  *  NOTE TO MAINTAINERS:
  *     If you modify this file at all, please set the number above to the
@@ -45,7 +45,7 @@
 
 #define PPP_MAX_RCV_QLEN       32      /* max # frames we queue up for pppd */
 
-/* $Id: ppp.c,v 1.24 1999/03/31 06:07:57 paulus Exp $ */
+/* $Id: ppp.c,v 1.33 1999/12/23 01:48:45 paulus Exp $ */
 
 #include <linux/version.h>
 #include <linux/config.h>
 #endif
 
 #undef PPP_VERSION
-#define PPP_VERSION    "2.3.7"
+#define PPP_VERSION    "2.3.11"
 
 #if LINUX_VERSION_CODE >= VERSION(2,1,4)
 
@@ -174,14 +174,16 @@ typedef size_t            rw_count_t;
 #define SUSER()                capable(CAP_NET_ADMIN)
 #endif
 
+#if LINUX_VERSION_CODE < VERSION(2,2,0)
+#define wmb()          mb()
+#endif
+
 /*
  * Local functions
  */
 
-#ifdef CONFIG_MODULES
 static int ppp_register_compressor (struct compressor *cp);
 static void ppp_unregister_compressor (struct compressor *cp);
-#endif
 
 static void ppp_async_init(struct ppp *ppp);
 static void ppp_async_release(struct ppp *ppp);
@@ -190,6 +192,7 @@ static int ppp_tty_push(struct ppp *ppp);
 static int ppp_async_encode(struct ppp *ppp);
 static int ppp_async_send(struct ppp *, struct sk_buff *);
 static int ppp_sync_send(struct ppp *, struct sk_buff *);
+static void ppp_tty_flush_output(struct ppp *);
 
 static int ppp_ioctl(struct ppp *, unsigned int, unsigned long);
 static int ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp);
@@ -338,6 +341,9 @@ __u16 ppp_crc16_table[256] =
        0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
        0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
 };
+#if LINUX_VERSION_CODE >= VERSION(2,1,18)
+EXPORT_SYMBOL(ppp_crc16_table);
+#endif
 
 #ifdef CHECK_CHARACTERS
 static __u32 paritytab[8] =
@@ -552,6 +558,7 @@ ppp_tty_close (struct tty_struct *tty)
                ppp->tty = ppp->backup_tty;
                if (ppp_tty_push(ppp))
                        ppp_output_wakeup(ppp);
+               wake_up_interruptible(&ppp->read_wait);
        } else {
                ppp->tty = 0;
                ppp->sc_xfer = 0;
@@ -831,6 +838,21 @@ ppp_tty_ioctl (struct tty_struct *tty, struct file * file,
                error = n_tty_ioctl (tty, file, param2, param3);
                break;
 
+       case TCFLSH:
+               /*
+                * Flush our buffers, then call the generic code to
+                * flush the serial port's buffer.
+                */
+               if (param3 == TCIFLUSH || param3 == TCIOFLUSH) {
+                       struct sk_buff *skb;
+                       while ((skb = skb_dequeue(&ppp->rcv_q)) != NULL)
+                               KFREE_SKB(skb);
+               }
+               if (param3 == TCIOFLUSH || param3 == TCOFLUSH)
+                       ppp_tty_flush_output(ppp);
+               error = n_tty_ioctl (tty, file, param2, param3);
+               break;
+
        case FIONREAD:
                /*
                 * Returns how many bytes are available for a read().
@@ -1035,7 +1057,7 @@ ppp_tty_sync_push(struct ppp *ppp)
        save_flags(flags);
        cli();
        if (ppp->tty_pushing) {
-               /* record wakeup attempt so we don't loose */
+               /* record wakeup attempt so we don't lose */
                /* a wakeup call while doing push processing */
                ppp->woke_up=1;
                restore_flags(flags);
@@ -1118,16 +1140,20 @@ ppp_tty_push(struct ppp *ppp)
        int avail, sent, done = 0;
        struct tty_struct *tty = ppp2tty(ppp);
        
-       if ( ppp->flags & SC_SYNC 
+       if (ppp->flags & SC_SYNC
                return ppp_tty_sync_push(ppp);
 
        CHECK_PPP(0);
-       if (ppp->tty_pushing)
+       if (ppp->tty_pushing) {
+               ppp->woke_up = 1;
                return 0;
+       }
        if (tty == NULL || tty->disc_data != (void *) ppp)
                goto flush;
        while (ppp->optr < ppp->olim || ppp->tpkt != 0) {
                ppp->tty_pushing = 1;
+               mb();
+               ppp->woke_up = 0;
                avail = ppp->olim - ppp->optr;
                if (avail > 0) {
                        tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
@@ -1137,18 +1163,24 @@ ppp_tty_push(struct ppp *ppp)
                        ppp->stats.ppp_obytes += sent;
                        ppp->optr += sent;
                        if (sent < avail) {
+                               wmb();
                                ppp->tty_pushing = 0;
+                               mb();
+                               if (ppp->woke_up)
+                                       continue;
                                return done;
                        }
                }
                if (ppp->tpkt != 0)
                        done = ppp_async_encode(ppp);
+               wmb();
                ppp->tty_pushing = 0;
        }
        return done;
 
 flush:
        ppp->tty_pushing = 1;
+       mb();
        ppp->stats.ppp_oerrors++;
        if (ppp->tpkt != 0) {
                KFREE_SKB(ppp->tpkt);
@@ -1156,6 +1188,7 @@ flush:
                done = 1;
        }
        ppp->optr = ppp->olim;
+       wmb();
        ppp->tty_pushing = 0;
        return done;
 }
@@ -1269,6 +1302,32 @@ ppp_async_encode(struct ppp *ppp)
        return 0;
 }
 
+/*
+ * Flush output from our internal buffers.
+ * Called for the TCFLSH ioctl.
+ */
+static void
+ppp_tty_flush_output(struct ppp *ppp)
+{
+       struct sk_buff *skb;
+       int done = 0;
+
+       while ((skb = skb_dequeue(&ppp->xmt_q)) != NULL)
+               KFREE_SKB(skb);
+       ppp->tty_pushing = 1;
+       mb();
+       ppp->optr = ppp->olim;
+       if (ppp->tpkt != NULL) {
+               KFREE_SKB(ppp->tpkt);
+               ppp->tpkt = 0;
+               done = 1;
+       }
+       wmb();
+       ppp->tty_pushing = 0;
+       if (done)
+               ppp_output_wakeup(ppp);
+}
+
 /*
  * Callback function from tty driver. Return the amount of space left
  * in the receiver's buffer to decide if remote transmitter is to be
@@ -1904,6 +1963,9 @@ ppp_ioctl(struct ppp *ppp, unsigned int param2, unsigned long param3)
                        break;
 
                switch (npi.protocol) {
+               case PPP_IPV6:
+                       npi.protocol = NP_IPV6;
+                       break;
                case PPP_IP:
                        npi.protocol = NP_IP;
                        break;
@@ -3190,7 +3252,6 @@ static struct compressor *find_compressor (int type)
        return (struct compressor *) 0;
 }
 
-#ifdef CONFIG_MODULES
 static int ppp_register_compressor (struct compressor *cp)
 {
        struct compressor_link *new;
@@ -3243,7 +3304,6 @@ static void ppp_unregister_compressor (struct compressor *cp)
        }
        restore_flags(flags);
 }
-#endif
 
 /*************************************************************
  * Module support routines